From 0eac326d1844066fecdb82dbc448ac40a35efd05 Mon Sep 17 00:00:00 2001 From: sunbreak1211 <sunbreak1211@proton.me> Date: Mon, 16 Sep 2024 23:35:31 -0300 Subject: [PATCH] Implement fileable escrow --- deploy/TokenBridgeDeploy.sol | 2 +- deploy/TokenBridgeInit.sol | 6 ++++-- src/L1TokenBridge.sol | 12 +++++++++--- test/L1TokenBridge.t.sol | 12 ++++++++---- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/deploy/TokenBridgeDeploy.sol b/deploy/TokenBridgeDeploy.sol index ee3b6a1..034584c 100644 --- a/deploy/TokenBridgeDeploy.sol +++ b/deploy/TokenBridgeDeploy.sol @@ -37,7 +37,7 @@ library TokenBridgeDeploy { ) internal returns (L1TokenBridgeInstance memory l1BridgeInstance) { l1BridgeInstance.govRelay = address(new L1GovernanceRelay(l2GovRelay, l1Messenger)); l1BridgeInstance.escrow = address(new Escrow()); - l1BridgeInstance.bridge = address(new L1TokenBridge(l2Bridge, l1BridgeInstance.escrow, l1Messenger)); + l1BridgeInstance.bridge = address(new L1TokenBridge(l2Bridge, l1Messenger)); ScriptTools.switchOwner(l1BridgeInstance.govRelay, deployer, owner); ScriptTools.switchOwner(l1BridgeInstance.escrow, deployer, owner); ScriptTools.switchOwner(l1BridgeInstance.bridge, deployer, owner); diff --git a/deploy/TokenBridgeInit.sol b/deploy/TokenBridgeInit.sol index 73e9911..9914211 100644 --- a/deploy/TokenBridgeInit.sol +++ b/deploy/TokenBridgeInit.sol @@ -27,7 +27,8 @@ interface L1TokenBridgeLike { function otherBridge() external view returns (address); function escrow() external view returns (address); function messenger() external view returns (address); - function registerToken(address l1Token, address l2Token) external; + function file(bytes32, address) external; + function registerToken(address, address) external; } interface L1RelayLike { @@ -69,13 +70,14 @@ library TokenBridgeInit { // sanity checks require(l1Bridge.isOpen() == 1, "TokenBridgeInit/not-open"); require(l1Bridge.otherBridge() == l2BridgeInstance.bridge, "TokenBridgeInit/other-bridge-mismatch"); - require(l1Bridge.escrow() == address(escrow), "TokenBridgeInit/escrow-mismatch"); require(l1Bridge.messenger() == cfg.l1Messenger, "TokenBridgeInit/l1-bridge-messenger-mismatch"); require(l1GovRelay.l2GovernanceRelay() == l2BridgeInstance.govRelay, "TokenBridgeInit/l2-gov-relay-mismatch"); require(l1GovRelay.messenger() == cfg.l1Messenger, "TokenBridgeInit/l1-gov-relay-messenger-mismatch"); require(cfg.l1Tokens.length == cfg.l2Tokens.length, "TokenBridgeInit/token-arrays-mismatch"); require(cfg.minGasLimit <= 1_000_000_000, "TokenBridgeInit/min-gas-limit-out-of-bounds"); + l1Bridge.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), "TokenBridgeInit/invalid-l1-token"); diff --git a/src/L1TokenBridge.sol b/src/L1TokenBridge.sol index 4debc8c..43a55c8 100644 --- a/src/L1TokenBridge.sol +++ b/src/L1TokenBridge.sol @@ -32,17 +32,18 @@ contract L1TokenBridge { mapping(address => uint256) public wards; mapping(address => address) public l1ToL2Token; uint256 public isOpen = 1; + address public escrow; // --- immutables --- address public immutable otherBridge; - address public immutable escrow; CrossDomainMessengerLike public immutable messenger; // --- events --- event Rely(address indexed usr); event Deny(address indexed usr); + event File(bytes32 indexed what, address data); event Closed(); event TokenSet(address indexed l1Token, address indexed l2Token); event ERC20BridgeInitiated( @@ -81,11 +82,9 @@ contract L1TokenBridge { constructor( address _otherBridge, - address _escrow, address _messenger ) { otherBridge = _otherBridge; - escrow = _escrow; messenger = CrossDomainMessengerLike(_messenger); wards[msg.sender] = 1; @@ -104,6 +103,13 @@ contract L1TokenBridge { emit Deny(usr); } + function file(bytes32 what, address data) external auth { + if (what == "escrow") { + escrow = data; + } else revert("L1TokenBridge/file-unrecognized-param"); + emit File(what, data); + } + function close() external auth { isOpen = 0; emit Closed(); diff --git a/test/L1TokenBridge.t.sol b/test/L1TokenBridge.t.sol index 9ebf688..6100867 100644 --- a/test/L1TokenBridge.t.sol +++ b/test/L1TokenBridge.t.sol @@ -61,7 +61,8 @@ contract L1TokenBridgeTest is DssTest { function setUp() public { messenger = new MessengerMock(); messenger.setXDomainMessageSender(otherBridge); - bridge = new L1TokenBridge(otherBridge, escrow, address(messenger)); + bridge = new L1TokenBridge(otherBridge, address(messenger)); + bridge.file("escrow", escrow); l1Token = new GemMock(1_000_000 ether); l1Token.transfer(address(0xe0a), 500_000 ether); vm.prank(escrow); l1Token.approve(address(bridge), type(uint256).max); @@ -71,12 +72,11 @@ contract L1TokenBridgeTest is DssTest { function testConstructor() public { vm.expectEmit(true, true, true, true); emit Rely(address(this)); - L1TokenBridge b = new L1TokenBridge(address(111), address(222), address(333)); + L1TokenBridge b = new L1TokenBridge(address(111), address(222)); assertEq(b.isOpen(), 1); assertEq(b.otherBridge(), address(111)); - assertEq(b.escrow(), address(222)); - assertEq(address(b.messenger()), address(333)); + assertEq(address(b.messenger()), address(222)); assertEq(b.wards(address(this)), 1); } @@ -93,6 +93,10 @@ contract L1TokenBridgeTest is DssTest { ]); } + function testFileAddress() public { + checkFileAddress(address(bridge), "L1TokenBridge", ["escrow"]); + } + function testTokenRegistration() public { assertEq(bridge.l1ToL2Token(address(11)), address(0));