synapsecns/sanguine

View on GitHub
agents/contracts/test/attestationharness/attestationharness.contractinfo.json

Summary

Maintainability
Test Coverage
{"solidity/AttestationHarness.t.sol:AttestationHarness":{"code":"0x608060405234801561001057600080fd5b50610a1f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063717b6ca91161008157806391bacf601161005b57806391bacf601461024b578063c4e1fa9c1461025e578063e948e6001461027157600080fd5b8063717b6ca91461018c578063730dbf631461019f57806386bf2253146101b257600080fd5b80633ae7034d116100b25780633ae7034d146101205780634e7650041461014357806360cf3bf01461016b57600080fd5b806311f6389c146100ce5780631c9aa222146100f7575b600080fd5b6100e16100dc3660046107d6565b610284565b6040516100ee91906108a5565b60405180910390f35b61010a6101053660046107d6565b6102a3565b60405164ffffffffff90911681526020016100ee565b61013361012e3660046107d6565b6102bc565b60405190151581526020016100ee565b6101566101513660046107d6565b6102e2565b60405163ffffffff90911681526020016100ee565b61017e6101793660046107d6565b6102f5565b6040519081526020016100ee565b61017e61019a366004610911565b610308565b61017e6101ad3660046107d6565b610314565b6100e16101c036600461094d565b6040805160208101969096528581019490945260e09290921b7fffffffff0000000000000000000000000000000000000000000000000000000016606085015260d890811b7fffffffffff000000000000000000000000000000000000000000000000000000908116606486015291901b1660698301528051604e818403018152606e909201905290565b61017e6102593660046107d6565b610327565b61017e61026c3660046107d6565b61033a565b61010a61027f3660046107d6565b61034d565b6060600061029183610360565b905061029c81610373565b9392505050565b60006102b66102b183610360565b6103d0565b92915050565b60006102b66102ca836103e2565b6fffffffffffffffffffffffffffffffff16604e1490565b60006102b66102f083610360565b6103fd565b60006102b661030383610360565b61040c565b600061029c838361043a565b60006102b661032283610360565b610470565b60006102b661033583610360565b61049c565b60006102b661034883610360565b6104ad565b60006102b661035b83610360565b6104bb565b60006102b661036e836103e2565b6104ca565b60405180610384836020830161051c565b506fffffffffffffffffffffffffffffffff83166000601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168301602001604052509052919050565b60006102b660496005845b91906105cb565b8051600090602083016103f581836105ec565b949350505050565b60006102b660406004846103db565b60006102b67fccfadb9c399e4e4257b6d0c3f92e1f9a9c00b1802b55a2f7d511702faa769090835b9061064f565b60408051602081018490529081018290526000906060015b60405160208183030381529060405280519060200120905092915050565b60006102b67f3464bf887f210604c594030208052a323ac6628785466262d75241769120164183610434565b60006102b6816020845b9190610672565b60006102b6602080846104a6565b60006102b660446005846103db565b6000604e6fffffffffffffffffffffffffffffffff831614610518576040517feb92662c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090565b6040516000906fffffffffffffffffffffffffffffffff841690608085901c9080851015610576576040517f4b2a158c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008386858560045afa9050806105b9576040517f7c7d772f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608086901b8417979650505050505050565b6000806105d9858585610672565b602084900360031b1c9150509392505050565b6000806105f983856109af565b9050604051811115610609575060005b80600003610643576040517f10bef38600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608084901b83176103f5565b60008161065b8461077c565b604080516020810193909352820152606001610452565b6000816000036106845750600061029c565b60208211156106bf576040517f31d784a800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6fffffffffffffffffffffffffffffffff84166106dc83856109af565b1115610714576040517fa3b99ded00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600382901b60006107258660801c90565b909401517f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092019190911d16949350505050565b6000806107898360801c90565b6fffffffffffffffffffffffffffffffff9390931690922092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156107e857600080fd5b813567ffffffffffffffff8082111561080057600080fd5b818401915084601f83011261081457600080fd5b813581811115610826576108266107a7565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561086c5761086c6107a7565b8160405282815287602084870101111561088557600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b818110156108d2578581018301518582016040015282016108b6565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000806040838503121561092457600080fd5b50508035926020909101359150565b803564ffffffffff8116811461094857600080fd5b919050565b600080600080600060a0868803121561096557600080fd5b8535945060208601359350604086013563ffffffff8116811461098757600080fd5b925061099560608701610933565b91506109a360808701610933565b90509295509295909350565b808201808211156102b6577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea264697066735822122017a3eb5b702cb4f167127397abe275160c1f1facdd2316b15ce7968b5b54775064736f6c63430008110033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100c95760003560e01c8063717b6ca91161008157806391bacf601161005b57806391bacf601461024b578063c4e1fa9c1461025e578063e948e6001461027157600080fd5b8063717b6ca91461018c578063730dbf631461019f57806386bf2253146101b257600080fd5b80633ae7034d116100b25780633ae7034d146101205780634e7650041461014357806360cf3bf01461016b57600080fd5b806311f6389c146100ce5780631c9aa222146100f7575b600080fd5b6100e16100dc3660046107d6565b610284565b6040516100ee91906108a5565b60405180910390f35b61010a6101053660046107d6565b6102a3565b60405164ffffffffff90911681526020016100ee565b61013361012e3660046107d6565b6102bc565b60405190151581526020016100ee565b6101566101513660046107d6565b6102e2565b60405163ffffffff90911681526020016100ee565b61017e6101793660046107d6565b6102f5565b6040519081526020016100ee565b61017e61019a366004610911565b610308565b61017e6101ad3660046107d6565b610314565b6100e16101c036600461094d565b6040805160208101969096528581019490945260e09290921b7fffffffff0000000000000000000000000000000000000000000000000000000016606085015260d890811b7fffffffffff000000000000000000000000000000000000000000000000000000908116606486015291901b1660698301528051604e818403018152606e909201905290565b61017e6102593660046107d6565b610327565b61017e61026c3660046107d6565b61033a565b61010a61027f3660046107d6565b61034d565b6060600061029183610360565b905061029c81610373565b9392505050565b60006102b66102b183610360565b6103d0565b92915050565b60006102b66102ca836103e2565b6fffffffffffffffffffffffffffffffff16604e1490565b60006102b66102f083610360565b6103fd565b60006102b661030383610360565b61040c565b600061029c838361043a565b60006102b661032283610360565b610470565b60006102b661033583610360565b61049c565b60006102b661034883610360565b6104ad565b60006102b661035b83610360565b6104bb565b60006102b661036e836103e2565b6104ca565b60405180610384836020830161051c565b506fffffffffffffffffffffffffffffffff83166000601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168301602001604052509052919050565b60006102b660496005845b91906105cb565b8051600090602083016103f581836105ec565b949350505050565b60006102b660406004846103db565b60006102b67fccfadb9c399e4e4257b6d0c3f92e1f9a9c00b1802b55a2f7d511702faa769090835b9061064f565b60408051602081018490529081018290526000906060015b60405160208183030381529060405280519060200120905092915050565b60006102b67f3464bf887f210604c594030208052a323ac6628785466262d75241769120164183610434565b60006102b6816020845b9190610672565b60006102b6602080846104a6565b60006102b660446005846103db565b6000604e6fffffffffffffffffffffffffffffffff831614610518576040517feb92662c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090565b6040516000906fffffffffffffffffffffffffffffffff841690608085901c9080851015610576576040517f4b2a158c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008386858560045afa9050806105b9576040517f7c7d772f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608086901b8417979650505050505050565b6000806105d9858585610672565b602084900360031b1c9150509392505050565b6000806105f983856109af565b9050604051811115610609575060005b80600003610643576040517f10bef38600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608084901b83176103f5565b60008161065b8461077c565b604080516020810193909352820152606001610452565b6000816000036106845750600061029c565b60208211156106bf576040517f31d784a800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6fffffffffffffffffffffffffffffffff84166106dc83856109af565b1115610714576040517fa3b99ded00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600382901b60006107258660801c90565b909401517f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092019190911d16949350505050565b6000806107898360801c90565b6fffffffffffffffffffffffffffffffff9390931690922092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156107e857600080fd5b813567ffffffffffffffff8082111561080057600080fd5b818401915084601f83011261081457600080fd5b813581811115610826576108266107a7565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561086c5761086c6107a7565b8160405282815287602084870101111561088557600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b818110156108d2578581018301518582016040015282016108b6565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000806040838503121561092457600080fd5b50508035926020909101359150565b803564ffffffffff8116811461094857600080fd5b919050565b600080600080600060a0868803121561096557600080fd5b8535945060208601359350604086013563ffffffff8116811461098757600080fd5b925061099560608701610933565b91506109a360808701610933565b90509295509295909350565b808201808211156102b6577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea264697066735822122017a3eb5b702cb4f167127397abe275160c1f1facdd2316b15ce7968b5b54775064736f6c63430008110033","info":{"source":"// SPDX-License-Identifier: MIT\npragma solidity =0.8.17;\n\n// contracts/libs/Constants.sol\n\n// Here we define common constants to enable their easier reusing later.\n\n// ══════════════════════════════════ MERKLE ═══════════════════════════════════\n/// @dev Height of the Agent Merkle Tree\nuint256 constant AGENT_TREE_HEIGHT = 32;\n/// @dev Height of the Origin Merkle Tree\nuint256 constant ORIGIN_TREE_HEIGHT = 32;\n/// @dev Height of the Snapshot Merkle Tree. Allows up to 64 leafs, e.g. up to 32 states\nuint256 constant SNAPSHOT_TREE_HEIGHT = 6;\n// ══════════════════════════════════ STRUCTS ══════════════════════════════════\n/// @dev See Attestation.sol: (bytes32,bytes32,uint32,uint40,uint40): 32+32+4+5+5\nuint256 constant ATTESTATION_LENGTH = 78;\n/// @dev See GasData.sol: (uint16,uint16,uint16,uint16,uint16,uint16): 2+2+2+2+2+2\nuint256 constant GAS_DATA_LENGTH = 12;\n/// @dev See Receipt.sol: (uint32,uint32,bytes32,bytes32,uint8,address,address,address): 4+4+32+32+1+20+20+20\nuint256 constant RECEIPT_LENGTH = 133;\n/// @dev See State.sol: (bytes32,uint32,uint32,uint40,uint40,GasData): 32+4+4+5+5+len(GasData)\nuint256 constant STATE_LENGTH = 50 + GAS_DATA_LENGTH;\n/// @dev Maximum amount of states in a single snapshot. Each state produces two leafs in the tree\nuint256 constant SNAPSHOT_MAX_STATES = 1 \u003c\u003c (SNAPSHOT_TREE_HEIGHT - 1);\n// ══════════════════════════════════ MESSAGE ══════════════════════════════════\n/// @dev See Header.sol: (uint8,uint32,uint32,uint32,uint32): 1+4+4+4+4\nuint256 constant HEADER_LENGTH = 17;\n/// @dev See Request.sol: (uint96,uint64,uint32): 12+8+4\nuint256 constant REQUEST_LENGTH = 24;\n/// @dev See Tips.sol: (uint64,uint64,uint64,uint64): 8+8+8+8\nuint256 constant TIPS_LENGTH = 32;\n/// @dev The amount of discarded last bits when encoding tip values\nuint256 constant TIPS_GRANULARITY = 32;\n/// @dev Tip values could be only the multiples of TIPS_MULTIPLIER\nuint256 constant TIPS_MULTIPLIER = 1 \u003c\u003c TIPS_GRANULARITY;\n// ══════════════════════════════ STATEMENT SALTS ══════════════════════════════\n/// @dev Salts for signing various statements\nbytes32 constant ATTESTATION_VALID_SALT = keccak256(\"ATTESTATION_VALID_SALT\");\nbytes32 constant ATTESTATION_INVALID_SALT = keccak256(\"ATTESTATION_INVALID_SALT\");\nbytes32 constant RECEIPT_VALID_SALT = keccak256(\"RECEIPT_VALID_SALT\");\nbytes32 constant RECEIPT_INVALID_SALT = keccak256(\"RECEIPT_INVALID_SALT\");\nbytes32 constant SNAPSHOT_VALID_SALT = keccak256(\"SNAPSHOT_VALID_SALT\");\nbytes32 constant STATE_INVALID_SALT = keccak256(\"STATE_INVALID_SALT\");\n// ═════════════════════════════════ PROTOCOL ══════════════════════════════════\n/// @dev Optimistic period for new agent roots in LightManager\nuint32 constant AGENT_ROOT_OPTIMISTIC_PERIOD = 1 days;\n/// @dev Timeout between the agent root could be proposed and resolved in LightManager\nuint32 constant AGENT_ROOT_PROPOSAL_TIMEOUT = 12 hours;\nuint32 constant BONDING_OPTIMISTIC_PERIOD = 1 days;\n/// @dev Amount of time that the Notary will not be considered active after they won a dispute\nuint32 constant DISPUTE_TIMEOUT_NOTARY = 12 hours;\n/// @dev Amount of time without fresh data from Notaries before contract owner can resolve stuck disputes manually\nuint256 constant FRESH_DATA_TIMEOUT = 4 hours;\n/// @dev Maximum bytes per message = 2 KiB (somewhat arbitrarily set to begin)\nuint256 constant MAX_CONTENT_BYTES = 2 * 2 ** 10;\n/// @dev Maximum value for the summit tip that could be set in GasOracle\nuint256 constant MAX_SUMMIT_TIP = 0.01 ether;\n\n// contracts/libs/Errors.sol\n\n// ══════════════════════════════ INVALID CALLER ═══════════════════════════════\n\nerror CallerNotAgentManager();\nerror CallerNotDestination();\nerror CallerNotInbox();\nerror CallerNotSummit();\n\n// ══════════════════════════════ INCORRECT DATA ═══════════════════════════════\n\nerror IncorrectAttestation();\nerror IncorrectAgentDomain();\nerror IncorrectAgentIndex();\nerror IncorrectAgentProof();\nerror IncorrectAgentRoot();\nerror IncorrectDataHash();\nerror IncorrectDestinationDomain();\nerror IncorrectOriginDomain();\nerror IncorrectSnapshotProof();\nerror IncorrectSnapshotRoot();\nerror IncorrectState();\nerror IncorrectStatesAmount();\nerror IncorrectTipsProof();\nerror IncorrectVersionLength();\n\nerror IncorrectNonce();\nerror IncorrectSender();\nerror IncorrectRecipient();\n\nerror FlagOutOfRange();\nerror IndexOutOfRange();\nerror NonceOutOfRange();\n\nerror OutdatedNonce();\n\nerror UnformattedAttestation();\nerror UnformattedAttestationReport();\nerror UnformattedBaseMessage();\nerror UnformattedCallData();\nerror UnformattedCallDataPrefix();\nerror UnformattedMessage();\nerror UnformattedReceipt();\nerror UnformattedReceiptReport();\nerror UnformattedSignature();\nerror UnformattedSnapshot();\nerror UnformattedState();\nerror UnformattedStateReport();\n\n// ═══════════════════════════════ MERKLE TREES ════════════════════════════════\n\nerror LeafNotProven();\nerror MerkleTreeFull();\nerror NotEnoughLeafs();\nerror TreeHeightTooLow();\n\n// ═════════════════════════════ OPTIMISTIC PERIOD ═════════════════════════════\n\nerror BaseClientOptimisticPeriod();\nerror MessageOptimisticPeriod();\nerror SlashAgentOptimisticPeriod();\nerror WithdrawTipsOptimisticPeriod();\nerror ZeroProofMaturity();\n\n// ═══════════════════════════════ AGENT MANAGER ═══════════════════════════════\n\nerror AgentNotGuard();\nerror AgentNotNotary();\n\nerror AgentCantBeAdded();\nerror AgentNotActive();\nerror AgentNotActiveNorUnstaking();\nerror AgentNotFraudulent();\nerror AgentNotUnstaking();\nerror AgentUnknown();\n\nerror AgentRootNotProposed();\nerror AgentRootTimeoutNotOver();\n\nerror NotStuck();\n\nerror DisputeAlreadyResolved();\nerror DisputeNotOpened();\nerror DisputeTimeoutNotOver();\nerror GuardInDispute();\nerror NotaryInDispute();\n\nerror MustBeSynapseDomain();\nerror SynapseDomainForbidden();\n\n// ════════════════════════════════ DESTINATION ════════════════════════════════\n\nerror AlreadyExecuted();\nerror AlreadyFailed();\nerror DuplicatedSnapshotRoot();\nerror IncorrectMagicValue();\nerror GasLimitTooLow();\nerror GasSuppliedTooLow();\n\n// ══════════════════════════════════ ORIGIN ═══════════════════════════════════\n\nerror ContentLengthTooBig();\nerror EthTransferFailed();\nerror InsufficientEthBalance();\n\n// ════════════════════════════════ GAS ORACLE ═════════════════════════════════\n\nerror LocalGasDataNotSet();\nerror RemoteGasDataNotSet();\n\n// ═══════════════════════════════════ TIPS ════════════════════════════════════\n\nerror SummitTipTooHigh();\nerror TipsClaimMoreThanEarned();\nerror TipsClaimZero();\nerror TipsOverflow();\nerror TipsValueTooLow();\n\n// ════════════════════════════════ MEMORY VIEW ════════════════════════════════\n\nerror IndexedTooMuch();\nerror ViewOverrun();\nerror OccupiedMemory();\nerror UnallocatedMemory();\nerror PrecompileOutOfGas();\n\n// ═════════════════════════════════ MULTICALL ═════════════════════════════════\n\nerror MulticallFailed();\n\n// contracts/libs/memory/MemView.sol\n\n/// @dev MemView is an untyped view over a portion of memory to be used instead of `bytes memory`\ntype MemView is uint256;\n\n/// @dev Attach library functions to MemView\nusing MemViewLib for MemView global;\n\n/// @notice Library for operations with the memory views.\n/// Forked from https://github.com/summa-tx/memview-sol with several breaking changes:\n/// - The codebase is ported to Solidity 0.8\n/// - Custom errors are added\n/// - The runtime type checking is replaced with compile-time check provided by User-Defined Value Types\n///   https://docs.soliditylang.org/en/latest/types.html#user-defined-value-types\n/// - uint256 is used as the underlying type for the \"memory view\" instead of bytes29.\n///   It is wrapped into MemView custom type in order not to be confused with actual integers.\n/// - Therefore the \"type\" field is discarded, allowing to allocate 16 bytes for both view location and length\n/// - The documentation is expanded\n/// - Library functions unused by the rest of the codebase are removed\n//  - Very pretty code separators are added :)\nlibrary MemViewLib {\n    /// @notice Stack layout for uint256 (from highest bits to lowest)\n    /// (32 .. 16]      loc     16 bytes    Memory address of underlying bytes\n    /// (16 .. 00]      len     16 bytes    Length of underlying bytes\n\n    // ═══════════════════════════════════════════ BUILDING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Instantiate a new untyped memory view. This should generally not be called directly.\n     * Prefer `ref` wherever possible.\n     * @param loc_          The memory address\n     * @param len_          The length\n     * @return The new view with the specified location and length\n     */\n    function build(uint256 loc_, uint256 len_) internal pure returns (MemView) {\n        uint256 end_ = loc_ + len_;\n        // Make sure that a view is not constructed that points to unallocated memory\n        // as this could be indicative of a buffer overflow attack\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            if gt(end_, mload(0x40)) { end_ := 0 }\n        }\n        if (end_ == 0) {\n            revert UnallocatedMemory();\n        }\n        return _unsafeBuildUnchecked(loc_, len_);\n    }\n\n    /**\n     * @notice Instantiate a memory view from a byte array.\n     * @dev Note that due to Solidity memory representation, it is not possible to\n     * implement a deref, as the `bytes` type stores its len in memory.\n     * @param arr           The byte array\n     * @return The memory view over the provided byte array\n     */\n    function ref(bytes memory arr) internal pure returns (MemView) {\n        uint256 len_ = arr.length;\n        // `bytes arr` is stored in memory in the following way\n        // 1. First, uint256 arr.length is stored. That requires 32 bytes (0x20).\n        // 2. Then, the array data is stored.\n        uint256 loc_;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // We add 0x20, so that the view starts exactly where the array data starts\n            loc_ := add(arr, 0x20)\n        }\n        return build(loc_, len_);\n    }\n\n    // ════════════════════════════════════════════ CLONING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to the new memory.\n     * @param memView       The memory view\n     * @return arr          The cloned byte array\n     */\n    function clone(MemView memView) internal view returns (bytes memory arr) {\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load unused memory pointer\n            ptr := mload(0x40)\n            // This is where the byte array will be stored\n            arr := ptr\n        }\n        unchecked {\n            _unsafeCopyTo(memView, ptr + 0x20);\n        }\n        // `bytes arr` is stored in memory in the following way\n        // 1. First, uint256 arr.length is stored. That requires 32 bytes (0x20).\n        // 2. Then, the array data is stored.\n        uint256 len_ = memView.len();\n        uint256 footprint_ = memView.footprint();\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Write new unused pointer: the old value + array footprint + 32 bytes to store the length\n            mstore(0x40, add(add(ptr, footprint_), 0x20))\n            // Write len of new array (in bytes)\n            mstore(ptr, len_)\n        }\n    }\n\n    /**\n     * @notice Copies all views, joins them into a new bytearray.\n     * @param memViews      The memory views\n     * @return arr          The new byte array with joined data behind the given views\n     */\n    function join(MemView[] memory memViews) internal view returns (bytes memory arr) {\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load unused memory pointer\n            ptr := mload(0x40)\n            // This is where the byte array will be stored\n            arr := ptr\n        }\n        MemView newView;\n        unchecked {\n            newView = _unsafeJoin(memViews, ptr + 0x20);\n        }\n        uint256 len_ = newView.len();\n        uint256 footprint_ = newView.footprint();\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Write new unused pointer: the old value + array footprint + 32 bytes to store the length\n            mstore(0x40, add(add(ptr, footprint_), 0x20))\n            // Write len of new array (in bytes)\n            mstore(ptr, len_)\n        }\n    }\n\n    // ══════════════════════════════════════════ INSPECTING MEMORY VIEW ═══════════════════════════════════════════════\n\n    /**\n     * @notice Returns the memory address of the underlying bytes.\n     * @param memView       The memory view\n     * @return loc_         The memory address\n     */\n    function loc(MemView memView) internal pure returns (uint256 loc_) {\n        // loc is stored in the highest 16 bytes of the underlying uint256\n        return MemView.unwrap(memView) \u003e\u003e 128;\n    }\n\n    /**\n     * @notice Returns the number of bytes of the view.\n     * @param memView       The memory view\n     * @return len_         The length of the view\n     */\n    function len(MemView memView) internal pure returns (uint256 len_) {\n        // len is stored in the lowest 16 bytes of the underlying uint256\n        return MemView.unwrap(memView) \u0026 type(uint128).max;\n    }\n\n    /**\n     * @notice Returns the endpoint of `memView`.\n     * @param memView       The memory view\n     * @return end_         The endpoint of `memView`\n     */\n    function end(MemView memView) internal pure returns (uint256 end_) {\n        // The endpoint never overflows uint128, let alone uint256, so we could use unchecked math here\n        unchecked {\n            return memView.loc() + memView.len();\n        }\n    }\n\n    /**\n     * @notice Returns the number of memory words this memory view occupies, rounded up.\n     * @param memView       The memory view\n     * @return words_       The number of memory words\n     */\n    function words(MemView memView) internal pure returns (uint256 words_) {\n        // returning ceil(length / 32.0)\n        unchecked {\n            return (memView.len() + 31) \u003e\u003e 5;\n        }\n    }\n\n    /**\n     * @notice Returns the in-memory footprint of a fresh copy of the view.\n     * @param memView       The memory view\n     * @return footprint_   The in-memory footprint of a fresh copy of the view.\n     */\n    function footprint(MemView memView) internal pure returns (uint256 footprint_) {\n        // words() * 32\n        return memView.words() \u003c\u003c 5;\n    }\n\n    // ════════════════════════════════════════════ HASHING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Returns the keccak256 hash of the underlying memory\n     * @param memView       The memory view\n     * @return digest       The keccak256 hash of the underlying memory\n     */\n    function keccak(MemView memView) internal pure returns (bytes32 digest) {\n        uint256 loc_ = memView.loc();\n        uint256 len_ = memView.len();\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            digest := keccak256(loc_, len_)\n        }\n    }\n\n    /**\n     * @notice Adds a salt to the keccak256 hash of the underlying data and returns the keccak256 hash of the\n     * resulting data.\n     * @param memView       The memory view\n     * @return digestSalted keccak256(salt, keccak256(memView))\n     */\n    function keccakSalted(MemView memView, bytes32 salt) internal pure returns (bytes32 digestSalted) {\n        return keccak256(bytes.concat(salt, memView.keccak()));\n    }\n\n    // ════════════════════════════════════════════ SLICING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Safe slicing without memory modification.\n     * @param memView       The memory view\n     * @param index_        The start index\n     * @param len_          The length\n     * @return The new view for the slice of the given length starting from the given index\n     */\n    function slice(MemView memView, uint256 index_, uint256 len_) internal pure returns (MemView) {\n        uint256 loc_ = memView.loc();\n        // Ensure it doesn't overrun the view\n        if (loc_ + index_ + len_ \u003e memView.end()) {\n            revert ViewOverrun();\n        }\n        // Build a view starting from index with the given length\n        unchecked {\n            // loc_ + index_ \u003c= memView.end()\n            return build({loc_: loc_ + index_, len_: len_});\n        }\n    }\n\n    /**\n     * @notice Shortcut to `slice`. Gets a view representing bytes from `index` to end(memView).\n     * @param memView       The memory view\n     * @param index_        The start index\n     * @return The new view for the slice starting from the given index until the initial view endpoint\n     */\n    function sliceFrom(MemView memView, uint256 index_) internal pure returns (MemView) {\n        uint256 len_ = memView.len();\n        // Ensure it doesn't overrun the view\n        if (index_ \u003e len_) {\n            revert ViewOverrun();\n        }\n        // Build a view starting from index with the given length\n        unchecked {\n            // index_ \u003c= len_ =\u003e memView.loc() + index_ \u003c= memView.loc() + memView.len() == memView.end()\n            return build({loc_: memView.loc() + index_, len_: len_ - index_});\n        }\n    }\n\n    /**\n     * @notice Shortcut to `slice`. Gets a view representing the first `len` bytes.\n     * @param memView       The memory view\n     * @param len_          The length\n     * @return The new view for the slice of the given length starting from the initial view beginning\n     */\n    function prefix(MemView memView, uint256 len_) internal pure returns (MemView) {\n        return memView.slice({index_: 0, len_: len_});\n    }\n\n    /**\n     * @notice Shortcut to `slice`. Gets a view representing the last `len` byte.\n     * @param memView       The memory view\n     * @param len_          The length\n     * @return The new view for the slice of the given length until the initial view endpoint\n     */\n    function postfix(MemView memView, uint256 len_) internal pure returns (MemView) {\n        uint256 viewLen = memView.len();\n        // Ensure it doesn't overrun the view\n        if (len_ \u003e viewLen) {\n            revert ViewOverrun();\n        }\n        // Could do the unchecked math due to the check above\n        uint256 index_;\n        unchecked {\n            index_ = viewLen - len_;\n        }\n        // Build a view starting from index with the given length\n        unchecked {\n            // len_ \u003c= memView.len() =\u003e memView.loc() \u003c= loc_ \u003c= memView.end()\n            return build({loc_: memView.loc() + viewLen - len_, len_: len_});\n        }\n    }\n\n    // ═══════════════════════════════════════════ INDEXING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Load up to 32 bytes from the view onto the stack.\n     * @dev Returns a bytes32 with only the `bytes_` HIGHEST bytes set.\n     * This can be immediately cast to a smaller fixed-length byte array.\n     * To automatically cast to an integer, use `indexUint`.\n     * @param memView       The memory view\n     * @param index_        The index\n     * @param bytes_        The amount of bytes to load onto the stack\n     * @return result       The 32 byte result having only `bytes_` highest bytes set\n     */\n    function index(MemView memView, uint256 index_, uint256 bytes_) internal pure returns (bytes32 result) {\n        if (bytes_ == 0) {\n            return bytes32(0);\n        }\n        // Can't load more than 32 bytes to the stack in one go\n        if (bytes_ \u003e 32) {\n            revert IndexedTooMuch();\n        }\n        // The last indexed byte should be within view boundaries\n        if (index_ + bytes_ \u003e memView.len()) {\n            revert ViewOverrun();\n        }\n        uint256 bitLength = bytes_ \u003c\u003c 3; // bytes_ * 8\n        uint256 loc_ = memView.loc();\n        // Get a mask with `bitLength` highest bits set\n        uint256 mask;\n        // 0x800...00 binary representation is 100...00\n        // sar stands for \"signed arithmetic shift\": https://en.wikipedia.org/wiki/Arithmetic_shift\n        // sar(N-1, 100...00) = 11...100..00, with exactly N highest bits set to 1\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            mask := sar(sub(bitLength, 1), 0x8000000000000000000000000000000000000000000000000000000000000000)\n        }\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load a full word using index offset, and apply mask to ignore non-relevant bytes\n            result := and(mload(add(loc_, index_)), mask)\n        }\n    }\n\n    /**\n     * @notice Parse an unsigned integer from the view at `index`.\n     * @dev Requires that the view have \u003e= `bytes_` bytes following that index.\n     * @param memView       The memory view\n     * @param index_        The index\n     * @param bytes_        The amount of bytes to load onto the stack\n     * @return The unsigned integer\n     */\n    function indexUint(MemView memView, uint256 index_, uint256 bytes_) internal pure returns (uint256) {\n        bytes32 indexedBytes = memView.index(index_, bytes_);\n        // `index()` returns left-aligned `bytes_`, while integers are right-aligned\n        // Shifting here to right-align with the full 32 bytes word: need to shift right `(32 - bytes_)` bytes\n        unchecked {\n            // memView.index() reverts when bytes_ \u003e 32, thus unchecked math\n            return uint256(indexedBytes) \u003e\u003e ((32 - bytes_) \u003c\u003c 3);\n        }\n    }\n\n    /**\n     * @notice Parse an address from the view at `index`.\n     * @dev Requires that the view have \u003e= 20 bytes following that index.\n     * @param memView       The memory view\n     * @param index_        The index\n     * @return The address\n     */\n    function indexAddress(MemView memView, uint256 index_) internal pure returns (address) {\n        // index 20 bytes as `uint160`, and then cast to `address`\n        return address(uint160(memView.indexUint(index_, 20)));\n    }\n\n    // ══════════════════════════════════════════════ PRIVATE HELPERS ══════════════════════════════════════════════════\n\n    /// @dev Returns a memory view over the specified memory location\n    /// without checking if it points to unallocated memory.\n    function _unsafeBuildUnchecked(uint256 loc_, uint256 len_) private pure returns (MemView) {\n        // There is no scenario where loc or len would overflow uint128, so we omit this check.\n        // We use the highest 128 bits to encode the location and the lowest 128 bits to encode the length.\n        return MemView.wrap((loc_ \u003c\u003c 128) | len_);\n    }\n\n    /**\n     * @notice Copy the view to a location, return an unsafe memory reference\n     * @dev Super Dangerous direct memory access.\n     * This reference can be overwritten if anything else modifies memory (!!!).\n     * As such it MUST be consumed IMMEDIATELY. Update the free memory pointer to ensure the copied data\n     * is not overwritten. This function is private to prevent unsafe usage by callers.\n     * @param memView       The memory view\n     * @param newLoc        The new location to copy the underlying view data\n     * @return The memory view over the unsafe memory with the copied underlying data\n     */\n    function _unsafeCopyTo(MemView memView, uint256 newLoc) private view returns (MemView) {\n        uint256 len_ = memView.len();\n        uint256 oldLoc = memView.loc();\n\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load unused memory pointer\n            ptr := mload(0x40)\n        }\n        // Revert if we're writing in occupied memory\n        if (newLoc \u003c ptr) {\n            revert OccupiedMemory();\n        }\n        bool res;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // use the identity precompile (0x04) to copy\n            res := staticcall(gas(), 0x04, oldLoc, len_, newLoc, len_)\n        }\n        if (!res) revert PrecompileOutOfGas();\n        return _unsafeBuildUnchecked({loc_: newLoc, len_: len_});\n    }\n\n    /**\n     * @notice Join the views in memory, return an unsafe reference to the memory.\n     * @dev Super Dangerous direct memory access.\n     * This reference can be overwritten if anything else modifies memory (!!!).\n     * As such it MUST be consumed IMMEDIATELY. Update the free memory pointer to ensure the copied data\n     * is not overwritten. This function is private to prevent unsafe usage by callers.\n     * @param memViews      The memory views\n     * @return The conjoined view pointing to the new memory\n     */\n    function _unsafeJoin(MemView[] memory memViews, uint256 location) private view returns (MemView) {\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load unused memory pointer\n            ptr := mload(0x40)\n        }\n        // Revert if we're writing in occupied memory\n        if (location \u003c ptr) {\n            revert OccupiedMemory();\n        }\n        // Copy the views to the specified location one by one, by tracking the amount of copied bytes so far\n        uint256 offset = 0;\n        for (uint256 i = 0; i \u003c memViews.length;) {\n            MemView memView = memViews[i];\n            // We can use the unchecked math here as location + sum(view.length) will never overflow uint256\n            unchecked {\n                _unsafeCopyTo(memView, location + offset);\n                offset += memView.len();\n                ++i;\n            }\n        }\n        return _unsafeBuildUnchecked({loc_: location, len_: offset});\n    }\n}\n\n// contracts/libs/memory/Attestation.sol\n\n/// Attestation is a memory view over a formatted attestation payload.\ntype Attestation is uint256;\n\nusing AttestationLib for Attestation global;\n\n/// # Attestation\n/// Attestation structure represents the \"Snapshot Merkle Tree\" created from\n/// every Notary snapshot accepted by the Summit contract. Attestation includes\"\n/// the root of the \"Snapshot Merkle Tree\", as well as additional metadata.\n///\n/// ## Steps for creation of \"Snapshot Merkle Tree\":\n/// 1. The list of hashes is composed for states in the Notary snapshot.\n/// 2. The list is padded with zero values until its length is 2**SNAPSHOT_TREE_HEIGHT.\n/// 3. Values from the list are used as leafs and the merkle tree is constructed.\n///\n/// ## Differences between a State and Attestation\n/// Similar to Origin, every derived Notary's \"Snapshot Merkle Root\" is saved in Summit contract.\n/// The main difference is that Origin contract itself is keeping track of an incremental merkle tree,\n/// by inserting the hash of the sent message and calculating the new \"Origin Merkle Root\".\n/// While Summit relies on Guards and Notaries to provide snapshot data, which is used to calculate the\n/// \"Snapshot Merkle Root\".\n///\n/// - Origin's State is \"state of Origin Merkle Tree after N-th message was sent\".\n/// - Summit's Attestation is \"data for the N-th accepted Notary Snapshot\" + \"agent merkle root at the\n/// time snapshot was submitted\" + \"attestation metadata\".\n///\n/// ## Attestation validity\n/// - Attestation is considered \"valid\" in Summit contract, if it matches the N-th (nonce)\n/// snapshot submitted by Notaries, as well as the historical agent merkle root.\n/// - Attestation is considered \"valid\" in Origin contract, if its underlying Snapshot is \"valid\".\n///\n/// - This means that a snapshot could be \"valid\" in Summit contract and \"invalid\" in Origin, if the underlying\n/// snapshot is invalid (i.e. one of the states in the list is invalid).\n/// - The opposite could also be true. If a perfectly valid snapshot was never submitted to Summit, its attestation\n/// would be valid in Origin, but invalid in Summit (it was never accepted, so the metadata would be incorrect).\n///\n/// - Attestation is considered \"globally valid\", if it is valid in the Summit and all the Origin contracts.\n/// # Memory layout of Attestation fields\n///\n/// | Position   | Field       | Type    | Bytes | Description                                                    |\n/// | ---------- | ----------- | ------- | ----- | -------------------------------------------------------------- |\n/// | [000..032) | snapRoot    | bytes32 | 32    | Root for \"Snapshot Merkle Tree\" created from a Notary snapshot |\n/// | [032..064) | dataHash    | bytes32 | 32    | Agent Root and SnapGasHash combined into a single hash         |\n/// | [064..068) | nonce       | uint32  | 4     | Total amount of all accepted Notary snapshots                  |\n/// | [068..073) | blockNumber | uint40  | 5     | Block when this Notary snapshot was accepted in Summit         |\n/// | [073..078) | timestamp   | uint40  | 5     | Time when this Notary snapshot was accepted in Summit          |\n///\n/// @dev Attestation could be signed by a Notary and submitted to `Destination` in order to use if for proving\n/// messages coming from origin chains that the initial snapshot refers to.\nlibrary AttestationLib {\n    using MemViewLib for bytes;\n\n    // TODO: compress three hashes into one?\n\n    /// @dev The variables below are not supposed to be used outside of the library directly.\n    uint256 private constant OFFSET_SNAP_ROOT = 0;\n    uint256 private constant OFFSET_DATA_HASH = 32;\n    uint256 private constant OFFSET_NONCE = 64;\n    uint256 private constant OFFSET_BLOCK_NUMBER = 68;\n    uint256 private constant OFFSET_TIMESTAMP = 73;\n\n    // ════════════════════════════════════════════════ ATTESTATION ════════════════════════════════════════════════════\n\n    /**\n     * @notice Returns a formatted Attestation payload with provided fields.\n     * @param snapRoot_     Snapshot merkle tree's root\n     * @param dataHash_     Agent Root and SnapGasHash combined into a single hash\n     * @param nonce_        Attestation Nonce\n     * @param blockNumber_  Block number when attestation was created in Summit\n     * @param timestamp_    Block timestamp when attestation was created in Summit\n     * @return Formatted attestation\n     */\n    function formatAttestation(\n        bytes32 snapRoot_,\n        bytes32 dataHash_,\n        uint32 nonce_,\n        uint40 blockNumber_,\n        uint40 timestamp_\n    ) internal pure returns (bytes memory) {\n        return abi.encodePacked(snapRoot_, dataHash_, nonce_, blockNumber_, timestamp_);\n    }\n\n    /**\n     * @notice Returns an Attestation view over the given payload.\n     * @dev Will revert if the payload is not an attestation.\n     */\n    function castToAttestation(bytes memory payload) internal pure returns (Attestation) {\n        return castToAttestation(payload.ref());\n    }\n\n    /**\n     * @notice Casts a memory view to an Attestation view.\n     * @dev Will revert if the memory view is not over an attestation.\n     */\n    function castToAttestation(MemView memView) internal pure returns (Attestation) {\n        if (!isAttestation(memView)) revert UnformattedAttestation();\n        return Attestation.wrap(MemView.unwrap(memView));\n    }\n\n    /// @notice Checks that a payload is a formatted Attestation.\n    function isAttestation(MemView memView) internal pure returns (bool) {\n        return memView.len() == ATTESTATION_LENGTH;\n    }\n\n    /// @notice Returns the hash of an Attestation, that could be later signed by a Notary to signal\n    /// that the attestation is valid.\n    function hashValid(Attestation att) internal pure returns (bytes32) {\n        // The final hash to sign is keccak(attestationSalt, keccak(attestation))\n        return att.unwrap().keccakSalted(ATTESTATION_VALID_SALT);\n    }\n\n    /// @notice Returns the hash of an Attestation, that could be later signed by a Guard to signal\n    /// that the attestation is invalid.\n    function hashInvalid(Attestation att) internal pure returns (bytes32) {\n        // The final hash to sign is keccak(attestationInvalidSalt, keccak(attestation))\n        return att.unwrap().keccakSalted(ATTESTATION_INVALID_SALT);\n    }\n\n    /// @notice Convenience shortcut for unwrapping a view.\n    function unwrap(Attestation att) internal pure returns (MemView) {\n        return MemView.wrap(Attestation.unwrap(att));\n    }\n\n    // ════════════════════════════════════════════ ATTESTATION SLICING ════════════════════════════════════════════════\n\n    /// @notice Returns root of the Snapshot merkle tree created in the Summit contract.\n    function snapRoot(Attestation att) internal pure returns (bytes32) {\n        return att.unwrap().index({index_: OFFSET_SNAP_ROOT, bytes_: 32});\n    }\n\n    /// @notice Returns hash of the Agent Root and SnapGasHash combined into a single hash.\n    function dataHash(Attestation att) internal pure returns (bytes32) {\n        return att.unwrap().index({index_: OFFSET_DATA_HASH, bytes_: 32});\n    }\n\n    /// @notice Returns hash of the Agent Root and SnapGasHash combined into a single hash.\n    function dataHash(bytes32 agentRoot_, bytes32 snapGasHash_) internal pure returns (bytes32) {\n        return keccak256(bytes.concat(agentRoot_, snapGasHash_));\n    }\n\n    /// @notice Returns nonce of Summit contract at the time, when attestation was created.\n    function nonce(Attestation att) internal pure returns (uint32) {\n        // Can be safely casted to uint32, since we index 4 bytes\n        return uint32(att.unwrap().indexUint({index_: OFFSET_NONCE, bytes_: 4}));\n    }\n\n    /// @notice Returns a block number when attestation was created in Summit.\n    function blockNumber(Attestation att) internal pure returns (uint40) {\n        // Can be safely casted to uint40, since we index 5 bytes\n        return uint40(att.unwrap().indexUint({index_: OFFSET_BLOCK_NUMBER, bytes_: 5}));\n    }\n\n    /// @notice Returns a block timestamp when attestation was created in Summit.\n    /// @dev This is the timestamp according to the Synapse Chain.\n    function timestamp(Attestation att) internal pure returns (uint40) {\n        // Can be safely casted to uint40, since we index 5 bytes\n        return uint40(att.unwrap().indexUint({index_: OFFSET_TIMESTAMP, bytes_: 5}));\n    }\n}\n\n// test/harnesses/libs/memory/AttestationHarness.t.sol\n\n// solhint-disable ordering\n/// @notice Exposes Attestation methods for testing against golang.\ncontract AttestationHarness {\n    using AttestationLib for bytes;\n    using AttestationLib for MemView;\n    using MemViewLib for bytes;\n\n    // Note: we don't add an empty test() function here, as it currently leads\n    // to zero coverage on the corresponding library.\n\n    // ══════════════════════════════════════════════════ GETTERS ══════════════════════════════════════════════════════\n\n    function castToAttestation(bytes memory payload) public view returns (bytes memory) {\n        // Walkaround to get the forge coverage working on libraries, see\n        // https://github.com/foundry-rs/foundry/pull/3128#issuecomment-1241245086\n        Attestation attestation = AttestationLib.castToAttestation(payload);\n        return attestation.unwrap().clone();\n    }\n\n    function snapRoot(bytes memory payload) public pure returns (bytes32) {\n        return payload.castToAttestation().snapRoot();\n    }\n\n    function dataHash(bytes memory payload) public pure returns (bytes32) {\n        return payload.castToAttestation().dataHash();\n    }\n\n    function dataHash(bytes32 agentRoot_, bytes32 snapGasHash_) public pure returns (bytes32) {\n        return AttestationLib.dataHash(agentRoot_, snapGasHash_);\n    }\n\n    function nonce(bytes memory payload) public pure returns (uint32) {\n        return payload.castToAttestation().nonce();\n    }\n\n    function blockNumber(bytes memory payload) public pure returns (uint40) {\n        return payload.castToAttestation().blockNumber();\n    }\n\n    function timestamp(bytes memory payload) public pure returns (uint40) {\n        return payload.castToAttestation().timestamp();\n    }\n\n    function hashValid(bytes memory payload) public pure returns (bytes32) {\n        return payload.castToAttestation().hashValid();\n    }\n\n    function hashInvalid(bytes memory payload) public pure returns (bytes32) {\n        return payload.castToAttestation().hashInvalid();\n    }\n\n    // ════════════════════════════════════════════════ FORMATTERS ═════════════════════════════════════════════════════\n\n    function formatAttestation(\n        bytes32 snapRoot_,\n        bytes32 dataHash_,\n        uint32 nonce_,\n        uint40 blockNumber_,\n        uint40 timestamp_\n    ) public pure returns (bytes memory) {\n        return AttestationLib.formatAttestation(snapRoot_, dataHash_, nonce_, blockNumber_, timestamp_);\n    }\n\n    function isAttestation(bytes memory payload) public pure returns (bool) {\n        return payload.ref().isAttestation();\n    }\n}\n","language":"Solidity","languageVersion":"0.8.17","compilerVersion":"0.8.17","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"38129:2893:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"38129:2893:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38734:370;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39829:133;;;;;;:::i;:::-;;:::i;:::-;;;1972:12:1;1960:25;;;1942:44;;1930:2;1915:18;39829:133:0;1798:194:1;40895:125:0;;;;;;:::i;:::-;;:::i;:::-;;;2162:14:1;;2155:22;2137:41;;2125:2;2110:18;40895:125:0;1997:187:1;39555:125:0;;;;;;:::i;:::-;;:::i;:::-;;;2363:10:1;2351:23;;;2333:42;;2321:2;2306:18;39555:125:0;2189:192:1;40108:138:0;;;;;;:::i;:::-;;:::i;:::-;;;2532:25:1;;;2520:2;2505:18;40108:138:0;2386:177:1;39386:163:0;;;;;;:::i;:::-;;:::i;39968:134::-;;;;;;:::i;:::-;;:::i;40576:313::-;;;;;;:::i;:::-;34020:72;;;;;;4041:19:1;;;;4076:12;;;4069:28;;;;4135:3;4131:16;;;;4149:66;4127:89;40763:12:0;4113::1;;4106:111;4340:3;4336:16;;;4236:66;4332:25;;;4318:12;;;4311:47;4392:16;;;4388:25;4374:12;;;4367:47;34020:72:0;;;;;;;;;4430:12:1;;;;34020:72:0;;;40576:313;39110:132;;;;;;:::i;:::-;;:::i;39248:::-;;;;;;:::i;:::-;;:::i;39686:137::-;;;;;;:::i;:::-;;:::i;38734:370::-;38804:12;38985:23;39011:41;39044:7;39011:32;:41::i;:::-;38985:67;-1:-1:-1;39069:28:0;38985:67;39069:26;:28::i;:::-;39062:35;38734:370;-1:-1:-1;;;38734:370:0:o;39829:133::-;39891:6;39916:39;:27;:7;:25;:27::i;:::-;:37;:39::i;:::-;39909:46;39829:133;-1:-1:-1;;39829:133:0:o;40895:125::-;40961:4;40984:29;:13;:7;:11;:13::i;:::-;16054:17;16028:43;1019:2;34916:35;;34830:128;39555:125;39613:6;39638:35;:27;:7;:25;:27::i;:::-;:33;:35::i;40108:138::-;40172:7;40198:41;:27;:7;:25;:27::i;:::-;:39;:41::i;39386:163::-;39467:7;39493:49;39517:10;39529:12;39493:23;:49::i;39968:134::-;40030:7;40056:39;:27;:7;:25;:27::i;:::-;:37;:39::i;39110:132::-;39171:7;39197:38;:27;:7;:25;:27::i;:::-;:36;:38::i;39248:132::-;39309:7;39335:38;:27;:7;:25;:27::i;:::-;:36;:38::i;39686:137::-;39750:6;39775:41;:27;:7;:25;:27::i;:::-;:39;:41::i;34250:141::-;34322:11;34352:32;34370:13;:7;:11;:13::i;:::-;34352:17;:32::i;12868:1041::-;13114:4;13108:11;;13244:34;13258:7;13273:4;13267:10;;13244:13;:34::i;:::-;-1:-1:-1;16054:17:0;16028:43;;13490:12;16886:2;16870:18;;17254:20;;13786;;13808:4;13782:31;13776:4;13769:45;-1:-1:-1;13876:17:0;;12868:1041;;-1:-1:-1;12868:1041:0:o;37747:226::-;37806:6;37904:61;32991:2;37962:1;37904:3;:12;:22;:61;:22;:61::i;11761:569::-;11849:10;;11815:7;;12275:4;12266:14;;12306:17;12266:14;11849:10;12306:5;:17::i;:::-;12299:24;11761:569;-1:-1:-1;;;;11761:569:0:o;37058:218::-;37113:6;37211:57;32884:2;37265:1;37211:3;:12;35774:126;35474:234;35535:7;35650:51;2734:37;35650:3;:12;:25;;:51::i;36795:165::-;36914:38;;;;;;3711:19:1;;;3746:12;;;3739:28;;;36878:7:0;;3783:12:1;;36914:38:0;;;;;;;;;;;;;36904:49;;;;;;36897:56;;36795:165;;;;:::o;35104:223::-;35163:7;35271:49;2653:35;35271:3;:12;35774:126;36301:149;36359:7;36385:58;36359:7;36439:2;36385:3;:12;:18;:58;:18;:58::i;36548:149::-;36606:7;36632:58;32836:2;;36632:3;:12;35774:126;37361:231;37422:6;37520:64;32939:2;37581:1;37520:3;:12;35774:126;34543:215;34610:11;1019:2;16054:17;16028:43;;34916:35;34633:60;;34669:24;;;;;;;;;;;;;;34633:60;-1:-1:-1;34742:7:0;34543:215::o;26802:842::-;27141:4;27135:11;26880:7;;16054:17;16028:43;;;15687:3;15660:30;;;;27223:12;;;27219:66;;;27258:16;;;;;;;;;;;;;;27219:66;27294:8;27510:4;27502:6;27496:4;27488:6;27482:4;27475:5;27464:51;27457:58;;27539:3;27534:37;;27551:20;;;;;;;;;;;;;;27534:37;26151:3;26143:11;;;26142:20;;27581:56;26802:842;-1:-1:-1;;;;;;;26802:842:0:o;24341:538::-;24432:7;;24474:29;:7;24488:6;24496;24474:13;:29::i;:::-;24844:2;:11;;;24860:1;24843:18;24817:45;;-1:-1:-1;;24341:538:0;;;;;:::o;10881:540::-;10947:7;;10981:11;10988:4;10981;:11;:::i;:::-;10966:26;;11260:4;11254:11;11248:4;11245:21;11242:38;;;-1:-1:-1;11277:1:0;11242:38;11303:4;11311:1;11303:9;11299:66;;11335:19;;;;;;;;;;;;;;11299:66;26151:3;26143:11;;;26142:20;;11381:33;25818:352;18347:169;18423:20;18485:4;18491:16;:7;:14;:16::i;:::-;18472:36;;;;;;3711:19:1;;;;3746:12;;3739:28;3783:12;;18472:36:0;3554:247:1;22649:1334:0;22736:14;22766:6;22776:1;22766:11;22762:59;;-1:-1:-1;22808:1:0;22793:17;;22762:59;22907:2;22898:6;:11;22894:65;;;22932:16;;;;;;;;;;;;;;22894:65;16054:17;16028:43;;23038:15;23047:6;23038;:15;:::i;:::-;:31;23034:82;;;23092:13;;;;;;;;;;;;;;23034:82;23155:1;23145:11;;;23125:17;23195:13;:7;15687:3;15660:30;;15501:196;23195:13;23942:17;;;23936:24;23653:66;23634:17;;;;;23630:90;;;;23932:35;;22649:1334;-1:-1:-1;;;;22649:1334:0:o;17792:292::-;17848:14;17874:12;17889:13;:7;15687:3;15660:30;;15501:196;17889:13;16054:17;16028:43;;;;18047:21;;;;;-1:-1:-1;;17792:292:0:o;14:184:1:-;66:77;63:1;56:88;163:4;160:1;153:15;187:4;184:1;177:15;203:980;271:6;324:2;312:9;303:7;299:23;295:32;292:52;;;340:1;337;330:12;292:52;380:9;367:23;409:18;450:2;442:6;439:14;436:34;;;466:1;463;456:12;436:34;504:6;493:9;489:22;479:32;;549:7;542:4;538:2;534:13;530:27;520:55;;571:1;568;561:12;520:55;607:2;594:16;629:2;625;622:10;619:36;;;635:18;;:::i;:::-;769:2;763:9;831:4;823:13;;674:66;819:22;;;843:2;815:31;811:40;799:53;;;867:18;;;887:22;;;864:46;861:72;;;913:18;;:::i;:::-;953:10;949:2;942:22;988:2;980:6;973:18;1028:7;1023:2;1018;1014;1010:11;1006:20;1003:33;1000:53;;;1049:1;1046;1039:12;1000:53;1105:2;1100;1096;1092:11;1087:2;1079:6;1075:15;1062:46;1150:1;1128:15;;;1145:2;1124:24;1117:35;;;;-1:-1:-1;1132:6:1;203:980;-1:-1:-1;;;;;203:980:1:o;1188:605::-;1298:4;1327:2;1356;1345:9;1338:21;1388:6;1382:13;1431:6;1426:2;1415:9;1411:18;1404:34;1456:1;1466:140;1480:6;1477:1;1474:13;1466:140;;;1575:14;;;1571:23;;1565:30;1541:17;;;1560:2;1537:26;1530:66;1495:10;;1466:140;;;1470:3;1655:1;1650:2;1641:6;1630:9;1626:22;1622:31;1615:42;1784:2;1714:66;1709:2;1701:6;1697:15;1693:88;1682:9;1678:104;1674:113;1666:121;;;;1188:605;;;;:::o;2568:248::-;2636:6;2644;2697:2;2685:9;2676:7;2672:23;2668:32;2665:52;;;2713:1;2710;2703:12;2665:52;-1:-1:-1;;2736:23:1;;;2806:2;2791:18;;;2778:32;;-1:-1:-1;2568:248:1:o;2821:165::-;2888:20;;2948:12;2937:24;;2927:35;;2917:63;;2976:1;2973;2966:12;2917:63;2821:165;;;:::o;2991:558::-;3083:6;3091;3099;3107;3115;3168:3;3156:9;3147:7;3143:23;3139:33;3136:53;;;3185:1;3182;3175:12;3136:53;3221:9;3208:23;3198:33;;3278:2;3267:9;3263:18;3250:32;3240:42;;3332:2;3321:9;3317:18;3304:32;3376:10;3369:5;3365:22;3358:5;3355:33;3345:61;;3402:1;3399;3392:12;3345:61;3425:5;-1:-1:-1;3449:37:1;3482:2;3467:18;;3449:37;:::i;:::-;3439:47;;3505:38;3538:3;3527:9;3523:19;3505:38;:::i;:::-;3495:48;;2991:558;;;;;;;;:::o;4453:279::-;4518:9;;;4539:10;;;4536:190;;;4582:77;4579:1;4572:88;4683:4;4680:1;4673:15;4711:4;4708:1;4701:15","abiDefinition":[{"inputs":[],"name":"IndexedTooMuch","type":"error"},{"inputs":[],"name":"OccupiedMemory","type":"error"},{"inputs":[],"name":"PrecompileOutOfGas","type":"error"},{"inputs":[],"name":"UnallocatedMemory","type":"error"},{"inputs":[],"name":"UnformattedAttestation","type":"error"},{"inputs":[],"name":"ViewOverrun","type":"error"},{"inputs":[{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"blockNumber","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"castToAttestation","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"agentRoot_","type":"bytes32"},{"internalType":"bytes32","name":"snapGasHash_","type":"bytes32"}],"name":"dataHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"dataHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"snapRoot_","type":"bytes32"},{"internalType":"bytes32","name":"dataHash_","type":"bytes32"},{"internalType":"uint32","name":"nonce_","type":"uint32"},{"internalType":"uint40","name":"blockNumber_","type":"uint40"},{"internalType":"uint40","name":"timestamp_","type":"uint40"}],"name":"formatAttestation","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"hashInvalid","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"hashValid","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"isAttestation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"snapRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"timestamp","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"pure","type":"function"}],"userDoc":{"kind":"user","methods":{},"notice":"Exposes Attestation methods for testing against golang.","version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"IndexedTooMuch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OccupiedMemory\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PrecompileOutOfGas\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnallocatedMemory\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnformattedAttestation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ViewOverrun\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint40\",\"name\":\"\",\"type\":\"uint40\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"castToAttestation\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"agentRoot_\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"snapGasHash_\",\"type\":\"bytes32\"}],\"name\":\"dataHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"dataHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"snapRoot_\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"dataHash_\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"nonce_\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"blockNumber_\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"timestamp_\",\"type\":\"uint40\"}],\"name\":\"formatAttestation\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"hashInvalid\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"hashValid\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"isAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"snapRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"timestamp\",\"outputs\":[{\"internalType\":\"uint40\",\"name\":\"\",\"type\":\"uint40\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Exposes Attestation methods for testing against golang.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationHarness.t.sol\":\"AttestationHarness\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationHarness.t.sol\":{\"keccak256\":\"0x027132e072bb0f43c3b2556612c2546f0908ba3e62d11624798ed9896df1fca8\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://00865d6038082824250d50297188c538484dab4dc8c827d95a07d15b0967623e\",\"dweb:/ipfs/QmWSV9Po78tGqv8hfRyvNwPAK14JbZ8vjH4jp7RFycYZrE\"]}},\"version\":1}"},"hashes":{"blockNumber(bytes)":"e948e600","castToAttestation(bytes)":"11f6389c","dataHash(bytes)":"c4e1fa9c","dataHash(bytes32,bytes32)":"717b6ca9","formatAttestation(bytes32,bytes32,uint32,uint40,uint40)":"86bf2253","hashInvalid(bytes)":"60cf3bf0","hashValid(bytes)":"730dbf63","isAttestation(bytes)":"3ae7034d","nonce(bytes)":"4e765004","snapRoot(bytes)":"91bacf60","timestamp(bytes)":"1c9aa222"}},"solidity/AttestationHarness.t.sol:AttestationLib":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e49f1028031a4dd826aabb420541a86fe8d62969ecd95191b3fea8ad3634515064736f6c63430008110033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e49f1028031a4dd826aabb420541a86fe8d62969ecd95191b3fea8ad3634515064736f6c63430008110033","info":{"source":"// SPDX-License-Identifier: MIT\npragma solidity =0.8.17;\n\n// contracts/libs/Constants.sol\n\n// Here we define common constants to enable their easier reusing later.\n\n// ══════════════════════════════════ MERKLE ═══════════════════════════════════\n/// @dev Height of the Agent Merkle Tree\nuint256 constant AGENT_TREE_HEIGHT = 32;\n/// @dev Height of the Origin Merkle Tree\nuint256 constant ORIGIN_TREE_HEIGHT = 32;\n/// @dev Height of the Snapshot Merkle Tree. Allows up to 64 leafs, e.g. up to 32 states\nuint256 constant SNAPSHOT_TREE_HEIGHT = 6;\n// ══════════════════════════════════ STRUCTS ══════════════════════════════════\n/// @dev See Attestation.sol: (bytes32,bytes32,uint32,uint40,uint40): 32+32+4+5+5\nuint256 constant ATTESTATION_LENGTH = 78;\n/// @dev See GasData.sol: (uint16,uint16,uint16,uint16,uint16,uint16): 2+2+2+2+2+2\nuint256 constant GAS_DATA_LENGTH = 12;\n/// @dev See Receipt.sol: (uint32,uint32,bytes32,bytes32,uint8,address,address,address): 4+4+32+32+1+20+20+20\nuint256 constant RECEIPT_LENGTH = 133;\n/// @dev See State.sol: (bytes32,uint32,uint32,uint40,uint40,GasData): 32+4+4+5+5+len(GasData)\nuint256 constant STATE_LENGTH = 50 + GAS_DATA_LENGTH;\n/// @dev Maximum amount of states in a single snapshot. Each state produces two leafs in the tree\nuint256 constant SNAPSHOT_MAX_STATES = 1 \u003c\u003c (SNAPSHOT_TREE_HEIGHT - 1);\n// ══════════════════════════════════ MESSAGE ══════════════════════════════════\n/// @dev See Header.sol: (uint8,uint32,uint32,uint32,uint32): 1+4+4+4+4\nuint256 constant HEADER_LENGTH = 17;\n/// @dev See Request.sol: (uint96,uint64,uint32): 12+8+4\nuint256 constant REQUEST_LENGTH = 24;\n/// @dev See Tips.sol: (uint64,uint64,uint64,uint64): 8+8+8+8\nuint256 constant TIPS_LENGTH = 32;\n/// @dev The amount of discarded last bits when encoding tip values\nuint256 constant TIPS_GRANULARITY = 32;\n/// @dev Tip values could be only the multiples of TIPS_MULTIPLIER\nuint256 constant TIPS_MULTIPLIER = 1 \u003c\u003c TIPS_GRANULARITY;\n// ══════════════════════════════ STATEMENT SALTS ══════════════════════════════\n/// @dev Salts for signing various statements\nbytes32 constant ATTESTATION_VALID_SALT = keccak256(\"ATTESTATION_VALID_SALT\");\nbytes32 constant ATTESTATION_INVALID_SALT = keccak256(\"ATTESTATION_INVALID_SALT\");\nbytes32 constant RECEIPT_VALID_SALT = keccak256(\"RECEIPT_VALID_SALT\");\nbytes32 constant RECEIPT_INVALID_SALT = keccak256(\"RECEIPT_INVALID_SALT\");\nbytes32 constant SNAPSHOT_VALID_SALT = keccak256(\"SNAPSHOT_VALID_SALT\");\nbytes32 constant STATE_INVALID_SALT = keccak256(\"STATE_INVALID_SALT\");\n// ═════════════════════════════════ PROTOCOL ══════════════════════════════════\n/// @dev Optimistic period for new agent roots in LightManager\nuint32 constant AGENT_ROOT_OPTIMISTIC_PERIOD = 1 days;\n/// @dev Timeout between the agent root could be proposed and resolved in LightManager\nuint32 constant AGENT_ROOT_PROPOSAL_TIMEOUT = 12 hours;\nuint32 constant BONDING_OPTIMISTIC_PERIOD = 1 days;\n/// @dev Amount of time that the Notary will not be considered active after they won a dispute\nuint32 constant DISPUTE_TIMEOUT_NOTARY = 12 hours;\n/// @dev Amount of time without fresh data from Notaries before contract owner can resolve stuck disputes manually\nuint256 constant FRESH_DATA_TIMEOUT = 4 hours;\n/// @dev Maximum bytes per message = 2 KiB (somewhat arbitrarily set to begin)\nuint256 constant MAX_CONTENT_BYTES = 2 * 2 ** 10;\n/// @dev Maximum value for the summit tip that could be set in GasOracle\nuint256 constant MAX_SUMMIT_TIP = 0.01 ether;\n\n// contracts/libs/Errors.sol\n\n// ══════════════════════════════ INVALID CALLER ═══════════════════════════════\n\nerror CallerNotAgentManager();\nerror CallerNotDestination();\nerror CallerNotInbox();\nerror CallerNotSummit();\n\n// ══════════════════════════════ INCORRECT DATA ═══════════════════════════════\n\nerror IncorrectAttestation();\nerror IncorrectAgentDomain();\nerror IncorrectAgentIndex();\nerror IncorrectAgentProof();\nerror IncorrectAgentRoot();\nerror IncorrectDataHash();\nerror IncorrectDestinationDomain();\nerror IncorrectOriginDomain();\nerror IncorrectSnapshotProof();\nerror IncorrectSnapshotRoot();\nerror IncorrectState();\nerror IncorrectStatesAmount();\nerror IncorrectTipsProof();\nerror IncorrectVersionLength();\n\nerror IncorrectNonce();\nerror IncorrectSender();\nerror IncorrectRecipient();\n\nerror FlagOutOfRange();\nerror IndexOutOfRange();\nerror NonceOutOfRange();\n\nerror OutdatedNonce();\n\nerror UnformattedAttestation();\nerror UnformattedAttestationReport();\nerror UnformattedBaseMessage();\nerror UnformattedCallData();\nerror UnformattedCallDataPrefix();\nerror UnformattedMessage();\nerror UnformattedReceipt();\nerror UnformattedReceiptReport();\nerror UnformattedSignature();\nerror UnformattedSnapshot();\nerror UnformattedState();\nerror UnformattedStateReport();\n\n// ═══════════════════════════════ MERKLE TREES ════════════════════════════════\n\nerror LeafNotProven();\nerror MerkleTreeFull();\nerror NotEnoughLeafs();\nerror TreeHeightTooLow();\n\n// ═════════════════════════════ OPTIMISTIC PERIOD ═════════════════════════════\n\nerror BaseClientOptimisticPeriod();\nerror MessageOptimisticPeriod();\nerror SlashAgentOptimisticPeriod();\nerror WithdrawTipsOptimisticPeriod();\nerror ZeroProofMaturity();\n\n// ═══════════════════════════════ AGENT MANAGER ═══════════════════════════════\n\nerror AgentNotGuard();\nerror AgentNotNotary();\n\nerror AgentCantBeAdded();\nerror AgentNotActive();\nerror AgentNotActiveNorUnstaking();\nerror AgentNotFraudulent();\nerror AgentNotUnstaking();\nerror AgentUnknown();\n\nerror AgentRootNotProposed();\nerror AgentRootTimeoutNotOver();\n\nerror NotStuck();\n\nerror DisputeAlreadyResolved();\nerror DisputeNotOpened();\nerror DisputeTimeoutNotOver();\nerror GuardInDispute();\nerror NotaryInDispute();\n\nerror MustBeSynapseDomain();\nerror SynapseDomainForbidden();\n\n// ════════════════════════════════ DESTINATION ════════════════════════════════\n\nerror AlreadyExecuted();\nerror AlreadyFailed();\nerror DuplicatedSnapshotRoot();\nerror IncorrectMagicValue();\nerror GasLimitTooLow();\nerror GasSuppliedTooLow();\n\n// ══════════════════════════════════ ORIGIN ═══════════════════════════════════\n\nerror ContentLengthTooBig();\nerror EthTransferFailed();\nerror InsufficientEthBalance();\n\n// ════════════════════════════════ GAS ORACLE ═════════════════════════════════\n\nerror LocalGasDataNotSet();\nerror RemoteGasDataNotSet();\n\n// ═══════════════════════════════════ TIPS ════════════════════════════════════\n\nerror SummitTipTooHigh();\nerror TipsClaimMoreThanEarned();\nerror TipsClaimZero();\nerror TipsOverflow();\nerror TipsValueTooLow();\n\n// ════════════════════════════════ MEMORY VIEW ════════════════════════════════\n\nerror IndexedTooMuch();\nerror ViewOverrun();\nerror OccupiedMemory();\nerror UnallocatedMemory();\nerror PrecompileOutOfGas();\n\n// ═════════════════════════════════ MULTICALL ═════════════════════════════════\n\nerror MulticallFailed();\n\n// contracts/libs/memory/MemView.sol\n\n/// @dev MemView is an untyped view over a portion of memory to be used instead of `bytes memory`\ntype MemView is uint256;\n\n/// @dev Attach library functions to MemView\nusing MemViewLib for MemView global;\n\n/// @notice Library for operations with the memory views.\n/// Forked from https://github.com/summa-tx/memview-sol with several breaking changes:\n/// - The codebase is ported to Solidity 0.8\n/// - Custom errors are added\n/// - The runtime type checking is replaced with compile-time check provided by User-Defined Value Types\n///   https://docs.soliditylang.org/en/latest/types.html#user-defined-value-types\n/// - uint256 is used as the underlying type for the \"memory view\" instead of bytes29.\n///   It is wrapped into MemView custom type in order not to be confused with actual integers.\n/// - Therefore the \"type\" field is discarded, allowing to allocate 16 bytes for both view location and length\n/// - The documentation is expanded\n/// - Library functions unused by the rest of the codebase are removed\n//  - Very pretty code separators are added :)\nlibrary MemViewLib {\n    /// @notice Stack layout for uint256 (from highest bits to lowest)\n    /// (32 .. 16]      loc     16 bytes    Memory address of underlying bytes\n    /// (16 .. 00]      len     16 bytes    Length of underlying bytes\n\n    // ═══════════════════════════════════════════ BUILDING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Instantiate a new untyped memory view. This should generally not be called directly.\n     * Prefer `ref` wherever possible.\n     * @param loc_          The memory address\n     * @param len_          The length\n     * @return The new view with the specified location and length\n     */\n    function build(uint256 loc_, uint256 len_) internal pure returns (MemView) {\n        uint256 end_ = loc_ + len_;\n        // Make sure that a view is not constructed that points to unallocated memory\n        // as this could be indicative of a buffer overflow attack\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            if gt(end_, mload(0x40)) { end_ := 0 }\n        }\n        if (end_ == 0) {\n            revert UnallocatedMemory();\n        }\n        return _unsafeBuildUnchecked(loc_, len_);\n    }\n\n    /**\n     * @notice Instantiate a memory view from a byte array.\n     * @dev Note that due to Solidity memory representation, it is not possible to\n     * implement a deref, as the `bytes` type stores its len in memory.\n     * @param arr           The byte array\n     * @return The memory view over the provided byte array\n     */\n    function ref(bytes memory arr) internal pure returns (MemView) {\n        uint256 len_ = arr.length;\n        // `bytes arr` is stored in memory in the following way\n        // 1. First, uint256 arr.length is stored. That requires 32 bytes (0x20).\n        // 2. Then, the array data is stored.\n        uint256 loc_;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // We add 0x20, so that the view starts exactly where the array data starts\n            loc_ := add(arr, 0x20)\n        }\n        return build(loc_, len_);\n    }\n\n    // ════════════════════════════════════════════ CLONING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to the new memory.\n     * @param memView       The memory view\n     * @return arr          The cloned byte array\n     */\n    function clone(MemView memView) internal view returns (bytes memory arr) {\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load unused memory pointer\n            ptr := mload(0x40)\n            // This is where the byte array will be stored\n            arr := ptr\n        }\n        unchecked {\n            _unsafeCopyTo(memView, ptr + 0x20);\n        }\n        // `bytes arr` is stored in memory in the following way\n        // 1. First, uint256 arr.length is stored. That requires 32 bytes (0x20).\n        // 2. Then, the array data is stored.\n        uint256 len_ = memView.len();\n        uint256 footprint_ = memView.footprint();\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Write new unused pointer: the old value + array footprint + 32 bytes to store the length\n            mstore(0x40, add(add(ptr, footprint_), 0x20))\n            // Write len of new array (in bytes)\n            mstore(ptr, len_)\n        }\n    }\n\n    /**\n     * @notice Copies all views, joins them into a new bytearray.\n     * @param memViews      The memory views\n     * @return arr          The new byte array with joined data behind the given views\n     */\n    function join(MemView[] memory memViews) internal view returns (bytes memory arr) {\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load unused memory pointer\n            ptr := mload(0x40)\n            // This is where the byte array will be stored\n            arr := ptr\n        }\n        MemView newView;\n        unchecked {\n            newView = _unsafeJoin(memViews, ptr + 0x20);\n        }\n        uint256 len_ = newView.len();\n        uint256 footprint_ = newView.footprint();\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Write new unused pointer: the old value + array footprint + 32 bytes to store the length\n            mstore(0x40, add(add(ptr, footprint_), 0x20))\n            // Write len of new array (in bytes)\n            mstore(ptr, len_)\n        }\n    }\n\n    // ══════════════════════════════════════════ INSPECTING MEMORY VIEW ═══════════════════════════════════════════════\n\n    /**\n     * @notice Returns the memory address of the underlying bytes.\n     * @param memView       The memory view\n     * @return loc_         The memory address\n     */\n    function loc(MemView memView) internal pure returns (uint256 loc_) {\n        // loc is stored in the highest 16 bytes of the underlying uint256\n        return MemView.unwrap(memView) \u003e\u003e 128;\n    }\n\n    /**\n     * @notice Returns the number of bytes of the view.\n     * @param memView       The memory view\n     * @return len_         The length of the view\n     */\n    function len(MemView memView) internal pure returns (uint256 len_) {\n        // len is stored in the lowest 16 bytes of the underlying uint256\n        return MemView.unwrap(memView) \u0026 type(uint128).max;\n    }\n\n    /**\n     * @notice Returns the endpoint of `memView`.\n     * @param memView       The memory view\n     * @return end_         The endpoint of `memView`\n     */\n    function end(MemView memView) internal pure returns (uint256 end_) {\n        // The endpoint never overflows uint128, let alone uint256, so we could use unchecked math here\n        unchecked {\n            return memView.loc() + memView.len();\n        }\n    }\n\n    /**\n     * @notice Returns the number of memory words this memory view occupies, rounded up.\n     * @param memView       The memory view\n     * @return words_       The number of memory words\n     */\n    function words(MemView memView) internal pure returns (uint256 words_) {\n        // returning ceil(length / 32.0)\n        unchecked {\n            return (memView.len() + 31) \u003e\u003e 5;\n        }\n    }\n\n    /**\n     * @notice Returns the in-memory footprint of a fresh copy of the view.\n     * @param memView       The memory view\n     * @return footprint_   The in-memory footprint of a fresh copy of the view.\n     */\n    function footprint(MemView memView) internal pure returns (uint256 footprint_) {\n        // words() * 32\n        return memView.words() \u003c\u003c 5;\n    }\n\n    // ════════════════════════════════════════════ HASHING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Returns the keccak256 hash of the underlying memory\n     * @param memView       The memory view\n     * @return digest       The keccak256 hash of the underlying memory\n     */\n    function keccak(MemView memView) internal pure returns (bytes32 digest) {\n        uint256 loc_ = memView.loc();\n        uint256 len_ = memView.len();\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            digest := keccak256(loc_, len_)\n        }\n    }\n\n    /**\n     * @notice Adds a salt to the keccak256 hash of the underlying data and returns the keccak256 hash of the\n     * resulting data.\n     * @param memView       The memory view\n     * @return digestSalted keccak256(salt, keccak256(memView))\n     */\n    function keccakSalted(MemView memView, bytes32 salt) internal pure returns (bytes32 digestSalted) {\n        return keccak256(bytes.concat(salt, memView.keccak()));\n    }\n\n    // ════════════════════════════════════════════ SLICING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Safe slicing without memory modification.\n     * @param memView       The memory view\n     * @param index_        The start index\n     * @param len_          The length\n     * @return The new view for the slice of the given length starting from the given index\n     */\n    function slice(MemView memView, uint256 index_, uint256 len_) internal pure returns (MemView) {\n        uint256 loc_ = memView.loc();\n        // Ensure it doesn't overrun the view\n        if (loc_ + index_ + len_ \u003e memView.end()) {\n            revert ViewOverrun();\n        }\n        // Build a view starting from index with the given length\n        unchecked {\n            // loc_ + index_ \u003c= memView.end()\n            return build({loc_: loc_ + index_, len_: len_});\n        }\n    }\n\n    /**\n     * @notice Shortcut to `slice`. Gets a view representing bytes from `index` to end(memView).\n     * @param memView       The memory view\n     * @param index_        The start index\n     * @return The new view for the slice starting from the given index until the initial view endpoint\n     */\n    function sliceFrom(MemView memView, uint256 index_) internal pure returns (MemView) {\n        uint256 len_ = memView.len();\n        // Ensure it doesn't overrun the view\n        if (index_ \u003e len_) {\n            revert ViewOverrun();\n        }\n        // Build a view starting from index with the given length\n        unchecked {\n            // index_ \u003c= len_ =\u003e memView.loc() + index_ \u003c= memView.loc() + memView.len() == memView.end()\n            return build({loc_: memView.loc() + index_, len_: len_ - index_});\n        }\n    }\n\n    /**\n     * @notice Shortcut to `slice`. Gets a view representing the first `len` bytes.\n     * @param memView       The memory view\n     * @param len_          The length\n     * @return The new view for the slice of the given length starting from the initial view beginning\n     */\n    function prefix(MemView memView, uint256 len_) internal pure returns (MemView) {\n        return memView.slice({index_: 0, len_: len_});\n    }\n\n    /**\n     * @notice Shortcut to `slice`. Gets a view representing the last `len` byte.\n     * @param memView       The memory view\n     * @param len_          The length\n     * @return The new view for the slice of the given length until the initial view endpoint\n     */\n    function postfix(MemView memView, uint256 len_) internal pure returns (MemView) {\n        uint256 viewLen = memView.len();\n        // Ensure it doesn't overrun the view\n        if (len_ \u003e viewLen) {\n            revert ViewOverrun();\n        }\n        // Could do the unchecked math due to the check above\n        uint256 index_;\n        unchecked {\n            index_ = viewLen - len_;\n        }\n        // Build a view starting from index with the given length\n        unchecked {\n            // len_ \u003c= memView.len() =\u003e memView.loc() \u003c= loc_ \u003c= memView.end()\n            return build({loc_: memView.loc() + viewLen - len_, len_: len_});\n        }\n    }\n\n    // ═══════════════════════════════════════════ INDEXING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Load up to 32 bytes from the view onto the stack.\n     * @dev Returns a bytes32 with only the `bytes_` HIGHEST bytes set.\n     * This can be immediately cast to a smaller fixed-length byte array.\n     * To automatically cast to an integer, use `indexUint`.\n     * @param memView       The memory view\n     * @param index_        The index\n     * @param bytes_        The amount of bytes to load onto the stack\n     * @return result       The 32 byte result having only `bytes_` highest bytes set\n     */\n    function index(MemView memView, uint256 index_, uint256 bytes_) internal pure returns (bytes32 result) {\n        if (bytes_ == 0) {\n            return bytes32(0);\n        }\n        // Can't load more than 32 bytes to the stack in one go\n        if (bytes_ \u003e 32) {\n            revert IndexedTooMuch();\n        }\n        // The last indexed byte should be within view boundaries\n        if (index_ + bytes_ \u003e memView.len()) {\n            revert ViewOverrun();\n        }\n        uint256 bitLength = bytes_ \u003c\u003c 3; // bytes_ * 8\n        uint256 loc_ = memView.loc();\n        // Get a mask with `bitLength` highest bits set\n        uint256 mask;\n        // 0x800...00 binary representation is 100...00\n        // sar stands for \"signed arithmetic shift\": https://en.wikipedia.org/wiki/Arithmetic_shift\n        // sar(N-1, 100...00) = 11...100..00, with exactly N highest bits set to 1\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            mask := sar(sub(bitLength, 1), 0x8000000000000000000000000000000000000000000000000000000000000000)\n        }\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load a full word using index offset, and apply mask to ignore non-relevant bytes\n            result := and(mload(add(loc_, index_)), mask)\n        }\n    }\n\n    /**\n     * @notice Parse an unsigned integer from the view at `index`.\n     * @dev Requires that the view have \u003e= `bytes_` bytes following that index.\n     * @param memView       The memory view\n     * @param index_        The index\n     * @param bytes_        The amount of bytes to load onto the stack\n     * @return The unsigned integer\n     */\n    function indexUint(MemView memView, uint256 index_, uint256 bytes_) internal pure returns (uint256) {\n        bytes32 indexedBytes = memView.index(index_, bytes_);\n        // `index()` returns left-aligned `bytes_`, while integers are right-aligned\n        // Shifting here to right-align with the full 32 bytes word: need to shift right `(32 - bytes_)` bytes\n        unchecked {\n            // memView.index() reverts when bytes_ \u003e 32, thus unchecked math\n            return uint256(indexedBytes) \u003e\u003e ((32 - bytes_) \u003c\u003c 3);\n        }\n    }\n\n    /**\n     * @notice Parse an address from the view at `index`.\n     * @dev Requires that the view have \u003e= 20 bytes following that index.\n     * @param memView       The memory view\n     * @param index_        The index\n     * @return The address\n     */\n    function indexAddress(MemView memView, uint256 index_) internal pure returns (address) {\n        // index 20 bytes as `uint160`, and then cast to `address`\n        return address(uint160(memView.indexUint(index_, 20)));\n    }\n\n    // ══════════════════════════════════════════════ PRIVATE HELPERS ══════════════════════════════════════════════════\n\n    /// @dev Returns a memory view over the specified memory location\n    /// without checking if it points to unallocated memory.\n    function _unsafeBuildUnchecked(uint256 loc_, uint256 len_) private pure returns (MemView) {\n        // There is no scenario where loc or len would overflow uint128, so we omit this check.\n        // We use the highest 128 bits to encode the location and the lowest 128 bits to encode the length.\n        return MemView.wrap((loc_ \u003c\u003c 128) | len_);\n    }\n\n    /**\n     * @notice Copy the view to a location, return an unsafe memory reference\n     * @dev Super Dangerous direct memory access.\n     * This reference can be overwritten if anything else modifies memory (!!!).\n     * As such it MUST be consumed IMMEDIATELY. Update the free memory pointer to ensure the copied data\n     * is not overwritten. This function is private to prevent unsafe usage by callers.\n     * @param memView       The memory view\n     * @param newLoc        The new location to copy the underlying view data\n     * @return The memory view over the unsafe memory with the copied underlying data\n     */\n    function _unsafeCopyTo(MemView memView, uint256 newLoc) private view returns (MemView) {\n        uint256 len_ = memView.len();\n        uint256 oldLoc = memView.loc();\n\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load unused memory pointer\n            ptr := mload(0x40)\n        }\n        // Revert if we're writing in occupied memory\n        if (newLoc \u003c ptr) {\n            revert OccupiedMemory();\n        }\n        bool res;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // use the identity precompile (0x04) to copy\n            res := staticcall(gas(), 0x04, oldLoc, len_, newLoc, len_)\n        }\n        if (!res) revert PrecompileOutOfGas();\n        return _unsafeBuildUnchecked({loc_: newLoc, len_: len_});\n    }\n\n    /**\n     * @notice Join the views in memory, return an unsafe reference to the memory.\n     * @dev Super Dangerous direct memory access.\n     * This reference can be overwritten if anything else modifies memory (!!!).\n     * As such it MUST be consumed IMMEDIATELY. Update the free memory pointer to ensure the copied data\n     * is not overwritten. This function is private to prevent unsafe usage by callers.\n     * @param memViews      The memory views\n     * @return The conjoined view pointing to the new memory\n     */\n    function _unsafeJoin(MemView[] memory memViews, uint256 location) private view returns (MemView) {\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load unused memory pointer\n            ptr := mload(0x40)\n        }\n        // Revert if we're writing in occupied memory\n        if (location \u003c ptr) {\n            revert OccupiedMemory();\n        }\n        // Copy the views to the specified location one by one, by tracking the amount of copied bytes so far\n        uint256 offset = 0;\n        for (uint256 i = 0; i \u003c memViews.length;) {\n            MemView memView = memViews[i];\n            // We can use the unchecked math here as location + sum(view.length) will never overflow uint256\n            unchecked {\n                _unsafeCopyTo(memView, location + offset);\n                offset += memView.len();\n                ++i;\n            }\n        }\n        return _unsafeBuildUnchecked({loc_: location, len_: offset});\n    }\n}\n\n// contracts/libs/memory/Attestation.sol\n\n/// Attestation is a memory view over a formatted attestation payload.\ntype Attestation is uint256;\n\nusing AttestationLib for Attestation global;\n\n/// # Attestation\n/// Attestation structure represents the \"Snapshot Merkle Tree\" created from\n/// every Notary snapshot accepted by the Summit contract. Attestation includes\"\n/// the root of the \"Snapshot Merkle Tree\", as well as additional metadata.\n///\n/// ## Steps for creation of \"Snapshot Merkle Tree\":\n/// 1. The list of hashes is composed for states in the Notary snapshot.\n/// 2. The list is padded with zero values until its length is 2**SNAPSHOT_TREE_HEIGHT.\n/// 3. Values from the list are used as leafs and the merkle tree is constructed.\n///\n/// ## Differences between a State and Attestation\n/// Similar to Origin, every derived Notary's \"Snapshot Merkle Root\" is saved in Summit contract.\n/// The main difference is that Origin contract itself is keeping track of an incremental merkle tree,\n/// by inserting the hash of the sent message and calculating the new \"Origin Merkle Root\".\n/// While Summit relies on Guards and Notaries to provide snapshot data, which is used to calculate the\n/// \"Snapshot Merkle Root\".\n///\n/// - Origin's State is \"state of Origin Merkle Tree after N-th message was sent\".\n/// - Summit's Attestation is \"data for the N-th accepted Notary Snapshot\" + \"agent merkle root at the\n/// time snapshot was submitted\" + \"attestation metadata\".\n///\n/// ## Attestation validity\n/// - Attestation is considered \"valid\" in Summit contract, if it matches the N-th (nonce)\n/// snapshot submitted by Notaries, as well as the historical agent merkle root.\n/// - Attestation is considered \"valid\" in Origin contract, if its underlying Snapshot is \"valid\".\n///\n/// - This means that a snapshot could be \"valid\" in Summit contract and \"invalid\" in Origin, if the underlying\n/// snapshot is invalid (i.e. one of the states in the list is invalid).\n/// - The opposite could also be true. If a perfectly valid snapshot was never submitted to Summit, its attestation\n/// would be valid in Origin, but invalid in Summit (it was never accepted, so the metadata would be incorrect).\n///\n/// - Attestation is considered \"globally valid\", if it is valid in the Summit and all the Origin contracts.\n/// # Memory layout of Attestation fields\n///\n/// | Position   | Field       | Type    | Bytes | Description                                                    |\n/// | ---------- | ----------- | ------- | ----- | -------------------------------------------------------------- |\n/// | [000..032) | snapRoot    | bytes32 | 32    | Root for \"Snapshot Merkle Tree\" created from a Notary snapshot |\n/// | [032..064) | dataHash    | bytes32 | 32    | Agent Root and SnapGasHash combined into a single hash         |\n/// | [064..068) | nonce       | uint32  | 4     | Total amount of all accepted Notary snapshots                  |\n/// | [068..073) | blockNumber | uint40  | 5     | Block when this Notary snapshot was accepted in Summit         |\n/// | [073..078) | timestamp   | uint40  | 5     | Time when this Notary snapshot was accepted in Summit          |\n///\n/// @dev Attestation could be signed by a Notary and submitted to `Destination` in order to use if for proving\n/// messages coming from origin chains that the initial snapshot refers to.\nlibrary AttestationLib {\n    using MemViewLib for bytes;\n\n    // TODO: compress three hashes into one?\n\n    /// @dev The variables below are not supposed to be used outside of the library directly.\n    uint256 private constant OFFSET_SNAP_ROOT = 0;\n    uint256 private constant OFFSET_DATA_HASH = 32;\n    uint256 private constant OFFSET_NONCE = 64;\n    uint256 private constant OFFSET_BLOCK_NUMBER = 68;\n    uint256 private constant OFFSET_TIMESTAMP = 73;\n\n    // ════════════════════════════════════════════════ ATTESTATION ════════════════════════════════════════════════════\n\n    /**\n     * @notice Returns a formatted Attestation payload with provided fields.\n     * @param snapRoot_     Snapshot merkle tree's root\n     * @param dataHash_     Agent Root and SnapGasHash combined into a single hash\n     * @param nonce_        Attestation Nonce\n     * @param blockNumber_  Block number when attestation was created in Summit\n     * @param timestamp_    Block timestamp when attestation was created in Summit\n     * @return Formatted attestation\n     */\n    function formatAttestation(\n        bytes32 snapRoot_,\n        bytes32 dataHash_,\n        uint32 nonce_,\n        uint40 blockNumber_,\n        uint40 timestamp_\n    ) internal pure returns (bytes memory) {\n        return abi.encodePacked(snapRoot_, dataHash_, nonce_, blockNumber_, timestamp_);\n    }\n\n    /**\n     * @notice Returns an Attestation view over the given payload.\n     * @dev Will revert if the payload is not an attestation.\n     */\n    function castToAttestation(bytes memory payload) internal pure returns (Attestation) {\n        return castToAttestation(payload.ref());\n    }\n\n    /**\n     * @notice Casts a memory view to an Attestation view.\n     * @dev Will revert if the memory view is not over an attestation.\n     */\n    function castToAttestation(MemView memView) internal pure returns (Attestation) {\n        if (!isAttestation(memView)) revert UnformattedAttestation();\n        return Attestation.wrap(MemView.unwrap(memView));\n    }\n\n    /// @notice Checks that a payload is a formatted Attestation.\n    function isAttestation(MemView memView) internal pure returns (bool) {\n        return memView.len() == ATTESTATION_LENGTH;\n    }\n\n    /// @notice Returns the hash of an Attestation, that could be later signed by a Notary to signal\n    /// that the attestation is valid.\n    function hashValid(Attestation att) internal pure returns (bytes32) {\n        // The final hash to sign is keccak(attestationSalt, keccak(attestation))\n        return att.unwrap().keccakSalted(ATTESTATION_VALID_SALT);\n    }\n\n    /// @notice Returns the hash of an Attestation, that could be later signed by a Guard to signal\n    /// that the attestation is invalid.\n    function hashInvalid(Attestation att) internal pure returns (bytes32) {\n        // The final hash to sign is keccak(attestationInvalidSalt, keccak(attestation))\n        return att.unwrap().keccakSalted(ATTESTATION_INVALID_SALT);\n    }\n\n    /// @notice Convenience shortcut for unwrapping a view.\n    function unwrap(Attestation att) internal pure returns (MemView) {\n        return MemView.wrap(Attestation.unwrap(att));\n    }\n\n    // ════════════════════════════════════════════ ATTESTATION SLICING ════════════════════════════════════════════════\n\n    /// @notice Returns root of the Snapshot merkle tree created in the Summit contract.\n    function snapRoot(Attestation att) internal pure returns (bytes32) {\n        return att.unwrap().index({index_: OFFSET_SNAP_ROOT, bytes_: 32});\n    }\n\n    /// @notice Returns hash of the Agent Root and SnapGasHash combined into a single hash.\n    function dataHash(Attestation att) internal pure returns (bytes32) {\n        return att.unwrap().index({index_: OFFSET_DATA_HASH, bytes_: 32});\n    }\n\n    /// @notice Returns hash of the Agent Root and SnapGasHash combined into a single hash.\n    function dataHash(bytes32 agentRoot_, bytes32 snapGasHash_) internal pure returns (bytes32) {\n        return keccak256(bytes.concat(agentRoot_, snapGasHash_));\n    }\n\n    /// @notice Returns nonce of Summit contract at the time, when attestation was created.\n    function nonce(Attestation att) internal pure returns (uint32) {\n        // Can be safely casted to uint32, since we index 4 bytes\n        return uint32(att.unwrap().indexUint({index_: OFFSET_NONCE, bytes_: 4}));\n    }\n\n    /// @notice Returns a block number when attestation was created in Summit.\n    function blockNumber(Attestation att) internal pure returns (uint40) {\n        // Can be safely casted to uint40, since we index 5 bytes\n        return uint40(att.unwrap().indexUint({index_: OFFSET_BLOCK_NUMBER, bytes_: 5}));\n    }\n\n    /// @notice Returns a block timestamp when attestation was created in Summit.\n    /// @dev This is the timestamp according to the Synapse Chain.\n    function timestamp(Attestation att) internal pure returns (uint40) {\n        // Can be safely casted to uint40, since we index 5 bytes\n        return uint40(att.unwrap().indexUint({index_: OFFSET_TIMESTAMP, bytes_: 5}));\n    }\n}\n\n// test/harnesses/libs/memory/AttestationHarness.t.sol\n\n// solhint-disable ordering\n/// @notice Exposes Attestation methods for testing against golang.\ncontract AttestationHarness {\n    using AttestationLib for bytes;\n    using AttestationLib for MemView;\n    using MemViewLib for bytes;\n\n    // Note: we don't add an empty test() function here, as it currently leads\n    // to zero coverage on the corresponding library.\n\n    // ══════════════════════════════════════════════════ GETTERS ══════════════════════════════════════════════════════\n\n    function castToAttestation(bytes memory payload) public view returns (bytes memory) {\n        // Walkaround to get the forge coverage working on libraries, see\n        // https://github.com/foundry-rs/foundry/pull/3128#issuecomment-1241245086\n        Attestation attestation = AttestationLib.castToAttestation(payload);\n        return attestation.unwrap().clone();\n    }\n\n    function snapRoot(bytes memory payload) public pure returns (bytes32) {\n        return payload.castToAttestation().snapRoot();\n    }\n\n    function dataHash(bytes memory payload) public pure returns (bytes32) {\n        return payload.castToAttestation().dataHash();\n    }\n\n    function dataHash(bytes32 agentRoot_, bytes32 snapGasHash_) public pure returns (bytes32) {\n        return AttestationLib.dataHash(agentRoot_, snapGasHash_);\n    }\n\n    function nonce(bytes memory payload) public pure returns (uint32) {\n        return payload.castToAttestation().nonce();\n    }\n\n    function blockNumber(bytes memory payload) public pure returns (uint40) {\n        return payload.castToAttestation().blockNumber();\n    }\n\n    function timestamp(bytes memory payload) public pure returns (uint40) {\n        return payload.castToAttestation().timestamp();\n    }\n\n    function hashValid(bytes memory payload) public pure returns (bytes32) {\n        return payload.castToAttestation().hashValid();\n    }\n\n    function hashInvalid(bytes memory payload) public pure returns (bytes32) {\n        return payload.castToAttestation().hashInvalid();\n    }\n\n    // ════════════════════════════════════════════════ FORMATTERS ═════════════════════════════════════════════════════\n\n    function formatAttestation(\n        bytes32 snapRoot_,\n        bytes32 dataHash_,\n        uint32 nonce_,\n        uint40 blockNumber_,\n        uint40 timestamp_\n    ) public pure returns (bytes memory) {\n        return AttestationLib.formatAttestation(snapRoot_, dataHash_, nonce_, blockNumber_, timestamp_);\n    }\n\n    function isAttestation(bytes memory payload) public pure returns (bool) {\n        return payload.ref().isAttestation();\n    }\n}\n","language":"Solidity","languageVersion":"0.8.17","compilerVersion":"0.8.17","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32539:5436:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32539:5436:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32539:5436:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"notice":"# Attestation Attestation structure represents the \"Snapshot Merkle Tree\" created from every Notary snapshot accepted by the Summit contract. Attestation includes\" the root of the \"Snapshot Merkle Tree\", as well as additional metadata. ## Steps for creation of \"Snapshot Merkle Tree\": 1. The list of hashes is composed for states in the Notary snapshot. 2. The list is padded with zero values until its length is 2**SNAPSHOT_TREE_HEIGHT. 3. Values from the list are used as leafs and the merkle tree is constructed. ## Differences between a State and Attestation Similar to Origin, every derived Notary's \"Snapshot Merkle Root\" is saved in Summit contract. The main difference is that Origin contract itself is keeping track of an incremental merkle tree, by inserting the hash of the sent message and calculating the new \"Origin Merkle Root\". While Summit relies on Guards and Notaries to provide snapshot data, which is used to calculate the \"Snapshot Merkle Root\". - Origin's State is \"state of Origin Merkle Tree after N-th message was sent\". - Summit's Attestation is \"data for the N-th accepted Notary Snapshot\" + \"agent merkle root at the time snapshot was submitted\" + \"attestation metadata\". ## Attestation validity - Attestation is considered \"valid\" in Summit contract, if it matches the N-th (nonce) snapshot submitted by Notaries, as well as the historical agent merkle root. - Attestation is considered \"valid\" in Origin contract, if its underlying Snapshot is \"valid\". - This means that a snapshot could be \"valid\" in Summit contract and \"invalid\" in Origin, if the underlying snapshot is invalid (i.e. one of the states in the list is invalid). - The opposite could also be true. If a perfectly valid snapshot was never submitted to Summit, its attestation would be valid in Origin, but invalid in Summit (it was never accepted, so the metadata would be incorrect). - Attestation is considered \"globally valid\", if it is valid in the Summit and all the Origin contracts. # Memory layout of Attestation fields | Position   | Field       | Type    | Bytes | Description                                                    | | ---------- | ----------- | ------- | ----- | -------------------------------------------------------------- | | [000..032) | snapRoot    | bytes32 | 32    | Root for \"Snapshot Merkle Tree\" created from a Notary snapshot | | [032..064) | dataHash    | bytes32 | 32    | Agent Root and SnapGasHash combined into a single hash         | | [064..068) | nonce       | uint32  | 4     | Total amount of all accepted Notary snapshots                  | | [068..073) | blockNumber | uint40  | 5     | Block when this Notary snapshot was accepted in Summit         | | [073..078) | timestamp   | uint40  | 5     | Time when this Notary snapshot was accepted in Summit          |","version":1},"developerDoc":{"details":"Attestation could be signed by a Notary and submitted to `Destination` in order to use if for proving messages coming from origin chains that the initial snapshot refers to.","kind":"dev","methods":{},"stateVariables":{"OFFSET_SNAP_ROOT":{"details":"The variables below are not supposed to be used outside of the library directly."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Attestation could be signed by a Notary and submitted to `Destination` in order to use if for proving messages coming from origin chains that the initial snapshot refers to.\",\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_SNAP_ROOT\":{\"details\":\"The variables below are not supposed to be used outside of the library directly.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"# Attestation Attestation structure represents the \\\"Snapshot Merkle Tree\\\" created from every Notary snapshot accepted by the Summit contract. Attestation includes\\\" the root of the \\\"Snapshot Merkle Tree\\\", as well as additional metadata. ## Steps for creation of \\\"Snapshot Merkle Tree\\\": 1. The list of hashes is composed for states in the Notary snapshot. 2. The list is padded with zero values until its length is 2**SNAPSHOT_TREE_HEIGHT. 3. Values from the list are used as leafs and the merkle tree is constructed. ## Differences between a State and Attestation Similar to Origin, every derived Notary's \\\"Snapshot Merkle Root\\\" is saved in Summit contract. The main difference is that Origin contract itself is keeping track of an incremental merkle tree, by inserting the hash of the sent message and calculating the new \\\"Origin Merkle Root\\\". While Summit relies on Guards and Notaries to provide snapshot data, which is used to calculate the \\\"Snapshot Merkle Root\\\". - Origin's State is \\\"state of Origin Merkle Tree after N-th message was sent\\\". - Summit's Attestation is \\\"data for the N-th accepted Notary Snapshot\\\" + \\\"agent merkle root at the time snapshot was submitted\\\" + \\\"attestation metadata\\\". ## Attestation validity - Attestation is considered \\\"valid\\\" in Summit contract, if it matches the N-th (nonce) snapshot submitted by Notaries, as well as the historical agent merkle root. - Attestation is considered \\\"valid\\\" in Origin contract, if its underlying Snapshot is \\\"valid\\\". - This means that a snapshot could be \\\"valid\\\" in Summit contract and \\\"invalid\\\" in Origin, if the underlying snapshot is invalid (i.e. one of the states in the list is invalid). - The opposite could also be true. If a perfectly valid snapshot was never submitted to Summit, its attestation would be valid in Origin, but invalid in Summit (it was never accepted, so the metadata would be incorrect). - Attestation is considered \\\"globally valid\\\", if it is valid in the Summit and all the Origin contracts. # Memory layout of Attestation fields | Position   | Field       | Type    | Bytes | Description                                                    | | ---------- | ----------- | ------- | ----- | -------------------------------------------------------------- | | [000..032) | snapRoot    | bytes32 | 32    | Root for \\\"Snapshot Merkle Tree\\\" created from a Notary snapshot | | [032..064) | dataHash    | bytes32 | 32    | Agent Root and SnapGasHash combined into a single hash         | | [064..068) | nonce       | uint32  | 4     | Total amount of all accepted Notary snapshots                  | | [068..073) | blockNumber | uint40  | 5     | Block when this Notary snapshot was accepted in Summit         | | [073..078) | timestamp   | uint40  | 5     | Time when this Notary snapshot was accepted in Summit          |\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationHarness.t.sol\":\"AttestationLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationHarness.t.sol\":{\"keccak256\":\"0x027132e072bb0f43c3b2556612c2546f0908ba3e62d11624798ed9896df1fca8\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://00865d6038082824250d50297188c538484dab4dc8c827d95a07d15b0967623e\",\"dweb:/ipfs/QmWSV9Po78tGqv8hfRyvNwPAK14JbZ8vjH4jp7RFycYZrE\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationHarness.t.sol:MemViewLib":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220da7c5d48c71483188e5822b3e56005de530c10b0e72805ab65fe8b37b0d9e2da64736f6c63430008110033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220da7c5d48c71483188e5822b3e56005de530c10b0e72805ab65fe8b37b0d9e2da64736f6c63430008110033","info":{"source":"// SPDX-License-Identifier: MIT\npragma solidity =0.8.17;\n\n// contracts/libs/Constants.sol\n\n// Here we define common constants to enable their easier reusing later.\n\n// ══════════════════════════════════ MERKLE ═══════════════════════════════════\n/// @dev Height of the Agent Merkle Tree\nuint256 constant AGENT_TREE_HEIGHT = 32;\n/// @dev Height of the Origin Merkle Tree\nuint256 constant ORIGIN_TREE_HEIGHT = 32;\n/// @dev Height of the Snapshot Merkle Tree. Allows up to 64 leafs, e.g. up to 32 states\nuint256 constant SNAPSHOT_TREE_HEIGHT = 6;\n// ══════════════════════════════════ STRUCTS ══════════════════════════════════\n/// @dev See Attestation.sol: (bytes32,bytes32,uint32,uint40,uint40): 32+32+4+5+5\nuint256 constant ATTESTATION_LENGTH = 78;\n/// @dev See GasData.sol: (uint16,uint16,uint16,uint16,uint16,uint16): 2+2+2+2+2+2\nuint256 constant GAS_DATA_LENGTH = 12;\n/// @dev See Receipt.sol: (uint32,uint32,bytes32,bytes32,uint8,address,address,address): 4+4+32+32+1+20+20+20\nuint256 constant RECEIPT_LENGTH = 133;\n/// @dev See State.sol: (bytes32,uint32,uint32,uint40,uint40,GasData): 32+4+4+5+5+len(GasData)\nuint256 constant STATE_LENGTH = 50 + GAS_DATA_LENGTH;\n/// @dev Maximum amount of states in a single snapshot. Each state produces two leafs in the tree\nuint256 constant SNAPSHOT_MAX_STATES = 1 \u003c\u003c (SNAPSHOT_TREE_HEIGHT - 1);\n// ══════════════════════════════════ MESSAGE ══════════════════════════════════\n/// @dev See Header.sol: (uint8,uint32,uint32,uint32,uint32): 1+4+4+4+4\nuint256 constant HEADER_LENGTH = 17;\n/// @dev See Request.sol: (uint96,uint64,uint32): 12+8+4\nuint256 constant REQUEST_LENGTH = 24;\n/// @dev See Tips.sol: (uint64,uint64,uint64,uint64): 8+8+8+8\nuint256 constant TIPS_LENGTH = 32;\n/// @dev The amount of discarded last bits when encoding tip values\nuint256 constant TIPS_GRANULARITY = 32;\n/// @dev Tip values could be only the multiples of TIPS_MULTIPLIER\nuint256 constant TIPS_MULTIPLIER = 1 \u003c\u003c TIPS_GRANULARITY;\n// ══════════════════════════════ STATEMENT SALTS ══════════════════════════════\n/// @dev Salts for signing various statements\nbytes32 constant ATTESTATION_VALID_SALT = keccak256(\"ATTESTATION_VALID_SALT\");\nbytes32 constant ATTESTATION_INVALID_SALT = keccak256(\"ATTESTATION_INVALID_SALT\");\nbytes32 constant RECEIPT_VALID_SALT = keccak256(\"RECEIPT_VALID_SALT\");\nbytes32 constant RECEIPT_INVALID_SALT = keccak256(\"RECEIPT_INVALID_SALT\");\nbytes32 constant SNAPSHOT_VALID_SALT = keccak256(\"SNAPSHOT_VALID_SALT\");\nbytes32 constant STATE_INVALID_SALT = keccak256(\"STATE_INVALID_SALT\");\n// ═════════════════════════════════ PROTOCOL ══════════════════════════════════\n/// @dev Optimistic period for new agent roots in LightManager\nuint32 constant AGENT_ROOT_OPTIMISTIC_PERIOD = 1 days;\n/// @dev Timeout between the agent root could be proposed and resolved in LightManager\nuint32 constant AGENT_ROOT_PROPOSAL_TIMEOUT = 12 hours;\nuint32 constant BONDING_OPTIMISTIC_PERIOD = 1 days;\n/// @dev Amount of time that the Notary will not be considered active after they won a dispute\nuint32 constant DISPUTE_TIMEOUT_NOTARY = 12 hours;\n/// @dev Amount of time without fresh data from Notaries before contract owner can resolve stuck disputes manually\nuint256 constant FRESH_DATA_TIMEOUT = 4 hours;\n/// @dev Maximum bytes per message = 2 KiB (somewhat arbitrarily set to begin)\nuint256 constant MAX_CONTENT_BYTES = 2 * 2 ** 10;\n/// @dev Maximum value for the summit tip that could be set in GasOracle\nuint256 constant MAX_SUMMIT_TIP = 0.01 ether;\n\n// contracts/libs/Errors.sol\n\n// ══════════════════════════════ INVALID CALLER ═══════════════════════════════\n\nerror CallerNotAgentManager();\nerror CallerNotDestination();\nerror CallerNotInbox();\nerror CallerNotSummit();\n\n// ══════════════════════════════ INCORRECT DATA ═══════════════════════════════\n\nerror IncorrectAttestation();\nerror IncorrectAgentDomain();\nerror IncorrectAgentIndex();\nerror IncorrectAgentProof();\nerror IncorrectAgentRoot();\nerror IncorrectDataHash();\nerror IncorrectDestinationDomain();\nerror IncorrectOriginDomain();\nerror IncorrectSnapshotProof();\nerror IncorrectSnapshotRoot();\nerror IncorrectState();\nerror IncorrectStatesAmount();\nerror IncorrectTipsProof();\nerror IncorrectVersionLength();\n\nerror IncorrectNonce();\nerror IncorrectSender();\nerror IncorrectRecipient();\n\nerror FlagOutOfRange();\nerror IndexOutOfRange();\nerror NonceOutOfRange();\n\nerror OutdatedNonce();\n\nerror UnformattedAttestation();\nerror UnformattedAttestationReport();\nerror UnformattedBaseMessage();\nerror UnformattedCallData();\nerror UnformattedCallDataPrefix();\nerror UnformattedMessage();\nerror UnformattedReceipt();\nerror UnformattedReceiptReport();\nerror UnformattedSignature();\nerror UnformattedSnapshot();\nerror UnformattedState();\nerror UnformattedStateReport();\n\n// ═══════════════════════════════ MERKLE TREES ════════════════════════════════\n\nerror LeafNotProven();\nerror MerkleTreeFull();\nerror NotEnoughLeafs();\nerror TreeHeightTooLow();\n\n// ═════════════════════════════ OPTIMISTIC PERIOD ═════════════════════════════\n\nerror BaseClientOptimisticPeriod();\nerror MessageOptimisticPeriod();\nerror SlashAgentOptimisticPeriod();\nerror WithdrawTipsOptimisticPeriod();\nerror ZeroProofMaturity();\n\n// ═══════════════════════════════ AGENT MANAGER ═══════════════════════════════\n\nerror AgentNotGuard();\nerror AgentNotNotary();\n\nerror AgentCantBeAdded();\nerror AgentNotActive();\nerror AgentNotActiveNorUnstaking();\nerror AgentNotFraudulent();\nerror AgentNotUnstaking();\nerror AgentUnknown();\n\nerror AgentRootNotProposed();\nerror AgentRootTimeoutNotOver();\n\nerror NotStuck();\n\nerror DisputeAlreadyResolved();\nerror DisputeNotOpened();\nerror DisputeTimeoutNotOver();\nerror GuardInDispute();\nerror NotaryInDispute();\n\nerror MustBeSynapseDomain();\nerror SynapseDomainForbidden();\n\n// ════════════════════════════════ DESTINATION ════════════════════════════════\n\nerror AlreadyExecuted();\nerror AlreadyFailed();\nerror DuplicatedSnapshotRoot();\nerror IncorrectMagicValue();\nerror GasLimitTooLow();\nerror GasSuppliedTooLow();\n\n// ══════════════════════════════════ ORIGIN ═══════════════════════════════════\n\nerror ContentLengthTooBig();\nerror EthTransferFailed();\nerror InsufficientEthBalance();\n\n// ════════════════════════════════ GAS ORACLE ═════════════════════════════════\n\nerror LocalGasDataNotSet();\nerror RemoteGasDataNotSet();\n\n// ═══════════════════════════════════ TIPS ════════════════════════════════════\n\nerror SummitTipTooHigh();\nerror TipsClaimMoreThanEarned();\nerror TipsClaimZero();\nerror TipsOverflow();\nerror TipsValueTooLow();\n\n// ════════════════════════════════ MEMORY VIEW ════════════════════════════════\n\nerror IndexedTooMuch();\nerror ViewOverrun();\nerror OccupiedMemory();\nerror UnallocatedMemory();\nerror PrecompileOutOfGas();\n\n// ═════════════════════════════════ MULTICALL ═════════════════════════════════\n\nerror MulticallFailed();\n\n// contracts/libs/memory/MemView.sol\n\n/// @dev MemView is an untyped view over a portion of memory to be used instead of `bytes memory`\ntype MemView is uint256;\n\n/// @dev Attach library functions to MemView\nusing MemViewLib for MemView global;\n\n/// @notice Library for operations with the memory views.\n/// Forked from https://github.com/summa-tx/memview-sol with several breaking changes:\n/// - The codebase is ported to Solidity 0.8\n/// - Custom errors are added\n/// - The runtime type checking is replaced with compile-time check provided by User-Defined Value Types\n///   https://docs.soliditylang.org/en/latest/types.html#user-defined-value-types\n/// - uint256 is used as the underlying type for the \"memory view\" instead of bytes29.\n///   It is wrapped into MemView custom type in order not to be confused with actual integers.\n/// - Therefore the \"type\" field is discarded, allowing to allocate 16 bytes for both view location and length\n/// - The documentation is expanded\n/// - Library functions unused by the rest of the codebase are removed\n//  - Very pretty code separators are added :)\nlibrary MemViewLib {\n    /// @notice Stack layout for uint256 (from highest bits to lowest)\n    /// (32 .. 16]      loc     16 bytes    Memory address of underlying bytes\n    /// (16 .. 00]      len     16 bytes    Length of underlying bytes\n\n    // ═══════════════════════════════════════════ BUILDING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Instantiate a new untyped memory view. This should generally not be called directly.\n     * Prefer `ref` wherever possible.\n     * @param loc_          The memory address\n     * @param len_          The length\n     * @return The new view with the specified location and length\n     */\n    function build(uint256 loc_, uint256 len_) internal pure returns (MemView) {\n        uint256 end_ = loc_ + len_;\n        // Make sure that a view is not constructed that points to unallocated memory\n        // as this could be indicative of a buffer overflow attack\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            if gt(end_, mload(0x40)) { end_ := 0 }\n        }\n        if (end_ == 0) {\n            revert UnallocatedMemory();\n        }\n        return _unsafeBuildUnchecked(loc_, len_);\n    }\n\n    /**\n     * @notice Instantiate a memory view from a byte array.\n     * @dev Note that due to Solidity memory representation, it is not possible to\n     * implement a deref, as the `bytes` type stores its len in memory.\n     * @param arr           The byte array\n     * @return The memory view over the provided byte array\n     */\n    function ref(bytes memory arr) internal pure returns (MemView) {\n        uint256 len_ = arr.length;\n        // `bytes arr` is stored in memory in the following way\n        // 1. First, uint256 arr.length is stored. That requires 32 bytes (0x20).\n        // 2. Then, the array data is stored.\n        uint256 loc_;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // We add 0x20, so that the view starts exactly where the array data starts\n            loc_ := add(arr, 0x20)\n        }\n        return build(loc_, len_);\n    }\n\n    // ════════════════════════════════════════════ CLONING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to the new memory.\n     * @param memView       The memory view\n     * @return arr          The cloned byte array\n     */\n    function clone(MemView memView) internal view returns (bytes memory arr) {\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load unused memory pointer\n            ptr := mload(0x40)\n            // This is where the byte array will be stored\n            arr := ptr\n        }\n        unchecked {\n            _unsafeCopyTo(memView, ptr + 0x20);\n        }\n        // `bytes arr` is stored in memory in the following way\n        // 1. First, uint256 arr.length is stored. That requires 32 bytes (0x20).\n        // 2. Then, the array data is stored.\n        uint256 len_ = memView.len();\n        uint256 footprint_ = memView.footprint();\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Write new unused pointer: the old value + array footprint + 32 bytes to store the length\n            mstore(0x40, add(add(ptr, footprint_), 0x20))\n            // Write len of new array (in bytes)\n            mstore(ptr, len_)\n        }\n    }\n\n    /**\n     * @notice Copies all views, joins them into a new bytearray.\n     * @param memViews      The memory views\n     * @return arr          The new byte array with joined data behind the given views\n     */\n    function join(MemView[] memory memViews) internal view returns (bytes memory arr) {\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load unused memory pointer\n            ptr := mload(0x40)\n            // This is where the byte array will be stored\n            arr := ptr\n        }\n        MemView newView;\n        unchecked {\n            newView = _unsafeJoin(memViews, ptr + 0x20);\n        }\n        uint256 len_ = newView.len();\n        uint256 footprint_ = newView.footprint();\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Write new unused pointer: the old value + array footprint + 32 bytes to store the length\n            mstore(0x40, add(add(ptr, footprint_), 0x20))\n            // Write len of new array (in bytes)\n            mstore(ptr, len_)\n        }\n    }\n\n    // ══════════════════════════════════════════ INSPECTING MEMORY VIEW ═══════════════════════════════════════════════\n\n    /**\n     * @notice Returns the memory address of the underlying bytes.\n     * @param memView       The memory view\n     * @return loc_         The memory address\n     */\n    function loc(MemView memView) internal pure returns (uint256 loc_) {\n        // loc is stored in the highest 16 bytes of the underlying uint256\n        return MemView.unwrap(memView) \u003e\u003e 128;\n    }\n\n    /**\n     * @notice Returns the number of bytes of the view.\n     * @param memView       The memory view\n     * @return len_         The length of the view\n     */\n    function len(MemView memView) internal pure returns (uint256 len_) {\n        // len is stored in the lowest 16 bytes of the underlying uint256\n        return MemView.unwrap(memView) \u0026 type(uint128).max;\n    }\n\n    /**\n     * @notice Returns the endpoint of `memView`.\n     * @param memView       The memory view\n     * @return end_         The endpoint of `memView`\n     */\n    function end(MemView memView) internal pure returns (uint256 end_) {\n        // The endpoint never overflows uint128, let alone uint256, so we could use unchecked math here\n        unchecked {\n            return memView.loc() + memView.len();\n        }\n    }\n\n    /**\n     * @notice Returns the number of memory words this memory view occupies, rounded up.\n     * @param memView       The memory view\n     * @return words_       The number of memory words\n     */\n    function words(MemView memView) internal pure returns (uint256 words_) {\n        // returning ceil(length / 32.0)\n        unchecked {\n            return (memView.len() + 31) \u003e\u003e 5;\n        }\n    }\n\n    /**\n     * @notice Returns the in-memory footprint of a fresh copy of the view.\n     * @param memView       The memory view\n     * @return footprint_   The in-memory footprint of a fresh copy of the view.\n     */\n    function footprint(MemView memView) internal pure returns (uint256 footprint_) {\n        // words() * 32\n        return memView.words() \u003c\u003c 5;\n    }\n\n    // ════════════════════════════════════════════ HASHING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Returns the keccak256 hash of the underlying memory\n     * @param memView       The memory view\n     * @return digest       The keccak256 hash of the underlying memory\n     */\n    function keccak(MemView memView) internal pure returns (bytes32 digest) {\n        uint256 loc_ = memView.loc();\n        uint256 len_ = memView.len();\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            digest := keccak256(loc_, len_)\n        }\n    }\n\n    /**\n     * @notice Adds a salt to the keccak256 hash of the underlying data and returns the keccak256 hash of the\n     * resulting data.\n     * @param memView       The memory view\n     * @return digestSalted keccak256(salt, keccak256(memView))\n     */\n    function keccakSalted(MemView memView, bytes32 salt) internal pure returns (bytes32 digestSalted) {\n        return keccak256(bytes.concat(salt, memView.keccak()));\n    }\n\n    // ════════════════════════════════════════════ SLICING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Safe slicing without memory modification.\n     * @param memView       The memory view\n     * @param index_        The start index\n     * @param len_          The length\n     * @return The new view for the slice of the given length starting from the given index\n     */\n    function slice(MemView memView, uint256 index_, uint256 len_) internal pure returns (MemView) {\n        uint256 loc_ = memView.loc();\n        // Ensure it doesn't overrun the view\n        if (loc_ + index_ + len_ \u003e memView.end()) {\n            revert ViewOverrun();\n        }\n        // Build a view starting from index with the given length\n        unchecked {\n            // loc_ + index_ \u003c= memView.end()\n            return build({loc_: loc_ + index_, len_: len_});\n        }\n    }\n\n    /**\n     * @notice Shortcut to `slice`. Gets a view representing bytes from `index` to end(memView).\n     * @param memView       The memory view\n     * @param index_        The start index\n     * @return The new view for the slice starting from the given index until the initial view endpoint\n     */\n    function sliceFrom(MemView memView, uint256 index_) internal pure returns (MemView) {\n        uint256 len_ = memView.len();\n        // Ensure it doesn't overrun the view\n        if (index_ \u003e len_) {\n            revert ViewOverrun();\n        }\n        // Build a view starting from index with the given length\n        unchecked {\n            // index_ \u003c= len_ =\u003e memView.loc() + index_ \u003c= memView.loc() + memView.len() == memView.end()\n            return build({loc_: memView.loc() + index_, len_: len_ - index_});\n        }\n    }\n\n    /**\n     * @notice Shortcut to `slice`. Gets a view representing the first `len` bytes.\n     * @param memView       The memory view\n     * @param len_          The length\n     * @return The new view for the slice of the given length starting from the initial view beginning\n     */\n    function prefix(MemView memView, uint256 len_) internal pure returns (MemView) {\n        return memView.slice({index_: 0, len_: len_});\n    }\n\n    /**\n     * @notice Shortcut to `slice`. Gets a view representing the last `len` byte.\n     * @param memView       The memory view\n     * @param len_          The length\n     * @return The new view for the slice of the given length until the initial view endpoint\n     */\n    function postfix(MemView memView, uint256 len_) internal pure returns (MemView) {\n        uint256 viewLen = memView.len();\n        // Ensure it doesn't overrun the view\n        if (len_ \u003e viewLen) {\n            revert ViewOverrun();\n        }\n        // Could do the unchecked math due to the check above\n        uint256 index_;\n        unchecked {\n            index_ = viewLen - len_;\n        }\n        // Build a view starting from index with the given length\n        unchecked {\n            // len_ \u003c= memView.len() =\u003e memView.loc() \u003c= loc_ \u003c= memView.end()\n            return build({loc_: memView.loc() + viewLen - len_, len_: len_});\n        }\n    }\n\n    // ═══════════════════════════════════════════ INDEXING MEMORY VIEW ════════════════════════════════════════════════\n\n    /**\n     * @notice Load up to 32 bytes from the view onto the stack.\n     * @dev Returns a bytes32 with only the `bytes_` HIGHEST bytes set.\n     * This can be immediately cast to a smaller fixed-length byte array.\n     * To automatically cast to an integer, use `indexUint`.\n     * @param memView       The memory view\n     * @param index_        The index\n     * @param bytes_        The amount of bytes to load onto the stack\n     * @return result       The 32 byte result having only `bytes_` highest bytes set\n     */\n    function index(MemView memView, uint256 index_, uint256 bytes_) internal pure returns (bytes32 result) {\n        if (bytes_ == 0) {\n            return bytes32(0);\n        }\n        // Can't load more than 32 bytes to the stack in one go\n        if (bytes_ \u003e 32) {\n            revert IndexedTooMuch();\n        }\n        // The last indexed byte should be within view boundaries\n        if (index_ + bytes_ \u003e memView.len()) {\n            revert ViewOverrun();\n        }\n        uint256 bitLength = bytes_ \u003c\u003c 3; // bytes_ * 8\n        uint256 loc_ = memView.loc();\n        // Get a mask with `bitLength` highest bits set\n        uint256 mask;\n        // 0x800...00 binary representation is 100...00\n        // sar stands for \"signed arithmetic shift\": https://en.wikipedia.org/wiki/Arithmetic_shift\n        // sar(N-1, 100...00) = 11...100..00, with exactly N highest bits set to 1\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            mask := sar(sub(bitLength, 1), 0x8000000000000000000000000000000000000000000000000000000000000000)\n        }\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load a full word using index offset, and apply mask to ignore non-relevant bytes\n            result := and(mload(add(loc_, index_)), mask)\n        }\n    }\n\n    /**\n     * @notice Parse an unsigned integer from the view at `index`.\n     * @dev Requires that the view have \u003e= `bytes_` bytes following that index.\n     * @param memView       The memory view\n     * @param index_        The index\n     * @param bytes_        The amount of bytes to load onto the stack\n     * @return The unsigned integer\n     */\n    function indexUint(MemView memView, uint256 index_, uint256 bytes_) internal pure returns (uint256) {\n        bytes32 indexedBytes = memView.index(index_, bytes_);\n        // `index()` returns left-aligned `bytes_`, while integers are right-aligned\n        // Shifting here to right-align with the full 32 bytes word: need to shift right `(32 - bytes_)` bytes\n        unchecked {\n            // memView.index() reverts when bytes_ \u003e 32, thus unchecked math\n            return uint256(indexedBytes) \u003e\u003e ((32 - bytes_) \u003c\u003c 3);\n        }\n    }\n\n    /**\n     * @notice Parse an address from the view at `index`.\n     * @dev Requires that the view have \u003e= 20 bytes following that index.\n     * @param memView       The memory view\n     * @param index_        The index\n     * @return The address\n     */\n    function indexAddress(MemView memView, uint256 index_) internal pure returns (address) {\n        // index 20 bytes as `uint160`, and then cast to `address`\n        return address(uint160(memView.indexUint(index_, 20)));\n    }\n\n    // ══════════════════════════════════════════════ PRIVATE HELPERS ══════════════════════════════════════════════════\n\n    /// @dev Returns a memory view over the specified memory location\n    /// without checking if it points to unallocated memory.\n    function _unsafeBuildUnchecked(uint256 loc_, uint256 len_) private pure returns (MemView) {\n        // There is no scenario where loc or len would overflow uint128, so we omit this check.\n        // We use the highest 128 bits to encode the location and the lowest 128 bits to encode the length.\n        return MemView.wrap((loc_ \u003c\u003c 128) | len_);\n    }\n\n    /**\n     * @notice Copy the view to a location, return an unsafe memory reference\n     * @dev Super Dangerous direct memory access.\n     * This reference can be overwritten if anything else modifies memory (!!!).\n     * As such it MUST be consumed IMMEDIATELY. Update the free memory pointer to ensure the copied data\n     * is not overwritten. This function is private to prevent unsafe usage by callers.\n     * @param memView       The memory view\n     * @param newLoc        The new location to copy the underlying view data\n     * @return The memory view over the unsafe memory with the copied underlying data\n     */\n    function _unsafeCopyTo(MemView memView, uint256 newLoc) private view returns (MemView) {\n        uint256 len_ = memView.len();\n        uint256 oldLoc = memView.loc();\n\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load unused memory pointer\n            ptr := mload(0x40)\n        }\n        // Revert if we're writing in occupied memory\n        if (newLoc \u003c ptr) {\n            revert OccupiedMemory();\n        }\n        bool res;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // use the identity precompile (0x04) to copy\n            res := staticcall(gas(), 0x04, oldLoc, len_, newLoc, len_)\n        }\n        if (!res) revert PrecompileOutOfGas();\n        return _unsafeBuildUnchecked({loc_: newLoc, len_: len_});\n    }\n\n    /**\n     * @notice Join the views in memory, return an unsafe reference to the memory.\n     * @dev Super Dangerous direct memory access.\n     * This reference can be overwritten if anything else modifies memory (!!!).\n     * As such it MUST be consumed IMMEDIATELY. Update the free memory pointer to ensure the copied data\n     * is not overwritten. This function is private to prevent unsafe usage by callers.\n     * @param memViews      The memory views\n     * @return The conjoined view pointing to the new memory\n     */\n    function _unsafeJoin(MemView[] memory memViews, uint256 location) private view returns (MemView) {\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // Load unused memory pointer\n            ptr := mload(0x40)\n        }\n        // Revert if we're writing in occupied memory\n        if (location \u003c ptr) {\n            revert OccupiedMemory();\n        }\n        // Copy the views to the specified location one by one, by tracking the amount of copied bytes so far\n        uint256 offset = 0;\n        for (uint256 i = 0; i \u003c memViews.length;) {\n            MemView memView = memViews[i];\n            // We can use the unchecked math here as location + sum(view.length) will never overflow uint256\n            unchecked {\n                _unsafeCopyTo(memView, location + offset);\n                offset += memView.len();\n                ++i;\n            }\n        }\n        return _unsafeBuildUnchecked({loc_: location, len_: offset});\n    }\n}\n\n// contracts/libs/memory/Attestation.sol\n\n/// Attestation is a memory view over a formatted attestation payload.\ntype Attestation is uint256;\n\nusing AttestationLib for Attestation global;\n\n/// # Attestation\n/// Attestation structure represents the \"Snapshot Merkle Tree\" created from\n/// every Notary snapshot accepted by the Summit contract. Attestation includes\"\n/// the root of the \"Snapshot Merkle Tree\", as well as additional metadata.\n///\n/// ## Steps for creation of \"Snapshot Merkle Tree\":\n/// 1. The list of hashes is composed for states in the Notary snapshot.\n/// 2. The list is padded with zero values until its length is 2**SNAPSHOT_TREE_HEIGHT.\n/// 3. Values from the list are used as leafs and the merkle tree is constructed.\n///\n/// ## Differences between a State and Attestation\n/// Similar to Origin, every derived Notary's \"Snapshot Merkle Root\" is saved in Summit contract.\n/// The main difference is that Origin contract itself is keeping track of an incremental merkle tree,\n/// by inserting the hash of the sent message and calculating the new \"Origin Merkle Root\".\n/// While Summit relies on Guards and Notaries to provide snapshot data, which is used to calculate the\n/// \"Snapshot Merkle Root\".\n///\n/// - Origin's State is \"state of Origin Merkle Tree after N-th message was sent\".\n/// - Summit's Attestation is \"data for the N-th accepted Notary Snapshot\" + \"agent merkle root at the\n/// time snapshot was submitted\" + \"attestation metadata\".\n///\n/// ## Attestation validity\n/// - Attestation is considered \"valid\" in Summit contract, if it matches the N-th (nonce)\n/// snapshot submitted by Notaries, as well as the historical agent merkle root.\n/// - Attestation is considered \"valid\" in Origin contract, if its underlying Snapshot is \"valid\".\n///\n/// - This means that a snapshot could be \"valid\" in Summit contract and \"invalid\" in Origin, if the underlying\n/// snapshot is invalid (i.e. one of the states in the list is invalid).\n/// - The opposite could also be true. If a perfectly valid snapshot was never submitted to Summit, its attestation\n/// would be valid in Origin, but invalid in Summit (it was never accepted, so the metadata would be incorrect).\n///\n/// - Attestation is considered \"globally valid\", if it is valid in the Summit and all the Origin contracts.\n/// # Memory layout of Attestation fields\n///\n/// | Position   | Field       | Type    | Bytes | Description                                                    |\n/// | ---------- | ----------- | ------- | ----- | -------------------------------------------------------------- |\n/// | [000..032) | snapRoot    | bytes32 | 32    | Root for \"Snapshot Merkle Tree\" created from a Notary snapshot |\n/// | [032..064) | dataHash    | bytes32 | 32    | Agent Root and SnapGasHash combined into a single hash         |\n/// | [064..068) | nonce       | uint32  | 4     | Total amount of all accepted Notary snapshots                  |\n/// | [068..073) | blockNumber | uint40  | 5     | Block when this Notary snapshot was accepted in Summit         |\n/// | [073..078) | timestamp   | uint40  | 5     | Time when this Notary snapshot was accepted in Summit          |\n///\n/// @dev Attestation could be signed by a Notary and submitted to `Destination` in order to use if for proving\n/// messages coming from origin chains that the initial snapshot refers to.\nlibrary AttestationLib {\n    using MemViewLib for bytes;\n\n    // TODO: compress three hashes into one?\n\n    /// @dev The variables below are not supposed to be used outside of the library directly.\n    uint256 private constant OFFSET_SNAP_ROOT = 0;\n    uint256 private constant OFFSET_DATA_HASH = 32;\n    uint256 private constant OFFSET_NONCE = 64;\n    uint256 private constant OFFSET_BLOCK_NUMBER = 68;\n    uint256 private constant OFFSET_TIMESTAMP = 73;\n\n    // ════════════════════════════════════════════════ ATTESTATION ════════════════════════════════════════════════════\n\n    /**\n     * @notice Returns a formatted Attestation payload with provided fields.\n     * @param snapRoot_     Snapshot merkle tree's root\n     * @param dataHash_     Agent Root and SnapGasHash combined into a single hash\n     * @param nonce_        Attestation Nonce\n     * @param blockNumber_  Block number when attestation was created in Summit\n     * @param timestamp_    Block timestamp when attestation was created in Summit\n     * @return Formatted attestation\n     */\n    function formatAttestation(\n        bytes32 snapRoot_,\n        bytes32 dataHash_,\n        uint32 nonce_,\n        uint40 blockNumber_,\n        uint40 timestamp_\n    ) internal pure returns (bytes memory) {\n        return abi.encodePacked(snapRoot_, dataHash_, nonce_, blockNumber_, timestamp_);\n    }\n\n    /**\n     * @notice Returns an Attestation view over the given payload.\n     * @dev Will revert if the payload is not an attestation.\n     */\n    function castToAttestation(bytes memory payload) internal pure returns (Attestation) {\n        return castToAttestation(payload.ref());\n    }\n\n    /**\n     * @notice Casts a memory view to an Attestation view.\n     * @dev Will revert if the memory view is not over an attestation.\n     */\n    function castToAttestation(MemView memView) internal pure returns (Attestation) {\n        if (!isAttestation(memView)) revert UnformattedAttestation();\n        return Attestation.wrap(MemView.unwrap(memView));\n    }\n\n    /// @notice Checks that a payload is a formatted Attestation.\n    function isAttestation(MemView memView) internal pure returns (bool) {\n        return memView.len() == ATTESTATION_LENGTH;\n    }\n\n    /// @notice Returns the hash of an Attestation, that could be later signed by a Notary to signal\n    /// that the attestation is valid.\n    function hashValid(Attestation att) internal pure returns (bytes32) {\n        // The final hash to sign is keccak(attestationSalt, keccak(attestation))\n        return att.unwrap().keccakSalted(ATTESTATION_VALID_SALT);\n    }\n\n    /// @notice Returns the hash of an Attestation, that could be later signed by a Guard to signal\n    /// that the attestation is invalid.\n    function hashInvalid(Attestation att) internal pure returns (bytes32) {\n        // The final hash to sign is keccak(attestationInvalidSalt, keccak(attestation))\n        return att.unwrap().keccakSalted(ATTESTATION_INVALID_SALT);\n    }\n\n    /// @notice Convenience shortcut for unwrapping a view.\n    function unwrap(Attestation att) internal pure returns (MemView) {\n        return MemView.wrap(Attestation.unwrap(att));\n    }\n\n    // ════════════════════════════════════════════ ATTESTATION SLICING ════════════════════════════════════════════════\n\n    /// @notice Returns root of the Snapshot merkle tree created in the Summit contract.\n    function snapRoot(Attestation att) internal pure returns (bytes32) {\n        return att.unwrap().index({index_: OFFSET_SNAP_ROOT, bytes_: 32});\n    }\n\n    /// @notice Returns hash of the Agent Root and SnapGasHash combined into a single hash.\n    function dataHash(Attestation att) internal pure returns (bytes32) {\n        return att.unwrap().index({index_: OFFSET_DATA_HASH, bytes_: 32});\n    }\n\n    /// @notice Returns hash of the Agent Root and SnapGasHash combined into a single hash.\n    function dataHash(bytes32 agentRoot_, bytes32 snapGasHash_) internal pure returns (bytes32) {\n        return keccak256(bytes.concat(agentRoot_, snapGasHash_));\n    }\n\n    /// @notice Returns nonce of Summit contract at the time, when attestation was created.\n    function nonce(Attestation att) internal pure returns (uint32) {\n        // Can be safely casted to uint32, since we index 4 bytes\n        return uint32(att.unwrap().indexUint({index_: OFFSET_NONCE, bytes_: 4}));\n    }\n\n    /// @notice Returns a block number when attestation was created in Summit.\n    function blockNumber(Attestation att) internal pure returns (uint40) {\n        // Can be safely casted to uint40, since we index 5 bytes\n        return uint40(att.unwrap().indexUint({index_: OFFSET_BLOCK_NUMBER, bytes_: 5}));\n    }\n\n    /// @notice Returns a block timestamp when attestation was created in Summit.\n    /// @dev This is the timestamp according to the Synapse Chain.\n    function timestamp(Attestation att) internal pure returns (uint40) {\n        // Can be safely casted to uint40, since we index 5 bytes\n        return uint40(att.unwrap().indexUint({index_: OFFSET_TIMESTAMP, bytes_: 5}));\n    }\n}\n\n// test/harnesses/libs/memory/AttestationHarness.t.sol\n\n// solhint-disable ordering\n/// @notice Exposes Attestation methods for testing against golang.\ncontract AttestationHarness {\n    using AttestationLib for bytes;\n    using AttestationLib for MemView;\n    using MemViewLib for bytes;\n\n    // Note: we don't add an empty test() function here, as it currently leads\n    // to zero coverage on the corresponding library.\n\n    // ══════════════════════════════════════════════════ GETTERS ══════════════════════════════════════════════════════\n\n    function castToAttestation(bytes memory payload) public view returns (bytes memory) {\n        // Walkaround to get the forge coverage working on libraries, see\n        // https://github.com/foundry-rs/foundry/pull/3128#issuecomment-1241245086\n        Attestation attestation = AttestationLib.castToAttestation(payload);\n        return attestation.unwrap().clone();\n    }\n\n    function snapRoot(bytes memory payload) public pure returns (bytes32) {\n        return payload.castToAttestation().snapRoot();\n    }\n\n    function dataHash(bytes memory payload) public pure returns (bytes32) {\n        return payload.castToAttestation().dataHash();\n    }\n\n    function dataHash(bytes32 agentRoot_, bytes32 snapGasHash_) public pure returns (bytes32) {\n        return AttestationLib.dataHash(agentRoot_, snapGasHash_);\n    }\n\n    function nonce(bytes memory payload) public pure returns (uint32) {\n        return payload.castToAttestation().nonce();\n    }\n\n    function blockNumber(bytes memory payload) public pure returns (uint40) {\n        return payload.castToAttestation().blockNumber();\n    }\n\n    function timestamp(bytes memory payload) public pure returns (uint40) {\n        return payload.castToAttestation().timestamp();\n    }\n\n    function hashValid(bytes memory payload) public pure returns (bytes32) {\n        return payload.castToAttestation().hashValid();\n    }\n\n    function hashInvalid(bytes memory payload) public pure returns (bytes32) {\n        return payload.castToAttestation().hashInvalid();\n    }\n\n    // ════════════════════════════════════════════════ FORMATTERS ═════════════════════════════════════════════════════\n\n    function formatAttestation(\n        bytes32 snapRoot_,\n        bytes32 dataHash_,\n        uint32 nonce_,\n        uint40 blockNumber_,\n        uint40 timestamp_\n    ) public pure returns (bytes memory) {\n        return AttestationLib.formatAttestation(snapRoot_, dataHash_, nonce_, blockNumber_, timestamp_);\n    }\n\n    function isAttestation(bytes memory payload) public pure returns (bool) {\n        return payload.ref().isAttestation();\n    }\n}\n","language":"Solidity","languageVersion":"0.8.17","compilerVersion":"0.8.17","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"10022:19162:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;10022:19162:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"10022:19162:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"notice":"Library for operations with the memory views. Forked from https://github.com/summa-tx/memview-sol with several breaking changes: - The codebase is ported to Solidity 0.8 - Custom errors are added - The runtime type checking is replaced with compile-time check provided by User-Defined Value Types   https://docs.soliditylang.org/en/latest/types.html#user-defined-value-types - uint256 is used as the underlying type for the \"memory view\" instead of bytes29.   It is wrapped into MemView custom type in order not to be confused with actual integers. - Therefore the \"type\" field is discarded, allowing to allocate 16 bytes for both view location and length - The documentation is expanded - Library functions unused by the rest of the codebase are removed","version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Library for operations with the memory views. Forked from https://github.com/summa-tx/memview-sol with several breaking changes: - The codebase is ported to Solidity 0.8 - Custom errors are added - The runtime type checking is replaced with compile-time check provided by User-Defined Value Types   https://docs.soliditylang.org/en/latest/types.html#user-defined-value-types - uint256 is used as the underlying type for the \\\"memory view\\\" instead of bytes29.   It is wrapped into MemView custom type in order not to be confused with actual integers. - Therefore the \\\"type\\\" field is discarded, allowing to allocate 16 bytes for both view location and length - The documentation is expanded - Library functions unused by the rest of the codebase are removed\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationHarness.t.sol\":\"MemViewLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationHarness.t.sol\":{\"keccak256\":\"0x027132e072bb0f43c3b2556612c2546f0908ba3e62d11624798ed9896df1fca8\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://00865d6038082824250d50297188c538484dab4dc8c827d95a07d15b0967623e\",\"dweb:/ipfs/QmWSV9Po78tGqv8hfRyvNwPAK14JbZ8vjH4jp7RFycYZrE\"]}},\"version\":1}"},"hashes":{}}}