Commit 53d95228 authored by smartcontracts's avatar smartcontracts Committed by GitHub

feat(ct): add constructors to interfaces (#12028)

* feat(ct): add constructors to interfaces

Adds a pseudo-constructor function called __constructor__ that
will be verified as part of the interface. This pseudo-function
is useful when we want to be able to maintain type safety
in the deploy script where we use vm.getCode.

* add a pseudo-constructor for all remaining contracts with constructors

* fix warning

* update check-interface.sh comment

---------
Co-authored-by: default avatarMichael Amadi <amadimichaeld@gmail.com>
parent 9936803a
......@@ -3,8 +3,9 @@ set -euo pipefail
# This script checks for ABI consistency between interfaces and their corresponding contracts.
# It compares the ABIs of interfaces (files starting with 'I') with their implementation contracts,
# excluding constructors and certain predefined files. The script reports any differences found
# and exits with an error if inconsistencies are detected.
# excluding certain predefined files. Constructors are expected to be represented in interfaces by a
# pseudo-constructor function `__constructor__(...)` with arguments the same as the contract's constructor.
# The script reports any differences found and exits with an error if inconsistencies are detected.
# NOTE: Script is fast enough but could be parallelized if necessary.
# Parse flags
......@@ -59,6 +60,7 @@ EXCLUDE_CONTRACTS=(
"MintableAndBurnable"
"IWETH"
"IDelayedWETH"
"IResolvedDelegateProxy"
# TODO: Kontrol interfaces that need to be removed
"IL1ERC721Bridge"
......@@ -175,8 +177,8 @@ for interface_file in $JSON_FILES; do
fi
# Extract and compare ABIs excluding constructors
interface_abi=$(jq '[.abi[] | select(.type != "constructor")]' < "$interface_file")
contract_abi=$(jq '[.abi[] | select(.type != "constructor")]' < "$corresponding_contract_file")
interface_abi=$(jq '[.abi[]]' < "$interface_file")
contract_abi=$(jq '[.abi[]]' < "$corresponding_contract_file")
# Function to normalize ABI by replacing interface name with contract name.
# Base contracts aren't allowed to inherit from their interfaces in order
......@@ -190,9 +192,15 @@ for interface_file in $JSON_FILES; do
# the contract type instead of the interface type but that's unlikely
# to happen in practice and should be an easy fix if it does.
local abi="$1"
# Remove the leading "I" from types.
abi="${abi//\"internalType\": \"contract I/\"internalType\": \"contract }"
abi="${abi//\"internalType\": \"enum I/\"internalType\": \"enum }"
abi="${abi//\"internalType\": \"struct I/\"internalType\": \"struct }"
# Handle translating pseudo-constructors.
abi=$(echo "$abi" | jq 'map(if .type == "function" and .name == "__constructor__" then .type = "constructor" | del(.name) | del(.outputs) else . end)')
echo "$abi"
}
......@@ -201,7 +209,7 @@ for interface_file in $JSON_FILES; do
normalized_contract_abi=$(normalize_abi "$contract_abi")
# Use jq to compare the ABIs
if ! diff_result=$(diff -u <(echo "$normalized_interface_abi" | jq -S .) <(echo "$normalized_contract_abi" | jq -S .)); then
if ! diff_result=$(diff -u <(echo "$normalized_interface_abi" | jq 'sort') <(echo "$normalized_contract_abi" | jq 'sort')); then
if ! grep -q "^$contract_name$" "$REPORTED_INTERFACES_FILE"; then
echo "$contract_name" >> "$REPORTED_INTERFACES_FILE"
if ! is_excluded "$contract_name"; then
......
......@@ -89,4 +89,6 @@ interface IDataAvailabilityChallenge {
function variableResolutionCostPrecision() external view returns (uint256);
function version() external view returns (string memory);
function withdraw() external;
function __constructor__() external;
}
......@@ -18,4 +18,6 @@ interface IDelayedVetoable {
function target() external returns (address target_);
function version() external view returns (string memory);
function vetoer() external returns (address vetoer_);
function __constructor__(address vetoer_, address initiator_, address target_, uint256 operatingDelay_) external;
}
......@@ -50,4 +50,6 @@ interface IL2OutputOracle {
function startingTimestamp() external view returns (uint256);
function submissionInterval() external view returns (uint256);
function version() external view returns (string memory);
function __constructor__() external;
}
......@@ -113,4 +113,6 @@ interface IOptimismPortal2 {
function superchainConfig() external view returns (ISuperchainConfig);
function systemConfig() external view returns (ISystemConfig);
function version() external pure returns (string memory);
function __constructor__(uint256 _proofMaturityDelaySeconds, uint256 _disputeGameFinalityDelaySeconds) external;
}
......@@ -115,4 +115,6 @@ interface IOptimismPortalInterop {
function superchainConfig() external view returns (ISuperchainConfig);
function systemConfig() external view returns (ISystemConfig);
function version() external pure returns (string memory);
function __constructor__(uint256 _proofMaturityDelaySeconds, uint256 _disputeGameFinalityDelaySeconds) external;
}
......@@ -25,4 +25,6 @@ interface IProtocolVersions {
function setRequired(ProtocolVersion _required) external;
function transferOwnership(address newOwner) external;
function version() external view returns (string memory);
function __constructor__() external;
}
......@@ -19,4 +19,6 @@ interface ISuperchainConfig {
function paused() external view returns (bool paused_);
function unpause() external;
function version() external view returns (string memory);
function __constructor__() external;
}
......@@ -78,4 +78,6 @@ interface ISystemConfig {
function transferOwnership(address newOwner) external;
function unsafeBlockSigner() external view returns (address addr_);
function version() external pure returns (string memory);
function __constructor__() external;
}
......@@ -4,8 +4,66 @@ pragma solidity ^0.8.0;
import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol";
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
interface ISystemConfigInterop is ISystemConfig {
interface ISystemConfigInterop {
event ConfigUpdate(uint256 indexed version, ISystemConfig.UpdateType indexed updateType, bytes data);
event Initialized(uint8 version);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function BATCH_INBOX_SLOT() external view returns (bytes32);
function DISPUTE_GAME_FACTORY_SLOT() external view returns (bytes32);
function L1_CROSS_DOMAIN_MESSENGER_SLOT() external view returns (bytes32);
function L1_ERC_721_BRIDGE_SLOT() external view returns (bytes32);
function L1_STANDARD_BRIDGE_SLOT() external view returns (bytes32);
function OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT() external view returns (bytes32);
function OPTIMISM_PORTAL_SLOT() external view returns (bytes32);
function START_BLOCK_SLOT() external view returns (bytes32);
function UNSAFE_BLOCK_SIGNER_SLOT() external view returns (bytes32);
function VERSION() external view returns (uint256);
function basefeeScalar() external view returns (uint32);
function batchInbox() external view returns (address addr_);
function batcherHash() external view returns (bytes32);
function blobbasefeeScalar() external view returns (uint32);
function disputeGameFactory() external view returns (address addr_);
function gasLimit() external view returns (uint64);
function gasPayingToken() external view returns (address addr_, uint8 decimals_);
function gasPayingTokenName() external view returns (string memory name_);
function gasPayingTokenSymbol() external view returns (string memory symbol_);
function initialize(
address _owner,
uint32 _basefeeScalar,
uint32 _blobbasefeeScalar,
bytes32 _batcherHash,
uint64 _gasLimit,
address _unsafeBlockSigner,
IResourceMetering.ResourceConfig memory _config,
address _batchInbox,
ISystemConfig.Addresses memory _addresses
)
external;
function isCustomGasToken() external view returns (bool);
function l1CrossDomainMessenger() external view returns (address addr_);
function l1ERC721Bridge() external view returns (address addr_);
function l1StandardBridge() external view returns (address addr_);
function maximumGasLimit() external pure returns (uint64);
function minimumGasLimit() external view returns (uint64);
function optimismMintableERC20Factory() external view returns (address addr_);
function optimismPortal() external view returns (address addr_);
function overhead() external view returns (uint256);
function owner() external view returns (address);
function renounceOwnership() external;
function resourceConfig() external view returns (IResourceMetering.ResourceConfig memory);
function scalar() external view returns (uint256);
function setBatcherHash(bytes32 _batcherHash) external;
function setGasConfig(uint256 _overhead, uint256 _scalar) external;
function setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobbasefeeScalar) external;
function setGasLimit(uint64 _gasLimit) external;
function setUnsafeBlockSigner(address _unsafeBlockSigner) external;
function startBlock() external view returns (uint256 startBlock_);
function transferOwnership(address newOwner) external;
function unsafeBlockSigner() external view returns (address addr_);
function addDependency(uint256 _chainId) external;
function removeDependency(uint256 _chainId) external;
function dependencyManager() external view returns (address);
function initialize(
address _owner,
......@@ -16,9 +74,9 @@ interface ISystemConfigInterop is ISystemConfig {
address _unsafeBlockSigner,
IResourceMetering.ResourceConfig memory _config,
address _batchInbox,
Addresses memory _addresses,
ISystemConfig.Addresses memory _addresses,
address _dependencyManager
)
external;
function removeDependency(uint256 _chainId) external;
function version() external pure returns (string memory);
}
......@@ -5,4 +5,11 @@ import { IFeeVault } from "src/universal/interfaces/IFeeVault.sol";
interface IBaseFeeVault is IFeeVault {
function version() external view returns (string memory);
function __constructor__(
address _recipient,
uint256 _minWithdrawalAmount,
WithdrawalNetwork _withdrawalNetwork
)
external;
}
......@@ -5,4 +5,11 @@ import { IFeeVault } from "src/universal/interfaces/IFeeVault.sol";
interface IL1FeeVault is IFeeVault {
function version() external view returns (string memory);
function __constructor__(
address _recipient,
uint256 _minWithdrawalAmount,
WithdrawalNetwork _withdrawalNetwork
)
external;
}
......@@ -8,4 +8,6 @@ interface IL2CrossDomainMessenger is ICrossDomainMessenger {
function initialize(ICrossDomainMessenger _l1CrossDomainMessenger) external;
function l1CrossDomainMessenger() external view returns (ICrossDomainMessenger);
function version() external view returns (string memory);
function __constructor__() external;
}
......@@ -15,4 +15,6 @@ interface IL2ERC721Bridge is IERC721Bridge {
external;
function initialize(address payable _l1ERC721Bridge) external;
function version() external view returns (string memory);
function __constructor__() external;
}
......@@ -43,4 +43,6 @@ interface IL2StandardBridge is IStandardBridge {
)
external
payable;
function __constructor__() external;
}
......@@ -2,14 +2,15 @@
pragma solidity ^0.8.0;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IL2StandardBridge } from "src/L2/interfaces/IL2StandardBridge.sol";
import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol";
import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol";
interface IMintableAndBurnable is IERC20 {
function mint(address, uint256) external;
function burn(address, uint256) external;
}
interface IL2StandardBridgeInterop is IL2StandardBridge {
interface IL2StandardBridgeInterop is IStandardBridge {
error InvalidDecimals();
error InvalidLegacyERC20Address();
error InvalidSuperchainERC20Address();
......@@ -19,5 +20,79 @@ interface IL2StandardBridgeInterop is IL2StandardBridge {
receive() external payable;
event DepositFinalized(
address indexed l1Token,
address indexed l2Token,
address indexed from,
address to,
uint256 amount,
bytes extraData
);
event WithdrawalInitiated(
address indexed l1Token,
address indexed l2Token,
address indexed from,
address to,
uint256 amount,
bytes extraData
);
function MESSENGER() external view returns (ICrossDomainMessenger);
function OTHER_BRIDGE() external view returns (IStandardBridge);
function bridgeERC20(
address _localToken,
address _remoteToken,
uint256 _amount,
uint32 _minGasLimit,
bytes memory _extraData
)
external;
function bridgeERC20To(
address _localToken,
address _remoteToken,
address _to,
uint256 _amount,
uint32 _minGasLimit,
bytes memory _extraData
)
external;
function bridgeETH(uint32 _minGasLimit, bytes memory _extraData) external payable;
function bridgeETHTo(address _to, uint32 _minGasLimit, bytes memory _extraData) external payable;
function deposits(address, address) external view returns (uint256);
function finalizeBridgeERC20(
address _localToken,
address _remoteToken,
address _from,
address _to,
uint256 _amount,
bytes memory _extraData
)
external;
function finalizeBridgeETH(address _from, address _to, uint256 _amount, bytes memory _extraData) external payable;
function messenger() external view returns (ICrossDomainMessenger);
function otherBridge() external view returns (IStandardBridge);
function paused() external view returns (bool);
function initialize(IStandardBridge _otherBridge) external;
function l1TokenBridge() external view returns (address);
function withdraw(
address _l2Token,
uint256 _amount,
uint32 _minGasLimit,
bytes memory _extraData
)
external
payable;
function withdrawTo(
address _l2Token,
address _to,
uint256 _amount,
uint32 _minGasLimit,
bytes memory _extraData
)
external
payable;
function convert(address _from, address _to, uint256 _amount) external;
function version() external pure returns (string memory);
}
......@@ -6,4 +6,11 @@ import { IFeeVault } from "src/universal/interfaces/IFeeVault.sol";
interface ISequencerFeeVault is IFeeVault {
function version() external view returns (string memory);
function l1FeeWallet() external view returns (address);
function __constructor__(
address _recipient,
uint256 _minWithdrawalAmount,
WithdrawalNetwork _withdrawalNetwork
)
external;
}
......@@ -12,4 +12,6 @@ interface IMIPS is ISemver {
function oracle() external view returns (IPreimageOracle oracle_);
function step(bytes memory _stateData, bytes memory _proof, bytes32 _localContext) external returns (bytes32);
function __constructor__(IPreimageOracle _oracle) external;
}
......@@ -14,4 +14,6 @@ interface IMIPS2 is ISemver {
function oracle() external view returns (IPreimageOracle oracle_);
function step(bytes memory _stateData, bytes memory _proof, bytes32 _localContext) external returns (bytes32);
function __constructor__(IPreimageOracle _oracle) external;
}
......@@ -29,4 +29,6 @@ interface IAnchorStateRegistry {
function superchainConfig() external view returns (ISuperchainConfig);
function tryUpdateAnchorState() external;
function version() external view returns (string memory);
function __constructor__(IDisputeGameFactory _disputeGameFactory) external;
}
......@@ -69,4 +69,6 @@ interface IDisputeGameFactory {
function setInitBond(GameType _gameType, uint256 _initBond) external;
function transferOwnership(address newOwner) external;
function version() external view returns (string memory);
function __constructor__() external;
}
......@@ -112,4 +112,18 @@ interface IFaultDisputeGame is IDisputeGame {
function version() external view returns (string memory);
function vm() external view returns (IBigStepper vm_);
function weth() external view returns (IDelayedWETH weth_);
function __constructor__(
GameType _gameType,
Claim _absolutePrestate,
uint256 _maxGameDepth,
uint256 _splitDepth,
Duration _clockExtension,
Duration _maxClockDuration,
IBigStepper _vm,
IDelayedWETH _weth,
IAnchorStateRegistry _anchorStateRegistry,
uint256 _l2ChainId
)
external;
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol";
import { Types } from "src/libraries/Types.sol";
import "src/dispute/lib/Types.sol";
import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol";
import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol";
import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol";
import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
interface IPermissionedDisputeGame is IDisputeGame {
struct ClaimData {
uint32 parentIndex;
address counteredBy;
address claimant;
uint128 bond;
Claim claim;
Position position;
Clock clock;
}
struct ResolutionCheckpoint {
bool initialCheckpointComplete;
uint32 subgameIndex;
Position leftmostPosition;
address counteredBy;
}
error AlreadyInitialized();
error AnchorRootNotFound();
error BlockNumberMatches();
error BondTransferFailed();
error CannotDefendRootClaim();
error ClaimAboveSplit();
error ClaimAlreadyExists();
error ClaimAlreadyResolved();
error ClockNotExpired();
error ClockTimeExceeded();
error ContentLengthMismatch();
error DuplicateStep();
error EmptyItem();
error GameDepthExceeded();
error GameNotInProgress();
error IncorrectBondAmount();
error InvalidChallengePeriod();
error InvalidClockExtension();
error InvalidDataRemainder();
error InvalidDisputedClaimIndex();
error InvalidHeader();
error InvalidHeaderRLP();
error InvalidLocalIdent();
error InvalidOutputRootProof();
error InvalidParent();
error InvalidPrestate();
error InvalidSplitDepth();
error L2BlockNumberChallenged();
error MaxDepthTooLarge();
error NoCreditToClaim();
error OutOfOrderResolution();
error UnexpectedList();
error UnexpectedRootClaim(Claim rootClaim);
error UnexpectedString();
error ValidStep();
event Move(uint256 indexed parentIndex, Claim indexed claim, address indexed claimant);
function absolutePrestate() external view returns (Claim absolutePrestate_);
function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external;
function anchorStateRegistry() external view returns (IAnchorStateRegistry registry_);
function attack(Claim _disputed, uint256 _parentIndex, Claim _claim) external payable;
function challengeRootL2Block(Types.OutputRootProof memory _outputRootProof, bytes memory _headerRLP) external;
function claimCredit(address _recipient) external;
function claimData(uint256)
external
view
returns (
uint32 parentIndex,
address counteredBy,
address claimant,
uint128 bond,
Claim claim,
Position position,
Clock clock
);
function claimDataLen() external view returns (uint256 len_);
function claims(Hash) external view returns (bool);
function clockExtension() external view returns (Duration clockExtension_);
function credit(address) external view returns (uint256);
function defend(Claim _disputed, uint256 _parentIndex, Claim _claim) external payable;
function getChallengerDuration(uint256 _claimIndex) external view returns (Duration duration_);
function getNumToResolve(uint256 _claimIndex) external view returns (uint256 numRemainingChildren_);
function getRequiredBond(Position _position) external view returns (uint256 requiredBond_);
function l2BlockNumber() external pure returns (uint256 l2BlockNumber_);
function l2BlockNumberChallenged() external view returns (bool);
function l2BlockNumberChallenger() external view returns (address);
function l2ChainId() external view returns (uint256 l2ChainId_);
function maxClockDuration() external view returns (Duration maxClockDuration_);
function maxGameDepth() external view returns (uint256 maxGameDepth_);
function move(Claim _disputed, uint256 _challengeIndex, Claim _claim, bool _isAttack) external payable;
function resolutionCheckpoints(uint256)
external
view
returns (bool initialCheckpointComplete, uint32 subgameIndex, Position leftmostPosition, address counteredBy);
function resolveClaim(uint256 _claimIndex, uint256 _numToResolve) external;
function resolvedSubgames(uint256) external view returns (bool);
function splitDepth() external view returns (uint256 splitDepth_);
function startingBlockNumber() external view returns (uint256 startingBlockNumber_);
function startingOutputRoot() external view returns (Hash root, uint256 l2BlockNumber);
function startingRootHash() external view returns (Hash startingRootHash_);
function step(uint256 _claimIndex, bool _isAttack, bytes memory _stateData, bytes memory _proof) external;
function subgames(uint256, uint256) external view returns (uint256);
function version() external view returns (string memory);
function vm() external view returns (IBigStepper vm_);
function weth() external view returns (IDelayedWETH weth_);
interface IPermissionedDisputeGame is IFaultDisputeGame {
error BadAuth();
function proposer() external view returns (address proposer_);
function challenger() external view returns (address challenger_);
function __constructor__(
GameType _gameType,
Claim _absolutePrestate,
uint256 _maxGameDepth,
uint256 _splitDepth,
Duration _clockExtension,
Duration _maxClockDuration,
IBigStepper _vm,
IDelayedWETH _weth,
IAnchorStateRegistry _anchorStateRegistry,
uint256 _l2ChainId,
address _proposer,
address _challenger
)
external;
}
......@@ -47,4 +47,6 @@ interface IGovernanceToken {
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function transferOwnership(address newOwner) external;
function __constructor__() external;
}
......@@ -16,4 +16,6 @@ interface IMintManager {
function renounceOwnership() external;
function transferOwnership(address newOwner) external;
function upgrade(address _newMintManager) external;
function __constructor__(address _upgrader, address _governanceToken) external;
}
......@@ -13,6 +13,8 @@ interface IL1ChugSplashProxy {
function setCode(bytes memory _code) external;
function setOwner(address _owner) external;
function setStorage(bytes32 _key, bytes32 _value) external;
function __constructor__(address _owner) external;
}
/// @title IStaticL1ChugSplashProxy
......
......@@ -33,4 +33,6 @@ interface IOptimismMintableERC20Factory {
function deployments(address) external view returns (address);
function initialize(address _bridge) external;
function version() external view returns (string memory);
function __constructor__() external;
}
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