Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
5882977 | 246 days ago | 0.0000001 ETH | ||||
5882977 | 246 days ago | 0.0000001 ETH | ||||
5877109 | 247 days ago | 0.0000001 ETH | ||||
5877109 | 247 days ago | 0.0000001 ETH | ||||
5877086 | 247 days ago | 0.0000001 ETH | ||||
5877086 | 247 days ago | 0.0000001 ETH | ||||
5876140 | 247 days ago | 0.0000001 ETH | ||||
5876140 | 247 days ago | 0.0000001 ETH | ||||
5876128 | 247 days ago | 0.0000001 ETH | ||||
5876128 | 247 days ago | 0.0000001 ETH | ||||
5876023 | 247 days ago | 0.0000001 ETH | ||||
5876023 | 247 days ago | 0.0000001 ETH | ||||
5876011 | 247 days ago | 0.0000001 ETH | ||||
5876011 | 247 days ago | 0.0000001 ETH | ||||
5875380 | 247 days ago | 0.0000001 ETH | ||||
5875380 | 247 days ago | 0.0000001 ETH | ||||
5875375 | 247 days ago | 0.0000001 ETH | ||||
5875375 | 247 days ago | 0.0000001 ETH | ||||
5875103 | 247 days ago | 0.0000001 ETH | ||||
5875103 | 247 days ago | 0.0000001 ETH | ||||
5875006 | 247 days ago | 0.0000001 ETH | ||||
5875006 | 247 days ago | 0.0000001 ETH | ||||
5871098 | 248 days ago | 0.0000001 ETH | ||||
5871098 | 248 days ago | 0.0000001 ETH | ||||
5871076 | 248 days ago | 0.0000001 ETH |
Loading...
Loading
Contract Name:
InterchainDB
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.20; import {InterchainDBEvents} from "./events/InterchainDBEvents.sol"; import {IInterchainDB} from "./interfaces/IInterchainDB.sol"; import {IInterchainModule} from "./interfaces/IInterchainModule.sol"; import {BatchingV1Lib} from "./libs/BatchingV1.sol"; import { InterchainBatch, InterchainBatchLib, BatchKey, BATCH_UNVERIFIED, BATCH_CONFLICT } from "./libs/InterchainBatch.sol"; import {InterchainEntry, InterchainEntryLib} from "./libs/InterchainEntry.sol"; import {VersionedPayloadLib} from "./libs/VersionedPayload.sol"; import {TypeCasts} from "./libs/TypeCasts.sol"; contract InterchainDB is InterchainDBEvents, IInterchainDB { using VersionedPayloadLib for bytes; /// @notice Struct representing a batch of entries from the remote Interchain DataBase, /// verified by the Interchain Module. /// @param verifiedAt The block timestamp at which the entry was verified by the module /// @param batchRoot The Merkle root of the batch struct RemoteBatch { uint256 verifiedAt; bytes32 batchRoot; } uint16 public constant DB_VERSION = 1; bytes32[] internal _entryValues; mapping(address module => mapping(BatchKey batchKey => RemoteBatch batch)) internal _remoteBatches; modifier onlyRemoteChainId(uint64 chainId) { if (chainId == block.chainid) { revert InterchainDB__ChainIdNotRemote(chainId); } _; } // ═══════════════════════════════════════════════ WRITER-FACING ═══════════════════════════════════════════════════ /// @inheritdoc IInterchainDB function writeEntry(bytes32 dataHash) external returns (uint64 dbNonce, uint64 entryIndex) { InterchainEntry memory entry = _writeEntry(dataHash); (dbNonce, entryIndex) = (entry.dbNonce, entry.entryIndex); } /// @inheritdoc IInterchainDB function requestBatchVerification( uint64 dstChainId, uint64 dbNonce, address[] calldata srcModules ) external payable onlyRemoteChainId(dstChainId) { InterchainBatch memory batch = getBatch(dbNonce); _requestVerification(dstChainId, batch, srcModules); } /// @inheritdoc IInterchainDB function writeEntryWithVerification( uint64 dstChainId, bytes32 dataHash, address[] calldata srcModules ) external payable onlyRemoteChainId(dstChainId) returns (uint64 dbNonce, uint64 entryIndex) { InterchainEntry memory entry = _writeEntry(dataHash); (dbNonce, entryIndex) = (entry.dbNonce, entry.entryIndex); // In "no batching" mode: the batch root is the same as the entry value InterchainBatch memory batch = InterchainBatchLib.constructLocalBatch(dbNonce, entry.entryValue()); _requestVerification(dstChainId, batch, srcModules); } // ═══════════════════════════════════════════════ MODULE-FACING ═══════════════════════════════════════════════════ /// @inheritdoc IInterchainDB function verifyRemoteBatch(bytes calldata versionedBatch) external { InterchainBatch memory batch = _assertCorrectBatch(versionedBatch); BatchKey batchKey = InterchainBatchLib.encodeBatchKey({srcChainId: batch.srcChainId, dbNonce: batch.dbNonce}); RemoteBatch memory existingBatch = _remoteBatches[msg.sender][batchKey]; // Check if that's the first time module verifies the batch if (existingBatch.verifiedAt == 0) { _saveVerifiedBatch(msg.sender, batchKey, batch); return; } // No-op if the batch root is the same if (existingBatch.batchRoot == batch.batchRoot) { return; } // Overwriting an empty (non-existent) batch with a different one is allowed if (existingBatch.batchRoot == 0) { _saveVerifiedBatch(msg.sender, batchKey, batch); return; } // Overwriting an existing batch with a different one is not allowed revert InterchainDB__BatchConflict(msg.sender, existingBatch.batchRoot, batch); } // ═══════════════════════════════════════════════════ VIEWS ═══════════════════════════════════════════════════════ /// @inheritdoc IInterchainDB function getBatchLeafs(uint64 dbNonce) external view returns (bytes32[] memory leafs) { uint256 batchSize = getBatchSize(dbNonce); leafs = new bytes32[](batchSize); for (uint64 i = 0; i < batchSize; ++i) { leafs[i] = getEntryValue(dbNonce, i); } } /// @inheritdoc IInterchainDB function getBatchLeafsPaginated( uint64 dbNonce, uint64 start, uint64 end ) external view returns (bytes32[] memory leafs) { uint256 size = getBatchSize(dbNonce); if (start > end || end > size) { revert InterchainDB__EntryRangeInvalid(dbNonce, start, end); } leafs = new bytes32[](end - start); for (uint64 i = start; i < end; ++i) { leafs[i - start] = getEntryValue(dbNonce, i); } } /// @inheritdoc IInterchainDB function getEntryProof(uint64 dbNonce, uint64 entryIndex) external view returns (bytes32[] memory proof) { // In "no batching" mode: the batch root is the same as the entry value, hence the proof is empty _assertEntryExists(dbNonce, entryIndex); return new bytes32[](0); } /// @inheritdoc IInterchainDB function getInterchainFee(uint64 dstChainId, address[] calldata srcModules) external view returns (uint256 fee) { (, fee) = _getModuleFees(dstChainId, getDBNonce(), srcModules); } /// @inheritdoc IInterchainDB function getNextEntryIndex() external view returns (uint64 dbNonce, uint64 entryIndex) { // In "no batching" mode: entry index is 0, batch size is 1 dbNonce = getDBNonce(); entryIndex = 0; } /// @inheritdoc IInterchainDB function checkBatchVerification( address dstModule, InterchainBatch memory batch ) external view onlyRemoteChainId(batch.srcChainId) returns (uint256 moduleVerifiedAt) { BatchKey batchKey = InterchainBatchLib.encodeBatchKey({srcChainId: batch.srcChainId, dbNonce: batch.dbNonce}); RemoteBatch memory remoteBatch = _remoteBatches[dstModule][batchKey]; // Check if module verified anything for this batch key first if (remoteBatch.verifiedAt == 0) { return BATCH_UNVERIFIED; } // Check if the batch root matches the one verified by the module return remoteBatch.batchRoot == batch.batchRoot ? remoteBatch.verifiedAt : BATCH_CONFLICT; } /// @inheritdoc IInterchainDB function getVersionedBatch(uint64 dbNonce) external view returns (bytes memory versionedBatch) { InterchainBatch memory batch = getBatch(dbNonce); return VersionedPayloadLib.encodeVersionedPayload({ version: DB_VERSION, payload: InterchainBatchLib.encodeBatch(batch) }); } /// @inheritdoc IInterchainDB function getBatchRoot(InterchainEntry memory entry, bytes32[] calldata proof) external pure returns (bytes32) { return BatchingV1Lib.getBatchRoot({ srcWriter: entry.srcWriter, dataHash: entry.dataHash, entryIndex: entry.entryIndex, proof: proof }); } /// @inheritdoc IInterchainDB function getBatchSize(uint64 dbNonce) public view returns (uint64) { // In "no batching" mode: the finalized batch size is 1, the pending batch size is 0 // We also return 0 for non-existent batches return dbNonce < getDBNonce() ? 1 : 0; } /// @inheritdoc IInterchainDB function getBatch(uint64 dbNonce) public view returns (InterchainBatch memory) { // In "no batching" mode: the batch root is the same as the entry hash. // For non-finalized or non-existent batches, the batch root is 0. bytes32 batchRoot = dbNonce < getDBNonce() ? getEntryValue(dbNonce, 0) : bytes32(0); return InterchainBatchLib.constructLocalBatch(dbNonce, batchRoot); } /// @inheritdoc IInterchainDB function getEntryValue(uint64 dbNonce, uint64 entryIndex) public view returns (bytes32) { _assertEntryExists(dbNonce, entryIndex); return _entryValues[dbNonce]; } /// @inheritdoc IInterchainDB function getDBNonce() public view returns (uint64) { // We can do the unsafe cast here as writing more than 2^64 entries is practically impossible return uint64(_entryValues.length); } // ══════════════════════════════════════════════ INTERNAL LOGIC ═══════════════════════════════════════════════════ /// @dev Write the entry to the database and emit the event. function _writeEntry(bytes32 dataHash) internal returns (InterchainEntry memory entry) { uint64 dbNonce = getDBNonce(); entry = InterchainEntryLib.constructLocalEntry({ dbNonce: dbNonce, entryIndex: 0, writer: msg.sender, dataHash: dataHash }); bytes32 entryValue = entry.entryValue(); _entryValues.push(entryValue); emit InterchainEntryWritten({ dbNonce: dbNonce, entryIndex: 0, srcWriter: TypeCasts.addressToBytes32(msg.sender), dataHash: dataHash }); // In the InterchainDB V1 the batch is finalized immediately after the entry is written emit InterchainBatchFinalized({dbNonce: dbNonce, batchRoot: entryValue}); } /// @dev Request the verification of the entry by the modules, and emit the event. /// Note: the validity of the passed entry and chain id being remote is enforced in the calling function. function _requestVerification( uint64 dstChainId, InterchainBatch memory batch, address[] calldata srcModules ) internal { (uint256[] memory fees, uint256 totalFee) = _getModuleFees(dstChainId, batch.dbNonce, srcModules); if (msg.value < totalFee) { revert InterchainDB__FeeAmountBelowMin(msg.value, totalFee); } else if (msg.value > totalFee) { // The exceeding amount goes to the first module fees[0] += msg.value - totalFee; } uint256 len = srcModules.length; bytes memory versionedBatch = VersionedPayloadLib.encodeVersionedPayload({ version: DB_VERSION, payload: InterchainBatchLib.encodeBatch(batch) }); for (uint256 i = 0; i < len; ++i) { IInterchainModule(srcModules[i]).requestBatchVerification{value: fees[i]}( dstChainId, batch.dbNonce, versionedBatch ); } emit InterchainBatchVerificationRequested(dstChainId, batch.dbNonce, batch.batchRoot, srcModules); } /// @dev Save the verified batch to the database and emit the event. function _saveVerifiedBatch(address module, BatchKey batchKey, InterchainBatch memory batch) internal { _remoteBatches[module][batchKey] = RemoteBatch({verifiedAt: block.timestamp, batchRoot: batch.batchRoot}); emit InterchainBatchVerified(module, batch.srcChainId, batch.dbNonce, batch.batchRoot); } // ══════════════════════════════════════════════ INTERNAL VIEWS ═══════════════════════════════════════════════════ /// @dev Asserts that the batch version is correct and that batch originates from a remote chain. /// Note: returns the decoded batch for chaining purposes. function _assertCorrectBatch(bytes calldata versionedBatch) internal view returns (InterchainBatch memory batch) { uint16 dbVersion = versionedBatch.getVersion(); if (dbVersion != DB_VERSION) { revert InterchainDB__BatchVersionMismatch(dbVersion, DB_VERSION); } batch = InterchainBatchLib.decodeBatch(versionedBatch.getPayload()); if (batch.srcChainId == block.chainid) { revert InterchainDB__ChainIdNotRemote(batch.srcChainId); } } /// @dev Check that the entry index is within the batch size. Also checks that the batch exists. function _assertEntryExists(uint64 dbNonce, uint64 entryIndex) internal view { // This will revert if the batch does not exist uint64 batchSize = getBatchSize(dbNonce); if (entryIndex >= batchSize) { revert InterchainDB__EntryIndexOutOfRange(dbNonce, entryIndex, batchSize); } } /// @dev Get the verification fees for the modules function _getModuleFees( uint64 dstChainId, uint64 dbNonce, address[] calldata srcModules ) internal view returns (uint256[] memory fees, uint256 totalFee) { uint256 len = srcModules.length; if (len == 0) { revert InterchainDB__ModulesNotProvided(); } fees = new uint256[](len); for (uint256 i = 0; i < len; ++i) { fees[i] = IInterchainModule(srcModules[i]).getModuleFee(dstChainId, dbNonce); totalFee += fees[i]; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; abstract contract InterchainDBEvents { /// @notice Emitted when a local entry is written to the database. /// @param dbNonce The nonce of the batch containing the entry. /// @param entryIndex The index of the entry within the batch. /// @param srcWriter The address of the writer. /// @param dataHash The written data hash. event InterchainEntryWritten( uint64 indexed dbNonce, uint64 entryIndex, bytes32 indexed srcWriter, bytes32 dataHash ); /// @notice Emitted when a local batch is finalized. /// @param dbNonce The nonce of the finalized batch. /// @param batchRoot The Merkle root hash of the finalized batch. event InterchainBatchFinalized(uint64 indexed dbNonce, bytes32 batchRoot); /// @notice Emitted when a remote batch is verified by the Interchain Module. /// @param module The address of the Interchain Module that verified the batch. /// @param srcChainId The ID of the source chain. /// @param dbNonce The nonce of the verified batch. /// @param batchRoot The Merkle root hash of the verified batch. event InterchainBatchVerified( address indexed module, uint64 indexed srcChainId, uint64 indexed dbNonce, bytes32 batchRoot ); /// @notice Emitted when a local batch is requested to be verified on a remote chain /// using the set of Interchain Modules. /// @param dstChainId The ID of the destination chain. /// @param dbNonce The nonce of the batch to be verified. /// @param batchRoot The Merkle root hash of the batch to be verified. /// @param srcModules The addresses of the Interchain Modules that will verify the batch. event InterchainBatchVerificationRequested( uint64 indexed dstChainId, uint64 indexed dbNonce, bytes32 batchRoot, address[] srcModules ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {InterchainBatch} from "../libs/InterchainBatch.sol"; import {InterchainEntry} from "../libs/InterchainEntry.sol"; interface IInterchainDB { error InterchainDB__BatchConflict(address module, bytes32 existingBatchRoot, InterchainBatch newBatch); error InterchainDB__BatchVersionMismatch(uint16 version, uint16 required); error InterchainDB__ChainIdNotRemote(uint64 chainId); error InterchainDB__EntryIndexOutOfRange(uint64 dbNonce, uint64 entryIndex, uint64 batchSize); error InterchainDB__EntryRangeInvalid(uint64 dbNonce, uint64 start, uint64 end); error InterchainDB__FeeAmountBelowMin(uint256 feeAmount, uint256 minRequired); error InterchainDB__ModulesNotProvided(); /// @notice Write data to the Interchain DataBase as a new entry in the current batch. /// Note: there are no guarantees that this entry will be available for reading on any of the remote chains. /// Use `requestBatchVerification` to ensure that the entry is available for reading on the destination chain. /// @param dataHash The hash of the data to be written to the Interchain DataBase as a new entry /// @return dbNonce The database nonce of the batch containing the written entry /// @return entryIndex The index of the written entry within the batch function writeEntry(bytes32 dataHash) external returns (uint64 dbNonce, uint64 entryIndex); /// @notice Request the given Interchain Modules to verify an existing batch. /// If the batch is not finalized, the module will verify it after finalization. /// For the finalized batch the batch root is already available, and the module can verify it immediately. /// Note: every module has a separate fee paid in the native gas token of the source chain, /// and `msg.value` must be equal to the sum of all fees. /// Note: this method is permissionless, and anyone can request verification for any batch. /// @dev Will revert if the batch with the given nonce does not exist. /// @param dstChainId The chain id of the destination chain /// @param dbNonce The database nonce of the existing batch /// @param srcModules The source chain addresses of the Interchain Modules to use for verification function requestBatchVerification( uint64 dstChainId, uint64 dbNonce, address[] memory srcModules ) external payable; /// @notice Write data to the Interchain DataBase as a new entry in the current batch. /// Then request the Interchain Modules to verify the batch containing the written entry on the destination chain. /// See `writeEntry` and `requestBatchVerification` for more details. /// @dev Will revert if the empty array of modules is provided. /// @param dstChainId The chain id of the destination chain /// @param dataHash The hash of the data to be written to the Interchain DataBase as a new entry /// @param srcModules The source chain addresses of the Interchain Modules to use for verification /// @return dbNonce The database nonce of the batch containing the written entry /// @return entryIndex The index of the written entry within the batch function writeEntryWithVerification( uint64 dstChainId, bytes32 dataHash, address[] memory srcModules ) external payable returns (uint64 dbNonce, uint64 entryIndex); /// @notice Allows the Interchain Module to verify the batch coming from the remote chain. /// The module SHOULD verify the exact finalized batch from the remote chain. If the batch with a given nonce /// is not finalized or does not exist, module CAN verify it with an empty root value. Once the batch is /// finalized, the module SHOULD re-verify the batch with the correct root value. /// Note: The DB will only accept the batch of the same version as the DB itself. /// @dev Will revert if the batch with the same nonce but a different non-empty root is already verified. /// @param versionedBatch The versioned Interchain Batch to verify function verifyRemoteBatch(bytes memory versionedBatch) external; // ═══════════════════════════════════════════════════ VIEWS ═══════════════════════════════════════════════════════ /// @notice Get the fee for writing data to the Interchain DataBase, and verifying it on the destination chain /// using the provided Interchain Modules. /// @dev Will revert if the empty array of modules is provided. /// @param dstChainId The chain id of the destination chain /// @param srcModules The source chain addresses of the Interchain Modules to use for verification function getInterchainFee(uint64 dstChainId, address[] memory srcModules) external view returns (uint256); /// @notice Returns the list of leafs of the finalized batch with the given nonce. /// Note: the leafs are ordered by the index of the written entry in the current batch, /// and the leafs value match the value of the written entry (srcWriter + dataHash hashed together). /// @dev Will revert if the batch with the given nonce does not exist, or is not finalized. /// @param dbNonce The database nonce of the finalized batch function getBatchLeafs(uint64 dbNonce) external view returns (bytes32[] memory); /// @notice Returns the list of leafs of the finalized batch with the given nonce, /// paginated by the given start and end indexes. The end index is exclusive. /// Note: this is useful when the batch contains a large number of leafs, and calling `getBatchLeafs` /// would result in a gas limit exceeded error. /// @dev Will revert if the batch with the given nonce does not exist, or is not finalized. /// Will revert if the provided range is invalid. /// @param dbNonce The database nonce of the finalized batch /// @param start The start index of the paginated leafs, inclusive /// @param end The end index of the paginated leafs, exclusive function getBatchLeafsPaginated( uint64 dbNonce, uint64 start, uint64 end ) external view returns (bytes32[] memory); /// @notice Returns the size of the finalized batch with the given nonce. /// @dev Will revert if the batch with the given nonce does not exist, or is not finalized. /// @param dbNonce The database nonce of the finalized batch function getBatchSize(uint64 dbNonce) external view returns (uint64); /// @notice Get the finalized Interchain Batch with the given nonce. /// @dev Will revert if the batch with the given nonce does not exist, or is not finalized. /// @param dbNonce The database nonce of the finalized batch function getBatch(uint64 dbNonce) external view returns (InterchainBatch memory); /// @notice Get the versioned Interchain Batch with the given nonce. /// Note: will return a batch with an empty root if the batch does not exist, or is not finalized. /// @param dbNonce The database nonce of the batch function getVersionedBatch(uint64 dbNonce) external view returns (bytes memory); /// @notice Get the Interchain Entry's value written on the local chain with the given batch nonce and entry index. /// Entry value is calculated as the hash of the writer address and the written data hash. /// Note: the batch does not have to be finalized to fetch the entry value. /// @dev Will revert if the batch with the given nonce does not exist, /// or the entry with the given index does not exist within the batch. /// @param dbNonce The database nonce of the existing batch /// @param entryIndex The index of the written entry within the batch function getEntryValue(uint64 dbNonce, uint64 entryIndex) external view returns (bytes32); /// @notice Get the Merkle proof of inclusion for the entry with the given index /// in the finalized batch with the given nonce. /// @dev Will revert if the batch with the given nonce does not exist, or is not finalized. /// Will revert if the entry with the given index does not exist within the batch. /// @param dbNonce The database nonce of the finalized batch /// @param entryIndex The index of the written entry within the batch /// @return proof The Merkle proof of inclusion for the entry function getEntryProof(uint64 dbNonce, uint64 entryIndex) external view returns (bytes32[] memory proof); /// @notice Get the nonce of the database, which is incremented every time a new batch is finalized. /// This is the nonce of the current non-finalized batch. function getDBNonce() external view returns (uint64); /// @notice Get the index of the next entry to be written to the database. /// @return dbNonce The database nonce of the batch including the next entry /// @return entryIndex The index of the next entry within that batch function getNextEntryIndex() external view returns (uint64 dbNonce, uint64 entryIndex); /// @notice Check if the batch is verified by the Interchain Module on the destination chain. /// Note: returned zero value indicates that the module has not verified the batch. /// @param dstModule The destination chain addresses of the Interchain Modules to use for verification /// @param batch The Interchain Batch to check /// @return moduleVerifiedAt The block timestamp at which the batch was verified by the module, /// or ZERO if the module has not verified the batch. function checkBatchVerification( address dstModule, InterchainBatch memory batch ) external view returns (uint256 moduleVerifiedAt); /// @notice Get the batch root containing the Interchain Entry with the given index. /// @param entry The Interchain Entry to get the batch root for /// @param proof The Merkle proof of inclusion for the entry in the batch function getBatchRoot(InterchainEntry memory entry, bytes32[] memory proof) external pure returns (bytes32); /// @notice Get the version of the Interchain DataBase. // solhint-disable-next-line func-name-mixedcase function DB_VERSION() external pure returns (uint16); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @notice Every Module may opt a different method to confirm the verified entries on destination chain, /// therefore this is not a part of a common interface. interface IInterchainModule { error InterchainModule__CallerNotInterchainDB(address caller); error InterchainModule__ChainIdNotRemote(uint64 chainId); error InterchainModule__FeeAmountBelowMin(uint256 feeAmount, uint256 minRequired); /// @notice Request the verification of a batch from the Interchain DataBase by the module. /// If the batch is not yet finalized, the verification on destination chain will be delayed until /// the finalization is done and batch root is saved on the source chain. /// Note: a fee is paid to the module for verification, and could be retrieved by using `getModuleFee`. /// Note: this will eventually trigger `InterchainDB.verifyRemoteBatch(batch)` function on destination chain, /// with no guarantee of ordering. /// @dev Could be only called by the Interchain DataBase contract. /// @param dstChainId The chain id of the destination chain /// @param batchNonce The nonce of the batch on the source chain /// @param versionedBatch The versioned batch to verify function requestBatchVerification( uint64 dstChainId, uint64 batchNonce, bytes memory versionedBatch ) external payable; /// @notice Get the Module fee for verifying a batch on the specified destination chain. /// @param dstChainId The chain id of the destination chain /// @param dbNonce The database nonce of the batch on the source chain function getModuleFee(uint64 dstChainId, uint64 dbNonce) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {InterchainEntryLib} from "./InterchainEntry.sol"; library BatchingV1Lib { error BatchingV1__EntryIndexNotZero(uint64 entryIndex); error BatchingV1__ProofNotEmpty(); /// @notice Get the batch root containing the Interchain Entry with the given index. /// @param srcWriter The entry writer of the source chain /// @param dataHash The hash of the data of the entry /// @param entryIndex The index of the entry in the batch /// @param proof The Merkle proof of inclusion for the entry in the batch /// @return batchRoot The root of the batch containing the entry function getBatchRoot( bytes32 srcWriter, bytes32 dataHash, uint64 entryIndex, bytes32[] calldata proof ) internal pure returns (bytes32 batchRoot) { // In "no batching" mode: entry index is 0, proof is empty if (entryIndex != 0) { revert BatchingV1__EntryIndexNotZero(entryIndex); } if (proof.length != 0) { revert BatchingV1__ProofNotEmpty(); } // In "no batching" mode: the batch root is the same as the entry value return InterchainEntryLib.getEntryValue({srcWriter: srcWriter, dataHash: dataHash}); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {VersionedPayloadLib} from "./VersionedPayload.sol"; import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; type BatchKey is uint128; /// @notice Struct representing a batch of entries in the Interchain DataBase. /// Batched entries are put together in a Merkle tree, which root is saved. /// Batch has a globally unique identifier (key) and a value. /// - key: srcChainId + dbNonce /// - value: batchRoot /// @param srcChainId The chain id of the source chain /// @param dbNonce The database nonce of the batch /// @param batchRoot The root of the Merkle tree containing the batched entries struct InterchainBatch { uint64 srcChainId; uint64 dbNonce; bytes32 batchRoot; } /// @dev Signals that the module has not verified any batch with the given key. uint256 constant BATCH_UNVERIFIED = 0; /// @dev Signals that the module has verified a conflicting batch with the given key. uint256 constant BATCH_CONFLICT = type(uint256).max; library InterchainBatchLib { using VersionedPayloadLib for bytes; /// @notice Constructs an InterchainBatch struct to be saved on the local chain. /// @param dbNonce The database nonce of the batch /// @param batchRoot The root of the Merkle tree containing the batched entries /// @return batch The constructed InterchainBatch struct function constructLocalBatch( uint64 dbNonce, bytes32 batchRoot ) internal view returns (InterchainBatch memory batch) { return InterchainBatch({srcChainId: SafeCast.toUint64(block.chainid), dbNonce: dbNonce, batchRoot: batchRoot}); } /// @notice Encodes the InterchainBatch struct into a non-versioned batch payload. function encodeBatch(InterchainBatch memory batch) internal pure returns (bytes memory) { return abi.encode(encodeBatchKey(batch.srcChainId, batch.dbNonce), batch.batchRoot); } /// @notice Decodes the InterchainBatch struct from a non-versioned batch payload in calldata. function decodeBatch(bytes calldata data) internal pure returns (InterchainBatch memory batch) { BatchKey key; (key, batch.batchRoot) = abi.decode(data, (BatchKey, bytes32)); (batch.srcChainId, batch.dbNonce) = decodeBatchKey(key); } /// @notice Decodes the InterchainBatch struct from a non-versioned batch payload in memory. function decodeBatchFromMemory(bytes memory data) internal pure returns (InterchainBatch memory batch) { BatchKey key; (key, batch.batchRoot) = abi.decode(data, (BatchKey, bytes32)); (batch.srcChainId, batch.dbNonce) = decodeBatchKey(key); } /// @notice Encodes the uint128 key of the batch from uint64 srcChainId and uint64 dbNonce. function encodeBatchKey(uint64 srcChainId, uint64 dbNonce) internal pure returns (BatchKey) { return BatchKey.wrap((uint128(srcChainId) << 64) | dbNonce); } /// @notice Decodes the uint128 key of the batch into uint64 srcChainId and uint64 dbNonce. function decodeBatchKey(BatchKey key) internal pure returns (uint64 srcChainId, uint64 dbNonce) { srcChainId = uint64(BatchKey.unwrap(key) >> 64); dbNonce = uint64(BatchKey.unwrap(key)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {TypeCasts} from "./TypeCasts.sol"; import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; /// @notice Struct representing an entry in the Interchain DataBase. /// Entry has a globally unique identifier (key) and a value. /// - key: srcChainId + dbNonce + entryIndex /// - value: srcWriter + dataHash /// @param srcChainId The chain id of the source chain /// @param dbNonce The database nonce of the batch containing the entry /// @param entryIndex The index of the entry in the batch /// @param srcWriter The address of the writer on the source chain /// @param dataHash The hash of the data written on the source chain struct InterchainEntry { uint64 srcChainId; uint64 dbNonce; uint64 entryIndex; bytes32 srcWriter; bytes32 dataHash; } using InterchainEntryLib for InterchainEntry global; library InterchainEntryLib { /// @notice Constructs an InterchainEntry struct to be written on the local chain /// @param dbNonce The database nonce of the entry on the source chain /// @param writer The address of the writer on the local chain /// @param dataHash The hash of the data written on the local chain /// @return entry The constructed InterchainEntry struct function constructLocalEntry( uint64 dbNonce, uint64 entryIndex, address writer, bytes32 dataHash ) internal view returns (InterchainEntry memory entry) { return InterchainEntry({ srcChainId: SafeCast.toUint64(block.chainid), dbNonce: dbNonce, entryIndex: entryIndex, srcWriter: TypeCasts.addressToBytes32(writer), dataHash: dataHash }); } /// @notice Returns the value of the entry: writer + dataHash hashed together function entryValue(InterchainEntry memory entry) internal pure returns (bytes32) { return getEntryValue(entry.srcWriter, entry.dataHash); } /// @notice Returns the value of the entry: writer + dataHash hashed together function getEntryValue(bytes32 srcWriter, bytes32 dataHash) internal pure returns (bytes32) { return keccak256(abi.encode(srcWriter, dataHash)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // solhint-disable no-inline-assembly // solhint-disable ordering library VersionedPayloadLib { /// @notice Amount of bytes reserved for the version (uint16) in the versioned payload uint256 internal constant VERSION_LENGTH = 2; error VersionedPayload__PayloadTooShort(bytes versionedPayload); error VersionedPayload__PrecompileFailed(); /// @notice Encodes the versioned payload into a single bytes array. /// @param version The payload's version. /// @param payload The payload to encode. function encodeVersionedPayload(uint16 version, bytes memory payload) internal pure returns (bytes memory) { return abi.encodePacked(version, payload); } /// @notice Extracts the version from the versioned payload (calldata reference). /// @param versionedPayload The versioned payload (calldata reference). function getVersion(bytes calldata versionedPayload) internal pure returns (uint16 version) { if (versionedPayload.length < VERSION_LENGTH) { revert VersionedPayload__PayloadTooShort(versionedPayload); } assembly { // We are only interested in the highest 16 bits of the loaded full 32 bytes word. version := shr(240, calldataload(versionedPayload.offset)) } } /// @notice Extracts the payload from the versioned payload (calldata reference). /// @dev The extracted payload is also returned as a calldata reference. /// @param versionedPayload The versioned payload. function getPayload(bytes calldata versionedPayload) internal pure returns (bytes calldata) { if (versionedPayload.length < VERSION_LENGTH) { revert VersionedPayload__PayloadTooShort(versionedPayload); } return versionedPayload[VERSION_LENGTH:]; } /// @notice Extracts the version from the versioned payload (memory reference). /// @param versionedPayload The versioned payload (memory reference). function getVersionFromMemory(bytes memory versionedPayload) internal pure returns (uint16 version) { if (versionedPayload.length < VERSION_LENGTH) { revert VersionedPayload__PayloadTooShort(versionedPayload); } assembly { // We are only interested in the highest 16 bits of the loaded full 32 bytes word. // We add 0x20 to skip the length of the bytes array. version := shr(240, mload(add(versionedPayload, 0x20))) } } /// @notice Extracts the payload from the versioned payload (memory reference). /// @dev The extracted payload is copied into a new memory location. Use `getPayload` when possible /// to avoid extra memory allocation. /// @param versionedPayload The versioned payload (memory reference). function getPayloadFromMemory(bytes memory versionedPayload) internal view returns (bytes memory payload) { if (versionedPayload.length < VERSION_LENGTH) { revert VersionedPayload__PayloadTooShort(versionedPayload); } // Figure how many bytes to copy and allocate the memory for the extracted payload. uint256 toCopy; unchecked { toCopy = versionedPayload.length - VERSION_LENGTH; } payload = new bytes(toCopy); // Use identity precompile (0x04) to copy the payload. Unlike MCOPY, this is available on all EVM chains. bool res; assembly { // We add 0x20 to skip the length of the bytes array. // We add 0x02 to skip the 2 bytes reserved for the version. // Copy the payload to the previously allocated memory. res := staticcall(gas(), 0x04, add(versionedPayload, 0x22), toCopy, add(payload, 0x20), toCopy) } if (!res) { revert VersionedPayload__PrecompileFailed(); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library TypeCasts { function addressToBytes32(address addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(addr))); } function bytes32ToAddress(bytes32 b) internal pure returns (address) { return address(uint160(uint256(b))); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } }
{ "remappings": [ "@openzeppelin/=node_modules/@openzeppelin/", "@synapsecns/=node_modules/@synapsecns/", "ds-test/=node_modules/ds-test/src/", "forge-std/=node_modules/forge-std/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
[{"inputs":[{"internalType":"uint64","name":"entryIndex","type":"uint64"}],"name":"BatchingV1__EntryIndexNotZero","type":"error"},{"inputs":[],"name":"BatchingV1__ProofNotEmpty","type":"error"},{"inputs":[{"internalType":"address","name":"module","type":"address"},{"internalType":"bytes32","name":"existingBatchRoot","type":"bytes32"},{"components":[{"internalType":"uint64","name":"srcChainId","type":"uint64"},{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"}],"internalType":"struct InterchainBatch","name":"newBatch","type":"tuple"}],"name":"InterchainDB__BatchConflict","type":"error"},{"inputs":[{"internalType":"uint16","name":"version","type":"uint16"},{"internalType":"uint16","name":"required","type":"uint16"}],"name":"InterchainDB__BatchVersionMismatch","type":"error"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"InterchainDB__ChainIdNotRemote","type":"error"},{"inputs":[{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"entryIndex","type":"uint64"},{"internalType":"uint64","name":"batchSize","type":"uint64"}],"name":"InterchainDB__EntryIndexOutOfRange","type":"error"},{"inputs":[{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"start","type":"uint64"},{"internalType":"uint64","name":"end","type":"uint64"}],"name":"InterchainDB__EntryRangeInvalid","type":"error"},{"inputs":[{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"minRequired","type":"uint256"}],"name":"InterchainDB__FeeAmountBelowMin","type":"error"},{"inputs":[],"name":"InterchainDB__ModulesNotProvided","type":"error"},{"inputs":[{"internalType":"uint8","name":"bits","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeCastOverflowedUintDowncast","type":"error"},{"inputs":[{"internalType":"bytes","name":"versionedPayload","type":"bytes"}],"name":"VersionedPayload__PayloadTooShort","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"dbNonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"batchRoot","type":"bytes32"}],"name":"InterchainBatchFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"dstChainId","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"dbNonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"batchRoot","type":"bytes32"},{"indexed":false,"internalType":"address[]","name":"srcModules","type":"address[]"}],"name":"InterchainBatchVerificationRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"module","type":"address"},{"indexed":true,"internalType":"uint64","name":"srcChainId","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"dbNonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"batchRoot","type":"bytes32"}],"name":"InterchainBatchVerified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"dbNonce","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"entryIndex","type":"uint64"},{"indexed":true,"internalType":"bytes32","name":"srcWriter","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"dataHash","type":"bytes32"}],"name":"InterchainEntryWritten","type":"event"},{"inputs":[],"name":"DB_VERSION","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dstModule","type":"address"},{"components":[{"internalType":"uint64","name":"srcChainId","type":"uint64"},{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"}],"internalType":"struct InterchainBatch","name":"batch","type":"tuple"}],"name":"checkBatchVerification","outputs":[{"internalType":"uint256","name":"moduleVerifiedAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"dbNonce","type":"uint64"}],"name":"getBatch","outputs":[{"components":[{"internalType":"uint64","name":"srcChainId","type":"uint64"},{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"}],"internalType":"struct InterchainBatch","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"dbNonce","type":"uint64"}],"name":"getBatchLeafs","outputs":[{"internalType":"bytes32[]","name":"leafs","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"start","type":"uint64"},{"internalType":"uint64","name":"end","type":"uint64"}],"name":"getBatchLeafsPaginated","outputs":[{"internalType":"bytes32[]","name":"leafs","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"srcChainId","type":"uint64"},{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"entryIndex","type":"uint64"},{"internalType":"bytes32","name":"srcWriter","type":"bytes32"},{"internalType":"bytes32","name":"dataHash","type":"bytes32"}],"internalType":"struct InterchainEntry","name":"entry","type":"tuple"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"getBatchRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint64","name":"dbNonce","type":"uint64"}],"name":"getBatchSize","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDBNonce","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"entryIndex","type":"uint64"}],"name":"getEntryProof","outputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"entryIndex","type":"uint64"}],"name":"getEntryValue","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"dstChainId","type":"uint64"},{"internalType":"address[]","name":"srcModules","type":"address[]"}],"name":"getInterchainFee","outputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNextEntryIndex","outputs":[{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"entryIndex","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"dbNonce","type":"uint64"}],"name":"getVersionedBatch","outputs":[{"internalType":"bytes","name":"versionedBatch","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"dstChainId","type":"uint64"},{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"address[]","name":"srcModules","type":"address[]"}],"name":"requestBatchVerification","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"versionedBatch","type":"bytes"}],"name":"verifyRemoteBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"dataHash","type":"bytes32"}],"name":"writeEntry","outputs":[{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"entryIndex","type":"uint64"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"dstChainId","type":"uint64"},{"internalType":"bytes32","name":"dataHash","type":"bytes32"},{"internalType":"address[]","name":"srcModules","type":"address[]"}],"name":"writeEntryWithVerification","outputs":[{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"entryIndex","type":"uint64"}],"stateMutability":"payable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50611a49806100206000396000f3fe6080604052600436106100fe5760003560e01c8063b8ba4ba111610095578063e39682c111610064578063e39682c1146102e7578063eb20fbfd14610307578063f338140e1461031a578063fc1ebc911461032f578063fec8dfb91461034f57600080fd5b8063b8ba4ba11461025a578063c72657811461027a578063d180db6f146102a7578063d961a48e146102c757600080fd5b80636c49312c116100d15780636c49312c146101cb578063727a5f91146101e0578063888775d914610218578063aa2f06ae1461024557600080fd5b80630166204f1461010357806315f53956146101365780631c679ac11461015e5780632ad8c7061461018b575b600080fd5b34801561010f57600080fd5b5061012361011e366004611354565b61036f565b6040519081526020015b60405180910390f35b34801561014257600080fd5b5061014b600181565b60405161ffff909116815260200161012d565b34801561016a57600080fd5b5061017e610179366004611421565b610392565b60405161012d9190611464565b34801561019757600080fd5b506101ab6101a63660046114a8565b6104d4565b604080516001600160401b0393841681529290911660208301520161012d565b6101de6101d93660046114c1565b6104f8565b005b3480156101ec57600080fd5b506102006101fb366004611521565b61054e565b6040516001600160401b03909116815260200161012d565b34801561022457600080fd5b50610238610233366004611521565b61057d565b60405161012d919061153c565b34801561025157600080fd5b506101ab6105db565b34801561026657600080fd5b5061012361027536600461156b565b6105f0565b34801561028657600080fd5b5061029a610295366004611521565b61060f565b60405161012d9190611600565b3480156102b357600080fd5b506101236102c2366004611613565b610631565b3480156102d357600080fd5b506101de6102e2366004611646565b61066d565b3480156102f357600080fd5b506101236103023660046116ce565b61074e565b6101ab610315366004611765565b610833565b34801561032657600080fd5b50600054610200565b34801561033b57600080fd5b5061017e61034a366004611521565b6108eb565b34801561035b57600080fd5b5061017e61036a366004611613565b6109a2565b600061038a84606001518560800151866040015186866109c4565b949350505050565b6060600061039f8561054e565b6001600160401b03169050826001600160401b0316846001600160401b031611806103d2575080836001600160401b0316115b15610410576040516372833e0d60e01b81526001600160401b0380871660048301528086166024830152841660448201526064015b60405180910390fd5b61041a84846117bc565b6001600160401b03166001600160401b0381111561043a5761043a6112de565b604051908082528060200260200182016040528015610463578160200160208202803683370190505b509150835b836001600160401b0316816001600160401b031610156104cb5761048c8682610631565b8361049787846117bc565b6001600160401b0316815181106104b0576104b06117dc565b60209081029190910101526104c4816117f2565b9050610468565b50509392505050565b60008060006104e284610a48565b6020810151604090910151909590945092505050565b8346816001600160401b03160361052d57604051630d9e106b60e41b81526001600160401b0382166004820152602401610407565b60006105388561057d565b905061054686828686610b8a565b505050505050565b600080546001600160401b0316826001600160401b031610610571576000610574565b60015b60ff1692915050565b6040805160608101825260008082526020820181905291810191909152600080546001600160401b0316836001600160401b0316106105bd5760006105c8565b6105c8836000610631565b90506105d48382610d3f565b9392505050565b6000806105e760005490565b92600092509050565b6000610606846105ff60005490565b8585610d99565b95945050505050565b6060600061061c8361057d565b90506105d4600161062c83610f0f565b610f73565b600061063d8383610f9f565b6000836001600160401b031681548110610659576106596117dc565b906000526020600020015490505b92915050565b60006106798383610ffe565b905060006106aa826000015183602001516001600160401b031660409190911b67ffffffffffffffff60401b161790565b3360009081526001602081815260408084206001600160801b03861685528252808420815180830190925280548083529301549181019190915292935090036106ff576106f83383856110a8565b5050505050565b8260400151816020015103610715575050505050565b602081015160000361072c576106f83383856110a8565b6020810151604051632d54ead760e11b81526104079133918690600401611818565b8051600090466001600160401b0382160361078757604051630d9e106b60e41b81526001600160401b0382166004820152602401610407565b60006107b6846000015185602001516001600160401b031660409190911b67ffffffffffffffff60401b161790565b6001600160a01b03861660009081526001602081815260408084206001600160801b038616855282528084208151808301909252805480835293015491810191909152929350900361080d5760009350505061082c565b846040015181602001511461082457600019610827565b80515b935050505b5092915050565b6000808546816001600160401b03160361086b57604051630d9e106b60e41b81526001600160401b0382166004820152602401610407565b600061087687610a48565b602081015160408201519095509350905060006108d1856108cc84600061066782606001518360800151604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b610d3f565b90506108df89828989610b8a565b50505094509492505050565b606060006108f88361054e565b6001600160401b03169050806001600160401b0381111561091b5761091b6112de565b604051908082528060200260200182016040528015610944578160200160208202803683370190505b50915060005b81816001600160401b0316101561099b576109658482610631565b83826001600160401b031681518110610980576109806117dc565b6020908102919091010152610994816117f2565b905061094a565b5050919050565b60606109ae8383610f9f565b5050604080516000815260208101909152919050565b60006001600160401b038416156109f95760405163d9c5be6160e01b81526001600160401b0385166004820152602401610407565b8115610a1857604051631a9b90c960e11b815260040160405180910390fd5b50506040805160208082019690965280820194909452805180850382018152606090940190525050805191012090565b6040805160a081018252600080825260208201819052918101829052606081018290526080810182905281549091610a839082903386611146565b91506000610ac683600061066782606001518360800151604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b600080546001810182559080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563018190559050336040805160008152602081018790526001600160401b038516917fb68afc0605cd0ae88c5b20fac83239f61bebdf93d94c8f6f6deed8e21cf2fa5d910160405180910390a3816001600160401b03167fdd11870a5e3366ac946d45a056101b609703ff29dae8c7d889a0f3f6ee455ace82604051610b7b91815260200190565b60405180910390a25050919050565b600080610b9d8686602001518686610d99565b9150915080341015610bcb5760405163805af60d60e01b815234600482015260248101829052604401610407565b80341115610c0857610bdd813461185d565b82600081518110610bf057610bf06117dc565b60200260200101818151610c049190611870565b9052505b826000610c19600161062c89610f0f565b905060005b82811015610cdd57868682818110610c3857610c386117dc565b9050602002016020810190610c4d9190611883565b6001600160a01b0316636b8d469f868381518110610c6d57610c6d6117dc565b60200260200101518b8b60200151866040518563ffffffff1660e01b8152600401610c9a9392919061189e565b6000604051808303818588803b158015610cb357600080fd5b505af1158015610cc7573d6000803e3d6000fd5b505050505080610cd6906118ca565b9050610c1e565b5086602001516001600160401b0316886001600160401b03167fddb2a81061691cd55f8c8bfa25d7d6da9dffe61f552c523de1821da5e1910ac189604001518989604051610d2d939291906118e3565b60405180910390a35050505050505050565b60408051606081018252600080825260208201819052918101919091526040518060600160405280610d70466111d2565b6001600160401b03168152602001846001600160401b0316815260200183815250905092915050565b6060600082808203610dbe576040516322f15d3d60e11b815260040160405180910390fd5b806001600160401b03811115610dd657610dd66112de565b604051908082528060200260200182016040528015610dff578160200160208202803683370190505b50925060005b81811015610f0457858582818110610e1f57610e1f6117dc565b9050602002016020810190610e349190611883565b6040516306223d3560e21b81526001600160401b03808b166004830152891660248201526001600160a01b039190911690631888f4d490604401602060405180830381865afa158015610e8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaf9190611939565b848281518110610ec157610ec16117dc565b602002602001018181525050838181518110610edf57610edf6117dc565b602002602001015183610ef29190611870565b9250610efd816118ca565b9050610e05565b505094509492505050565b6060610f3e826000015183602001516001600160401b031660409190911b67ffffffffffffffff60401b161790565b60408084015181516001600160801b039093166020840152908201526060016040516020818303038152906040529050919050565b60608282604051602001610f88929190611952565b604051602081830303815290604052905092915050565b6000610faa8361054e565b9050806001600160401b0316826001600160401b031610610ff957604051630299215760e31b81526001600160401b038085166004830152808416602483015282166044820152606401610407565b505050565b6040805160608101825260008082526020820181905291810182905290611025848461120c565b905061ffff811660011461105957604051633199e11760e01b815261ffff8216600482015260016024820152604401610407565b61106b611066858561123d565b61127f565b91504682600001516001600160401b03160361082c578151604051630d9e106b60e41b81526001600160401b039091166004820152602401610407565b604080518082018252428152828201805160208084019182526001600160a01b038816600081815260018084528782206001600160801b038b1683528452908790209551865592519490920193909355828501518551925194519485526001600160401b039081169492169290917f76a643c92bd448082982f23dc803017708bcce282ba837e92611b3e876c45927910160405180910390a4505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040518060a00160405280611185466111d2565b6001600160401b03168152602001866001600160401b03168152602001856001600160401b031681526020016111c1856001600160a01b031690565b815260200192909252509392505050565b60006001600160401b0382111561120857604080516306dfcc6560e41b8152600481019190915260248101839052604401610407565b5090565b60006002821015611234578282604051635840c5b160e11b8152600401610407929190611982565b50503560f01c90565b3660006002831015611266578383604051635840c5b160e11b8152600401610407929190611982565b61127383600281876119b1565b915091505b9250929050565b60408051606081018252600080825260208201819052918101829052906112a8848401856119db565b604084015290506112c4816001600160401b03604082901c1691565b6001600160401b0390811660208501521682525092915050565b634e487b7160e01b600052604160045260246000fd5b80356001600160401b038116811461130b57600080fd5b919050565b60008083601f84011261132257600080fd5b5081356001600160401b0381111561133957600080fd5b6020830191508360208260051b850101111561127857600080fd5b600080600083850360c081121561136a57600080fd5b60a081121561137857600080fd5b5060405160a081016001600160401b0382821081831117156113aa57634e487b7160e01b600052604160045260246000fd5b816040526113b7876112f4565b83526113c5602088016112f4565b60208401526113d6604088016112f4565b6040840152606087013560608401526080870135608084015282955060a087013592508083111561140657600080fd5b505061141486828701611310565b9497909650939450505050565b60008060006060848603121561143657600080fd5b61143f846112f4565b925061144d602085016112f4565b915061145b604085016112f4565b90509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561149c57835183529284019291840191600101611480565b50909695505050505050565b6000602082840312156114ba57600080fd5b5035919050565b600080600080606085870312156114d757600080fd5b6114e0856112f4565b93506114ee602086016112f4565b925060408501356001600160401b0381111561150957600080fd5b61151587828801611310565b95989497509550505050565b60006020828403121561153357600080fd5b6105d4826112f4565b81516001600160401b039081168252602080840151909116908201526040808301519082015260608101610667565b60008060006040848603121561158057600080fd5b611589846112f4565b925060208401356001600160401b038111156115a457600080fd5b61141486828701611310565b60005b838110156115cb5781810151838201526020016115b3565b50506000910152565b600081518084526115ec8160208601602086016115b0565b601f01601f19169290920160200192915050565b6020815260006105d460208301846115d4565b6000806040838503121561162657600080fd5b61162f836112f4565b915061163d602084016112f4565b90509250929050565b6000806020838503121561165957600080fd5b82356001600160401b038082111561167057600080fd5b818501915085601f83011261168457600080fd5b81358181111561169357600080fd5b8660208285010111156116a557600080fd5b60209290920196919550909350505050565b80356001600160a01b038116811461130b57600080fd5b60008082840360808112156116e257600080fd5b6116eb846116b7565b92506060601f19820112156116ff57600080fd5b50604051606081018181106001600160401b038211171561173057634e487b7160e01b600052604160045260246000fd5b60405261173f602085016112f4565b815261174d604085016112f4565b60208201526060939093013560408401525092909150565b6000806000806060858703121561177b57600080fd5b611784856112f4565b93506020850135925060408501356001600160401b0381111561150957600080fd5b634e487b7160e01b600052601160045260246000fd5b6001600160401b0382811682821603908082111561082c5761082c6117a6565b634e487b7160e01b600052603260045260246000fd5b60006001600160401b0380831681810361180e5761180e6117a6565b6001019392505050565b6001600160a01b0384168152602080820184905282516001600160401b0390811660408085019190915291840151166060830152820151608082015260a0810161038a565b81810381811115610667576106676117a6565b80820180821115610667576106676117a6565b60006020828403121561189557600080fd5b6105d4826116b7565b60006001600160401b0380861683528085166020840152506060604083015261060660608301846115d4565b6000600182016118dc576118dc6117a6565b5060010190565b83815260406020808301829052908201839052600090849060608401835b8681101561192d576001600160a01b0361191a856116b7565b1682529282019290820190600101611901565b50979650505050505050565b60006020828403121561194b57600080fd5b5051919050565b61ffff60f01b8360f01b168152600082516119748160028501602087016115b0565b919091016002019392505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b600080858511156119c157600080fd5b838611156119ce57600080fd5b5050820193919092039150565b600080604083850312156119ee57600080fd5b82356001600160801b0381168114611a0557600080fd5b94602093909301359350505056fea26469706673582212202b48e2cdc8c436bb57dd8dce706e3103d8bc8ccfdffaf019732d9d17e5e86dee64736f6c63430008140033
Deployed Bytecode
0x6080604052600436106100fe5760003560e01c8063b8ba4ba111610095578063e39682c111610064578063e39682c1146102e7578063eb20fbfd14610307578063f338140e1461031a578063fc1ebc911461032f578063fec8dfb91461034f57600080fd5b8063b8ba4ba11461025a578063c72657811461027a578063d180db6f146102a7578063d961a48e146102c757600080fd5b80636c49312c116100d15780636c49312c146101cb578063727a5f91146101e0578063888775d914610218578063aa2f06ae1461024557600080fd5b80630166204f1461010357806315f53956146101365780631c679ac11461015e5780632ad8c7061461018b575b600080fd5b34801561010f57600080fd5b5061012361011e366004611354565b61036f565b6040519081526020015b60405180910390f35b34801561014257600080fd5b5061014b600181565b60405161ffff909116815260200161012d565b34801561016a57600080fd5b5061017e610179366004611421565b610392565b60405161012d9190611464565b34801561019757600080fd5b506101ab6101a63660046114a8565b6104d4565b604080516001600160401b0393841681529290911660208301520161012d565b6101de6101d93660046114c1565b6104f8565b005b3480156101ec57600080fd5b506102006101fb366004611521565b61054e565b6040516001600160401b03909116815260200161012d565b34801561022457600080fd5b50610238610233366004611521565b61057d565b60405161012d919061153c565b34801561025157600080fd5b506101ab6105db565b34801561026657600080fd5b5061012361027536600461156b565b6105f0565b34801561028657600080fd5b5061029a610295366004611521565b61060f565b60405161012d9190611600565b3480156102b357600080fd5b506101236102c2366004611613565b610631565b3480156102d357600080fd5b506101de6102e2366004611646565b61066d565b3480156102f357600080fd5b506101236103023660046116ce565b61074e565b6101ab610315366004611765565b610833565b34801561032657600080fd5b50600054610200565b34801561033b57600080fd5b5061017e61034a366004611521565b6108eb565b34801561035b57600080fd5b5061017e61036a366004611613565b6109a2565b600061038a84606001518560800151866040015186866109c4565b949350505050565b6060600061039f8561054e565b6001600160401b03169050826001600160401b0316846001600160401b031611806103d2575080836001600160401b0316115b15610410576040516372833e0d60e01b81526001600160401b0380871660048301528086166024830152841660448201526064015b60405180910390fd5b61041a84846117bc565b6001600160401b03166001600160401b0381111561043a5761043a6112de565b604051908082528060200260200182016040528015610463578160200160208202803683370190505b509150835b836001600160401b0316816001600160401b031610156104cb5761048c8682610631565b8361049787846117bc565b6001600160401b0316815181106104b0576104b06117dc565b60209081029190910101526104c4816117f2565b9050610468565b50509392505050565b60008060006104e284610a48565b6020810151604090910151909590945092505050565b8346816001600160401b03160361052d57604051630d9e106b60e41b81526001600160401b0382166004820152602401610407565b60006105388561057d565b905061054686828686610b8a565b505050505050565b600080546001600160401b0316826001600160401b031610610571576000610574565b60015b60ff1692915050565b6040805160608101825260008082526020820181905291810191909152600080546001600160401b0316836001600160401b0316106105bd5760006105c8565b6105c8836000610631565b90506105d48382610d3f565b9392505050565b6000806105e760005490565b92600092509050565b6000610606846105ff60005490565b8585610d99565b95945050505050565b6060600061061c8361057d565b90506105d4600161062c83610f0f565b610f73565b600061063d8383610f9f565b6000836001600160401b031681548110610659576106596117dc565b906000526020600020015490505b92915050565b60006106798383610ffe565b905060006106aa826000015183602001516001600160401b031660409190911b67ffffffffffffffff60401b161790565b3360009081526001602081815260408084206001600160801b03861685528252808420815180830190925280548083529301549181019190915292935090036106ff576106f83383856110a8565b5050505050565b8260400151816020015103610715575050505050565b602081015160000361072c576106f83383856110a8565b6020810151604051632d54ead760e11b81526104079133918690600401611818565b8051600090466001600160401b0382160361078757604051630d9e106b60e41b81526001600160401b0382166004820152602401610407565b60006107b6846000015185602001516001600160401b031660409190911b67ffffffffffffffff60401b161790565b6001600160a01b03861660009081526001602081815260408084206001600160801b038616855282528084208151808301909252805480835293015491810191909152929350900361080d5760009350505061082c565b846040015181602001511461082457600019610827565b80515b935050505b5092915050565b6000808546816001600160401b03160361086b57604051630d9e106b60e41b81526001600160401b0382166004820152602401610407565b600061087687610a48565b602081015160408201519095509350905060006108d1856108cc84600061066782606001518360800151604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b610d3f565b90506108df89828989610b8a565b50505094509492505050565b606060006108f88361054e565b6001600160401b03169050806001600160401b0381111561091b5761091b6112de565b604051908082528060200260200182016040528015610944578160200160208202803683370190505b50915060005b81816001600160401b0316101561099b576109658482610631565b83826001600160401b031681518110610980576109806117dc565b6020908102919091010152610994816117f2565b905061094a565b5050919050565b60606109ae8383610f9f565b5050604080516000815260208101909152919050565b60006001600160401b038416156109f95760405163d9c5be6160e01b81526001600160401b0385166004820152602401610407565b8115610a1857604051631a9b90c960e11b815260040160405180910390fd5b50506040805160208082019690965280820194909452805180850382018152606090940190525050805191012090565b6040805160a081018252600080825260208201819052918101829052606081018290526080810182905281549091610a839082903386611146565b91506000610ac683600061066782606001518360800151604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b600080546001810182559080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563018190559050336040805160008152602081018790526001600160401b038516917fb68afc0605cd0ae88c5b20fac83239f61bebdf93d94c8f6f6deed8e21cf2fa5d910160405180910390a3816001600160401b03167fdd11870a5e3366ac946d45a056101b609703ff29dae8c7d889a0f3f6ee455ace82604051610b7b91815260200190565b60405180910390a25050919050565b600080610b9d8686602001518686610d99565b9150915080341015610bcb5760405163805af60d60e01b815234600482015260248101829052604401610407565b80341115610c0857610bdd813461185d565b82600081518110610bf057610bf06117dc565b60200260200101818151610c049190611870565b9052505b826000610c19600161062c89610f0f565b905060005b82811015610cdd57868682818110610c3857610c386117dc565b9050602002016020810190610c4d9190611883565b6001600160a01b0316636b8d469f868381518110610c6d57610c6d6117dc565b60200260200101518b8b60200151866040518563ffffffff1660e01b8152600401610c9a9392919061189e565b6000604051808303818588803b158015610cb357600080fd5b505af1158015610cc7573d6000803e3d6000fd5b505050505080610cd6906118ca565b9050610c1e565b5086602001516001600160401b0316886001600160401b03167fddb2a81061691cd55f8c8bfa25d7d6da9dffe61f552c523de1821da5e1910ac189604001518989604051610d2d939291906118e3565b60405180910390a35050505050505050565b60408051606081018252600080825260208201819052918101919091526040518060600160405280610d70466111d2565b6001600160401b03168152602001846001600160401b0316815260200183815250905092915050565b6060600082808203610dbe576040516322f15d3d60e11b815260040160405180910390fd5b806001600160401b03811115610dd657610dd66112de565b604051908082528060200260200182016040528015610dff578160200160208202803683370190505b50925060005b81811015610f0457858582818110610e1f57610e1f6117dc565b9050602002016020810190610e349190611883565b6040516306223d3560e21b81526001600160401b03808b166004830152891660248201526001600160a01b039190911690631888f4d490604401602060405180830381865afa158015610e8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaf9190611939565b848281518110610ec157610ec16117dc565b602002602001018181525050838181518110610edf57610edf6117dc565b602002602001015183610ef29190611870565b9250610efd816118ca565b9050610e05565b505094509492505050565b6060610f3e826000015183602001516001600160401b031660409190911b67ffffffffffffffff60401b161790565b60408084015181516001600160801b039093166020840152908201526060016040516020818303038152906040529050919050565b60608282604051602001610f88929190611952565b604051602081830303815290604052905092915050565b6000610faa8361054e565b9050806001600160401b0316826001600160401b031610610ff957604051630299215760e31b81526001600160401b038085166004830152808416602483015282166044820152606401610407565b505050565b6040805160608101825260008082526020820181905291810182905290611025848461120c565b905061ffff811660011461105957604051633199e11760e01b815261ffff8216600482015260016024820152604401610407565b61106b611066858561123d565b61127f565b91504682600001516001600160401b03160361082c578151604051630d9e106b60e41b81526001600160401b039091166004820152602401610407565b604080518082018252428152828201805160208084019182526001600160a01b038816600081815260018084528782206001600160801b038b1683528452908790209551865592519490920193909355828501518551925194519485526001600160401b039081169492169290917f76a643c92bd448082982f23dc803017708bcce282ba837e92611b3e876c45927910160405180910390a4505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040518060a00160405280611185466111d2565b6001600160401b03168152602001866001600160401b03168152602001856001600160401b031681526020016111c1856001600160a01b031690565b815260200192909252509392505050565b60006001600160401b0382111561120857604080516306dfcc6560e41b8152600481019190915260248101839052604401610407565b5090565b60006002821015611234578282604051635840c5b160e11b8152600401610407929190611982565b50503560f01c90565b3660006002831015611266578383604051635840c5b160e11b8152600401610407929190611982565b61127383600281876119b1565b915091505b9250929050565b60408051606081018252600080825260208201819052918101829052906112a8848401856119db565b604084015290506112c4816001600160401b03604082901c1691565b6001600160401b0390811660208501521682525092915050565b634e487b7160e01b600052604160045260246000fd5b80356001600160401b038116811461130b57600080fd5b919050565b60008083601f84011261132257600080fd5b5081356001600160401b0381111561133957600080fd5b6020830191508360208260051b850101111561127857600080fd5b600080600083850360c081121561136a57600080fd5b60a081121561137857600080fd5b5060405160a081016001600160401b0382821081831117156113aa57634e487b7160e01b600052604160045260246000fd5b816040526113b7876112f4565b83526113c5602088016112f4565b60208401526113d6604088016112f4565b6040840152606087013560608401526080870135608084015282955060a087013592508083111561140657600080fd5b505061141486828701611310565b9497909650939450505050565b60008060006060848603121561143657600080fd5b61143f846112f4565b925061144d602085016112f4565b915061145b604085016112f4565b90509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561149c57835183529284019291840191600101611480565b50909695505050505050565b6000602082840312156114ba57600080fd5b5035919050565b600080600080606085870312156114d757600080fd5b6114e0856112f4565b93506114ee602086016112f4565b925060408501356001600160401b0381111561150957600080fd5b61151587828801611310565b95989497509550505050565b60006020828403121561153357600080fd5b6105d4826112f4565b81516001600160401b039081168252602080840151909116908201526040808301519082015260608101610667565b60008060006040848603121561158057600080fd5b611589846112f4565b925060208401356001600160401b038111156115a457600080fd5b61141486828701611310565b60005b838110156115cb5781810151838201526020016115b3565b50506000910152565b600081518084526115ec8160208601602086016115b0565b601f01601f19169290920160200192915050565b6020815260006105d460208301846115d4565b6000806040838503121561162657600080fd5b61162f836112f4565b915061163d602084016112f4565b90509250929050565b6000806020838503121561165957600080fd5b82356001600160401b038082111561167057600080fd5b818501915085601f83011261168457600080fd5b81358181111561169357600080fd5b8660208285010111156116a557600080fd5b60209290920196919550909350505050565b80356001600160a01b038116811461130b57600080fd5b60008082840360808112156116e257600080fd5b6116eb846116b7565b92506060601f19820112156116ff57600080fd5b50604051606081018181106001600160401b038211171561173057634e487b7160e01b600052604160045260246000fd5b60405261173f602085016112f4565b815261174d604085016112f4565b60208201526060939093013560408401525092909150565b6000806000806060858703121561177b57600080fd5b611784856112f4565b93506020850135925060408501356001600160401b0381111561150957600080fd5b634e487b7160e01b600052601160045260246000fd5b6001600160401b0382811682821603908082111561082c5761082c6117a6565b634e487b7160e01b600052603260045260246000fd5b60006001600160401b0380831681810361180e5761180e6117a6565b6001019392505050565b6001600160a01b0384168152602080820184905282516001600160401b0390811660408085019190915291840151166060830152820151608082015260a0810161038a565b81810381811115610667576106676117a6565b80820180821115610667576106676117a6565b60006020828403121561189557600080fd5b6105d4826116b7565b60006001600160401b0380861683528085166020840152506060604083015261060660608301846115d4565b6000600182016118dc576118dc6117a6565b5060010190565b83815260406020808301829052908201839052600090849060608401835b8681101561192d576001600160a01b0361191a856116b7565b1682529282019290820190600101611901565b50979650505050505050565b60006020828403121561194b57600080fd5b5051919050565b61ffff60f01b8360f01b168152600082516119748160028501602087016115b0565b919091016002019392505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b600080858511156119c157600080fd5b838611156119ce57600080fd5b5050820193919092039150565b600080604083850312156119ee57600080fd5b82356001600160801b0381168114611a0557600080fd5b94602093909301359350505056fea26469706673582212202b48e2cdc8c436bb57dd8dce706e3103d8bc8ccfdffaf019732d9d17e5e86dee64736f6c63430008140033
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.