Skip to content

Commit c7187e5

Browse files
committed
✅ contracts: add polygon hyperlane bridge test
1 parent cefa35c commit c7187e5

3 files changed

Lines changed: 83 additions & 18 deletions

File tree

contracts/.gas-snapshot

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
ExaAccountFactoryTest:testFuzz_createAccount_EOAOwners(uint256,address[63]) (runs: 256, μ: 5959727, ~: 5214436)
22
ExaAccountFactoryTest:test_deploy_deploysToSameAddress() (gas: 13989314)
3-
ExaPluginTest:testFork_claimAndVestEscrowedEXA_claimsAndVests() (gas: 38658455)
4-
ExaPluginTest:testFork_collectCollateral_collects() (gas: 32168077)
5-
ExaPluginTest:testFork_crossRepay_repays() (gas: 33984480)
6-
ExaPluginTest:testFork_repay_whenFlashLoanerHasFees() (gas: 25622346)
7-
ExaPluginTest:testFork_stakeEXA_stakes() (gas: 32742698)
8-
ExaPluginTest:testFork_swap_swaps() (gas: 28110123)
3+
ExaPluginTest:testFork_claimAndVestEscrowedEXA_claimsAndVests() (gas: 38661570)
4+
ExaPluginTest:testFork_collectCollateral_collects() (gas: 32170991)
5+
ExaPluginTest:testFork_crossRepay_repays() (gas: 33987394)
6+
ExaPluginTest:testFork_repay_whenFlashLoanerHasFees() (gas: 25623545)
7+
ExaPluginTest:testFork_stakeEXA_stakes() (gas: 32745698)
8+
ExaPluginTest:testFork_swap_swaps() (gas: 28112771)
99
ExaPluginTest:test_allowPlugin_emitsPluginAllowed() (gas: 58464)
1010
ExaPluginTest:test_allowPlugin_reverts_whenAddressZero() (gas: 32411)
1111
ExaPluginTest:test_allowPlugin_reverts_whenNotAdmin() (gas: 38464)
@@ -32,12 +32,12 @@ ExaPluginTest:test_collectCredit_collects_whenHealthFactorHigherThanOne() (gas:
3232
ExaPluginTest:test_collectCredit_collects_whenProposalCausesInsufficientLiquidity() (gas: 1064982)
3333
ExaPluginTest:test_collectCredit_collects_whenProposalLeavesHealthFactorLowerThanOne() (gas: 1055379)
3434
ExaPluginTest:test_collectCredit_collects_withEnoughSlippage() (gas: 782246)
35-
ExaPluginTest:test_collectCredit_collects_withPrevIssuerSignature() (gas: 983635)
35+
ExaPluginTest:test_collectCredit_collects_withPrevIssuerSignature() (gas: 983692)
3636
ExaPluginTest:test_collectCredit_passes_whenProposalLeavesEnoughLiquidity() (gas: 1082579)
3737
ExaPluginTest:test_collectCredit_reverts_asNotKeeper() (gas: 342148)
3838
ExaPluginTest:test_collectCredit_reverts_whenDisagreement() (gas: 538817)
3939
ExaPluginTest:test_collectCredit_reverts_whenExpired() (gas: 352767)
40-
ExaPluginTest:test_collectCredit_reverts_whenPrevSignatureNotValidAnymore() (gas: 483048)
40+
ExaPluginTest:test_collectCredit_reverts_whenPrevSignatureNotValidAnymore() (gas: 483105)
4141
ExaPluginTest:test_collectCredit_reverts_whenReplay() (gas: 825827)
4242
ExaPluginTest:test_collectCredit_reverts_whenTimelocked() (gas: 334568)
4343
ExaPluginTest:test_collectCredit_toleratesTimeDrift() (gas: 796346)
@@ -58,7 +58,7 @@ ExaPluginTest:test_collectInstallments_reverts_whenTimelocked() (gas: 336703)
5858
ExaPluginTest:test_collectInstallments_toleratesTimeDrift() (gas: 1159087)
5959
ExaPluginTest:test_collect_collects_whenProposalsLeaveNoLiquidity() (gas: 1783636)
6060
ExaPluginTest:test_collect_collects_whenTooMuchProposedDebt() (gas: 1923835)
61-
ExaPluginTest:test_crossRepay_avoidsFrozenDeposit() (gas: 976494)
61+
ExaPluginTest:test_crossRepay_avoidsFrozenDeposit() (gas: 976551)
6262
ExaPluginTest:test_crossRepay_avoidsZeroSharesDeposit() (gas: 1394086)
6363
ExaPluginTest:test_crossRepay_consumesProposal() (gas: 2192689)
6464
ExaPluginTest:test_crossRepay_repays() (gas: 2263979)
@@ -202,8 +202,9 @@ ExaPreviewerTest:test_collect_reverts_whenProposalsLeaveNoLiquidity() (gas: 1437
202202
ExaPreviewerTest:test_markets_returnsMarkets() (gas: 150447)
203203
ExaPreviewerTest:test_pendingProposals_returnsPendingProposals() (gas: 1976593)
204204
ExaPreviewerTest:test_utilizations_returns() (gas: 134922)
205-
HypEXATest:test_handle_reverts_withoutBridgeRole() (gas: 122474)
205+
HypEXATest:test_handle_reverts_withoutBridgeRole() (gas: 122511)
206206
HypEXATest:test_roundTrip_opToBaseToOp() (gas: 1034001)
207+
HypEXATest:test_roundTrip_opToPolygonToBaseToOp() (gas: 1534147)
207208
HypEXATest:test_transferRemote_reverts_withoutBridgeRole() (gas: 227758)
208209
IssuerCheckerTest:test_setIssuer_emits_IssuerSet() (gas: 77935)
209210
IssuerCheckerTest:test_setIssuer_reverts_whenNotAdmin() (gas: 41208)
@@ -215,14 +216,14 @@ IssuerCheckerTest:test_setPrevIssuerWindow_emits_PrevIssuerWindowSet() (gas: 501
215216
IssuerCheckerTest:test_setPrevIssuerWindow_reverts_whenNotAdmin() (gas: 43048)
216217
MockSwapperTest:test_swapExactAmountIn_swaps() (gas: 264807)
217218
MockSwapperTest:test_swapExactAmountOut_swaps() (gas: 264803)
218-
RedeployerTest:test_deployEXA_deploysAtSameAddress_onBase() (gas: 59976066)
219-
RedeployerTest:test_deployExaFactory_deploysAtSameAddress_onEthereum() (gas: 276598819)
220-
RedeployerTest:test_deployExaFactory_deploysAtSameAddress_onPolygon() (gas: 371270451)
221-
RedeployerTest:test_deployExaFactory_deploysViaCreate3AtSameAddress_onPolygon() (gas: 48248322)
222-
RedeployerTest:test_prepare_reverts_whenAdminIsDeployer() (gas: 32034087)
223-
RedeployerTest:test_recoversNativeETHOnPolygon() (gas: 48419495)
224-
RedeployerTest:test_run_reverts_whenAttackerUpgradesProxy() (gas: 42866122)
225-
RedeployerTest:test_run_reverts_whenTargetNonceTooLow() (gas: 32498932)
219+
RedeployerTest:test_deployEXA_deploysAtSameAddress_onBase() (gas: 59976446)
220+
RedeployerTest:test_deployExaFactory_deploysAtSameAddress_onEthereum() (gas: 276599537)
221+
RedeployerTest:test_deployExaFactory_deploysAtSameAddress_onPolygon() (gas: 371270980)
222+
RedeployerTest:test_deployExaFactory_deploysViaCreate3AtSameAddress_onPolygon() (gas: 48248553)
223+
RedeployerTest:test_prepare_reverts_whenAdminIsDeployer() (gas: 32034206)
224+
RedeployerTest:test_recoversNativeETHOnPolygon() (gas: 48419750)
225+
RedeployerTest:test_run_reverts_whenAttackerUpgradesProxy() (gas: 42866465)
226+
RedeployerTest:test_run_reverts_whenTargetNonceTooLow() (gas: 32499108)
226227
RefunderTest:test_refund_refunds() (gas: 260863)
227228
RefunderTest:test_refund_reverts_whenExpired() (gas: 88359)
228229
RefunderTest:test_refund_reverts_whenNotKeeper() (gas: 66361)

contracts/deploy.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
},
4242
"mailbox": {
4343
"10": "0xd4C1905BB1D26BC93DAC913e13CaCC278CdCC80D",
44+
"137": "0x5d934f4e2f797775e53561bB72aca21ba36B96BB",
4445
"8453": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D"
4546
}
4647
},

contracts/test/HypEXA.t.sol

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)