mega-system-contracts 1.7.0

System contracts for the MegaETH EVM
Documentation
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title IKeylessDeploy
/// @notice Interface for the KeylessDeploy system contract.
/// @dev This contract enables deploying contracts using pre-EIP-155 transactions (Nick's Method)
/// with custom gas limits, solving the problem of contracts failing to deploy on MegaETH
/// due to the different gas model.
interface IKeylessDeploy {
    /// @notice The transaction data is not valid RLP encoding.
    error MalformedEncoding();

    /// @notice The transaction is not a contract creation (to address is not empty).
    error NotContractCreation();

    /// @notice The transaction is not pre-EIP-155 (v must be 27 or 28).
    error NotPreEIP155();

    /// @notice The nonce in the signed transaction is not zero.
    /// @param txNonce The nonce value in the signed transaction.
    error NonZeroTxNonce(uint64 txNonce);

    /// @notice The caller tried to transfer ether to this contract.
    error NoEtherTransfer();

    /// @notice Failed to recover signer from signature (invalid signature).
    error InvalidSignature();

    /// @notice The signer does not have enough balance to cover the sandbox transaction's
    ///         pre-execution debit. Pre-Rex5 specs require `gas_limit × gas_price + value`;
    ///         Rex5+ requires `value` only because the sandbox transaction runs fee-free.
    error InsufficientBalance();

    /// @notice The deploy address already has code (contract already exists).
    error ContractAlreadyExists();

    /// @notice The signer nonce is higher than allowed for keyless deploy.
    /// @param signerNonce The on-chain nonce of the recovered signer.
    error SignerNonceTooHigh(uint64 signerNonce);

    /// @notice The sandbox execution reverted.
    /// @param gasUsed The amount of gas used before reverting.
    /// @param output The revert output data.
    error ExecutionReverted(uint64 gasUsed, bytes output);

    /// @notice The sandbox execution halted (out of gas, stack overflow, etc.).
    /// @param gasUsed The amount of gas used before halting.
    error ExecutionHalted(uint64 gasUsed);

    /// @notice Rex5 preflight rejected the call because the parent transaction's remaining budget
    ///         for a resource dimension is smaller than the sandbox's known pre-frame intrinsic usage.
    /// @dev Emitted as a Revert by the Rust interceptor when the preflight check fails.
    ///      Not used by the on-chain KeylessDeploy bytecode.
    /// @param kind The resource dimension that exceeded (0=DataSize, 1=KVUpdate, 2=ComputeGas,
    ///        3=StateGrowth).
    /// @param limit The parent's remaining limit for that dimension.
    /// @param used The sandbox's known pre-frame intrinsic usage for that dimension.
    error ParentBudgetExceeded(uint8 kind, uint64 limit, uint64 used);

    /// @notice Contract creation succeeded but returned empty bytecode.
    /// @param gasUsed The amount of gas used.
    error EmptyCodeDeployed(uint64 gasUsed);

    /// @notice Contract creation succeeded but no address was returned.
    /// @dev This is a defensive check that should never occur. It indicates an EVM implementation
    /// bug where CREATE returned success without an address. If encountered, report to MegaETH team.
    error NoContractCreated();

    /// @notice The created contract address doesn't match the expected address.
    /// @dev This is a defensive check that should never occur. It would indicate the EVM computed
    /// a different CREATE address than keccak256(rlp([signer, 0])). If encountered, report to MegaETH team.
    error AddressMismatch();

    /// @notice The gas limit override is less than the gas limit in the keyless transaction.
    /// @param txGasLimit The gas limit from the keyless transaction.
    /// @param providedGasLimit The gas limit override provided by the caller.
    error GasLimitTooLow(uint64 txGasLimit, uint64 providedGasLimit);

    /// @notice The remaining compute gas is insufficient to pay for the keyless deploy overhead.
    /// @param limit The configured compute gas limit.
    /// @param used The compute gas usage.
    error InsufficientComputeGas(uint64 limit, uint64 used);

    /// @notice The init code of the keyless deployment transaction exceeds the configured
    ///         maximum initcode size for the current spec.
    /// @dev REX5+: enforced by the Rust interceptor before the sandbox is constructed, because
    ///      the deposit-style sandbox bypasses op-revm's `validate_env` (which would otherwise
    ///      apply the same limit via revm's EIP-3860 check).
    /// @param size The init code length in bytes.
    /// @param max The configured maximum init code size (from `cfg().max_initcode_size()`).
    error InitCodeTooLarge(uint64 size, uint64 max);

    /// @notice The recovered signer of the keyless deployment transaction has non-empty,
    ///         non-EIP-7702 code in parent state, so it cannot originate transactions per
    ///         EIP-3607.
    /// @dev REX5+: enforced by the Rust interceptor because the deposit-style sandbox
    ///      bypasses op-revm's `validate_account_nonce_and_code` check.
    error SignerHasCode();

    /// @notice Internal sandbox failure (DB I/O, header validation, etc.).
    /// @dev Selector-only: precompile return data is consensus-affecting, so the wire
    ///      must not pin consensus to upstream revm/op-revm `Display` impls.
    error InternalError();

    /// @notice Sandbox rejected the inner transaction as a tx-validation error — any
    /// `IsTxError::is_tx_error() == true` outcome of the sandbox `transact_raw` call.
    /// Behaviorally identical to `InternalError` (outer call reverts, signer is not
    /// charged because `pre_execution()` never ran); a dedicated selector lets
    /// relayer-side decoders distinguish this from a genuine internal failure.
    /// @dev Selector-only for the same consensus-decoupling reason as `InternalError`.
    error InvalidTransaction();

    /// @notice The call was not intercepted by the EVM (called on unsupported network).
    error NotIntercepted();

    /// @notice Deploys a contract using a pre-EIP-155 signed transaction with a custom gas limit.
    /// @dev The keyless deployment transaction must be a valid RLP-encoded legacy transaction:
    ///      - nonce: any value
    ///      - gasPrice: any value (typically 100 gwei for Nick's Method)
    ///      - gasLimit: any value (must be <= gasLimitOverride)
    ///      - to: must be empty (contract creation)
    ///      - value: any value (typically 0)
    ///      - data: contract creation bytecode
    ///      - v: must be 27 or 28 (pre-EIP-155, no chain ID)
    ///      - r: signature component
    ///      - s: signature component
    /// @param keylessDeploymentTransaction The RLP-encoded pre-EIP-155 signed transaction.
    /// @param gasLimitOverride The gas limit for the inner deployment transaction.
    ///        Must be >= the gas limit in the keyless transaction.
    /// @return gasUsed The amount of gas used by the deployment transaction execution.
    ///         Uses uint64 to match the EVM's native gas accounting type (max ~18 exagas).
    /// @return deployedAddress The address of the deployed contract (zero if execution failed).
    /// @return errorData ABI-encoded error if execution failed, empty bytes on success.
    ///         Execution errors (ExecutionReverted, ExecutionHalted, EmptyCodeDeployed) return
    ///         success with errorData populated. Validation errors revert the entire call.
    function keylessDeploy(bytes calldata keylessDeploymentTransaction, uint256 gasLimitOverride)
        external
        returns (uint64 gasUsed, address deployedAddress, bytes memory errorData);
}