@@ -13,18 +13,33 @@ contract HypEXATest is ForkTest {
1313
1414 uint256 internal opFork;
1515 uint256 internal baseFork;
16+ uint256 internal polygonFork;
1617 HypXERC20 internal opRouter;
1718 HypXERC20 internal baseRouter;
19+ HypXERC20 internal polygonRouter;
1820 address internal admin;
1921 address internal opMailbox;
2022 address internal baseMailbox;
23+ address internal polygonMailbox;
2124 EXA internal exa = EXA (0x1e925De1c68ef83bD98eE3E130eF14a50309C01B );
2225 address internal exaHolder = 0x92024C4bDa9DA602b711B9AbB610d072018eb58b ;
2326
2427 uint32 internal constant OP_DOMAIN = 10 ;
2528 uint32 internal constant BASE_DOMAIN = 8453 ;
29+ uint32 internal constant POLYGON_DOMAIN = 137 ;
2630
2731 function setUp () external {
32+ polygonFork = vm.createSelectFork ("polygon " , 83_700_000 );
33+ polygonMailbox = acct ("mailbox " );
34+ Redeployer polygonRedeployer = new Redeployer ();
35+ polygonRedeployer.setUp ();
36+ if (address (polygonRedeployer.proxyAdmin ()).code.length == 0 ) polygonRedeployer.prepare ();
37+ polygonRedeployer.run (polygonRedeployer.findNonce (acct ("deployer " ), address (exa), 1000 ) + 1 );
38+ polygonRedeployer.deployEXA (address (exa));
39+ polygonRouter = polygonRedeployer.deployRouter (address (exa));
40+ polygonRedeployer.setupRouter (address (exa), OP_DOMAIN);
41+ polygonRedeployer.setupRouter (address (exa), BASE_DOMAIN);
42+
2843 baseFork = vm.createSelectFork ("base " , 42_380_000 );
2944 baseMailbox = acct ("mailbox " );
3045 Redeployer baseRedeployer = new Redeployer ();
@@ -34,6 +49,7 @@ contract HypEXATest is ForkTest {
3449 baseRedeployer.deployEXA (address (exa));
3550 baseRouter = baseRedeployer.deployRouter (address (exa));
3651 baseRedeployer.setupRouter (address (exa), OP_DOMAIN);
52+ baseRedeployer.setupRouter (address (exa), POLYGON_DOMAIN);
3753
3854 opFork = vm.createSelectFork ("optimism " , 147_967_000 );
3955 opMailbox = acct ("mailbox " );
@@ -44,6 +60,7 @@ contract HypEXATest is ForkTest {
4460 opRedeployer.upgradeEXA (address (exa));
4561 opRouter = opRedeployer.deployRouter (address (exa));
4662 opRedeployer.setupRouter (address (exa), BASE_DOMAIN);
63+ opRedeployer.setupRouter (address (exa), POLYGON_DOMAIN);
4764 }
4865
4966 // solhint-disable func-name-mixedcase
@@ -82,6 +99,52 @@ contract HypEXATest is ForkTest {
8299 assertEq (exa.totalSupply (), opSupply, "op didn't restore supply " );
83100 }
84101
102+ function test_roundTrip_opToPolygonToBaseToOp () external {
103+ uint256 amount = 100e18 ;
104+ uint256 opSupply = exa.totalSupply ();
105+
106+ uint256 fee = opRouter.quoteGasPayment (POLYGON_DOMAIN);
107+ vm.deal (exaHolder, fee);
108+ vm.prank (exaHolder);
109+ opRouter.transferRemote { value: fee }(POLYGON_DOMAIN, exaHolder.addressToBytes32 (), amount);
110+ assertEq (exa.totalSupply (), opSupply - amount, "op didn't burn " );
111+
112+ vm.selectFork (polygonFork);
113+ uint256 polygonSupply = exa.totalSupply ();
114+ vm.prank (polygonMailbox);
115+ polygonRouter.handle (
116+ OP_DOMAIN, address (opRouter).addressToBytes32 (), abi.encodePacked (exaHolder.addressToBytes32 (), amount)
117+ );
118+ assertEq (exa.totalSupply (), polygonSupply + amount, "polygon didn't mint " );
119+
120+ fee = polygonRouter.quoteGasPayment (BASE_DOMAIN);
121+ vm.deal (exaHolder, fee);
122+ vm.prank (exaHolder);
123+ polygonRouter.transferRemote { value: fee }(BASE_DOMAIN, exaHolder.addressToBytes32 (), amount);
124+ assertEq (exa.totalSupply (), polygonSupply, "polygon didn't burn " );
125+
126+ vm.selectFork (baseFork);
127+ uint256 baseSupply = exa.totalSupply ();
128+ vm.prank (baseMailbox);
129+ baseRouter.handle (
130+ POLYGON_DOMAIN, address (polygonRouter).addressToBytes32 (), abi.encodePacked (exaHolder.addressToBytes32 (), amount)
131+ );
132+ assertEq (exa.totalSupply (), baseSupply + amount, "base didn't mint " );
133+
134+ fee = baseRouter.quoteGasPayment (OP_DOMAIN);
135+ vm.deal (exaHolder, fee);
136+ vm.prank (exaHolder);
137+ baseRouter.transferRemote { value: fee }(OP_DOMAIN, exaHolder.addressToBytes32 (), amount);
138+ assertEq (exa.totalSupply (), baseSupply, "base didn't burn " );
139+
140+ vm.selectFork (opFork);
141+ vm.prank (opMailbox);
142+ opRouter.handle (
143+ BASE_DOMAIN, address (baseRouter).addressToBytes32 (), abi.encodePacked (exaHolder.addressToBytes32 (), amount)
144+ );
145+ assertEq (exa.totalSupply (), opSupply, "op didn't restore supply " );
146+ }
147+
85148 function test_transferRemote_reverts_withoutBridgeRole () external {
86149 vm.prank (admin);
87150 exa.revokeRole (keccak256 ("BRIDGE_ROLE " ), address (opRouter));
0 commit comments