Commit 7a1c7a92 authored by smartcontracts's avatar smartcontracts Committed by GitHub

test(ctb): bridge return to sender on fail (#3041)

Adds a test that bridge contracts return to sender on failed deposits or
withdrawals.
Co-authored-by: default avatarmergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
parent 86a08b76
...@@ -49,19 +49,20 @@ L1CrossDomainMessenger_Test:test_L1MessengerSendMessage() (gas: 297745) ...@@ -49,19 +49,20 @@ L1CrossDomainMessenger_Test:test_L1MessengerSendMessage() (gas: 297745)
L1CrossDomainMessenger_Test:test_L1MessengerTwiceSendMessage() (gas: 1490048) L1CrossDomainMessenger_Test:test_L1MessengerTwiceSendMessage() (gas: 1490048)
L1CrossDomainMessenger_Test:test_L1MessengerUnpause() (gas: 40908) L1CrossDomainMessenger_Test:test_L1MessengerUnpause() (gas: 40908)
L1CrossDomainMessenger_Test:test_L1MessengerXDomainSenderReverts() (gas: 24249) L1CrossDomainMessenger_Test:test_L1MessengerXDomainSenderReverts() (gas: 24249)
L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 86191) L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 86168)
L1StandardBridge_Test:test_depositERC20() (gas: 578867) L1StandardBridge_Test:test_depositERC20() (gas: 578911)
L1StandardBridge_Test:test_depositERC20To() (gas: 581048) L1StandardBridge_Test:test_depositERC20To() (gas: 581092)
L1StandardBridge_Test:test_depositETH() (gas: 372975) L1StandardBridge_Test:test_depositETH() (gas: 372953)
L1StandardBridge_Test:test_depositETHTo() (gas: 330097) L1StandardBridge_Test:test_depositETHTo() (gas: 330097)
L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 490759) L1StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 681339)
L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 64409) L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 490817)
L1StandardBridge_Test:test_initialize() (gas: 26336) L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 64453)
L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 22363) L1StandardBridge_Test:test_initialize() (gas: 26401)
L1StandardBridge_Test:test_onlyEOADepositETH() (gas: 40816) L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 22341)
L1StandardBridge_Test:test_onlyL2BridgeFinalizeERC20Withdrawal() (gas: 36271) L1StandardBridge_Test:test_onlyEOADepositETH() (gas: 40882)
L1StandardBridge_Test:test_onlyPortalFinalizeERC20Withdrawal() (gas: 35600) L1StandardBridge_Test:test_onlyL2BridgeFinalizeERC20Withdrawal() (gas: 36294)
L1StandardBridge_Test:test_receive() (gas: 519560) L1StandardBridge_Test:test_onlyPortalFinalizeERC20Withdrawal() (gas: 35578)
L1StandardBridge_Test:test_receive() (gas: 519538)
L2CrossDomainMessenger_Test:testCannot_L2MessengerPause() (gas: 10823) L2CrossDomainMessenger_Test:testCannot_L2MessengerPause() (gas: 10823)
L2CrossDomainMessenger_Test:test_L1MessengerRelayMessageRevertsOnReentrancy() (gas: 171968) L2CrossDomainMessenger_Test:test_L1MessengerRelayMessageRevertsOnReentrancy() (gas: 171968)
L2CrossDomainMessenger_Test:test_L2MessengerMessageVersion() (gas: 8455) L2CrossDomainMessenger_Test:test_L2MessengerMessageVersion() (gas: 8455)
...@@ -99,12 +100,13 @@ L2OutputOracleUpgradeable_Test:test_initValuesOnProxy() (gas: 38899) ...@@ -99,12 +100,13 @@ L2OutputOracleUpgradeable_Test:test_initValuesOnProxy() (gas: 38899)
L2OutputOracleUpgradeable_Test:test_upgrading() (gas: 230843) L2OutputOracleUpgradeable_Test:test_upgrading() (gas: 230843)
L2StandardBridge_Test:test_ERC20BridgeFailed_whenLocalTokenIsBridge() (gas: 133459) L2StandardBridge_Test:test_ERC20BridgeFailed_whenLocalTokenIsBridge() (gas: 133459)
L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21656) L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21656)
L2StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 499042)
L2StandardBridge_Test:test_finalizeDeposit() (gas: 93203) L2StandardBridge_Test:test_finalizeDeposit() (gas: 93203)
L2StandardBridge_Test:test_finalizeDeposit_failsToCompleteOutboundTransfer() (gas: 140469) L2StandardBridge_Test:test_finalizeDeposit_failsToCompleteOutboundTransfer() (gas: 140492)
L2StandardBridge_Test:test_initialize() (gas: 14802) L2StandardBridge_Test:test_initialize() (gas: 14802)
L2StandardBridge_Test:test_receive() (gas: 136864) L2StandardBridge_Test:test_receive() (gas: 136864)
L2StandardBridge_Test:test_withdraw() (gas: 353020) L2StandardBridge_Test:test_withdraw() (gas: 353022)
L2StandardBridge_Test:test_withdrawTo() (gas: 353705) L2StandardBridge_Test:test_withdrawTo() (gas: 353706)
L2StandardBridge_Test:test_withdraw_onlyEOA() (gas: 252006) L2StandardBridge_Test:test_withdraw_onlyEOA() (gas: 252006)
L2ToL1MessagePasserTest:test_burn() (gas: 112037) L2ToL1MessagePasserTest:test_burn() (gas: 112037)
L2ToL1MessagePasserTest:test_initiateWithdrawal_fromContract() (gas: 67892) L2ToL1MessagePasserTest:test_initiateWithdrawal_fromContract() (gas: 67892)
......
...@@ -228,8 +228,10 @@ contract Bridge_Initializer is Messenger_Initializer { ...@@ -228,8 +228,10 @@ contract Bridge_Initializer is Messenger_Initializer {
OptimismMintableERC20Factory L2TokenFactory; OptimismMintableERC20Factory L2TokenFactory;
OptimismMintableERC20Factory L1TokenFactory; OptimismMintableERC20Factory L1TokenFactory;
ERC20 L1Token; ERC20 L1Token;
ERC20 BadL1Token;
OptimismMintableERC20 L2Token; OptimismMintableERC20 L2Token;
ERC20 NativeL2Token; ERC20 NativeL2Token;
ERC20 BadL2Token;
OptimismMintableERC20 RemoteL1Token; OptimismMintableERC20 RemoteL1Token;
event ETHDepositInitiated( event ETHDepositInitiated(
...@@ -387,6 +389,14 @@ contract Bridge_Initializer is Messenger_Initializer { ...@@ -387,6 +389,14 @@ contract Bridge_Initializer is Messenger_Initializer {
) )
); );
BadL2Token = OptimismMintableERC20(
L2TokenFactory.createStandardL2Token(
address(1),
string(abi.encodePacked("L2-", L1Token.name())),
string(abi.encodePacked("L2-", L1Token.symbol()))
)
);
NativeL2Token = new ERC20("Native L2 Token", "L2T"); NativeL2Token = new ERC20("Native L2 Token", "L2T");
L1TokenFactory = new OptimismMintableERC20Factory(address(L1Bridge)); L1TokenFactory = new OptimismMintableERC20Factory(address(L1Bridge));
...@@ -397,6 +407,14 @@ contract Bridge_Initializer is Messenger_Initializer { ...@@ -397,6 +407,14 @@ contract Bridge_Initializer is Messenger_Initializer {
string(abi.encodePacked("L1-", NativeL2Token.symbol())) string(abi.encodePacked("L1-", NativeL2Token.symbol()))
) )
); );
BadL1Token = OptimismMintableERC20(
L1TokenFactory.createStandardL2Token(
address(1),
string(abi.encodePacked("L1-", NativeL2Token.name())),
string(abi.encodePacked("L1-", NativeL2Token.symbol()))
)
);
} }
} }
......
...@@ -391,4 +391,48 @@ contract L1StandardBridge_Test is Bridge_Initializer { ...@@ -391,4 +391,48 @@ contract L1StandardBridge_Test is Bridge_Initializer {
hex"" hex""
); );
} }
function test_finalizeBridgeERC20FailSendBack() external {
deal(address(BadL1Token), address(L1Bridge), 100, true);
uint256 slot = stdstore
.target(address(L1Bridge))
.sig("deposits(address,address)")
.with_key(address(BadL1Token))
.with_key(address(L2Token))
.find();
// Give the L1 bridge some ERC20 tokens
vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100)));
assertEq(L1Bridge.deposits(address(BadL1Token), address(L2Token)), 100);
vm.expectEmit(true, true, true, true);
emit ERC20BridgeInitiated(
address(BadL1Token),
address(L2Token),
bob,
alice,
100,
hex""
);
vm.mockCall(
address(L1Bridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge.otherBridge()))
);
vm.prank(address(L1Bridge.messenger()));
L1Bridge.finalizeBridgeERC20(
address(BadL1Token),
address(L2Token),
alice,
bob,
100,
hex""
);
assertEq(BadL1Token.balanceOf(address(L1Bridge)), 100);
assertEq(BadL1Token.balanceOf(address(alice)), 0);
}
} }
...@@ -197,5 +197,48 @@ contract L2StandardBridge_Test is Bridge_Initializer { ...@@ -197,5 +197,48 @@ contract L2StandardBridge_Test is Bridge_Initializer {
vm.prank(address(L2Messenger)); vm.prank(address(L2Messenger));
L2Bridge.finalizeDeposit(address(L1Token), address(L2Bridge), alice, bob, 100, hex""); L2Bridge.finalizeDeposit(address(L1Token), address(L2Bridge), alice, bob, 100, hex"");
} }
}
function test_finalizeBridgeERC20FailSendBack() external {
deal(address(BadL2Token), address(L2Bridge), 100, true);
uint256 slot = stdstore
.target(address(L2Bridge))
.sig("deposits(address,address)")
.with_key(address(BadL2Token))
.with_key(address(L1Token))
.find();
// Give the L2 bridge some ERC20 tokens
vm.store(address(L2Bridge), bytes32(slot), bytes32(uint256(100)));
assertEq(L2Bridge.deposits(address(BadL2Token), address(L1Token)), 100);
vm.expectEmit(true, true, true, true);
emit ERC20BridgeInitiated(
address(BadL2Token),
address(L1Token),
bob,
alice,
100,
hex""
);
vm.mockCall(
address(L2Bridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L2Bridge.otherBridge()))
);
vm.prank(address(L2Bridge.messenger()));
L2Bridge.finalizeBridgeERC20(
address(BadL2Token),
address(L1Token),
alice,
bob,
100,
hex""
);
assertEq(BadL2Token.balanceOf(address(L2Bridge)), 100);
assertEq(BadL2Token.balanceOf(address(alice)), 0);
}
}
...@@ -22,7 +22,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { ...@@ -22,7 +22,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
function test_createStandardL2Token() external { function test_createStandardL2Token() external {
address remote = address(4); address remote = address(4);
address local = LibRLP.computeAddress(address(L2TokenFactory), 1); address local = LibRLP.computeAddress(address(L2TokenFactory), 2);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit StandardL2TokenCreated( emit StandardL2TokenCreated(
...@@ -47,7 +47,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { ...@@ -47,7 +47,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
vm.prank(alice); vm.prank(alice);
L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP"); L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP");
address local = LibRLP.computeAddress(address(L2TokenFactory), 2); address local = LibRLP.computeAddress(address(L2TokenFactory), 3);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit StandardL2TokenCreated( emit StandardL2TokenCreated(
......
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