Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,20 @@ contract L1StandardBridge_Receive_Test is CommonTest {
(bool revertsAsExpected,) = address(l1StandardBridge).call{ value: 100 }(hex"");
assertTrue(revertsAsExpected, "expectRevert: call did not revert");
}

/// @notice Tests that receive reverts when custom gas token is enabled and value is sent.
function testFuzz_receive_withCustomGasToken_reverts(uint256 _value) external {
skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN);

_value = bound(_value, 1, type(uint128).max);
vm.deal(alice, _value);

vm.prank(alice, alice);
vm.expectRevert(IOptimismPortal2.OptimismPortal_NotAllowedOnCGTMode.selector);

(bool revertsAsExpected,) = address(l1StandardBridge).call{ value: _value }(hex"");
assertTrue(revertsAsExpected, "expectRevert: call did not revert");
}
}

/// @title L1StandardBridge_DepositETH_Test
Expand Down Expand Up @@ -427,6 +441,32 @@ contract L1StandardBridge_DepositETH_Test is L1StandardBridge_TestInit {
vm.prank(alice);
l1StandardBridge.depositETH{ value: 1 }(300, hex"");
}

/// @notice Tests that depositETH reverts when custom gas token is enabled and value is sent.
function testFuzz_depositETH_withCustomGasToken_reverts(uint256 _value, uint32 _minGasLimit) external {
skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN);

_value = bound(_value, 1, type(uint128).max);
vm.deal(alice, _value);

vm.prank(alice, alice);
vm.expectRevert(IOptimismPortal2.OptimismPortal_NotAllowedOnCGTMode.selector);
l1StandardBridge.depositETH{ value: _value }(_minGasLimit, hex"dead");
}

/// @notice Tests that depositETH reverts when custom gas token is enabled for EOA with 7702 delegation.
function testFuzz_depositETH_fromEOA7702WithCustomGasToken_reverts(uint256 _value, uint32 _minGasLimit) external {
skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN);
_value = bound(_value, 1, type(uint128).max);

// Set alice to have 7702 code.
vm.etch(alice, abi.encodePacked(hex"EF0100", address(0)));

vm.deal(alice, _value);
vm.prank(alice, alice);
vm.expectRevert(IOptimismPortal2.OptimismPortal_NotAllowedOnCGTMode.selector);
l1StandardBridge.depositETH{ value: _value }(_minGasLimit, hex"dead");
}
}

/// @title L1StandardBridge_DepositETHTo_Test
Expand Down Expand Up @@ -474,6 +514,23 @@ contract L1StandardBridge_DepositETHTo_Test is L1StandardBridge_TestInit {
assertEq(address(optimismPortal2).balance, portalBalanceBefore + _amount);
}
}

/// @notice Tests that depositETHTo reverts when custom gas token is enabled and value is sent.
function testFuzz_depositETHTo_withCustomGasToken_reverts(
address _to,
uint256 _value,
uint32 _minGasLimit
)
external
{
skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN);
vm.assume(_to != address(0));
_value = bound(_value, 1, type(uint128).max);
vm.deal(alice, _value);
vm.prank(alice);
vm.expectRevert(IOptimismPortal2.OptimismPortal_NotAllowedOnCGTMode.selector);
l1StandardBridge.depositETHTo{ value: _value }(_to, _minGasLimit, hex"dead");
}
}

/// @title L1StandardBridge_DepositERC20_Test
Expand Down Expand Up @@ -877,4 +934,35 @@ contract L1StandardBridge_Uncategorized_Test is L1StandardBridge_TestInit {
vm.expectRevert("StandardBridge: cannot send to messenger");
l1StandardBridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex"");
}

/// @notice Tests that bridgeETH reverts when custom gas token is enabled and value is sent.
function testFuzz_bridgeETH_withCustomGasToken_reverts(uint256 _value, uint32 _minGasLimit) external {
skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN);

_value = bound(_value, 1, type(uint128).max);
vm.deal(alice, _value);

vm.prank(alice, alice);
vm.expectRevert(IOptimismPortal2.OptimismPortal_NotAllowedOnCGTMode.selector);
l1StandardBridge.bridgeETH{ value: _value }(_minGasLimit, hex"dead");
}

/// @notice Tests that bridgeETHTo reverts when custom gas token is enabled and value is sent.
function testFuzz_bridgeETHTo_withCustomGasToken_reverts(
address _to,
uint256 _value,
uint32 _minGasLimit
)
external
{
skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN);

vm.assume(_to != address(0));
_value = bound(_value, 1, type(uint128).max);
vm.deal(alice, _value);

vm.prank(alice);
vm.expectRevert(IOptimismPortal2.OptimismPortal_NotAllowedOnCGTMode.selector);
l1StandardBridge.bridgeETHTo{ value: _value }(_to, _minGasLimit, hex"dead");
}
}
26 changes: 26 additions & 0 deletions packages/contracts-bedrock/test/L2/FeeVault.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { CommonTest } from "test/setup/CommonTest.sol";
import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol";
import { IFeeVault } from "interfaces/L2/IFeeVault.sol";
import { IL2ToL1MessagePasser } from "interfaces/L2/IL2ToL1MessagePasser.sol";
import { IL2ToL1MessagePasserCGT } from "interfaces/L2/IL2ToL1MessagePasserCGT.sol";

// Libraries
import { Hashing } from "src/libraries/Hashing.sol";
Expand Down Expand Up @@ -145,6 +146,31 @@ abstract contract FeeVault_Uncategorized_Test is CommonTest {
assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, amount);
}

/// @notice Tests that withdraw to L1 reverts when custom gas token is enabled and value is sent.
function testFuzz_withdraw_toL1WithCustomGasToken_reverts(uint256 _amount) external {
skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN);

// Setup L1 withdrawal
vm.prank(IProxyAdmin(Predeploys.PROXY_ADMIN).owner());
feeVault.setWithdrawalNetwork(Types.WithdrawalNetwork.L1);

// Set recipient
vm.prank(IProxyAdmin(Predeploys.PROXY_ADMIN).owner());
feeVault.setRecipient(recipient);

// Set minimum withdrawal amount
vm.prank(IProxyAdmin(Predeploys.PROXY_ADMIN).owner());
feeVault.setMinWithdrawalAmount(minWithdrawalAmount);

// Set the balance to be greater than the minimum withdrawal amount
_amount = bound(_amount, feeVault.minWithdrawalAmount() + 1, type(uint128).max);
vm.deal(address(feeVault), _amount);

// Withdrawal should revert due to CGT mode
vm.expectRevert(IL2ToL1MessagePasserCGT.L2ToL1MessagePasserCGT_NotAllowedOnCGTMode.selector);
feeVault.withdraw();
}

/// @notice Tests that `withdraw` successfully initiates a withdrawal to L2.
function test_withdraw_toL2_succeeds() public {
_setupL2Withdrawal();
Expand Down
65 changes: 65 additions & 0 deletions packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { Features } from "src/libraries/Features.sol";
import { ICrossDomainMessenger } from "interfaces/universal/ICrossDomainMessenger.sol";
import { IStandardBridge } from "interfaces/universal/IStandardBridge.sol";
import { IL2ToL1MessagePasser } from "interfaces/L2/IL2ToL1MessagePasser.sol";
import { IL2ToL1MessagePasserCGT } from "interfaces/L2/IL2ToL1MessagePasserCGT.sol";
import { IL2StandardBridge } from "interfaces/L2/IL2StandardBridge.sol";

/// @title L2StandardBridge_TestInit
Expand Down Expand Up @@ -299,6 +300,20 @@ contract L2StandardBridge_Receive_Test is L2StandardBridge_TestInit {
assertEq(success, true);
assertEq(address(l2ToL1MessagePasser).balance, 100);
}

/// @notice Tests that receive reverts when custom gas token is enabled and value is sent.
function testFuzz_receive_withCustomGasToken_reverts(uint256 _value) external {
skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN);

_value = bound(_value, 1, type(uint128).max);
vm.deal(alice, _value);

vm.prank(alice, alice);
vm.expectRevert(IL2ToL1MessagePasserCGT.L2ToL1MessagePasserCGT_NotAllowedOnCGTMode.selector);

(bool revertsAsExpected,) = address(l2StandardBridge).call{ value: _value }(hex"");
assertTrue(revertsAsExpected, "expectRevert: call did not revert");
}
}

/// @title L2StandardBridge_Withdraw_Test
Expand Down Expand Up @@ -376,6 +391,18 @@ contract L2StandardBridge_Withdraw_Test is L2StandardBridge_TestInit {
vm.expectRevert("StandardBridge: function can only be called from an EOA");
l2StandardBridge.withdraw(address(L2Token), 100, 1000, hex"");
}

/// @notice Tests that withdraw reverts when custom gas token is enabled and value is sent.
function testFuzz_withdraw_withCustomGasToken_reverts(uint256 _value, uint32 _minGasLimit) external {
skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN);

_value = bound(_value, 1, type(uint128).max);
vm.deal(alice, _value);

vm.prank(alice, alice);
vm.expectRevert(IL2ToL1MessagePasserCGT.L2ToL1MessagePasserCGT_NotAllowedOnCGTMode.selector);
l2StandardBridge.withdraw{ value: _value }(Predeploys.LEGACY_ERC20_ETH, _value, _minGasLimit, hex"");
}
}

/// @title L2StandardBridge_WithdrawTo_Test
Expand Down Expand Up @@ -595,4 +622,42 @@ contract L2StandardBridge_Uncategorized_Test is L2StandardBridge_TestInit {
vm.expectRevert("StandardBridge: wrong remote token for Optimism Mintable ERC20 local token");
l2StandardBridge.finalizeBridgeERC20(localToken, remoteToken, alice, alice, 100, hex"");
}

/// @notice Tests that bridgeETH reverts when custom gas token is enabled and value is sent.
function testFuzz_bridgeETH_withCustomGasToken_reverts(
uint256 _value,
uint32 _minGasLimit,
bytes calldata _extraData
)
external
{
skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN);

_value = bound(_value, 1, type(uint128).max);
vm.deal(alice, _value);

vm.prank(alice, alice);
vm.expectRevert(IL2ToL1MessagePasserCGT.L2ToL1MessagePasserCGT_NotAllowedOnCGTMode.selector);
l2StandardBridge.bridgeETH{ value: _value }(_minGasLimit, _extraData);
}

/// @notice Tests that bridgeETHTo reverts when custom gas token is enabled and value is sent.
function testFuzz_bridgeETHTo_withCustomGasToken_reverts(
address _to,
uint256 _value,
uint32 _minGasLimit,
bytes calldata _extraData
)
external
{
skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN);

vm.assume(_to != address(0));
_value = bound(_value, 1, type(uint128).max);
vm.deal(alice, _value);

vm.prank(alice, alice);
vm.expectRevert(IL2ToL1MessagePasserCGT.L2ToL1MessagePasserCGT_NotAllowedOnCGTMode.selector);
l2StandardBridge.bridgeETHTo{ value: _value }(_to, _minGasLimit, _extraData);
}
}