Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3adaa1b
feat: add cgt to opcmv2
0xniha Dec 1, 2025
8056846
feat: add cgt to opcmv2
0xniha Dec 1, 2025
c372ddc
Merge pull request #715 from defi-wonderland/feat/ocpm2-cgt-rebase
0xniha Dec 2, 2025
1bea1af
refactor: change disputeGameConfigs order in _loadFullConfig
0xniha Dec 2, 2025
589263f
fix: comment slash rules
0xniha Dec 2, 2025
457e671
feat: add opcmv2-cgt matrix in CI
0xniha Dec 2, 2025
cc039a3
Merge branch 'develop' into sync/opcm2
0xiamflux Dec 3, 2025
df3ecf5
Merge pull request #721 from defi-wonderland/sync/opcm2
0xiamflux Dec 3, 2025
2614984
fix: enable cgt overrides on OPCMv2 (#724)
0xiamflux Dec 3, 2025
d4ed6d1
fix: add extra instruction overrides for useCustomGasToken on OPCMv2 …
0xiamflux Dec 4, 2025
92672f6
chore: link TODO to issue (#727)
0xiamflux Dec 4, 2025
ba4dea9
fix: opcm2 revert upgrade cgt (#728)
0xiamflux Dec 4, 2025
01382eb
Merge branch 'develop' into sync/opcm2
0xiamflux Dec 5, 2025
715ea8c
chore: pre-pr ready
0xiamflux Dec 5, 2025
deb91df
Merge pull request #730 from defi-wonderland/sync/opcm2
0xiamflux Dec 5, 2025
e30a758
Merge branch 'develop' into sync/opcm2
0xiamflux Dec 5, 2025
8db31c9
Merge pull request #733 from defi-wonderland/sync/opcm2
0xiamflux Dec 5, 2025
493b1f6
refactor: remove unnecessary check for CGT feature (#735)
0xiamflux Dec 5, 2025
bd67266
fix: cgt upgrade in opcm v2 and semver (#738)
0xniha Dec 8, 2025
b666260
fix: Full checkout for FFI build (#18527)
janjakubnanista Dec 6, 2025
d168a33
chore(op-acceptance-tests): delete very old logs (#18529)
scharissis Dec 6, 2025
c5f78b7
chore(op-acceptance-tests): op-acceptor v3.8.0 (#18530)
scharissis Dec 6, 2025
6ee7464
jovian: remove feature toggles (#17978)
geoknee Dec 8, 2025
6014659
chore(ai-eng): add ReinitializableBase test to exclusion list (#18531)
aliersh Dec 8, 2025
bbd28e0
feat: have OPCM upgrade allowances be upgrade specific (#18462)
smartcontracts Dec 8, 2025
516a62f
fix(op-acceptance-test): flake-shake; empty slack notifications. (#18…
scharissis Dec 8, 2025
9dc54e5
feat: add cgt to opcmv2
0xniha Dec 1, 2025
7eb2ee0
feat: add cgt to opcmv2
0xniha Dec 1, 2025
25dfddf
refactor: change disputeGameConfigs order in _loadFullConfig
0xniha Dec 2, 2025
c8fc998
fix: enable cgt overrides on OPCMv2 (#724)
0xiamflux Dec 3, 2025
14f18c5
fix: opcm2 revert upgrade cgt (#728)
0xiamflux Dec 4, 2025
1e17cda
fix: cgt upgrade in opcm v2 and semver (#738)
0xniha Dec 8, 2025
997ca49
fix: merge conflicts
0xniha Dec 8, 2025
8b5554f
fix: pre-pr
0xniha Dec 8, 2025
810c320
fix: add missing isMatchingInstruction for cgt in false
0xniha Dec 9, 2025
9043cd0
Merge pull request #740 from defi-wonderland/chore/opcm2-cgt-sync
0xiamflux Dec 9, 2025
ad74c46
Merge branch 'develop' into sync/opcm2
0xiamflux Dec 9, 2025
eb2e248
Merge pull request #742 from defi-wonderland/sync/opcm2
0xiamflux Dec 9, 2025
538323f
Merge develop into sc-feat/opcm2-add-cgt
0xiamflux Dec 9, 2025
550f2be
Merge pull request #743 from defi-wonderland/sync/opcm2
0xiamflux Dec 9, 2025
7aea894
refactor: opcm2 extra instruction keymatch (#747)
0xiamflux Dec 9, 2025
6cee90f
fix: opcmv2 semver
0xniha Dec 10, 2025
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
3 changes: 2 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2582,8 +2582,9 @@ workflows:
- OPTIMISM_PORTAL_INTEROP
- CANNON_KONA,DEPLOY_V2_DISPUTE_GAMES
- OPCM_V2
- OPCM_V2,OPTIMISM_PORTAL_INTEROP
- CUSTOM_GAS_TOKEN
- OPCM_V2,CUSTOM_GAS_TOKEN
- OPCM_V2,OPTIMISM_PORTAL_INTEROP
context:
- circleci-repo-readonly-authenticated-github-token
- contracts-bedrock-tests:
Expand Down
12 changes: 11 additions & 1 deletion .cursor/rules/solidity-styles.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ description:
globs: *.sol
alwaysApply: false
---

# Optimism Solidity Style Guide

Applies to Solidity files.

## Comments
- Use triple-slash solidity natspec comment style

- NatSpec documentation comments must use the triple-slash `///` style
- Use `//` for regular inline comments that are not NatSpec
- Always use `@notice` instead of `@dev`
- Use a line-length of 100 characters
- Custom tags:
Expand All @@ -19,10 +22,12 @@ Applies to Solidity files.
- `@custom:network-specific`: Add to state variables which vary between OP Chains

## Errors

- When adding new errors, always use custom Solidity errors
- Custom errors should take the format `ContractName_ErrorDescription`

## Naming Conventions

- Function parameters should be prefixed with an underscore
- Function return arguments should be suffixed with an underscore
- Event parameters should NOT be prefixed with an underscore
Expand All @@ -33,6 +38,7 @@ Applies to Solidity files.
- Spacers must be named `spacer_<slot>_<offset>_<length>` and be `private`

## Upgradeability

- Contracts should be built assuming upgradeability by default
- Extend OpenZeppelin's `Initializable` or base contract
- Use the `ReinitializableBase` contract
Expand All @@ -43,6 +49,7 @@ Applies to Solidity files.
- Set any immutables (though generally avoid immutables)

## Versioning

- All non-library/non-abstract contracts must inherit `ISemver` and expose `version()`
- Production-ready contracts must have version `1.0.0` or greater
- Version increments:
Expand All @@ -53,12 +60,15 @@ Applies to Solidity files.
AI code review tools should NOT comment on the choice of version increment.

## Dependencies

- Prefer OpenZeppelin's Upgradeable contracts for basic functionality

## State Changes

- All state changing functions should emit a corresponding event

## Testing

- Tests should be written using Foundry
- For testing reverts with low-level calls, use the `revertsAsExpected` pattern
- Test function naming: `[method]_[functionName]_[reason]_[status]`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ interface IOPContractsManagerUtils {
pure
returns (bytes32);

function isMatchingInstructionByKey(
ExtraInstruction memory _instruction,
string memory _key
)
external
pure
returns (bool);

function isMatchingInstruction(
ExtraInstruction memory _instruction,
string memory _key,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ interface IOPContractsManagerV2 {
uint256 l2ChainId;
IResourceMetering.ResourceConfig resourceConfig;
DisputeGameConfig[] disputeGameConfigs;
bool useCustomGasToken;
}

struct ExtraInstruction {
string key;
bytes data;
}

struct UpgradeInput {
Expand All @@ -99,6 +105,7 @@ interface IOPContractsManagerV2 {
error OPContractsManagerV2_SuperchainConfigNeedsUpgrade();
error OPContractsManagerV2_UnsupportedGameType();
error OPContractsManagerV2_InvalidUpgradeInstruction(string _key);
error OPContractsManagerV2_CannotUpgradeToCustomGasToken();
error IdentityPrecompileCallFailed();
error ReservedBitsSet();
error BytesArrayTooLong();
Expand Down Expand Up @@ -131,9 +138,7 @@ interface IOPContractsManagerV2 {
function version() external view returns (string memory);

/// @notice Upgrades Superchain-wide contracts.
function upgradeSuperchain(SuperchainUpgradeInput memory _inp)
external
returns (SuperchainContracts memory);
function upgradeSuperchain(SuperchainUpgradeInput memory _inp) external returns (SuperchainContracts memory);

/// @notice Deploys and wires a complete OP Chain per the provided configuration.
function deploy(FullConfig memory _cfg) external returns (ChainContracts memory);
Expand Down
3 changes: 2 additions & 1 deletion packages/contracts-bedrock/scripts/deploy/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,8 @@ contract Deploy is Deployer {
gasLimit: uint64(cfg.l2GenesisBlockGasLimit()),
l2ChainId: cfg.l2ChainID(),
resourceConfig: Constants.DEFAULT_RESOURCE_CONFIG(),
disputeGameConfigs: disputeGameConfigs
disputeGameConfigs: disputeGameConfigs,
useCustomGasToken: cfg.useCustomGasToken()
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,42 @@
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "string",
"name": "key",
"type": "string"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"internalType": "struct OPContractsManagerUtils.ExtraInstruction",
"name": "_instruction",
"type": "tuple"
},
{
"internalType": "string",
"name": "_key",
"type": "string"
}
],
"name": "isMatchingInstructionByKey",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,11 @@
"internalType": "struct OPContractsManagerV2.DisputeGameConfig[]",
"name": "disputeGameConfigs",
"type": "tuple[]"
},
{
"internalType": "bool",
"name": "useCustomGasToken",
"type": "bool"
}
],
"internalType": "struct OPContractsManagerV2.FullConfig",
Expand Down Expand Up @@ -700,6 +705,11 @@
"name": "NotABlueprint",
"type": "error"
},
{
"inputs": [],
"name": "OPContractsManagerV2_CannotUpgradeToCustomGasToken",
"type": "error"
},
{
"inputs": [],
"name": "OPContractsManagerV2_InvalidGameConfigs",
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts-bedrock/snapshots/semver-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
"sourceCodeHash": "0xb3184aa5d95a82109e7134d1f61941b30e25f655b9849a0e303d04bbce0cde0b"
},
"src/L1/opcm/OPContractsManagerV2.sol:OPContractsManagerV2": {
"initCodeHash": "0x9b6b84f8b87f60c5a38460e78aa6768205f741b17fa60c6d93a1094a8681bd79",
"sourceCodeHash": "0x846dca230392d8e378a2e208a708fc9be342715fd1ca3e3d7c1700f667e25fff"
"initCodeHash": "0xf853fa9b9320cd355d1dc729bda114f19335dac7ba384b96ba3d88a8d5f3b0c1",
"sourceCodeHash": "0x0352c9337f1f81271eaf968b6d95f8a80c3a8ad31a61989d845e72e52e438f03"
},
"src/L2/BaseFeeVault.sol:BaseFeeVault": {
"initCodeHash": "0x838bbd7f381e84e21887f72bd1da605bfc4588b3c39aed96cbce67c09335b3ee",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,21 @@ contract OPContractsManagerUtils {
return keccak256(abi.encode(_l2ChainId, _saltMixer, _contractName));
}

/// @notice Helper function to check if an instruction matches a given key.
/// @param _instruction The instruction to check.
/// @param _key The key of the instruction to check for.
/// @return True if the instruction matches, false otherwise.
function isMatchingInstructionByKey(
ExtraInstruction memory _instruction,
string memory _key
)
public
pure
returns (bool)
{
return LibString.eq(_instruction.key, _key);
}

/// @notice Helper function to check if an instruction matches a given key and data.
/// @param _instruction The instruction to check.
/// @param _key The key of the instruction to check for.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,24 @@ abstract contract OPContractsManagerUtilsCaller {
);
}

/// @notice Helper function to check if an instruction matches a given key.
/// @param _instruction The instruction to check.
/// @param _key The key of the instruction to check for.
/// @return True if the instruction matches, false otherwise.
function _isMatchingInstructionByKey(
IOPContractsManagerUtils.ExtraInstruction memory _instruction,
string memory _key
)
internal
view
returns (bool)
{
return abi.decode(
_staticcall(abi.encodeCall(IOPContractsManagerUtils.isMatchingInstructionByKey, (_instruction, _key))),
(bool)
);
}

/// @notice Helper function to check if an instruction matches a given key and data.
/// @param _instruction The instruction to check.
/// @param _key The key of the instruction to check for.
Expand Down
43 changes: 39 additions & 4 deletions packages/contracts-bedrock/src/L1/opcm/OPContractsManagerV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ contract OPContractsManagerV2 is ISemver, OPContractsManagerUtilsCaller {
IResourceMetering.ResourceConfig resourceConfig;
// Dispute game configuration.
DisputeGameConfig[] disputeGameConfigs;
// CGT
bool useCustomGasToken;
}

/// @notice Partial input required for an upgrade.
Expand Down Expand Up @@ -146,6 +148,9 @@ contract OPContractsManagerV2 is ISemver, OPContractsManagerUtilsCaller {
/// @notice Thrown when an invalid upgrade instruction is provided.
error OPContractsManagerV2_InvalidUpgradeInstruction(string _key);

/// @notice Thrown when a chain attempts to upgrade to custom gas token after initial deployment.
error OPContractsManagerV2_CannotUpgradeToCustomGasToken();

/// @notice Container of blueprint and implementation contract addresses.
IOPContractsManagerContainer public immutable contractsContainer;

Expand All @@ -161,8 +166,8 @@ contract OPContractsManagerV2 is ISemver, OPContractsManagerUtilsCaller {
/// - Major bump: New required sequential upgrade
/// - Minor bump: Replacement OPCM for same upgrade
/// - Patch bump: Development changes (expected for normal dev work)
/// @custom:semver 6.0.4
string public constant version = "6.0.4";
/// @custom:semver 6.0.5
string public constant version = "6.0.5";

/// @param _contractsContainer The container of blueprint and implementation contract addresses.
/// @param _standardValidator The standard validator for this OPCM release.
Expand Down Expand Up @@ -297,7 +302,14 @@ contract OPContractsManagerV2 is ISemver, OPContractsManagerUtilsCaller {
if (SemverComp.lt(version, "7.0.0")) {
// Unified DelayedWETH is being deployed for the first time.
// TODO:(#18382): Remove this allowance after unified DelayedWETH is deployed.
return _isMatchingInstruction(_instruction, Constants.PERMITTED_PROXY_DEPLOYMENT_KEY, "DelayedWETH");
if (_isMatchingInstruction(_instruction, Constants.PERMITTED_PROXY_DEPLOYMENT_KEY, "DelayedWETH")) {
return true;
}
// Custom Gas Token is being enabled for the first time.
// TODO:(#18502): Remove this allowance after U18 ships.
if (_isMatchingInstructionByKey(_instruction, "overrides.cfg.useCustomGasToken")) {
return true;
}
}

// Always return false by default.
Expand All @@ -310,6 +322,7 @@ contract OPContractsManagerV2 is ISemver, OPContractsManagerUtilsCaller {
/// @param _saltMixer The salt mixer for creating new proxies if needed.
/// @param _extraInstructions The extra upgrade instructions for the chain.
/// @return The chain contracts.

function _loadChainContracts(
ISystemConfig _systemConfig,
uint256 _l2ChainId,
Expand Down Expand Up @@ -503,6 +516,7 @@ contract OPContractsManagerV2 is ISemver, OPContractsManagerUtilsCaller {
{
// Load the full config.
return FullConfig({
disputeGameConfigs: _upgradeInput.disputeGameConfigs,
saltMixer: string(bytes.concat(bytes32(uint256(uint160(address(_chainContracts.systemConfig)))))),
superchainConfig: abi.decode(
_loadBytes(
Expand Down Expand Up @@ -612,7 +626,15 @@ contract OPContractsManagerV2 is ISemver, OPContractsManagerUtilsCaller {
),
(GameType)
),
disputeGameConfigs: _upgradeInput.disputeGameConfigs
useCustomGasToken: abi.decode(
_loadBytes(
address(_chainContracts.systemConfig),
_chainContracts.systemConfig.isCustomGasToken.selector,
"overrides.cfg.useCustomGasToken",
_upgradeInput.extraInstructions
),
(bool)
)
});
}

Expand Down Expand Up @@ -816,6 +838,19 @@ contract OPContractsManagerV2 is ISemver, OPContractsManagerUtilsCaller {
);
}

// If the custom gas token feature was requested, enable it in the SystemConfig.
// If the cgt is enabled, we skip this step.
if (_cfg.useCustomGasToken && !_cts.systemConfig.isCustomGasToken()) {
// NOTE: Enabling the custom gas token feature is only allowed during initial deployment to prevent
// chains from enabling it during upgrades. Passing in true for this flag during an upgrade is considered an
// error and will revert.
// Revert only if trying to upgrade from CGT disabled to CGT enabled.
if (!_isInitialDeployment) {
revert OPContractsManagerV2_CannotUpgradeToCustomGasToken();
}
_cts.systemConfig.setFeature(Features.CUSTOM_GAS_TOKEN, true);
}

// If critical transfer is allowed, tranfer ownership of the DisputeGameFactory and
// ProxyAdmin to the PAO. During deployments, this means transferring ownership from the
// OPCM contract to the target PAO. During upgrades, this would theoretically mean
Expand Down
Loading