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
152 changes: 82 additions & 70 deletions .circleci/config.yml

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions op-deployer/pkg/deployer/devfeatures.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ var (

// DeployV2DisputeGamesDevFlag enables deployment of V2 dispute game contracts.
DeployV2DisputeGamesDevFlag = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000100")

// CustomGasTokenDevFlag enables the custom gas token.
CustomGasTokenDevFlag = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000001000")
)

// IsDevFeatureEnabled checks if a specific development feature is enabled in a feature bitmap.
Expand Down
4 changes: 0 additions & 4 deletions op-deployer/pkg/deployer/integration_test/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,6 @@ func TestEndToEndApply(t *testing.T) {
Symbol: "CGT",
InitialLiquidity: (*hexutil.Big)(amount),
}
// CGT config for OPCM
intent.GlobalDeployOverrides = map[string]interface{}{
"devFeatureBitmap": deployer.CustomGasTokenDevFlag,
}

require.NoError(t, deployer.ApplyPipeline(ctx, deployer.ApplyPipelineOpts{
DeploymentTarget: deployer.DeploymentTargetLive,
Expand Down
5 changes: 5 additions & 0 deletions packages/contracts-bedrock/scripts/deploy/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@ contract Deploy is Deployer {
deploySuperchain();
}

// Override useCustomGasToken config if system feature flag is set
if (Config.sysFeatureCustomGasToken()) {
cfg.setUseCustomGasToken(true);
}

deployImplementations({ _isInterop: cfg.useInterop() });

// Deploy Current OPChain Contracts
Expand Down
10 changes: 5 additions & 5 deletions packages/contracts-bedrock/scripts/libraries/Config.sol
Original file line number Diff line number Diff line change
Expand Up @@ -286,13 +286,13 @@ library Config {
return vm.envOr("DEV_FEATURE__DEPLOY_V2_DISPUTE_GAMES", false);
}

/// @notice Returns true if the development feature custom gas token is enabled.
function devFeatureCustomGasToken() internal view returns (bool) {
return vm.envOr("DEV_FEATURE__CUSTOM_GAS_TOKEN", false);
}

/// @notice Returns true if the development feature opcm_v2 is enabled.
function devFeatureOpcmV2() internal view returns (bool) {
return vm.envOr("DEV_FEATURE__OPCM_V2", false);
}

/// @notice Returns true if the system feature custom_gas_token is enabled.
function sysFeatureCustomGasToken() internal view returns (bool) {
return vm.envOr("SYS_FEATURE__CUSTOM_GAS_TOKEN", false);
}
}
4 changes: 0 additions & 4 deletions packages/contracts-bedrock/src/libraries/DevFeatures.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ library DevFeatures {
bytes32 public constant DEPLOY_V2_DISPUTE_GAMES =
bytes32(0x0000000000000000000000000000000000000000000000000000000000000100);

/// @notice The feature that enables the custom gas token.
bytes32 public constant CUSTOM_GAS_TOKEN =
bytes32(0x0000000000000000000000000000000000000000000000000000000000001000);

/// @notice The feature that enables the OPContractsManagerV2 contract.
bytes32 public constant OPCM_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000010000);

Expand Down
5 changes: 2 additions & 3 deletions packages/contracts-bedrock/test/L1/FeesDepositor.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { FeesDepositor } from "src/L1/FeesDepositor.sol";
import { IProxyAdminOwnedBase } from "interfaces/L1/IProxyAdminOwnedBase.sol";
import { Proxy } from "src/universal/Proxy.sol";
import { Features } from "src/libraries/Features.sol";
import { DevFeatures } from "src/libraries/DevFeatures.sol";

/// @title FeesDepositor_TestInit
/// @notice Base test contract with initialization for `FeesDepositor` tests.
Expand Down Expand Up @@ -98,7 +97,7 @@ contract FeesDepositor_Receive_Test is FeesDepositor_TestInit {
}

function testFuzz_receive_atOrAboveThreshold_succeeds(uint256 _sendAmount) external {
skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN);
skipIfSysFeatureEnabled(Features.CUSTOM_GAS_TOKEN);

// Handling the fork tests scenario case for the fork tests
uint256 depositFeesRecipientBalanceBefore = depositFeesRecipient.balance;
Expand Down Expand Up @@ -126,7 +125,7 @@ contract FeesDepositor_Receive_Test is FeesDepositor_TestInit {
}

function testFuzz_receive_multipleDeposits_succeeds(uint256 _firstAmount, uint256 _secondAmount) external {
skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN);
skipIfSysFeatureEnabled(Features.CUSTOM_GAS_TOKEN);

// Handling the fork tests scenario
uint256 depositFeesRecipientBalanceBefore = depositFeesRecipient.balance;
Expand Down
103 changes: 95 additions & 8 deletions packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { Predeploys } from "src/libraries/Predeploys.sol";
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
import { Features } from "src/libraries/Features.sol";
import { DevFeatures } from "src/libraries/DevFeatures.sol";

// Interfaces
import { ICrossDomainMessenger } from "interfaces/universal/ICrossDomainMessenger.sol";
Expand Down Expand Up @@ -333,7 +332,7 @@ contract L1StandardBridge_Paused_Test is CommonTest {
contract L1StandardBridge_Receive_Test is CommonTest {
/// @notice Tests receive bridges ETH successfully.
function test_receive_succeeds() external {
skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN);
skipIfSysFeatureEnabled(Features.CUSTOM_GAS_TOKEN);
uint256 portalBalanceBefore = address(optimismPortal2).balance;
uint256 ethLockboxBalanceBefore = address(ethLockbox).balance;

Expand Down Expand Up @@ -377,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 All @@ -388,7 +401,7 @@ contract L1StandardBridge_DepositETH_Test is L1StandardBridge_TestInit {
/// Only EOA can call depositETH.
/// ETH ends up in the optimismPortal.
function test_depositETH_fromEOA_succeeds() external {
skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN);
skipIfSysFeatureEnabled(Features.CUSTOM_GAS_TOKEN);
_preBridgeETH({ isLegacy: true, value: 500 });
uint256 portalBalanceBefore = address(optimismPortal2).balance;
uint256 ethLockboxBalanceBefore = address(ethLockbox).balance;
Expand All @@ -404,7 +417,7 @@ contract L1StandardBridge_DepositETH_Test is L1StandardBridge_TestInit {

/// @notice Tests that depositing ETH succeeds for an EOA using 7702 delegation.
function test_depositETH_fromEOA7702_succeeds() external {
skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN);
skipIfSysFeatureEnabled(Features.CUSTOM_GAS_TOKEN);
Comment thread
agusduha marked this conversation as resolved.
// Set alice to have 7702 code.
vm.etch(alice, abi.encodePacked(hex"EF0100", address(0)));

Expand All @@ -428,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 All @@ -439,7 +478,7 @@ contract L1StandardBridge_DepositETHTo_Test is L1StandardBridge_TestInit {
/// EOA or contract can call depositETHTo.
/// ETH ends up in the optimismPortal.
function test_depositETHTo_succeeds() external {
skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN);
skipIfSysFeatureEnabled(Features.CUSTOM_GAS_TOKEN);
_preBridgeETHTo({ isLegacy: true, value: 600 });
uint256 portalBalanceBefore = address(optimismPortal2).balance;
uint256 ethLockboxBalanceBefore = address(ethLockbox).balance;
Expand All @@ -457,7 +496,7 @@ contract L1StandardBridge_DepositETHTo_Test is L1StandardBridge_TestInit {
/// @param _to Random recipient address
/// @param _amount Random ETH amount to deposit
function testFuzz_depositETHTo_randomRecipient_succeeds(address _to, uint256 _amount) external {
skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN);
skipIfSysFeatureEnabled(Features.CUSTOM_GAS_TOKEN);
vm.assume(_to != address(0));
_amount = bound(_amount, 1, 10 ether);

Expand All @@ -475,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 @@ -786,7 +842,7 @@ contract L1StandardBridge_Uncategorized_Test is L1StandardBridge_TestInit {
/// Only EOA can call bridgeETH.
/// ETH ends up in the optimismPortal.
function test_bridgeETH_succeeds() external {
skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN);
skipIfSysFeatureEnabled(Features.CUSTOM_GAS_TOKEN);
_preBridgeETH({ isLegacy: false, value: 500 });
uint256 portalBalanceBefore = address(optimismPortal2).balance;
uint256 ethLockboxBalanceBefore = address(ethLockbox).balance;
Expand All @@ -806,7 +862,7 @@ contract L1StandardBridge_Uncategorized_Test is L1StandardBridge_TestInit {
/// Only EOA can call bridgeETHTo.
/// ETH ends up in the optimismPortal.
function test_bridgeETHTo_succeeds() external {
skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN);
skipIfSysFeatureEnabled(Features.CUSTOM_GAS_TOKEN);
_preBridgeETHTo({ isLegacy: false, value: 600 });
uint256 portalBalanceBefore = address(optimismPortal2).balance;
uint256 ethLockboxBalanceBefore = address(ethLockbox).balance;
Expand Down Expand Up @@ -878,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");
}
}
5 changes: 0 additions & 5 deletions packages/contracts-bedrock/test/L2/FeeSplitter.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { ReentrantMockFeeVault } from "test/mocks/ReentrantMockFeeVault.sol";
// Libraries
import { Predeploys } from "src/libraries/Predeploys.sol";
import { Types } from "src/libraries/Types.sol";
import { DevFeatures } from "src/libraries/DevFeatures.sol";

// Interfaces
import { IFeeSplitter } from "interfaces/L2/IFeeSplitter.sol";
Expand Down Expand Up @@ -42,10 +41,6 @@ contract FeeSplitter_TestInit is CommonTest {

/// @notice Test setup.
function setUp() public virtual override {
// Resolve features and skip whole test suite if custom gas token is enabled
resolveFeaturesFromEnv();
skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN);

// Enable revenue sharing before calling parent setUp
super.enableRevenueShare();
super.setUp();
Expand Down
30 changes: 28 additions & 2 deletions packages/contracts-bedrock/test/L2/FeeVault.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ 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";
import { Types } from "src/libraries/Types.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
import { DevFeatures } from "src/libraries/DevFeatures.sol";
import { Features } from "src/libraries/Features.sol";

/// @title FeeVault_Uncategorized_Test
/// @notice Abstract test contract for fee feeVault testing.
Expand Down Expand Up @@ -83,7 +84,7 @@ abstract contract FeeVault_Uncategorized_Test is CommonTest {

/// @notice Tests that `withdraw` successfully initiates a withdrawal to L1.
function test_withdraw_toL1_succeeds() external {
skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN);
skipIfSysFeatureEnabled(Features.CUSTOM_GAS_TOKEN);

// Setup L1 withdrawal
vm.prank(IProxyAdmin(Predeploys.PROXY_ADMIN).owner());
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
Loading
Loading