// 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);
}