Commit 574aba77 authored by gotzenx's avatar gotzenx Committed by GitHub

feat: SuperchainWETH redesign (#12514)

* feat: SuperchainWETH redesign (#101)

* feat: add superchain erc20 bridge (#61)

* feat: add superchain erc20 bridge

* fix: interfaces and versions

* refactor: optimism superchain erc20 redesign (#62)

* refactor: use oz upgradeable erc20 as dependency

* chore: update interfaces

* fix: tests based on changes

* refactor: remove op as dependency

* feat: add check for supererc20 bridge on modifier

* chore: update tests and interfaces

* chore: update stack vars name on test

* chore: remove empty gitmodules file

* chore: update superchain weth errors

* test: add superchain erc20 bridge tests (#65)

* test: add superchain erc20 bridge tests

* test: add optimism superchain erc20 beacon tests

* test: remove unnecessary test

* test: tests fixes

* test: tests fixes

* chore: update missing bridge on natspec (#69)

* chore: update missing bridge on natspec

* fix: natspecs

---------
Co-authored-by: default avataragusduha <agusnduha@gmail.com>

* fix: remove superchain erc20 base (#70)

* refactor: update isuperchainweth (#71)


---------
Co-authored-by: default avataragusduha <agusnduha@gmail.com>

* feat: rename mint/burn and add SuperchainERC20 (#74)

* refactor: rename mint and burn functions on superchain erc20

* chore: rename optimism superchain erc20 to superchain erc20

* feat: create optimism superchain erc20 contract

* chore: update natspec and errors

* fix: superchain erc20 tests

* refactor: make superchain erc20 abstract

* refactor: move storage and erc20 metadata functions to implementation

* chore: update interfaces

* chore: update superchain erc20 events

* fix: tests

* fix: natspecs

* fix: add semmver lock and snapshots

* fix: remove unused imports

* fix: natspecs

---------
Co-authored-by: default avatar0xDiscotech <131301107+0xDiscotech@users.noreply.github.com>

* fix: refactor zero check (#76)

* fix: pre pr

* fix: semver natspec check failure (#79)

* fix: semver natspec check failure

* fix: ignore mock contracts in semver natspec script

* fix: error message

* feat: add crosschain erc20 interface (#80)

* feat: add crosschain erc20 interface

* fix: refactor interfaces

* fix: superchain bridge natspec (#83)

* fix: superchain weth natspec (#84)
Co-authored-by: default avatar0xng <ng@defi.sucks>
Co-authored-by: default avatar0xParticle <particle@defi.sucks>
Co-authored-by: default avatargotzenx <78360669+gotzenx@users.noreply.github.com>

* fix: stop inheriting superchain interfaces (#85)

* fix: stop inheriting superchain interfaces

* fix: move events and erros into the implementation

* fix: make superchainERC20 inherits from crosschainERC20

* fix: superchain bridge rename (#86)

* fix: fee vault compiler error (#87)

* fix: remove unused imports

* fix: refactor common errors (#90)

* fix: refactor common errors

* fix: remove unused version

* fix: reuse unauthorized error (#92)

* fix: superchain erc20 factory conflicts

* fix: rename crosschain functions (#94)

* feat: superweth redesign

* fix: pr fixes

* fix: fixes post merge

---------
Co-authored-by: default avatarDisco <131301107+0xDiscotech@users.noreply.github.com>
Co-authored-by: default avatar0xng <ng@defi.sucks>
Co-authored-by: default avatar0xParticle <particle@defi.sucks>
Co-authored-by: default avatargotzenx <78360669+gotzenx@users.noreply.github.com>

* fix: SuperchainWETH redesign fixes (#110)

* fix: superchainWETH redesign fixes

* fix: withdraw arg

* fix: fix revert in SuperchainWETH tests (#112)

---------
Co-authored-by: default avatarAgusDuha <81362284+agusduha@users.noreply.github.com>
Co-authored-by: default avatarDisco <131301107+0xDiscotech@users.noreply.github.com>
Co-authored-by: default avatar0xng <ng@defi.sucks>
Co-authored-by: default avatar0xParticle <particle@defi.sucks>
Co-authored-by: default avataragusduha <agusnduha@gmail.com>
parent 76beff3d
...@@ -132,8 +132,8 @@ ...@@ -132,8 +132,8 @@
"sourceCodeHash": "0x4f539e9d9096d31e861982b8f751fa2d7de0849590523375cf92e175294d1036" "sourceCodeHash": "0x4f539e9d9096d31e861982b8f751fa2d7de0849590523375cf92e175294d1036"
}, },
"src/L2/SuperchainWETH.sol": { "src/L2/SuperchainWETH.sol": {
"initCodeHash": "0x50f6ea9bfe650fcf792e98e44b1bf66c036fd0e6d4b753da680253d7d8609816", "initCodeHash": "0x09c7efed7d6c8ae5981f6e7a75c7b8c675f73d679265d15a010844ad9b41fa9b",
"sourceCodeHash": "0x82d03262decf52d5954d40bca8703f96a0f3ba7accf6c1d75292856c2f34cf8f" "sourceCodeHash": "0x8d7612a71deaadfb324c4136673df96019211292ff54494fa4b7724e2e5dd22a"
}, },
"src/L2/WETH.sol": { "src/L2/WETH.sol": {
"initCodeHash": "0xfb253765520690623f177941c2cd9eba23e4c6d15063bccdd5e98081329d8956", "initCodeHash": "0xfb253765520690623f177941c2cd9eba23e4c6d15063bccdd5e98081329d8956",
......
...@@ -74,6 +74,42 @@ ...@@ -74,6 +74,42 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
}
],
"name": "crosschainBurn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
}
],
"name": "crosschainMint",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "decimals", "name": "decimals",
...@@ -107,52 +143,6 @@ ...@@ -107,52 +143,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "dst",
"type": "address"
},
{
"internalType": "uint256",
"name": "wad",
"type": "uint256"
}
],
"name": "relayERC20",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "dst",
"type": "address"
},
{
"internalType": "uint256",
"name": "wad",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "chainId",
"type": "uint256"
}
],
"name": "sendERC20",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "symbol", "name": "symbol",
...@@ -249,7 +239,7 @@ ...@@ -249,7 +239,7 @@
"inputs": [ "inputs": [
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "wad", "name": "_amount",
"type": "uint256" "type": "uint256"
} }
], ],
...@@ -289,28 +279,22 @@ ...@@ -289,28 +279,22 @@
{ {
"indexed": true, "indexed": true,
"internalType": "address", "internalType": "address",
"name": "dst", "name": "from",
"type": "address" "type": "address"
}, },
{ {
"indexed": false, "indexed": false,
"internalType": "uint256", "internalType": "uint256",
"name": "wad", "name": "amount",
"type": "uint256" "type": "uint256"
} }
], ],
"name": "Deposit", "name": "CrosschainBurnt",
"type": "event" "type": "event"
}, },
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{ {
"indexed": true, "indexed": true,
"internalType": "address", "internalType": "address",
...@@ -322,15 +306,9 @@ ...@@ -322,15 +306,9 @@
"internalType": "uint256", "internalType": "uint256",
"name": "amount", "name": "amount",
"type": "uint256" "type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "source",
"type": "uint256"
} }
], ],
"name": "RelayERC20", "name": "CrosschainMinted",
"type": "event" "type": "event"
}, },
{ {
...@@ -339,29 +317,17 @@ ...@@ -339,29 +317,17 @@
{ {
"indexed": true, "indexed": true,
"internalType": "address", "internalType": "address",
"name": "from", "name": "dst",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address" "type": "address"
}, },
{ {
"indexed": false, "indexed": false,
"internalType": "uint256", "internalType": "uint256",
"name": "amount", "name": "wad",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "destination",
"type": "uint256" "type": "uint256"
} }
], ],
"name": "SendERC20", "name": "Deposit",
"type": "event" "type": "event"
}, },
{ {
...@@ -410,17 +376,12 @@ ...@@ -410,17 +376,12 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "CallerNotL2ToL2CrossDomainMessenger", "name": "NotCustomGasToken",
"type": "error"
},
{
"inputs": [],
"name": "InvalidCrossDomainSender",
"type": "error" "type": "error"
}, },
{ {
"inputs": [], "inputs": [],
"name": "NotCustomGasToken", "name": "Unauthorized",
"type": "error" "type": "error"
} }
] ]
\ No newline at end of file
...@@ -9,10 +9,10 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; ...@@ -9,10 +9,10 @@ import { Predeploys } from "src/libraries/Predeploys.sol";
// Interfaces // Interfaces
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol";
import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; import { IL1Block } from "src/L2/interfaces/IL1Block.sol";
import { IETHLiquidity } from "src/L2/interfaces/IETHLiquidity.sol"; import { IETHLiquidity } from "src/L2/interfaces/IETHLiquidity.sol";
import { ISuperchainWETH } from "src/L2/interfaces/ISuperchainWETH.sol"; import { ICrosschainERC20 } from "src/L2/interfaces/ICrosschainERC20.sol";
import { Unauthorized, NotCustomGasToken } from "src/libraries/errors/CommonErrors.sol";
/// @custom:proxied true /// @custom:proxied true
/// @custom:predeploy 0x4200000000000000000000000000000000000024 /// @custom:predeploy 0x4200000000000000000000000000000000000024
...@@ -20,10 +20,10 @@ import { ISuperchainWETH } from "src/L2/interfaces/ISuperchainWETH.sol"; ...@@ -20,10 +20,10 @@ import { ISuperchainWETH } from "src/L2/interfaces/ISuperchainWETH.sol";
/// @notice SuperchainWETH is a version of WETH that can be freely transfrered between chains /// @notice SuperchainWETH is a version of WETH that can be freely transfrered between chains
/// within the superchain. SuperchainWETH can be converted into native ETH on chains that /// within the superchain. SuperchainWETH can be converted into native ETH on chains that
/// do not use a custom gas token. /// do not use a custom gas token.
contract SuperchainWETH is WETH98, ISuperchainWETH, ISemver { contract SuperchainWETH is WETH98, ICrosschainERC20, ISemver {
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 1.0.0-beta.6 /// @custom:semver 1.0.0-beta.7
string public constant version = "1.0.0-beta.6"; string public constant version = "1.0.0-beta.7";
/// @inheritdoc WETH98 /// @inheritdoc WETH98
function deposit() public payable override { function deposit() public payable override {
...@@ -32,68 +32,56 @@ contract SuperchainWETH is WETH98, ISuperchainWETH, ISemver { ...@@ -32,68 +32,56 @@ contract SuperchainWETH is WETH98, ISuperchainWETH, ISemver {
} }
/// @inheritdoc WETH98 /// @inheritdoc WETH98
function withdraw(uint256 wad) public override { function withdraw(uint256 _amount) public override {
if (IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) revert NotCustomGasToken(); if (IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) revert NotCustomGasToken();
super.withdraw(wad); super.withdraw(_amount);
} }
/// @inheritdoc ISuperchainWETH /// @notice Mints WETH to an address.
function sendERC20(address dst, uint256 wad, uint256 chainId) public { /// @param _to The address to mint WETH to.
// Burn from user's balance. /// @param _amount The amount of WETH to mint.
_burn(msg.sender, wad); function _mint(address _to, uint256 _amount) internal {
balanceOf[_to] += _amount;
// Burn to ETHLiquidity contract. emit Transfer(address(0), _to, _amount);
if (!IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) { }
IETHLiquidity(Predeploys.ETH_LIQUIDITY).burn{ value: wad }();
}
// Send message to other chain.
IL2ToL2CrossDomainMessenger(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER).sendMessage({
_destination: chainId,
_target: address(this),
_message: abi.encodeCall(this.relayERC20, (msg.sender, dst, wad))
});
// Emit event. /// @notice Burns WETH from an address.
emit SendERC20(msg.sender, dst, wad, chainId); /// @param _from The address to burn WETH from.
/// @param _amount The amount of WETH to burn.
function _burn(address _from, uint256 _amount) internal {
balanceOf[_from] -= _amount;
emit Transfer(_from, address(0), _amount);
} }
/// @inheritdoc ISuperchainWETH /// @notice Allows the SuperchainTokenBridge to mint tokens.
function relayERC20(address from, address dst, uint256 wad) external { /// @param _to Address to mint tokens to.
// Receive message from other chain. /// @param _amount Amount of tokens to mint.
IL2ToL2CrossDomainMessenger messenger = IL2ToL2CrossDomainMessenger(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER); function crosschainMint(address _to, uint256 _amount) external {
if (msg.sender != address(messenger)) revert CallerNotL2ToL2CrossDomainMessenger(); if (msg.sender != Predeploys.SUPERCHAIN_TOKEN_BRIDGE) revert Unauthorized();
if (messenger.crossDomainMessageSender() != address(this)) revert InvalidCrossDomainSender();
_mint(_to, _amount);
// Mint from ETHLiquidity contract. // Mint from ETHLiquidity contract.
if (!IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) { if (!IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) {
IETHLiquidity(Predeploys.ETH_LIQUIDITY).mint(wad); IETHLiquidity(Predeploys.ETH_LIQUIDITY).mint(_amount);
} }
// Get source chain ID. emit CrosschainMinted(_to, _amount);
uint256 source = messenger.crossDomainMessageSource(); }
// Mint to user's balance. /// @notice Allows the SuperchainTokenBridge to burn tokens.
_mint(dst, wad); /// @param _from Address to burn tokens from.
/// @param _amount Amount of tokens to burn.
function crosschainBurn(address _from, uint256 _amount) external {
if (msg.sender != Predeploys.SUPERCHAIN_TOKEN_BRIDGE) revert Unauthorized();
// Emit event. _burn(_from, _amount);
emit RelayERC20(from, dst, wad, source);
}
/// @notice Mints WETH to an address. // Burn to ETHLiquidity contract.
/// @param guy The address to mint WETH to. if (!IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) {
/// @param wad The amount of WETH to mint. IETHLiquidity(Predeploys.ETH_LIQUIDITY).burn{ value: _amount }();
function _mint(address guy, uint256 wad) internal { }
balanceOf[guy] += wad;
emit Transfer(address(0), guy, wad);
}
/// @notice Burns WETH from an address. emit CrosschainBurnt(_from, _amount);
/// @param guy The address to burn WETH from.
/// @param wad The amount of WETH to burn.
function _burn(address guy, uint256 wad) internal {
require(balanceOf[guy] >= wad);
balanceOf[guy] -= wad;
emit Transfer(guy, address(0), wad);
} }
} }
...@@ -2,43 +2,12 @@ ...@@ -2,43 +2,12 @@
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { IWETH } from "src/universal/interfaces/IWETH.sol"; import { IWETH } from "src/universal/interfaces/IWETH.sol";
import { ICrosschainERC20 } from "src/L2/interfaces/ICrosschainERC20.sol";
import { ISemver } from "src/universal/interfaces/ISemver.sol";
interface ISuperchainWETH { interface ISuperchainWETH is IWETH, ICrosschainERC20, ISemver {
/// @notice Thrown when attempting a deposit or withdrawal and the chain uses a custom gas token. error Unauthorized();
error NotCustomGasToken(); error NotCustomGasToken();
/// @notice Thrown when attempting to relay a message and the function caller (msg.sender) is not function __constructor__() external;
/// L2ToL2CrossDomainMessenger.
error CallerNotL2ToL2CrossDomainMessenger();
/// @notice Thrown when attempting to relay a message and the cross domain message sender is not `address(this)`
error InvalidCrossDomainSender();
/// @notice Emitted whenever tokens are successfully relayed on this chain.
/// @param from Address of the msg.sender of sendERC20 on the source chain.
/// @param to Address of the recipient.
/// @param amount Amount of tokens relayed.
/// @param source Chain ID of the source chain.
event RelayERC20(address indexed from, address indexed to, uint256 amount, uint256 source);
/// @notice Emitted when tokens are sent from one chain to another.
/// @param from Address of the sender.
/// @param to Address of the recipient.
/// @param amount Number of tokens sent.
/// @param destination Chain ID of the destination chain.
event SendERC20(address indexed from, address indexed to, uint256 amount, uint256 destination);
/// @notice Sends tokens to some target address on another chain.
/// @param _dst Address to send tokens to.
/// @param _wad Amount of tokens to send.
/// @param _chainId Chain ID of the destination chain.
function sendERC20(address _dst, uint256 _wad, uint256 _chainId) external;
/// @notice Relays tokens received from another chain.
/// @param _from Address of the msg.sender of sendERC20 on the source chain.
/// @param _dst Address to relay tokens to.
/// @param _wad Amount of tokens to relay.
function relayERC20(address _from, address _dst, uint256 _wad) external;
} }
interface ISuperchainWETHERC20 is IWETH, ISuperchainWETH { }
...@@ -6,22 +6,12 @@ import { StdUtils } from "forge-std/Test.sol"; ...@@ -6,22 +6,12 @@ import { StdUtils } from "forge-std/Test.sol";
import { Vm } from "forge-std/Vm.sol"; import { Vm } from "forge-std/Vm.sol";
import { CommonTest } from "test/setup/CommonTest.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
// Libraries
import { Predeploys } from "src/libraries/Predeploys.sol";
// Interfaces // Interfaces
import { ISuperchainWETHERC20 } from "src/L2/interfaces/ISuperchainWETH.sol"; import { ISuperchainWETH } from "src/L2/interfaces/ISuperchainWETH.sol";
import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol";
/// @title SuperchainWETH_User /// @title SuperchainWETH_User
/// @notice Actor contract that interacts with the SuperchainWETH contract. /// @notice Actor contract that interacts with the SuperchainWETH contract.
contract SuperchainWETH_User is StdUtils { contract SuperchainWETH_User is StdUtils {
/// @notice Cross domain message data.
struct MessageData {
bytes32 id;
uint256 amount;
}
/// @notice Flag to indicate if the test has failed. /// @notice Flag to indicate if the test has failed.
bool public failed = false; bool public failed = false;
...@@ -29,18 +19,12 @@ contract SuperchainWETH_User is StdUtils { ...@@ -29,18 +19,12 @@ contract SuperchainWETH_User is StdUtils {
Vm internal vm; Vm internal vm;
/// @notice The SuperchainWETH contract. /// @notice The SuperchainWETH contract.
ISuperchainWETHERC20 internal weth; ISuperchainWETH internal weth;
/// @notice Mapping of sent messages.
mapping(bytes32 => bool) internal sent;
/// @notice Array of unrelayed messages.
MessageData[] internal unrelayed;
/// @param _vm The Vm contract. /// @param _vm The Vm contract.
/// @param _weth The SuperchainWETH contract. /// @param _weth The SuperchainWETH contract.
/// @param _balance The initial balance of the contract. /// @param _balance The initial balance of the contract.
constructor(Vm _vm, ISuperchainWETHERC20 _weth, uint256 _balance) { constructor(Vm _vm, ISuperchainWETH _weth, uint256 _balance) {
vm = _vm; vm = _vm;
weth = _weth; weth = _weth;
vm.deal(address(this), _balance); vm.deal(address(this), _balance);
...@@ -76,72 +60,6 @@ contract SuperchainWETH_User is StdUtils { ...@@ -76,72 +60,6 @@ contract SuperchainWETH_User is StdUtils {
failed = true; failed = true;
} }
} }
/// @notice Send ERC20 tokens to another chain.
/// @param _amount The amount of ERC20 tokens to send.
/// @param _chainId The chain ID to send the tokens to.
/// @param _messageId The message ID.
function sendERC20(uint256 _amount, uint256 _chainId, bytes32 _messageId) public {
// Make sure we aren't reusing a message ID.
if (sent[_messageId]) {
return;
}
// Bound send amount to our WETH balance.
_amount = bound(_amount, 0, weth.balanceOf(address(this)));
// Prevent receiving chain ID from being the same as the current chain ID.
_chainId = _chainId == block.chainid ? _chainId + 1 : _chainId;
// Send the amount.
try weth.sendERC20(address(this), _amount, _chainId) {
// Success.
} catch {
failed = true;
}
// Mark message as sent.
sent[_messageId] = true;
unrelayed.push(MessageData({ id: _messageId, amount: _amount }));
}
/// @notice Relay a message from another chain.
function relayMessage(uint256 _source) public {
// Make sure there are unrelayed messages.
if (unrelayed.length == 0) {
return;
}
// Grab the latest unrelayed message.
MessageData memory message = unrelayed[unrelayed.length - 1];
// Simulate the cross-domain message.
// Make sure the cross-domain message sender is set to this contract.
vm.mockCall(
Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER,
abi.encodeCall(IL2ToL2CrossDomainMessenger.crossDomainMessageSender, ()),
abi.encode(address(weth))
);
// Simulate the cross-domain message source to any chain.
vm.mockCall(
Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER,
abi.encodeCall(IL2ToL2CrossDomainMessenger.crossDomainMessageSource, ()),
abi.encode(_source)
);
// Prank the relayERC20 function.
// Balance will just go back to our own account.
vm.prank(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER);
try weth.relayERC20(address(this), address(this), message.amount) {
// Success.
} catch {
failed = true;
}
// Remove the message from the unrelayed list.
unrelayed.pop();
}
} }
/// @title SuperchainWETH_SendSucceeds_Invariant /// @title SuperchainWETH_SendSucceeds_Invariant
...@@ -167,11 +85,9 @@ contract SuperchainWETH_SendSucceeds_Invariant is CommonTest { ...@@ -167,11 +85,9 @@ contract SuperchainWETH_SendSucceeds_Invariant is CommonTest {
targetContract(address(actor)); targetContract(address(actor));
// Set the target selectors. // Set the target selectors.
bytes4[] memory selectors = new bytes4[](4); bytes4[] memory selectors = new bytes4[](2);
selectors[0] = actor.deposit.selector; selectors[0] = actor.deposit.selector;
selectors[1] = actor.withdraw.selector; selectors[1] = actor.withdraw.selector;
selectors[2] = actor.sendERC20.selector;
selectors[3] = actor.relayMessage.selector;
FuzzSelector memory selector = FuzzSelector({ addr: address(actor), selectors: selectors }); FuzzSelector memory selector = FuzzSelector({ addr: address(actor), selectors: selectors });
targetSelector(selector); targetSelector(selector);
} }
......
...@@ -43,7 +43,7 @@ import { ISequencerFeeVault } from "src/L2/interfaces/ISequencerFeeVault.sol"; ...@@ -43,7 +43,7 @@ import { ISequencerFeeVault } from "src/L2/interfaces/ISequencerFeeVault.sol";
import { IL1FeeVault } from "src/L2/interfaces/IL1FeeVault.sol"; import { IL1FeeVault } from "src/L2/interfaces/IL1FeeVault.sol";
import { IGasPriceOracle } from "src/L2/interfaces/IGasPriceOracle.sol"; import { IGasPriceOracle } from "src/L2/interfaces/IGasPriceOracle.sol";
import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; import { IL1Block } from "src/L2/interfaces/IL1Block.sol";
import { ISuperchainWETHERC20 } from "src/L2/interfaces/ISuperchainWETH.sol"; import { ISuperchainWETH } from "src/L2/interfaces/ISuperchainWETH.sol";
import { IETHLiquidity } from "src/L2/interfaces/IETHLiquidity.sol"; import { IETHLiquidity } from "src/L2/interfaces/IETHLiquidity.sol";
import { IWETH } from "src/universal/interfaces/IWETH.sol"; import { IWETH } from "src/universal/interfaces/IWETH.sol";
import { IGovernanceToken } from "src/governance/interfaces/IGovernanceToken.sol"; import { IGovernanceToken } from "src/governance/interfaces/IGovernanceToken.sol";
...@@ -106,7 +106,7 @@ contract Setup { ...@@ -106,7 +106,7 @@ contract Setup {
IGovernanceToken governanceToken = IGovernanceToken(Predeploys.GOVERNANCE_TOKEN); IGovernanceToken governanceToken = IGovernanceToken(Predeploys.GOVERNANCE_TOKEN);
ILegacyMessagePasser legacyMessagePasser = ILegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER); ILegacyMessagePasser legacyMessagePasser = ILegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER);
IWETH weth = IWETH(payable(Predeploys.WETH)); IWETH weth = IWETH(payable(Predeploys.WETH));
ISuperchainWETHERC20 superchainWeth = ISuperchainWETHERC20(payable(Predeploys.SUPERCHAIN_WETH)); ISuperchainWETH superchainWeth = ISuperchainWETH(payable(Predeploys.SUPERCHAIN_WETH));
IETHLiquidity ethLiquidity = IETHLiquidity(Predeploys.ETH_LIQUIDITY); IETHLiquidity ethLiquidity = IETHLiquidity(Predeploys.ETH_LIQUIDITY);
ISuperchainTokenBridge superchainTokenBridge = ISuperchainTokenBridge(Predeploys.SUPERCHAIN_TOKEN_BRIDGE); ISuperchainTokenBridge superchainTokenBridge = ISuperchainTokenBridge(Predeploys.SUPERCHAIN_TOKEN_BRIDGE);
IOptimismSuperchainERC20Factory l2OptimismSuperchainERC20Factory = IOptimismSuperchainERC20Factory l2OptimismSuperchainERC20Factory =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment