diff --git a/deploy/TokenGatewayDeploy.sol b/deploy/TokenGatewayDeploy.sol index 3514b1d..cff3e3e 100644 --- a/deploy/TokenGatewayDeploy.sol +++ b/deploy/TokenGatewayDeploy.sol @@ -29,10 +29,9 @@ library TokenGatewayDeploy { address owner, address l2Gateway, address l1Router, - address inbox, - address escrow + address inbox ) internal returns (address l1Gateway) { - l1Gateway = address(new L1TokenGateway(l2Gateway, l1Router, inbox, escrow)); + l1Gateway = address(new L1TokenGateway(l2Gateway, l1Router, inbox)); ScriptTools.switchOwner(l1Gateway, deployer, owner); } diff --git a/deploy/TokenGatewayInit.sol b/deploy/TokenGatewayInit.sol index cbe5ac8..98af03a 100644 --- a/deploy/TokenGatewayInit.sol +++ b/deploy/TokenGatewayInit.sol @@ -27,7 +27,8 @@ interface L1TokenGatewayLike { function l1Router() external view returns (address); function inbox() external view returns (address); function escrow() external view returns (address); - function registerToken(address l1Token, address l2Token) external; + function file(bytes32, address) external; + function registerToken(address, address) external; } interface L1RelayLike { @@ -80,7 +81,6 @@ library TokenGatewayInit { require(l1Gateway.counterpartGateway() == l2GatewayInstance.gateway, "TokenGatewayInit/counterpart-gateway-mismatch"); require(l1Gateway.l1Router() == cfg.l1Router, "TokenGatewayInit/l1-router-mismatch"); require(l1Gateway.inbox() == cfg.inbox, "TokenGatewayInit/inbox-mismatch"); - require(l1Gateway.escrow() == address(escrow), "TokenGatewayInit/incorrect-escrow"); require(cfg.l1Tokens.length == cfg.l2Tokens.length, "TokenGatewayInit/token-arrays-mismatch"); uint256 l1CallValue = cfg.xchainMsg.maxSubmissionCost + cfg.xchainMsg.maxGas * cfg.xchainMsg.gasPriceBid; @@ -89,6 +89,8 @@ library TokenGatewayInit { // but makes the eth balance requirement more explicit require(address(l1GovRelay).balance >= l1CallValue, "TokenGatewayInit/insufficient-relay-balance"); + l1Gateway.file("escrow", address(escrow)); + for (uint256 i; i < cfg.l1Tokens.length; ++i) { (address l1Token, address l2Token) = (cfg.l1Tokens[i], cfg.l2Tokens[i]); require(l1Token != address(0), "TokenGatewayInit/invalid-l1-token"); diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 1252a78..6557e6b 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -146,7 +146,7 @@ contract Deploy is Script { l1Domain.selectFork(); vm.startBroadcast(l1PrivKey); - address l1Gateway = TokenGatewayDeploy.deployL1Gateway(l1Deployer, owner, l2Gateway, l1Router, inbox, escrow); + address l1Gateway = TokenGatewayDeploy.deployL1Gateway(l1Deployer, owner, l2Gateway, l1Router, inbox); vm.stopBroadcast(); address l2Router = L1RouterLike(l1Router).counterpartGateway(); diff --git a/src/L1TokenGateway.sol b/src/L1TokenGateway.sol index aeb32fd..7a990fe 100644 --- a/src/L1TokenGateway.sol +++ b/src/L1TokenGateway.sol @@ -33,18 +33,19 @@ contract L1TokenGateway is ITokenGateway, IL1ArbitrumGateway, ICustomGateway, ER mapping(address => uint256) public wards; mapping(address => address) public l1ToL2Token; uint256 public isOpen = 1; + address public escrow; // --- immutables --- address public immutable counterpartGateway; address public immutable l1Router; address public immutable inbox; - address public immutable escrow; // --- events --- event Rely(address indexed usr); event Deny(address indexed usr); + event File(bytes32 indexed what, address data); event Closed(); event DepositInitiated( address l1Token, @@ -84,13 +85,11 @@ contract L1TokenGateway is ITokenGateway, IL1ArbitrumGateway, ICustomGateway, ER constructor( address _counterpartGateway, address _l1Router, - address _inbox, - address _escrow + address _inbox ) { counterpartGateway = _counterpartGateway; l1Router = _l1Router; inbox = _inbox; - escrow = _escrow; wards[msg.sender] = 1; emit Rely(msg.sender); @@ -108,6 +107,13 @@ contract L1TokenGateway is ITokenGateway, IL1ArbitrumGateway, ICustomGateway, ER emit Deny(usr); } + function file(bytes32 what, address data) external auth { + if (what == "escrow") { + escrow = data; + } else revert("L1TokenGateway/file-unrecognized-param"); + emit File(what, data); + } + function close() external auth { isOpen = 0; emit Closed(); diff --git a/test/Integration.t.sol b/test/Integration.t.sol index 5a4b9ce..d40841c 100644 --- a/test/Integration.t.sol +++ b/test/Integration.t.sol @@ -106,8 +106,7 @@ contract IntegrationTest is DssTest { owner: PAUSE_PROXY, l2Gateway: address(l2Gateway), l1Router: L1_ROUTER, - inbox: INBOX, - escrow: ESCROW + inbox: INBOX })); assertEq(address(l1Gateway), l1Gateway_); diff --git a/test/L1TokenGateway.t.sol b/test/L1TokenGateway.t.sol index 48fdac9..8a5f51d 100644 --- a/test/L1TokenGateway.t.sol +++ b/test/L1TokenGateway.t.sol @@ -52,7 +52,8 @@ contract L1TokenGatewayTest is DssTest { function setUp() public { inbox = new InboxMock(); - gateway = new L1TokenGateway(counterpartGateway, l1Router, address(inbox), escrow); + gateway = new L1TokenGateway(counterpartGateway, l1Router, address(inbox)); + gateway.file("escrow", escrow); l1Token = new GemMock(1_000_000 ether); vm.prank(escrow); l1Token.approve(address(gateway), type(uint256).max); gateway.registerToken(address(l1Token), address(0xf00)); @@ -61,13 +62,12 @@ contract L1TokenGatewayTest is DssTest { function testConstructor() public { vm.expectEmit(true, true, true, true); emit Rely(address(this)); - L1TokenGateway g = new L1TokenGateway(address(111), address(222), address(333), address(444)); + L1TokenGateway g = new L1TokenGateway(address(111), address(222), address(333)); assertEq(g.isOpen(), 1); assertEq(g.counterpartGateway(), address(111)); assertEq(g.l1Router(), address(222)); assertEq(g.inbox(), address(333)); - assertEq(g.escrow(), address(444)); assertEq(g.wards(address(this)), 1); } @@ -84,6 +84,10 @@ contract L1TokenGatewayTest is DssTest { ]); } + function testFileAddress() public { + checkFileAddress(address(gateway), "L1TokenGateway", ["escrow"]); + } + function testErc165() public view { assertEq(gateway.supportsInterface(gateway.supportsInterface.selector), true); assertEq(gateway.supportsInterface(gateway.outboundTransferCustomRefund.selector), true);