Commit 02dd16aa authored by smartcontracts's avatar smartcontracts Committed by GitHub

maint(ct): use mips and oracle interfaces (#12493)

Updates all contracts and tests to use the MIPS and PreimageOracle
interfaces.
parent dea04890
......@@ -26,7 +26,7 @@ var excludeContracts = []string{
"IEAS", "ISchemaResolver", "ISchemaRegistry",
// TODO: Interfaces that need to be fixed
"IInitializable", "IPreimageOracle", "ILegacyMintableERC20", "IOptimismMintableERC20",
"IInitializable", "ILegacyMintableERC20", "IOptimismMintableERC20",
"IOptimismMintableERC721", "KontrolCheatsBase", "IWETH", "IDelayedWETH", "ISuperchainWETH",
"IL2ToL2CrossDomainMessenger", "ICrossL2Inbox", "ISystemConfigInterop", "IResolvedDelegateProxy",
}
......
......@@ -103,6 +103,11 @@ library DeployUtils {
require(preComputedAddress.code.length == 0, "DeployUtils: contract already deployed");
assembly {
addr_ := create2(0, add(initCode, 0x20), mload(initCode), _salt)
if iszero(addr_) {
let size := returndatasize()
returndatacopy(0, 0, size)
revert(0, size)
}
}
assertValidContractAddress(addr_);
}
......@@ -215,6 +220,10 @@ library DeployUtils {
/// @notice Asserts that the given address is a valid contract address.
/// @param _who Address to check.
function assertValidContractAddress(address _who) internal view {
// Foundry will set returned address to address(1) whenever a contract creation fails
// inside of a test. If this is the case then let Foundry handle the error itself and don't
// trigger a revert (which would probably break a test).
if (_who == address(1)) return;
require(_who != address(0), "DeployUtils: zero address");
require(_who.code.length > 0, string.concat("DeployUtils: no code at ", LibString.toHexStringChecksummed(_who)));
}
......
......@@ -7,6 +7,21 @@ import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol";
/// @title IMIPS
/// @notice Interface for the MIPS contract.
interface IMIPS is ISemver {
struct State {
bytes32 memRoot;
bytes32 preimageKey;
uint32 preimageOffset;
uint32 pc;
uint32 nextPC;
uint32 lo;
uint32 hi;
uint32 heap;
uint8 exitCode;
bool exited;
uint64 step;
uint32[32] registers;
}
error InvalidMemoryProof();
error InvalidRMWInstruction();
......
......@@ -7,6 +7,39 @@ import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol";
/// @title IMIPS2
/// @notice Interface for the MIPS2 contract.
interface IMIPS2 is ISemver {
struct ThreadState {
uint32 threadID;
uint8 exitCode;
bool exited;
uint32 futexAddr;
uint32 futexVal;
uint64 futexTimeoutStep;
uint32 pc;
uint32 nextPC;
uint32 lo;
uint32 hi;
uint32[32] registers;
}
struct State {
bytes32 memRoot;
bytes32 preimageKey;
uint32 preimageOffset;
uint32 heap;
uint8 llReservationStatus;
uint32 llAddress;
uint32 llOwnerThread;
uint8 exitCode;
bool exited;
uint64 step;
uint64 stepsSinceLastContextSwitch;
uint32 wakeup;
bool traverseRight;
bytes32 leftThreadStack;
bytes32 rightThreadStack;
uint32 nextThreadID;
}
error InvalidExitedValue();
error InvalidMemoryProof();
error InvalidSecondMemoryProof();
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title IPreimageOracle
/// @notice Interface for a preimage oracle.
import { LibKeccak } from "@lib-keccak/LibKeccak.sol";
import { LPPMetaData } from "src/cannon/libraries/CannonTypes.sol";
interface IPreimageOracle {
/// @notice Returns the length of the large preimage proposal challenge period.
/// @return challengePeriod_ The length of the challenge period in seconds.
function challengePeriod() external view returns (uint256 challengePeriod_);
struct Leaf {
bytes input;
uint256 index;
bytes32 stateCommitment;
}
/// @notice Reads a preimage from the oracle.
/// @param _key The key of the preimage to read.
/// @param _offset The offset of the preimage to read.
/// @return dat_ The preimage data.
/// @return datLen_ The length of the preimage data.
function readPreimage(bytes32 _key, uint256 _offset) external view returns (bytes32 dat_, uint256 datLen_);
error ActiveProposal();
error AlreadyFinalized();
error AlreadyInitialized();
error BadProposal();
error BondTransferFailed();
error InsufficientBond();
error InvalidInputSize();
error InvalidPreimage();
error InvalidProof();
error NotEOA();
error NotInitialized();
error PartOffsetOOB();
error PostStateMatches();
error StatesNotContiguous();
error TreeSizeOverflow();
error WrongStartingBlock();
/// @notice Loads of local data part into the preimage oracle.
/// @param _ident The identifier of the local data.
/// @param _localContext The local key context for the preimage oracle. Optionally, can be set as a constant
/// if the caller only requires one set of local keys.
/// @param _word The local data word.
/// @param _size The number of bytes in `_word` to load.
/// @param _partOffset The offset of the local data part to write to the oracle.
/// @dev The local data parts are loaded into the preimage oracle under the context
/// of the caller - no other account can write to the caller's context
/// specific data.
///
/// There are 5 local data identifiers:
/// ┌────────────┬────────────────────────┐
/// │ Identifier │ Data │
/// ├────────────┼────────────────────────┤
/// │ 1 │ L1 Head Hash (bytes32) │
/// │ 2 │ Output Root (bytes32) │
/// │ 3 │ Root Claim (bytes32) │
/// │ 4 │ L2 Block Number (u64) │
/// │ 5 │ Chain ID (u64) │
/// └────────────┴────────────────────────┘
function KECCAK_TREE_DEPTH() external view returns (uint256);
function MAX_LEAF_COUNT() external view returns (uint256);
function MIN_BOND_SIZE() external view returns (uint256);
function PRECOMPILE_CALL_RESERVED_GAS() external view returns (uint256);
function addLeavesLPP(
uint256 _uuid,
uint256 _inputStartBlock,
bytes memory _input,
bytes32[] memory _stateCommitments,
bool _finalize
)
external;
function challengeFirstLPP(
address _claimant,
uint256 _uuid,
Leaf memory _postState,
bytes32[] memory _postStateProof
)
external;
function challengeLPP(
address _claimant,
uint256 _uuid,
LibKeccak.StateMatrix memory _stateMatrix,
Leaf memory _preState,
bytes32[] memory _preStateProof,
Leaf memory _postState,
bytes32[] memory _postStateProof
)
external;
function challengePeriod() external view returns (uint256 challengePeriod_);
function getTreeRootLPP(address _owner, uint256 _uuid) external view returns (bytes32 treeRoot_);
function initLPP(uint256 _uuid, uint32 _partOffset, uint32 _claimedSize) external payable;
function loadBlobPreimagePart(
uint256 _z,
uint256 _y,
bytes memory _commitment,
bytes memory _proof,
uint256 _partOffset
)
external;
function loadKeccak256PreimagePart(uint256 _partOffset, bytes memory _preimage) external;
function loadLocalData(
uint256 _ident,
bytes32 _localContext,
......@@ -45,52 +78,40 @@ interface IPreimageOracle {
)
external
returns (bytes32 key_);
/// @notice Prepares a preimage to be read by keccak256 key, starting at the given offset and up to 32 bytes
/// (clipped at preimage length, if out of data).
/// @param _partOffset The offset of the preimage to read.
/// @param _preimage The preimage data.
function loadKeccak256PreimagePart(uint256 _partOffset, bytes calldata _preimage) external;
/// @notice Prepares a preimage to be read by sha256 key, starting at the given offset and up to 32 bytes
/// (clipped at preimage length, if out of data).
/// @param _partOffset The offset of the preimage to read.
/// @param _preimage The preimage data.
function loadSha256PreimagePart(uint256 _partOffset, bytes calldata _preimage) external;
/// @notice Verifies that `p(_z) = _y` given `_commitment` that corresponds to the polynomial `p(x)` and a KZG
// proof. The value `y` is the pre-image, and the preimage key is `5 ++ keccak256(_commitment ++ z)[1:]`.
/// @param _z Big endian point value. Part of the preimage key.
/// @param _y Big endian point value. The preimage for the key.
/// @param _commitment The commitment to the polynomial. 48 bytes, part of the preimage key.
/// @param _proof The KZG proof, part of the preimage key.
/// @param _partOffset The offset of the preimage to store.
function loadBlobPreimagePart(
uint256 _z,
uint256 _y,
bytes calldata _commitment,
bytes calldata _proof,
uint256 _partOffset
)
external;
/// @notice Prepares a precompile result to be read by a precompile key for the specified offset.
/// The precompile result data is a concatenation of the precompile call status byte and its return data.
/// The preimage key is `6 ++ keccak256(precompile ++ input)[1:]`.
/// @param _partOffset The offset of the precompile result being loaded.
/// @param _precompile The precompile address
/// @param _requiredGas The gas required to fully execute an L1 precompile.
/// @param _input The input to the precompile call.
function loadPrecompilePreimagePart(
uint256 _partOffset,
address _precompile,
uint64 _requiredGas,
bytes calldata _input
bytes memory _input
)
external;
/// @notice Returns the minimum size (in bytes) of a large preimage proposal.
function minProposalSize() external view returns (uint256);
function loadSha256PreimagePart(uint256 _partOffset, bytes memory _preimage) external;
function minProposalSize() external view returns (uint256 minProposalSize_);
function preimageLengths(bytes32) external view returns (uint256);
function preimagePartOk(bytes32, uint256) external view returns (bool);
function preimageParts(bytes32, uint256) external view returns (bytes32);
function proposalBlocks(address, uint256, uint256) external view returns (uint64);
function proposalBlocksLen(address _claimant, uint256 _uuid) external view returns (uint256 len_);
function proposalBonds(address, uint256) external view returns (uint256);
function proposalBranches(address, uint256, uint256) external view returns (bytes32);
function proposalCount() external view returns (uint256 count_);
function proposalMetadata(address, uint256) external view returns (LPPMetaData);
function proposalParts(address, uint256) external view returns (bytes32);
function proposals(uint256) external view returns (address claimant, uint256 uuid); // nosemgrep:
// sol-style-return-arg-fmt
function readPreimage(bytes32 _key, uint256 _offset) external view returns (bytes32 dat_, uint256 datLen_);
function squeezeLPP(
address _claimant,
uint256 _uuid,
LibKeccak.StateMatrix memory _stateMatrix,
Leaf memory _preState,
bytes32[] memory _preStateProof,
Leaf memory _postState,
bytes32[] memory _postStateProof
)
external;
function version() external view returns (string memory);
function zeroHashes(uint256) external view returns (bytes32);
function __constructor__(uint256 _minProposalSize, uint256 _challengePeriod) external;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -6,10 +6,8 @@ import { Test } from "forge-std/Test.sol";
import { DisputeGameFactory_Init } from "test/dispute/DisputeGameFactory.t.sol";
import { AlphabetVM } from "test/mocks/AlphabetVM.sol";
// Contracts
import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol";
import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
import { DelayedWETH } from "src/dispute/DelayedWETH.sol";
// Scripts
import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
// Libraries
import "src/dispute/lib/Types.sol";
......@@ -45,29 +43,46 @@ contract PermissionedDisputeGame_Init is DisputeGameFactory_Init {
// Set the extra data for the game creation
extraData = abi.encode(l2BlockNumber);
AlphabetVM _vm = new AlphabetVM(absolutePrestate, IPreimageOracle(address(new PreimageOracle(0, 0))));
IPreimageOracle oracle = IPreimageOracle(
DeployUtils.create1({
_name: "PreimageOracle",
_args: DeployUtils.encodeConstructor(abi.encodeCall(IPreimageOracle.__constructor__, (0, 0)))
})
);
AlphabetVM _vm = new AlphabetVM(absolutePrestate, oracle);
// Use a 7 day delayed WETH to simulate withdrawals.
IDelayedWETH _weth = IDelayedWETH(payable(new DelayedWETH(7 days)));
IDelayedWETH _weth = IDelayedWETH(
DeployUtils.create1({
_name: "DelayedWETH",
_args: DeployUtils.encodeConstructor(abi.encodeCall(IDelayedWETH.__constructor__, (7 days)))
})
);
// Deploy an implementation of the fault game
gameImpl = IPermissionedDisputeGame(
address(
new PermissionedDisputeGame({
_gameType: GAME_TYPE,
_absolutePrestate: absolutePrestate,
_maxGameDepth: 2 ** 3,
_splitDepth: 2 ** 2,
_clockExtension: Duration.wrap(3 hours),
_maxClockDuration: Duration.wrap(3.5 days),
_vm: _vm,
_weth: _weth,
_anchorStateRegistry: anchorStateRegistry,
_l2ChainId: 10,
_proposer: PROPOSER,
_challenger: CHALLENGER
})
)
DeployUtils.create1({
_name: "PermissionedDisputeGame",
_args: DeployUtils.encodeConstructor(
abi.encodeCall(
IPermissionedDisputeGame.__constructor__,
(
GAME_TYPE,
absolutePrestate,
2 ** 3,
2 ** 2,
Duration.wrap(3 hours),
Duration.wrap(3.5 days),
_vm,
_weth,
anchorStateRegistry,
10,
PROPOSER,
CHALLENGER
)
)
)
})
);
// Register the game implementation with the factory.
disputeGameFactory.setImplementation(GAME_TYPE, gameImpl);
......
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