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)
L1CrossDomainMessenger_Test:test_L1MessengerTwiceSendMessage() (gas: 1490048)
L1CrossDomainMessenger_Test:test_L1MessengerUnpause() (gas: 40908)
L1CrossDomainMessenger_Test:test_L1MessengerXDomainSenderReverts() (gas: 24249)
L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 86191)
L1StandardBridge_Test:test_depositERC20() (gas: 578867)
L1StandardBridge_Test:test_depositERC20To() (gas: 581048)
L1StandardBridge_Test:test_depositETH() (gas: 372975)
L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 86168)
L1StandardBridge_Test:test_depositERC20() (gas: 578911)
L1StandardBridge_Test:test_depositERC20To() (gas: 581092)
L1StandardBridge_Test:test_depositETH() (gas: 372953)
L1StandardBridge_Test:test_depositETHTo() (gas: 330097)
L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 490759)
L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 64409)
L1StandardBridge_Test:test_initialize() (gas: 26336)
L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 22363)
L1StandardBridge_Test:test_onlyEOADepositETH() (gas: 40816)
L1StandardBridge_Test:test_onlyL2BridgeFinalizeERC20Withdrawal() (gas: 36271)
L1StandardBridge_Test:test_onlyPortalFinalizeERC20Withdrawal() (gas: 35600)
L1StandardBridge_Test:test_receive() (gas: 519560)
L1StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 681339)
L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 490817)
L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 64453)
L1StandardBridge_Test:test_initialize() (gas: 26401)
L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 22341)
L1StandardBridge_Test:test_onlyEOADepositETH() (gas: 40882)
L1StandardBridge_Test:test_onlyL2BridgeFinalizeERC20Withdrawal() (gas: 36294)
L1StandardBridge_Test:test_onlyPortalFinalizeERC20Withdrawal() (gas: 35578)
L1StandardBridge_Test:test_receive() (gas: 519538)
L2CrossDomainMessenger_Test:testCannot_L2MessengerPause() (gas: 10823)
L2CrossDomainMessenger_Test:test_L1MessengerRelayMessageRevertsOnReentrancy() (gas: 171968)
L2CrossDomainMessenger_Test:test_L2MessengerMessageVersion() (gas: 8455)
......@@ -99,12 +100,13 @@ L2OutputOracleUpgradeable_Test:test_initValuesOnProxy() (gas: 38899)
L2OutputOracleUpgradeable_Test:test_upgrading() (gas: 230843)
L2StandardBridge_Test:test_ERC20BridgeFailed_whenLocalTokenIsBridge() (gas: 133459)
L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21656)
L2StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 499042)
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_receive() (gas: 136864)
L2StandardBridge_Test:test_withdraw() (gas: 353020)
L2StandardBridge_Test:test_withdrawTo() (gas: 353705)
L2StandardBridge_Test:test_withdraw() (gas: 353022)
L2StandardBridge_Test:test_withdrawTo() (gas: 353706)
L2StandardBridge_Test:test_withdraw_onlyEOA() (gas: 252006)
L2ToL1MessagePasserTest:test_burn() (gas: 112037)
L2ToL1MessagePasserTest:test_initiateWithdrawal_fromContract() (gas: 67892)
......
......@@ -228,8 +228,10 @@ contract Bridge_Initializer is Messenger_Initializer {
OptimismMintableERC20Factory L2TokenFactory;
OptimismMintableERC20Factory L1TokenFactory;
ERC20 L1Token;
ERC20 BadL1Token;
OptimismMintableERC20 L2Token;
ERC20 NativeL2Token;
ERC20 BadL2Token;
OptimismMintableERC20 RemoteL1Token;
event ETHDepositInitiated(
......@@ -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");
L1TokenFactory = new OptimismMintableERC20Factory(address(L1Bridge));
......@@ -397,6 +407,14 @@ contract Bridge_Initializer is Messenger_Initializer {
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 {
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 {
vm.prank(address(L2Messenger));
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 {
function test_createStandardL2Token() external {
address remote = address(4);
address local = LibRLP.computeAddress(address(L2TokenFactory), 1);
address local = LibRLP.computeAddress(address(L2TokenFactory), 2);
vm.expectEmit(true, true, true, true);
emit StandardL2TokenCreated(
......@@ -47,7 +47,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
vm.prank(alice);
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);
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