OP StateRoot Invariant
This Gate monitor checks that a state root posted on L1 in a new dispute game to the state root on OP mainnet:
use Len, StateRoot, BlockHash, StorageHash, Keccak256, Events, Call from hexagate;
// Define the DisputeGameFactoryProxy contract address
source disputeGameFactoryProxy: address = 0xe5965Ab5962eDc7477C8520243A95517CD252fA9;
// Fetch DisputeGameCreated events from the DisputeGameFactoryProxy
source disputeGameCreatedEvents: list<tuple<address, integer, bytes>> = Events {
contract: disputeGameFactoryProxy,
signature: "event DisputeGameCreated(address indexed disputeProxy, uint32 indexed gameType, bytes32 indexed rootClaim)"
};
// Parse out the Latest DisputeGameCreated event
source disputeGameCreated: tuple<address, integer, bytes> = disputeGameCreatedEvents[0];
// Extract relevant information from the event
source disputeProxy: address = disputeGameCreated[0];
source gameType: integer = disputeGameCreated[1];
source l2OutputProposal: bytes = disputeGameCreated[2];
// Get the starting block number from the disputeProxy contract
source optimismBlockNumber: integer = Call {
contract: disputeProxy,
signature: "function l2BlockNumber() public pure returns (uint256 l2BlockNumber_)"
};
// Get the optimism block hash
source optimismBlockHash: bytes = BlockHash {
block: optimismBlockNumber,
chainId: 10
};
// Get the optimism state root
source optimismStateRoot: bytes = StateRoot {
block: optimismBlockNumber,
chainId: 10
};
// Get the message passer storage hash
source optimismMessagePasserStorageHash: bytes = StorageHash {
address: 0x4200000000000000000000000000000000000016,
block: optimismBlockNumber,
chainId: 10
};
// Compute the L2 output proposal hash
source computedL2OutputProposal: bytes = Keccak256 {
input: bytes(0x0000000000000000000000000000000000000000000000000000000000000000) + optimismStateRoot + optimismMessagePasserStorageHash + optimismBlockHash
};
// Invariant to check that the computed L2 output proposal matches the L2 output proposal from the event
invariant {
description: "Dispute game created with correct L2 output proposal",
condition: Len { sequence: disputeGameCreatedEvents } > 0 ? computedL2OutputProposal == l2OutputProposal : true
};
// Invariant to ensure only one DisputeGameCreated event per block
invariant {
description: "Only one DisputeGameCreated event should appear in the same block",
condition: Len { sequence: disputeGameCreatedEvents } < 2
};Last updated