Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 16 from a total of 16 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Interchain Execu... | 5882989 | 246 days ago | IN | 0 ETH | 0.00010374 | ||||
Interchain Execu... | 5877121 | 247 days ago | IN | 0 ETH | 0.00009072 | ||||
Interchain Execu... | 5877096 | 247 days ago | IN | 0 ETH | 0.00009979 | ||||
Interchain Execu... | 5876140 | 247 days ago | IN | 0 ETH | 0.00026202 | ||||
Interchain Execu... | 5876023 | 247 days ago | IN | 0 ETH | 0.0002463 | ||||
Interchain Execu... | 5875389 | 247 days ago | IN | 0 ETH | 0.00010387 | ||||
Interchain Execu... | 5875388 | 247 days ago | IN | 0 ETH | 0.00009085 | ||||
Interchain Execu... | 5875112 | 247 days ago | IN | 0 ETH | 0.00009089 | ||||
Interchain Execu... | 5875016 | 247 days ago | IN | 0 ETH | 0.00009077 | ||||
Interchain Execu... | 5871111 | 248 days ago | IN | 0 ETH | 0.00003695 | ||||
Interchain Execu... | 5871089 | 248 days ago | IN | 0 ETH | 0.00003695 | ||||
Interchain Execu... | 5870585 | 248 days ago | IN | 0 ETH | 0.00006224 | ||||
Interchain Execu... | 5869848 | 248 days ago | IN | 0 ETH | 0.00009076 | ||||
Interchain Execu... | 5869836 | 248 days ago | IN | 0 ETH | 0.00026206 | ||||
Interchain Execu... | 5868980 | 248 days ago | IN | 0 ETH | 0.00060436 | ||||
Set Linked Clien... | 5847992 | 252 days ago | IN | 0 ETH | 0.00282884 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
5882977 | 246 days ago | 0.00000052 ETH | ||||
5882977 | 246 days ago | 0.0000001 ETH | ||||
5882977 | 246 days ago | 0.00000062 ETH | ||||
5877109 | 247 days ago | 0.0000005 ETH | ||||
5877109 | 247 days ago | 0.0000001 ETH | ||||
5877109 | 247 days ago | 0.0000006 ETH | ||||
5877086 | 247 days ago | 0.0000005 ETH | ||||
5877086 | 247 days ago | 0.0000001 ETH | ||||
5877086 | 247 days ago | 0.0000006 ETH | ||||
5876140 | 247 days ago | 0.0000005 ETH | ||||
5876140 | 247 days ago | 0.0000001 ETH | ||||
5876140 | 247 days ago | 0.0000006 ETH | ||||
5876128 | 247 days ago | 0.0000005 ETH | ||||
5876128 | 247 days ago | 0.0000001 ETH | ||||
5876128 | 247 days ago | 0.0000006 ETH | ||||
5876023 | 247 days ago | 0.0000005 ETH | ||||
5876023 | 247 days ago | 0.0000001 ETH | ||||
5876023 | 247 days ago | 0.0000006 ETH | ||||
5876011 | 247 days ago | 0.0000005 ETH | ||||
5876011 | 247 days ago | 0.0000001 ETH | ||||
5876011 | 247 days ago | 0.0000006 ETH | ||||
5875380 | 247 days ago | 0.00000052 ETH | ||||
5875380 | 247 days ago | 0.0000001 ETH | ||||
5875380 | 247 days ago | 0.00000062 ETH | ||||
5875375 | 247 days ago | 0.0000005 ETH |
Loading...
Loading
Contract Name:
InterchainClientV1
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 {InterchainClientV1Events} from "./events/InterchainClientV1Events.sol"; import {IExecutionService} from "./interfaces/IExecutionService.sol"; import {IInterchainApp} from "./interfaces/IInterchainApp.sol"; import {IInterchainClientV1} from "./interfaces/IInterchainClientV1.sol"; import {IInterchainDB} from "./interfaces/IInterchainDB.sol"; import {AppConfigV1, AppConfigLib, APP_CONFIG_GUARD_DISABLED, APP_CONFIG_GUARD_DEFAULT} from "./libs/AppConfig.sol"; import {BatchingV1Lib} from "./libs/BatchingV1.sol"; import {InterchainBatch, BATCH_UNVERIFIED, BATCH_CONFLICT} from "./libs/InterchainBatch.sol"; import { InterchainTransaction, InterchainTxDescriptor, InterchainTransactionLib } from "./libs/InterchainTransaction.sol"; import {OptionsLib, OptionsV1} from "./libs/Options.sol"; import {TypeCasts} from "./libs/TypeCasts.sol"; import {VersionedPayloadLib} from "./libs/VersionedPayload.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; /** * @title InterchainClientV1 * @dev Implements the operations of the Interchain Execution Layer. */ contract InterchainClientV1 is Ownable, InterchainClientV1Events, IInterchainClientV1 { using AppConfigLib for bytes; using OptionsLib for bytes; using TypeCasts for address; using TypeCasts for bytes32; using VersionedPayloadLib for bytes; /// @notice Version of the InterchainClient contract. Sent and received transactions must have the same version. uint16 public constant CLIENT_VERSION = 1; /// @notice Address of the InterchainDB contract, set at the time of deployment. address public immutable INTERCHAIN_DB; /// @notice Address of the Guard module used to verify the validity of batches. /// Note: batches marked as invalid by the Guard could not be used for message execution, /// if the app opts in to use the Guard. address public defaultGuard; /// @dev Address of the InterchainClient contract on the remote chain mapping(uint64 chainId => bytes32 remoteClient) internal _linkedClient; /// @dev Executor address that completed the transaction. Address(0) if not executed yet. mapping(bytes32 transactionId => address executor) internal _txExecutor; constructor(address interchainDB, address owner_) Ownable(owner_) { INTERCHAIN_DB = interchainDB; } // @inheritdoc IInterchainClientV1 function setDefaultGuard(address guard) external onlyOwner { if (guard == address(0)) { revert InterchainClientV1__GuardZeroAddress(); } defaultGuard = guard; emit DefaultGuardSet(guard); } // @inheritdoc IInterchainClientV1 function setLinkedClient(uint64 chainId, bytes32 client) external onlyOwner { _linkedClient[chainId] = client; emit LinkedClientSet(chainId, client); } // @inheritdoc IInterchainClientV1 function interchainSend( uint64 dstChainId, bytes32 receiver, address srcExecutionService, address[] calldata srcModules, bytes calldata options, bytes calldata message ) external payable returns (InterchainTxDescriptor memory desc) { return _interchainSend(dstChainId, receiver, srcExecutionService, srcModules, options, message); } // @inheritdoc IInterchainClientV1 function interchainSendEVM( uint64 dstChainId, address receiver, address srcExecutionService, address[] calldata srcModules, bytes calldata options, bytes calldata message ) external payable returns (InterchainTxDescriptor memory desc) { bytes32 receiverBytes32 = receiver.addressToBytes32(); return _interchainSend(dstChainId, receiverBytes32, srcExecutionService, srcModules, options, message); } // @inheritdoc IInterchainClientV1 function interchainExecute( uint256 gasLimit, bytes calldata transaction, bytes32[] calldata proof ) external payable { InterchainTransaction memory icTx = _assertCorrectTransaction(transaction); bytes32 transactionId = keccak256(transaction); _assertExecutable(icTx, transactionId, proof); _txExecutor[transactionId] = msg.sender; OptionsV1 memory decodedOptions = icTx.options.decodeOptionsV1(); if (msg.value != decodedOptions.gasAirdrop) { revert InterchainClientV1__MsgValueMismatch(msg.value, decodedOptions.gasAirdrop); } // We should always use at least as much as the requested gas limit. // The executor can specify a higher gas limit if they wanted. if (decodedOptions.gasLimit > gasLimit) gasLimit = decodedOptions.gasLimit; // Check the the Executor has provided big enough gas limit for the whole transaction. uint256 gasLeft = gasleft(); if (gasLeft <= gasLimit) { revert InterchainClientV1__GasLeftBelowMin(gasLeft, gasLimit); } // Pass the full msg.value to the app: we have already checked that it matches the requested gas airdrop. IInterchainApp(icTx.dstReceiver.bytes32ToAddress()).appReceive{gas: gasLimit, value: msg.value}({ srcChainId: icTx.srcChainId, sender: icTx.srcSender, dbNonce: icTx.dbNonce, entryIndex: icTx.entryIndex, message: icTx.message }); emit InterchainTransactionReceived( transactionId, icTx.dbNonce, icTx.entryIndex, icTx.srcChainId, icTx.srcSender, icTx.dstReceiver ); } /// @inheritdoc IInterchainClientV1 function writeExecutionProof(bytes32 transactionId) external returns (uint64 dbNonce, uint64 entryIndex) { address executor = _txExecutor[transactionId]; if (executor == address(0)) { revert InterchainClientV1__TxNotExecuted(transactionId); } bytes memory proof = abi.encode(transactionId, executor); (dbNonce, entryIndex) = IInterchainDB(INTERCHAIN_DB).writeEntry(keccak256(proof)); emit ExecutionProofWritten(transactionId, dbNonce, entryIndex, executor); } // ═══════════════════════════════════════════════════ VIEWS ═══════════════════════════════════════════════════════ // @inheritdoc IInterchainClientV1 function isExecutable(bytes calldata encodedTx, bytes32[] calldata proof) external view returns (bool) { InterchainTransaction memory icTx = _assertCorrectTransaction(encodedTx); // Check that options could be decoded icTx.options.decodeOptionsV1(); bytes32 transactionId = keccak256(encodedTx); _assertExecutable(icTx, transactionId, proof); return true; } // @inheritdoc IInterchainClientV1 // solhint-disable-next-line code-complexity function getTxReadinessV1( InterchainTransaction memory icTx, bytes32[] calldata proof ) external view returns (TxReadiness status, bytes32 firstArg, bytes32 secondArg) { bytes memory encodedTx = encodeTransaction(icTx); try this.isExecutable(encodedTx, proof) returns (bool) { return (TxReadiness.Ready, 0, 0); } catch (bytes memory errorData) { bytes4 selector; (selector, firstArg, secondArg) = _decodeRevertData(errorData); if (selector == InterchainClientV1__TxAlreadyExecuted.selector) { status = TxReadiness.AlreadyExecuted; } else if (selector == InterchainClientV1__ResponsesAmountBelowMin.selector) { status = TxReadiness.BatchAwaitingResponses; } else if (selector == InterchainClientV1__BatchConflict.selector) { status = TxReadiness.BatchConflict; } else if (selector == InterchainClientV1__ReceiverNotICApp.selector) { status = TxReadiness.ReceiverNotICApp; } else if (selector == InterchainClientV1__ReceiverZeroRequiredResponses.selector) { status = TxReadiness.ReceiverZeroRequiredResponses; } else if (selector == InterchainClientV1__DstChainIdNotLocal.selector) { status = TxReadiness.TxWrongDstChainId; } else { status = TxReadiness.UndeterminedRevert; firstArg = 0; secondArg = 0; } } } // @inheritdoc IInterchainClientV1 function getExecutor(bytes calldata encodedTx) external view returns (address) { return _txExecutor[keccak256(encodedTx)]; } // @inheritdoc IInterchainClientV1 function getExecutorById(bytes32 transactionId) external view returns (address) { return _txExecutor[transactionId]; } // @inheritdoc IInterchainClientV1 function getInterchainFee( uint64 dstChainId, address srcExecutionService, address[] calldata srcModules, bytes calldata options, uint256 messageLen ) external view returns (uint256 fee) { _assertLinkedClient(dstChainId); if (srcExecutionService == address(0)) { revert InterchainClientV1__ExecutionServiceZeroAddress(); } // Check that options could be decoded on destination chain options.decodeOptionsV1(); // Verification fee from InterchainDB fee = IInterchainDB(INTERCHAIN_DB).getInterchainFee(dstChainId, srcModules); // Add execution fee from ExecutionService uint256 payloadSize = InterchainTransactionLib.payloadSize(options.length, messageLen); fee += IExecutionService(srcExecutionService).getExecutionFee(dstChainId, payloadSize, options); } /// @inheritdoc IInterchainClientV1 function getLinkedClient(uint64 chainId) external view returns (bytes32) { if (chainId == block.chainid) { revert InterchainClientV1__ChainIdNotRemote(chainId); } return _linkedClient[chainId]; } /// @inheritdoc IInterchainClientV1 function getLinkedClientEVM(uint64 chainId) external view returns (address linkedClientEVM) { if (chainId == block.chainid) { revert InterchainClientV1__ChainIdNotRemote(chainId); } bytes32 linkedClient = _linkedClient[chainId]; linkedClientEVM = linkedClient.bytes32ToAddress(); // Check that the linked client address fits into the EVM address space if (linkedClientEVM.addressToBytes32() != linkedClient) { revert InterchainClientV1__LinkedClientNotEVM(linkedClient); } } /// @notice Decodes the encoded options data into a OptionsV1 struct. function decodeOptions(bytes memory encodedOptions) external view returns (OptionsV1 memory) { return encodedOptions.decodeOptionsV1(); } /// @notice Gets the V1 app config and trusted modules for the receiving app. function getAppReceivingConfigV1(address receiver) public view returns (AppConfigV1 memory config, address[] memory modules) { // First, check that receiver is a contract if (receiver.code.length == 0) { revert InterchainClientV1__ReceiverNotICApp(receiver); } // Then, use a low-level static call to get the config and modules (bool success, bytes memory returnData) = receiver.staticcall(abi.encodeCall(IInterchainApp.getReceivingConfig, ())); if (!success || returnData.length == 0) { revert InterchainClientV1__ReceiverNotICApp(receiver); } bytes memory encodedConfig; (encodedConfig, modules) = abi.decode(returnData, (bytes, address[])); config = encodedConfig.decodeAppConfigV1(); } /// @notice Encodes the transaction data into a bytes format. function encodeTransaction(InterchainTransaction memory icTx) public pure returns (bytes memory) { return VersionedPayloadLib.encodeVersionedPayload({ version: CLIENT_VERSION, payload: InterchainTransactionLib.encodeTransaction(icTx) }); } // ═════════════════════════════════════════════════ INTERNAL ══════════════════════════════════════════════════════ /// @dev Internal logic for sending a message to another chain. function _interchainSend( uint64 dstChainId, bytes32 receiver, address srcExecutionService, address[] calldata srcModules, bytes calldata options, bytes calldata message ) internal returns (InterchainTxDescriptor memory desc) { _assertLinkedClient(dstChainId); if (receiver == 0) { revert InterchainClientV1__ReceiverZeroAddress(); } if (srcExecutionService == address(0)) { revert InterchainClientV1__ExecutionServiceZeroAddress(); } // Check that options could be decoded on destination chain options.decodeOptionsV1(); uint256 verificationFee = IInterchainDB(INTERCHAIN_DB).getInterchainFee(dstChainId, srcModules); if (msg.value < verificationFee) { revert InterchainClientV1__FeeAmountBelowMin(msg.value, verificationFee); } (desc.dbNonce, desc.entryIndex) = IInterchainDB(INTERCHAIN_DB).getNextEntryIndex(); InterchainTransaction memory icTx = InterchainTransactionLib.constructLocalTransaction({ srcSender: msg.sender, dstReceiver: receiver, dstChainId: dstChainId, dbNonce: desc.dbNonce, entryIndex: desc.entryIndex, options: options, message: message }); desc.transactionId = keccak256(encodeTransaction(icTx)); // Sanity check: nonce returned from DB should match the nonce used to construct the transaction { (uint64 dbNonce, uint64 entryIndex) = IInterchainDB(INTERCHAIN_DB).writeEntryWithVerification{ value: verificationFee }(icTx.dstChainId, desc.transactionId, srcModules); assert(dbNonce == desc.dbNonce && entryIndex == desc.entryIndex); } uint256 executionFee; unchecked { executionFee = msg.value - verificationFee; } IExecutionService(srcExecutionService).requestTxExecution{value: executionFee}({ dstChainId: icTx.dstChainId, txPayloadSize: InterchainTransactionLib.payloadSize(options.length, message.length), transactionId: desc.transactionId, options: options }); emit InterchainTransactionSent( desc.transactionId, icTx.dbNonce, icTx.entryIndex, icTx.dstChainId, icTx.srcSender, icTx.dstReceiver, verificationFee, executionFee, icTx.options, icTx.message ); } // ══════════════════════════════════════════════ INTERNAL VIEWS ═══════════════════════════════════════════════════ /// @dev Asserts that the transaction is executable. function _assertExecutable( InterchainTransaction memory icTx, bytes32 transactionId, bytes32[] calldata proof ) internal view { bytes32 linkedClient = _assertLinkedClient(icTx.srcChainId); if (_txExecutor[transactionId] != address(0)) { revert InterchainClientV1__TxAlreadyExecuted(transactionId); } // Construct expected batch based on interchain transaction data InterchainBatch memory batch = InterchainBatch({ srcChainId: icTx.srcChainId, dbNonce: icTx.dbNonce, batchRoot: BatchingV1Lib.getBatchRoot({ srcWriter: linkedClient, dataHash: transactionId, entryIndex: icTx.entryIndex, proof: proof }) }); address receiver = icTx.dstReceiver.bytes32ToAddress(); (AppConfigV1 memory appConfig, address[] memory approvedModules) = getAppReceivingConfigV1(receiver); if (appConfig.requiredResponses == 0) { revert InterchainClientV1__ReceiverZeroRequiredResponses(receiver); } // Verify against the Guard if the app opts in to use it _assertNoGuardConflict(_getGuard(appConfig), batch); uint256 finalizedResponses = _getFinalizedResponsesCount(approvedModules, batch, appConfig.optimisticPeriod); if (finalizedResponses < appConfig.requiredResponses) { revert InterchainClientV1__ResponsesAmountBelowMin(finalizedResponses, appConfig.requiredResponses); } } /// @dev Asserts that the chain is linked and returns the linked client address. function _assertLinkedClient(uint64 chainId) internal view returns (bytes32 linkedClient) { if (chainId == block.chainid) { revert InterchainClientV1__ChainIdNotRemote(chainId); } linkedClient = _linkedClient[chainId]; if (linkedClient == 0) { revert InterchainClientV1__ChainIdNotLinked(chainId); } } /// @dev Asserts that the Guard has not submitted a conflicting batch. function _assertNoGuardConflict(address guard, InterchainBatch memory batch) internal view { if (guard != address(0)) { uint256 confirmedAt = IInterchainDB(INTERCHAIN_DB).checkBatchVerification(guard, batch); if (confirmedAt == BATCH_CONFLICT) { revert InterchainClientV1__BatchConflict(guard); } } } /// @dev Returns the Guard address to use for the given app config. function _getGuard(AppConfigV1 memory appConfig) internal view returns (address) { if (appConfig.guardFlag == APP_CONFIG_GUARD_DISABLED) { return address(0); } if (appConfig.guardFlag == APP_CONFIG_GUARD_DEFAULT) { return defaultGuard; } return appConfig.guard; } /// @dev Counts the number of finalized responses for the given batch. /// Note: Reverts if a conflicting batch has been verified by any of the approved modules. function _getFinalizedResponsesCount( address[] memory approvedModules, InterchainBatch memory batch, uint256 optimisticPeriod ) internal view returns (uint256 finalizedResponses) { for (uint256 i = 0; i < approvedModules.length; ++i) { address module = approvedModules[i]; uint256 confirmedAt = IInterchainDB(INTERCHAIN_DB).checkBatchVerification(module, batch); // No-op if the module has not verified anything with the same batch key if (confirmedAt == BATCH_UNVERIFIED) { continue; } // Revert if the module has verified a conflicting batch with the same batch key if (confirmedAt == BATCH_CONFLICT) { revert InterchainClientV1__BatchConflict(module); } // The module has verified this exact batch, check if optimistic period has passed if (confirmedAt + optimisticPeriod < block.timestamp) { unchecked { ++finalizedResponses; } } } } /// @dev Asserts that the transaction version is correct and that the transaction is for the current chain. /// Note: returns the decoded transaction for chaining purposes. function _assertCorrectTransaction(bytes calldata versionedTx) internal view returns (InterchainTransaction memory icTx) { uint16 version = versionedTx.getVersion(); if (version != CLIENT_VERSION) { revert InterchainClientV1__TxVersionMismatch(version, CLIENT_VERSION); } icTx = InterchainTransactionLib.decodeTransaction(versionedTx.getPayload()); if (icTx.dstChainId != block.chainid) { revert InterchainClientV1__DstChainIdNotLocal(icTx.dstChainId); } } // solhint-disable no-inline-assembly /// @dev Decodes the revert data into a selector and two arguments. /// Zero values are returned if the revert data is not long enough. /// Note: this is only used in `getTxReadinessV1` to decode the revert data, /// so usage of assembly is not a security risk. function _decodeRevertData(bytes memory revertData) internal pure returns (bytes4 selector, bytes32 firstArg, bytes32 secondArg) { // The easiest way to load the bytes chunks onto the stack is to use assembly. // Each time we try to load a value, we check if the revert data is long enough. // We add 0x20 to skip the length field of the revert data. if (revertData.length >= 4) { // Load the first 32 bytes, then apply the mask that has only the 4 highest bytes set. // There is no need to shift, as `bytesN` variables are right-aligned. // https://github.com/ProjectOpenSea/seaport/blob/2ff6ea37/contracts/helpers/SeaportRouter.sol#L161-L175 selector = bytes4(0xFFFFFFFF); assembly { selector := and(mload(add(revertData, 0x20)), selector) } } if (revertData.length >= 36) { // Skip the length field + selector to get the 32 bytes of the first argument. assembly { firstArg := mload(add(revertData, 0x24)) } } if (revertData.length >= 68) { // Skip the length field + selector + first argument to get the 32 bytes of the second argument. assembly { secondArg := mload(add(revertData, 0x44)) } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; abstract contract InterchainClientV1Events { /// @notice Emitted when the Guard module is set. /// @param guard The address of the Guard module. event DefaultGuardSet(address guard); /// @notice Emitted when the InterchainClientV1 deployment on a remote chain is linked. /// @param chainId The chain ID of the remote chain. /// @param client The address of the InterchainClientV1 deployment on the remote chain. event LinkedClientSet(uint64 chainId, bytes32 client); /// @notice Emitted when a new interchain transaction is sent through the InterchainClientV1. /// The Receiver on the destination chain will receive the specified message once the transaction is executed. /// @param transactionId The unique identifier of the interchain transaction. /// @param dbNonce The nonce of batch containing the transaction's DB entry. /// @param entryIndex The index of the transaction's DB entry in the batch. /// @param dstChainId The chain ID of the destination chain. /// @param srcSender The sender of the transaction on the source chain. /// @param dstReceiver The receiver of the transaction on the destination chain. /// @param verificationFee The fee paid to verify the batch on the destination chain. /// @param executionFee The fee paid to execute the transaction on the destination chain. /// @param options The execution options for the transaction. /// @param message The payload of the message being sent. event InterchainTransactionSent( bytes32 indexed transactionId, uint64 dbNonce, uint64 entryIndex, uint64 dstChainId, bytes32 indexed srcSender, bytes32 indexed dstReceiver, uint256 verificationFee, uint256 executionFee, bytes options, bytes message ); /// @notice Emitted when an interchain transaction is received by the InterchainClientV1. /// The Receiver on the destination chain has just received the message sent from the source chain. /// @param transactionId The unique identifier of the interchain transaction. /// @param dbNonce The nonce of batch containing the transaction's DB entry. /// @param entryIndex The index of the transaction's DB entry in the batch. /// @param srcChainId The chain ID of the source chain. /// @param srcSender The sender of the transaction on the source chain. /// @param dstReceiver The receiver of the transaction on the destination chain. event InterchainTransactionReceived( bytes32 indexed transactionId, uint64 dbNonce, uint64 entryIndex, uint64 srcChainId, bytes32 indexed srcSender, bytes32 indexed dstReceiver ); /// @notice Emitted when the proof of execution is written to InterchainDB. This allows the source chain /// to verify that the transaction was executed by a specific executor, if necessary. /// @param transactionId The unique identifier of the interchain transaction. /// @param dbNonce The nonce of batch containing the written proof's DB entry. /// @param entryIndex The index of the written proof's DB entry in the batch. /// @param executor The address of the executor that completed the transaction. event ExecutionProofWritten( bytes32 indexed transactionId, uint64 dbNonce, uint64 entryIndex, address indexed executor ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IExecutionService { /// @notice Request the execution of an Interchain Transaction on a remote chain in exchange for /// the execution fee, attached to the transaction as `msg.value`. /// Note: the off-chain actor needs to fetch the transaction payload from the InterchainClient /// event with the same transactionId, then execute the transaction on the remote chain: /// `dstInterchainClient.executeTransaction(transactionPayload)` /// @dev Could only be called by `InterchainClient` contracts. /// Will revert if the execution fee is not big enough. /// @param dstChainId The chain id of the destination chain. /// @param txPayloadSize The size of the transaction payload to use for the execution. /// @param transactionId The id of the transaction to execute. /// @param options The options to use for the execution. function requestTxExecution( uint64 dstChainId, uint256 txPayloadSize, bytes32 transactionId, bytes memory options ) external payable; /// @notice Get the address of the EOA account that will be used to execute transactions on the /// remote chains. function executorEOA() external view returns (address); /// @notice Get the execution fee for executing an Interchain Transaction on a remote chain. /// @param dstChainId The chain id of the destination chain. /// @param txPayloadSize The size of the transaction payload to use for the execution. /// @param options The options to use for the execution. function getExecutionFee( uint64 dstChainId, uint256 txPayloadSize, bytes memory options ) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @notice Minimal interface for the Interchain App to work with the Interchain Client. interface IInterchainApp { /// @notice Allows the Interchain Client to pass the message to the Interchain App. /// @dev App is responsible for keeping track of interchain clients, and must verify the message sender. /// @param srcChainId Chain ID of the source chain, where the message was sent from. /// @param sender Sender address on the source chain, as a bytes32 value. /// @param dbNonce The Interchain DB nonce of the batch containing the message entry. /// @param entryIndex The index of the message entry within the batch. /// @param message The message being sent. function appReceive( uint64 srcChainId, bytes32 sender, uint64 dbNonce, uint64 entryIndex, bytes calldata message ) external payable; /// @notice Returns the verification configuration of the Interchain App. /// @dev This configuration is used by the Interchain Client to verify that message has been confirmed /// by the Interchain Modules on the destination chain. /// Note: V1 version of AppConfig includes the required responses count, and optimistic period after which /// the message is considered confirmed by the module. Following versions may include additional fields. /// @return appConfig The versioned configuration of the Interchain App, encoded as bytes. /// @return modules The list of Interchain Modules that app is trusting to confirm the messages. function getReceivingConfig() external view returns (bytes memory appConfig, address[] memory modules); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {InterchainTransaction, InterchainTxDescriptor} from "../libs/InterchainTransaction.sol"; interface IInterchainClientV1 { enum TxReadiness { Ready, AlreadyExecuted, BatchAwaitingResponses, BatchConflict, ReceiverNotICApp, ReceiverZeroRequiredResponses, TxWrongDstChainId, UndeterminedRevert } error InterchainClientV1__BatchConflict(address module); error InterchainClientV1__ChainIdNotLinked(uint64 chainId); error InterchainClientV1__ChainIdNotRemote(uint64 chainId); error InterchainClientV1__DstChainIdNotLocal(uint64 chainId); error InterchainClientV1__ExecutionServiceZeroAddress(); error InterchainClientV1__FeeAmountBelowMin(uint256 feeAmount, uint256 minRequired); error InterchainClientV1__GasLeftBelowMin(uint256 gasLeft, uint256 minRequired); error InterchainClientV1__GuardZeroAddress(); error InterchainClientV1__LinkedClientNotEVM(bytes32 client); error InterchainClientV1__MsgValueMismatch(uint256 msgValue, uint256 required); error InterchainClientV1__ReceiverNotICApp(address receiver); error InterchainClientV1__ReceiverZeroAddress(); error InterchainClientV1__ReceiverZeroRequiredResponses(address receiver); error InterchainClientV1__ResponsesAmountBelowMin(uint256 responsesAmount, uint256 minRequired); error InterchainClientV1__TxAlreadyExecuted(bytes32 transactionId); error InterchainClientV1__TxNotExecuted(bytes32 transactionId); error InterchainClientV1__TxVersionMismatch(uint16 txVersion, uint16 required); /// @notice Allows the contract owner to set the address of the Guard module. /// Note: batches marked as invalid by the Guard could not be used for message execution, /// if the app opts in to use the Guard. /// @param guard_ The address of the Guard module. function setDefaultGuard(address guard_) external; /** * @notice Sets the linked client for a specific chain ID. * @dev Stores the address of the linked client in a mapping with the chain ID as the key. * @param chainId The chain ID for which the client is being set. * @param client The address of the client being linked. */ function setLinkedClient(uint64 chainId, bytes32 client) external; /** * @notice Sends a message to another chain via the Interchain Communication Protocol. * @dev Charges a fee for the message, which is payable upon calling this function: * - Verification fees: paid to every module that verifies the message. * - Execution fee: paid to the executor that executes the message. * Note: while a specific execution service is specified to request the execution of the message, * any executor is able to execute the message on destination chain, earning the execution fee. * @param dstChainId The chain ID of the destination chain. * @param receiver The address of the receiver on the destination chain. * @param srcExecutionService The address of the execution service to use for the message. * @param srcModules The source modules involved in the message sending. * @param options Execution options for the message sent, encoded as bytes, currently gas limit + native gas drop. * @param message The message being sent. * @return desc The descriptor of the sent transaction: * - transactionId: the ID of the transaction that was sent. * - dbNonce: the database nonce of the batch containing the written entry for transaction. * - entryIndex: the index of the written entry for transaction within the batch. */ function interchainSend( uint64 dstChainId, bytes32 receiver, address srcExecutionService, address[] calldata srcModules, bytes calldata options, bytes calldata message ) external payable returns (InterchainTxDescriptor memory desc); function interchainSendEVM( uint64 dstChainId, address receiver, address srcExecutionService, address[] calldata srcModules, bytes calldata options, bytes calldata message ) external payable returns (InterchainTxDescriptor memory desc); /** * @notice Executes a transaction that has been sent via the Interchain. * @dev The transaction must have been previously sent and recorded. * Transaction data includes the requested gas limit, but the executors could specify a different gas limit. * If the specified gas limit is lower than requested, the requested gas limit will be used. * Otherwise, the specified gas limit will be used. * This allows to execute the transactions with requested gas limit set too low. * @param gasLimit The gas limit to use for the execution. * @param transaction The transaction data. * @param proof The Merkle proof for transaction execution, fetched from the source chain. */ function interchainExecute( uint256 gasLimit, bytes calldata transaction, bytes32[] calldata proof ) external payable; /// @notice Writes the proof of execution for a transaction into the InterchainDB. /// @dev Will revert if the transaction has not been executed. /// @param transactionId The ID of the transaction to write the proof for. /// @return dbNonce The database nonce of the batch containing the written proof for transaction. /// @return entryIndex The index of the written proof for transaction within the batch. function writeExecutionProof(bytes32 transactionId) external returns (uint64 dbNonce, uint64 entryIndex); /** * @notice Checks if a transaction is executable. * @dev Determines if a transaction meets the criteria to be executed based on: * - If approved modules have written to the InterchainDB * - If the threshold of approved modules have been met * - If the optimistic window has passed for all modules * @param transaction The InterchainTransaction struct to be checked. * @param proof The Merkle proof for transaction execution, fetched from the source chain. * @return bool Returns true if the transaction is executable, false otherwise. */ function isExecutable(bytes calldata transaction, bytes32[] calldata proof) external view returns (bool); /// @notice Returns the readiness status of a transaction to be executed. /// @dev Some of the possible statuses have additional arguments that are returned: /// - Ready: the transaction is ready to be executed. /// - AlreadyExecuted: the transaction has already been executed. /// - `firstArg` is the transaction ID. /// - BatchAwaitingResponses: not enough responses have been received for the transaction. /// - `firstArg` is the number of responses received. /// - `secondArg` is the number of responses required. /// - BatchConflict: one of the modules have submitted a conflicting batch. /// - `firstArg` is the address of the module. /// - This is either one of the modules that the app trusts, or the Guard module used by the app. /// - ReceiverNotICApp: the receiver is not an Interchain app. /// - `firstArg` is the receiver address. /// - ReceiverZeroRequiredResponses: the app config requires zero responses for the transaction. /// - TxWrongDstChainId: the destination chain ID does not match the local chain ID. /// - `firstArg` is the destination chain ID. /// - UndeterminedRevert: the transaction will revert for another reason. /// /// Note: the arguments are abi-encoded bytes32 values (as their types could be different). function getTxReadinessV1( InterchainTransaction memory icTx, bytes32[] calldata proof ) external view returns (TxReadiness status, bytes32 firstArg, bytes32 secondArg); /// @notice Returns the fee for sending an Interchain message. /// @param dstChainId The chain ID of the destination chain. /// @param srcExecutionService The address of the execution service to use for the message. /// @param srcModules The source modules involved in the message sending. /// @param options Execution options for the message sent, currently gas limit + native gas drop. /// @param messageLen The length of the message being sent. function getInterchainFee( uint64 dstChainId, address srcExecutionService, address[] calldata srcModules, bytes calldata options, uint256 messageLen ) external view returns (uint256); /// @notice Returns the address of the executor for a transaction that has been sent to the local chain. function getExecutor(bytes calldata transaction) external view returns (address); /// @notice Returns the address of the executor for a transaction that has been sent to the local chain. function getExecutorById(bytes32 transactionId) external view returns (address); /// @notice Returns the address of the linked client (as bytes32) for a specific chain ID. /// @dev Will return 0x0 if no client is linked for the chain ID. function getLinkedClient(uint64 chainId) external view returns (bytes32); /// @notice Returns the EVM address of the linked client for a specific chain ID. /// @dev Will return 0x0 if no client is linked for the chain ID. /// Will revert if the client is not an EVM client. function getLinkedClientEVM(uint64 chainId) external view returns (address); }
// 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.13; import {VersionedPayloadLib} from "./VersionedPayload.sol"; // TODO: all of these could fit into a single 32 bytes slot struct AppConfigV1 { uint256 requiredResponses; uint256 optimisticPeriod; uint256 guardFlag; address guard; } using AppConfigLib for AppConfigV1 global; /// @dev Signals that the app opted out of using any Guard module. uint8 constant APP_CONFIG_GUARD_DISABLED = 0; /// @dev Signals that the app uses the default Guard module provided by InterchainClient contract. uint8 constant APP_CONFIG_GUARD_DEFAULT = 1; /// @dev Signals that the app uses a custom Guard module. uint8 constant APP_CONFIG_GUARD_CUSTOM = 2; library AppConfigLib { using VersionedPayloadLib for bytes; uint16 internal constant APP_CONFIG_V1 = 1; error AppConfigLib__VersionInvalid(uint16 version); /// @notice Decodes app config (V1 or higher) from a bytes format back into an AppConfigV1 struct. /// @param data The app config data in bytes format. function decodeAppConfigV1(bytes memory data) internal view returns (AppConfigV1 memory) { uint16 version = data.getVersionFromMemory(); if (version < APP_CONFIG_V1) { revert AppConfigLib__VersionInvalid(version); } // Structs of the same version will always be decoded correctly. // Following versions will be decoded correctly if they have the same fields as the previous version, // and new fields at the end: abi.decode ignores the extra bytes in the decoded payload. return abi.decode(data.getPayloadFromMemory(), (AppConfigV1)); } /// @notice Encodes V1 app config into a bytes format. /// @param appConfig The AppConfigV1 to encode. function encodeAppConfigV1(AppConfigV1 memory appConfig) internal pure returns (bytes memory) { return VersionedPayloadLib.encodeVersionedPayload(APP_CONFIG_V1, abi.encode(appConfig)); } }
// 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 {MathLib} from "./Math.sol"; import {TypeCasts} from "./TypeCasts.sol"; import {VersionedPayloadLib} from "./VersionedPayload.sol"; import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; type ICTxHeader is uint256; struct InterchainTransaction { uint64 srcChainId; uint64 dstChainId; uint64 dbNonce; uint64 entryIndex; bytes32 srcSender; bytes32 dstReceiver; bytes options; bytes message; } struct InterchainTxDescriptor { bytes32 transactionId; uint64 dbNonce; uint64 entryIndex; } using InterchainTransactionLib for InterchainTransaction global; library InterchainTransactionLib { using MathLib for uint256; using VersionedPayloadLib for bytes; function constructLocalTransaction( address srcSender, uint64 dstChainId, bytes32 dstReceiver, uint64 dbNonce, uint64 entryIndex, bytes memory options, bytes memory message ) internal view returns (InterchainTransaction memory transaction) { return InterchainTransaction({ srcChainId: SafeCast.toUint64(block.chainid), srcSender: TypeCasts.addressToBytes32(srcSender), dstChainId: dstChainId, dstReceiver: dstReceiver, dbNonce: dbNonce, entryIndex: entryIndex, options: options, message: message }); } function encodeTransaction(InterchainTransaction memory transaction) internal pure returns (bytes memory) { return abi.encode( encodeTxHeader(transaction.srcChainId, transaction.dstChainId, transaction.dbNonce, transaction.entryIndex), transaction.srcSender, transaction.dstReceiver, transaction.options, transaction.message ); } function decodeTransaction(bytes calldata transaction) internal pure returns (InterchainTransaction memory icTx) { ICTxHeader header; (header, icTx.srcSender, icTx.dstReceiver, icTx.options, icTx.message) = abi.decode(transaction, (ICTxHeader, bytes32, bytes32, bytes, bytes)); (icTx.srcChainId, icTx.dstChainId, icTx.dbNonce, icTx.entryIndex) = decodeTxHeader(header); } function payloadSize(uint256 optionsLen, uint256 messageLen) internal pure returns (uint256) { // 2 bytes are reserved for the transaction version // + 5 fields * 32 bytes (3 values for static, 2 offsets for dynamic) + 2 * 32 bytes (lengths for dynamic) = 226 // (srcChainId, dstChainId, dbNonce, entryIndex) are merged into a single 32 bytes field // Both options and message are dynamic fields, which are padded up to 32 bytes return 226 + optionsLen.roundUpToWord() + messageLen.roundUpToWord(); } function encodeTxHeader( uint64 srcChainId, uint64 dstChainId, uint64 dbNonce, uint64 entryIndex ) internal pure returns (ICTxHeader) { return ICTxHeader.wrap( (uint256(srcChainId) << 192) | (uint256(dstChainId) << 128) | (uint256(dbNonce) << 64) | uint256(entryIndex) ); } function decodeTxHeader(ICTxHeader header) internal pure returns (uint64 srcChainId, uint64 dstChainId, uint64 dbNonce, uint64 entryIndex) { srcChainId = uint64(ICTxHeader.unwrap(header) >> 192); dstChainId = uint64(ICTxHeader.unwrap(header) >> 128); dbNonce = uint64(ICTxHeader.unwrap(header) >> 64); entryIndex = uint64(ICTxHeader.unwrap(header)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {VersionedPayloadLib} from "./VersionedPayload.sol"; /// @notice Struct to hold V1 of options data. /// @dev Next versions have to use the fields from the previous version and add new fields at the end. /// @param gasLimit The gas limit for the transaction. /// @param gasAirdrop The amount of gas to airdrop. struct OptionsV1 { uint256 gasLimit; uint256 gasAirdrop; } using OptionsLib for OptionsV1 global; /// @title OptionsLib /// @notice A library for encoding and decoding Interchain options related to interchain messages. library OptionsLib { using VersionedPayloadLib for bytes; uint16 internal constant OPTIONS_V1 = 1; error OptionsLib__VersionInvalid(uint16 version); /// @notice Decodes options (V1 or higher) from a bytes format back into an OptionsV1 struct. /// @param data The options data in bytes format. function decodeOptionsV1(bytes memory data) internal view returns (OptionsV1 memory) { uint16 version = data.getVersionFromMemory(); if (version < OPTIONS_V1) { revert OptionsLib__VersionInvalid(version); } // Structs of the same version will always be decoded correctly. // Following versions will be decoded correctly if they have the same fields as the previous version, // and new fields at the end: abi.decode ignores the extra bytes in the decoded payload. return abi.decode(data.getPayloadFromMemory(), (OptionsV1)); } /// @notice Encodes V1 options into a bytes format. /// @param options The OptionsV1 to encode. function encodeOptionsV1(OptionsV1 memory options) internal pure returns (bytes memory) { return VersionedPayloadLib.encodeVersionedPayload(OPTIONS_V1, abi.encode(options)); } }
// 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 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 // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// 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 // 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); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library MathLib { /// @notice Rounds up to the nearest multiple of 32. /// Note: Returns zero on overflows instead of reverting. This is fine for practical /// use cases, as this is used for determining the size of the payload in memory. function roundUpToWord(uint256 x) internal pure returns (uint256) { unchecked { return (x + 31) & ~uint256(31); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
{ "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":"address","name":"interchainDB","type":"address"},{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint16","name":"version","type":"uint16"}],"name":"AppConfigLib__VersionInvalid","type":"error"},{"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"}],"name":"InterchainClientV1__BatchConflict","type":"error"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"InterchainClientV1__ChainIdNotLinked","type":"error"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"InterchainClientV1__ChainIdNotRemote","type":"error"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"InterchainClientV1__DstChainIdNotLocal","type":"error"},{"inputs":[],"name":"InterchainClientV1__ExecutionServiceZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"minRequired","type":"uint256"}],"name":"InterchainClientV1__FeeAmountBelowMin","type":"error"},{"inputs":[{"internalType":"uint256","name":"gasLeft","type":"uint256"},{"internalType":"uint256","name":"minRequired","type":"uint256"}],"name":"InterchainClientV1__GasLeftBelowMin","type":"error"},{"inputs":[],"name":"InterchainClientV1__GuardZeroAddress","type":"error"},{"inputs":[{"internalType":"bytes32","name":"client","type":"bytes32"}],"name":"InterchainClientV1__LinkedClientNotEVM","type":"error"},{"inputs":[{"internalType":"uint256","name":"msgValue","type":"uint256"},{"internalType":"uint256","name":"required","type":"uint256"}],"name":"InterchainClientV1__MsgValueMismatch","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"InterchainClientV1__ReceiverNotICApp","type":"error"},{"inputs":[],"name":"InterchainClientV1__ReceiverZeroAddress","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"InterchainClientV1__ReceiverZeroRequiredResponses","type":"error"},{"inputs":[{"internalType":"uint256","name":"responsesAmount","type":"uint256"},{"internalType":"uint256","name":"minRequired","type":"uint256"}],"name":"InterchainClientV1__ResponsesAmountBelowMin","type":"error"},{"inputs":[{"internalType":"bytes32","name":"transactionId","type":"bytes32"}],"name":"InterchainClientV1__TxAlreadyExecuted","type":"error"},{"inputs":[{"internalType":"bytes32","name":"transactionId","type":"bytes32"}],"name":"InterchainClientV1__TxNotExecuted","type":"error"},{"inputs":[{"internalType":"uint16","name":"txVersion","type":"uint16"},{"internalType":"uint16","name":"required","type":"uint16"}],"name":"InterchainClientV1__TxVersionMismatch","type":"error"},{"inputs":[{"internalType":"uint16","name":"version","type":"uint16"}],"name":"OptionsLib__VersionInvalid","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","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"},{"inputs":[],"name":"VersionedPayload__PrecompileFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"DefaultGuardSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"dbNonce","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"entryIndex","type":"uint64"},{"indexed":true,"internalType":"address","name":"executor","type":"address"}],"name":"ExecutionProofWritten","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"dbNonce","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"entryIndex","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"srcChainId","type":"uint64"},{"indexed":true,"internalType":"bytes32","name":"srcSender","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"dstReceiver","type":"bytes32"}],"name":"InterchainTransactionReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"dbNonce","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"entryIndex","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"dstChainId","type":"uint64"},{"indexed":true,"internalType":"bytes32","name":"srcSender","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"dstReceiver","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"verificationFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"executionFee","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"options","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"InterchainTransactionSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"client","type":"bytes32"}],"name":"LinkedClientSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"CLIENT_VERSION","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INTERCHAIN_DB","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedOptions","type":"bytes"}],"name":"decodeOptions","outputs":[{"components":[{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"gasAirdrop","type":"uint256"}],"internalType":"struct OptionsV1","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultGuard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"srcChainId","type":"uint64"},{"internalType":"uint64","name":"dstChainId","type":"uint64"},{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"entryIndex","type":"uint64"},{"internalType":"bytes32","name":"srcSender","type":"bytes32"},{"internalType":"bytes32","name":"dstReceiver","type":"bytes32"},{"internalType":"bytes","name":"options","type":"bytes"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct InterchainTransaction","name":"icTx","type":"tuple"}],"name":"encodeTransaction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"getAppReceivingConfigV1","outputs":[{"components":[{"internalType":"uint256","name":"requiredResponses","type":"uint256"},{"internalType":"uint256","name":"optimisticPeriod","type":"uint256"},{"internalType":"uint256","name":"guardFlag","type":"uint256"},{"internalType":"address","name":"guard","type":"address"}],"internalType":"struct AppConfigV1","name":"config","type":"tuple"},{"internalType":"address[]","name":"modules","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedTx","type":"bytes"}],"name":"getExecutor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"transactionId","type":"bytes32"}],"name":"getExecutorById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"dstChainId","type":"uint64"},{"internalType":"address","name":"srcExecutionService","type":"address"},{"internalType":"address[]","name":"srcModules","type":"address[]"},{"internalType":"bytes","name":"options","type":"bytes"},{"internalType":"uint256","name":"messageLen","type":"uint256"}],"name":"getInterchainFee","outputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"getLinkedClient","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"getLinkedClientEVM","outputs":[{"internalType":"address","name":"linkedClientEVM","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"srcChainId","type":"uint64"},{"internalType":"uint64","name":"dstChainId","type":"uint64"},{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"entryIndex","type":"uint64"},{"internalType":"bytes32","name":"srcSender","type":"bytes32"},{"internalType":"bytes32","name":"dstReceiver","type":"bytes32"},{"internalType":"bytes","name":"options","type":"bytes"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct InterchainTransaction","name":"icTx","type":"tuple"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"getTxReadinessV1","outputs":[{"internalType":"enum IInterchainClientV1.TxReadiness","name":"status","type":"uint8"},{"internalType":"bytes32","name":"firstArg","type":"bytes32"},{"internalType":"bytes32","name":"secondArg","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"bytes","name":"transaction","type":"bytes"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"interchainExecute","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64","name":"dstChainId","type":"uint64"},{"internalType":"bytes32","name":"receiver","type":"bytes32"},{"internalType":"address","name":"srcExecutionService","type":"address"},{"internalType":"address[]","name":"srcModules","type":"address[]"},{"internalType":"bytes","name":"options","type":"bytes"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"interchainSend","outputs":[{"components":[{"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"entryIndex","type":"uint64"}],"internalType":"struct InterchainTxDescriptor","name":"desc","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64","name":"dstChainId","type":"uint64"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"srcExecutionService","type":"address"},{"internalType":"address[]","name":"srcModules","type":"address[]"},{"internalType":"bytes","name":"options","type":"bytes"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"interchainSendEVM","outputs":[{"components":[{"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"entryIndex","type":"uint64"}],"internalType":"struct InterchainTxDescriptor","name":"desc","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedTx","type":"bytes"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"isExecutable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guard","type":"address"}],"name":"setDefaultGuard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"bytes32","name":"client","type":"bytes32"}],"name":"setLinkedClient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"transactionId","type":"bytes32"}],"name":"writeExecutionProof","outputs":[{"internalType":"uint64","name":"dbNonce","type":"uint64"},{"internalType":"uint64","name":"entryIndex","type":"uint64"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162002ef638038062002ef68339810160408190526200003491620000f0565b806001600160a01b0381166200006457604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200006f8162000083565b50506001600160a01b031660805262000128565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b0381168114620000eb57600080fd5b919050565b600080604083850312156200010457600080fd5b6200010f83620000d3565b91506200011f60208401620000d3565b90509250929050565b608051612d81620001756000396000818161041501528181610a5e01528181610dea01528181611317015281816113bf0152818161152701528181611c720152611d4e0152612d816000f3fe6080604052600436106101355760003560e01c80638da5cb5b116100ab578063d5e788a01161006f578063d5e788a0146103c8578063e4c6124714610403578063f1a61fac14610437578063f2fde38b1461046d578063f3c66e2b1461048d578063f92a79ff146104ad57600080fd5b80638da5cb5b146102fb57806390e810771461031957806394bf49f414610359578063c8cf934814610379578063cbb3c631146103a857600080fd5b806353b67d74116100fd57806353b67d741461023b578063547efb8414610250578063695fd54f14610263578063715018a6146102915780637813cd52146102a65780638654ddd4146102ce57600080fd5b80631450c2811461013a5780632a20521e1461016f5780632e568739146101a757806335c4a191146101d55780633f34448e146101f5575b600080fd5b34801561014657600080fd5b5061015a610155366004611fd8565b6104cd565b60405190151581526020015b60405180910390f35b34801561017b57600080fd5b5060015461018f906001600160a01b031681565b6040516001600160a01b039091168152602001610166565b3480156101b357600080fd5b506101c76101c2366004612063565b61051f565b604051908152602001610166565b3480156101e157600080fd5b5061018f6101f0366004612063565b610576565b610208610203366004612095565b6105f9565b60408051825181526020808401516001600160401b03908116918301919091529282015190921690820152606001610166565b61024e610249366004612168565b610640565b005b61020861025e3660046121e1565b610810565b34801561026f57600080fd5b5061028361027e366004612221565b61084c565b60405161016692919061223e565b34801561029d57600080fd5b5061024e6109a2565b3480156102b257600080fd5b506102bb600181565b60405161ffff9091168152602001610166565b3480156102da57600080fd5b506102ee6102e936600461246c565b6109b6565b60405161016691906124f8565b34801561030757600080fd5b506000546001600160a01b031661018f565b34801561032557600080fd5b5061033961033436600461250b565b6109d1565b604080516001600160401b03938416815292909116602083015201610166565b34801561036557600080fd5b5061024e610374366004612221565b610b2f565b34801561038557600080fd5b50610399610394366004612524565b610bb2565b6040516101669392919061258c565b3480156103b457600080fd5b506101c76103c33660046125c2565b610d60565b3480156103d457600080fd5b506103e86103e336600461265f565b610eff565b60408051825181526020928301519281019290925201610166565b34801561040f57600080fd5b5061018f7f000000000000000000000000000000000000000000000000000000000000000081565b34801561044357600080fd5b5061018f61045236600461250b565b6000908152600360205260409020546001600160a01b031690565b34801561047957600080fd5b5061024e610488366004612221565b610f1c565b34801561049957600080fd5b5061024e6104a8366004612693565b610f5a565b3480156104b957600080fd5b5061018f6104c83660046126bf565b610fba565b6000806104da8686610ffa565b90506104e98160c0015161109b565b50600086866040516104fc929190612700565b604051809103902090506105128282878761110b565b5060019695505050505050565b600046826001600160401b03160361055a57604051636b0dc00560e11b81526001600160401b03831660048201526024015b60405180910390fd5b506001600160401b031660009081526002602052604090205490565b600046826001600160401b0316036105ac57604051636b0dc00560e11b81526001600160401b0383166004820152602401610551565b506001600160401b038116600090815260026020526040902054806001600160a01b03811681146105f35760405163ec3822b160e01b815260048101829052602401610551565b50919050565b60408051606081018252600080825260208201819052918101919091526001600160a01b0389166106318b828b8b8b8b8b8b8b61124d565b9b9a5050505050505050505050565b600061064c8585610ffa565b905060008585604051610660929190612700565b604051809103902090506106768282868661110b565b600081815260036020526040812080546001600160a01b0319163317905560c08301516106a29061109b565b9050806020015134146106d75760208101516040516366f7ba5d60e01b81523460048201526024810191909152604401610551565b80518810156106e557805197505b60005a90508881116107145760405163176b11a760e21b815260048101829052602481018a9052604401610551565b60a08401516001600160a01b0316636e9fd6098a348760000151886080015189604001518a606001518b60e001516040518863ffffffff1660e01b8152600401610762959493929190612710565b6000604051808303818589803b15801561077b57600080fd5b5088f115801561078f573d6000803e3d6000fd5b5050505050508360a001518460800151847f589f737f4049c62fcbcd8274eeacc86e17d29c6621f36e698bcc4c90525ce28f8760400151886060015189600001516040516107fd939291906001600160401b0393841681529183166020830152909116604082015260600190565b60405180910390a4505050505050505050565b604080516060810182526000808252602082018190529181019190915261083e8a8a8a8a8a8a8a8a8a61124d565b9a9950505050505050505050565b610880604051806080016040528060008152602001600081526020016000815260200160006001600160a01b031681525090565b6060826001600160a01b03163b6000036108b857604051630a293ffd60e41b81526001600160a01b0384166004820152602401610551565b60408051600481526024810182526020810180516001600160e01b031663287bc05760e01b179052905160009182916001600160a01b038716916108fb91612755565b600060405180830381855afa9150503d8060008114610936576040519150601f19603f3d011682016040523d82523d6000602084013e61093b565b606091505b509150915081158061094c57508051155b1561097557604051630a293ffd60e41b81526001600160a01b0386166004820152602401610551565b60608180602001905181019061098b9190612771565b9450905061099881611706565b9450505050915091565b6109aa61178f565b6109b460006117bc565b565b60606109cb60016109c68461180c565b6118b0565b92915050565b60008181526003602052604081205481906001600160a01b031680610a0c5760405163e99eb48d60e01b815260048101859052602401610551565b60008482604051602001610a339291909182526001600160a01b0316602082015260400190565b60408051808303601f19018152908290528051602082012063156c638360e11b8352600483015291507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632ad8c7069060240160408051808303816000875af1158015610aae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad29190612885565b604080516001600160401b038085168252831660208201529296509094506001600160a01b0384169187917f1c45fee34c18589980aa86a2b9910fac2a0be9beca86376b6d93fa4ce7f010ae910160405180910390a35050915091565b610b3761178f565b6001600160a01b038116610b5e57604051633184f16960e21b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527fa42a6dc10e430cab5d4ba037ea6d7eee30240c6b6d7dd5b12a3d2acf41e7264f9060200160405180910390a150565b600080600080610bc1876109b6565b604051631450c28160e01b81529091503090631450c28190610beb9084908a908a906004016128bf565b602060405180830381865afa925050508015610c24575060408051601f3d908101601f19168201909252610c2191810190612909565b60015b610d43573d808015610c52576040519150601f19603f3d011682016040523d82523d6000602084013e610c57565b606091505b506000610c63826118dc565b909650945090506327f5146f60e01b6001600160e01b0319821601610c8b5760019550610d3c565b6357761ca160e11b6001600160e01b0319821601610cac5760029550610d3c565b6317c4157360e11b6001600160e01b0319821601610ccd5760039550610d3c565b6305d6c00360e41b6001600160e01b0319821601610cee5760049550610d3c565b6318c9944360e21b6001600160e01b0319821601610d0f5760059550610d3c565b631515fcbb60e01b6001600160e01b0319821601610d305760069550610d3c565b60079550600094508493505b5050610d55565b5060009350839250829150610d579050565b505b93509350939050565b6000610d6b88611924565b506001600160a01b038716610d935760405163146fd3c560e21b815260040160405180910390fd5b610dd284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061109b92505050565b5060405163b8ba4ba160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063b8ba4ba190610e23908b908a908a90600401612974565b602060405180830381865afa158015610e40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6491906129a0565b90506000610e7284846119a5565b604051634b7ed26d60e11b81529091506001600160a01b038916906396fda4da90610ea7908c9085908a908a906004016129e2565b602060405180830381865afa158015610ec4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee891906129a0565b610ef29083612a21565b9998505050505050505050565b60408051808201909152600080825260208201526109cb8261109b565b610f2461178f565b6001600160a01b038116610f4e57604051631e4fbdf760e01b815260006004820152602401610551565b610f57816117bc565b50565b610f6261178f565b6001600160401b038216600081815260026020908152604091829020849055815192835282018390527ffdc2498138df0de25c8fc9bd75bb8e856dac69aaf28d3dd5e0fc48e5e9f6e93f910160405180910390a15050565b6000600360008484604051610fd0929190612700565b60408051918290039091208252602082019290925201600020546001600160a01b03169392505050565b611002611f0d565b600061100e84846119cc565b905061ffff8116600114611042576040516316d8807d60e11b815261ffff8216600482015260016024820152604401610551565b61105461104f85856119fd565b611a3f565b91504682602001516001600160401b03161461109457602082015160405163eaea034560e01b81526001600160401b039091166004820152602401610551565b5092915050565b604080518082019091526000808252602082015260006110ba83611aad565b9050600161ffff821610156110e857604051632b346f3760e01b815261ffff82166004820152602401610551565b6110f183611adf565b8060200190518101906111049190612a34565b9392505050565b600061111a8560000151611924565b6000858152600360205260409020549091506001600160a01b0316156111565760405163d80aeb9160e01b815260048101859052602401610551565b6000604051806060016040528087600001516001600160401b0316815260200187604001516001600160401b0316815260200161119a84888a606001518989611b88565b815250905060006111ac8760a0015190565b90506000806111ba8361084c565b815191935091506000036111ec576040516327366bbd60e21b81526001600160a01b0384166004820152602401610551565b6111fe6111f883611c0f565b85611c49565b600061120f82868560200151611d1f565b8351909150811015611241578251604051632889e35f60e11b8152610551918391600401918252602082015260400190565b50505050505050505050565b60408051606081018252600080825260208201819052918101919091526112738a611924565b506000899003611296576040516330014e4760e21b815260040160405180910390fd5b6001600160a01b0388166112bd5760405163146fd3c560e21b815260040160405180910390fd5b6112fc85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061109b92505050565b5060405163b8ba4ba160e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063b8ba4ba190611350908e908c908c90600401612974565b602060405180830381865afa15801561136d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139191906129a0565b9050803410156113bd5760405163457bf1e160e11b815234600482015260248101829052604401610551565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663aa2f06ae6040518163ffffffff1660e01b81526004016040805180830381865afa15801561141a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143e9190612885565b8360200184604001826001600160401b03166001600160401b0316815250826001600160401b03166001600160401b031681525050506000611507338d8d866020015187604001518c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e4992505050565b9050611512816109b6565b805190602001208360000181815250506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663eb20fbfd85856020015188600001518f8f6040518663ffffffff1660e01b81526004016115809493929190612a82565b604080518083038185885af115801561159d573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906115c29190612885565b9150915084602001516001600160401b0316826001600160401b0316148015611600575084604001516001600160401b0316816001600160401b0316145b61160c5761160c612aab565b5050602081015134839003906001600160a01b038c16906358efb47d9083906116358b8a6119a5565b88516040516001600160e01b031960e087901b16815261165e939291908f908f90600401612ac1565b6000604051808303818588803b15801561167757600080fd5b505af115801561168b573d6000803e3d6000fd5b50505050508160a00151826080015185600001517f73b3ea77e781779ca7d3bd994ecd1ad739e22cda0120925bbf4e30de70ebc7e885604001518660600151876020015189888a60c001518b60e001516040516116ee9796959493929190612af0565b60405180910390a45050509998505050505050505050565b61173a604051806080016040528060008152602001600081526020016000815260200160006001600160a01b031681525090565b600061174583611aad565b9050600161ffff8216101561177357604051635b72a46360e11b815261ffff82166004820152602401610551565b61177c83611adf565b8060200190518101906111049190612b42565b6000546001600160a01b031633146109b45760405163118cdaa760e01b8152336004820152602401610551565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606061187282600001518360200151846040015185606001516001600160c01b031960c085901b1667ffffffffffffffff60801b608085901b16176fffffffffffffffff0000000000000000604084901b16176001600160401b03821617949350505050565b82608001518360a001518460c001518560e0015160405160200161189a959493929190612bad565b6040516020818303038152906040529050919050565b606082826040516020016118c5929190612bf0565b604051602081830303815290604052905092915050565b600080600060048451106118fc5760208401516001600160e01b03191692505b602484511061190d57602484015191505b604484511061191d575060448301515b9193909250565b600046826001600160401b03160361195a57604051636b0dc00560e11b81526001600160401b0383166004820152602401610551565b506001600160401b038116600090815260026020526040812054908190036119a057604051632e3a383760e21b81526001600160401b0383166004820152602401610551565b919050565b6000601f19601f830116601f19601f8501166119c29060e2612a21565b6111049190612a21565b600060028210156119f4578282604051635840c5b160e11b8152600401610551929190612c20565b50503560f01c90565b3660006002831015611a26578383604051635840c5b160e11b8152600401610551929190612c20565b611a338360028187612c34565b915091505b9250929050565b611a47611f0d565b6000611a5583850185612c5e565b60e087015260c086015260a085015260808401529050611a838160c081901c91608082901c91604081901c91565b6001600160401b039081166060870152908116604086015290811660208501521682525092915050565b6000600282511015611ad45781604051635840c5b160e11b815260040161055191906124f8565b506020015160f01c90565b6060600282511015611b065781604051635840c5b160e11b815260040161055191906124f8565b815160011901806001600160401b03811115611b2457611b246122b9565b6040519080825280601f01601f191660200182016040528015611b4e576020820181803683370190505b50915060008160208401836022870160045afa905080611b815760405163080f227d60e11b815260040160405180910390fd5b5050919050565b60006001600160401b03841615611bbd5760405163d9c5be6160e01b81526001600160401b0385166004820152602401610551565b8115611bdc57604051631a9b90c960e11b815260040160405180910390fd5b604080516020808201899052818301889052825180830384018152606090920190925280519101205b9695505050505050565b6040810151600090611c2357506000919050565b604082015160001901611c415750506001546001600160a01b031690565b506060015190565b6001600160a01b03821615611d1b5760405163e39682c160e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063e39682c190611ca99086908690600401612cde565b602060405180830381865afa158015611cc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cea91906129a0565b90506000198103611d195760405163683bea8d60e11b81526001600160a01b0384166004820152602401610551565b505b5050565b6000805b8451811015611e41576000858281518110611d4057611d40612d1c565b6020026020010151905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e39682c183886040518363ffffffff1660e01b8152600401611d9a929190612cde565b602060405180830381865afa158015611db7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ddb91906129a0565b905080611de9575050611e31565b6000198103611e165760405163683bea8d60e11b81526001600160a01b0383166004820152602401610551565b42611e218683612a21565b1015611e2e578360010193505b50505b611e3a81612d32565b9050611d23565b509392505050565b611e51611f0d565b604051806101000160405280611e6646611ed3565b6001600160401b03168152602001886001600160401b03168152602001866001600160401b03168152602001856001600160401b03168152602001611eb18a6001600160a01b031690565b8152602001878152602001848152602001838152509050979650505050505050565b60006001600160401b03821115611f0957604080516306dfcc6560e41b8152600481019190915260248101839052604401610551565b5090565b604080516101008101825260008082526020820181905291810182905260608082018390526080820183905260a082019290925260c0810182905260e081019190915290565b60008083601f840112611f6557600080fd5b5081356001600160401b03811115611f7c57600080fd5b602083019150836020828501011115611a3857600080fd5b60008083601f840112611fa657600080fd5b5081356001600160401b03811115611fbd57600080fd5b6020830191508360208260051b8501011115611a3857600080fd5b60008060008060408587031215611fee57600080fd5b84356001600160401b038082111561200557600080fd5b61201188838901611f53565b9096509450602087013591508082111561202a57600080fd5b5061203787828801611f94565b95989497509550505050565b6001600160401b0381168114610f5757600080fd5b80356119a081612043565b60006020828403121561207557600080fd5b813561110481612043565b6001600160a01b0381168114610f5757600080fd5b600080600080600080600080600060c08a8c0312156120b357600080fd5b89356120be81612043565b985060208a01356120ce81612080565b975060408a01356120de81612080565b965060608a01356001600160401b03808211156120fa57600080fd5b6121068d838e01611f94565b909850965060808c013591508082111561211f57600080fd5b61212b8d838e01611f53565b909650945060a08c013591508082111561214457600080fd5b506121518c828d01611f53565b915080935050809150509295985092959850929598565b60008060008060006060868803121561218057600080fd5b8535945060208601356001600160401b038082111561219e57600080fd5b6121aa89838a01611f53565b909650945060408801359150808211156121c357600080fd5b506121d088828901611f94565b969995985093965092949392505050565b600080600080600080600080600060c08a8c0312156121ff57600080fd5b893561220a81612043565b985060208a0135975060408a01356120de81612080565b60006020828403121561223357600080fd5b813561110481612080565b600060a08201845183526020808601518185015260408601516040850152606086015160018060a01b03808216606087015260a06080870152839150865180855260c087019250838801945060005b818110156122ab57855183168452948401949284019260010161228d565b509198975050505050505050565b634e487b7160e01b600052604160045260246000fd5b60405161010081016001600160401b03811182821017156122f2576122f26122b9565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612320576123206122b9565b604052919050565b60006001600160401b03821115612341576123416122b9565b50601f01601f191660200190565b600082601f83011261236057600080fd5b813561237361236e82612328565b6122f8565b81815284602083860101111561238857600080fd5b816020850160208301376000918101602001919091529392505050565b600061010082840312156123b857600080fd5b6123c06122cf565b90506123cb82612058565b81526123d960208301612058565b60208201526123ea60408301612058565b60408201526123fb60608301612058565b60608201526080820135608082015260a082013560a082015260c08201356001600160401b038082111561242e57600080fd5b61243a8583860161234f565b60c084015260e084013591508082111561245357600080fd5b506124608482850161234f565b60e08301525092915050565b60006020828403121561247e57600080fd5b81356001600160401b0381111561249457600080fd5b6124a0848285016123a5565b949350505050565b60005b838110156124c35781810151838201526020016124ab565b50506000910152565b600081518084526124e48160208601602086016124a8565b601f01601f19169290920160200192915050565b60208152600061110460208301846124cc565b60006020828403121561251d57600080fd5b5035919050565b60008060006040848603121561253957600080fd5b83356001600160401b038082111561255057600080fd5b61255c878388016123a5565b9450602086013591508082111561257257600080fd5b5061257f86828701611f94565b9497909650939450505050565b60608101600885106125ae57634e487b7160e01b600052602160045260246000fd5b938152602081019290925260409091015290565b600080600080600080600060a0888a0312156125dd57600080fd5b87356125e881612043565b965060208801356125f881612080565b955060408801356001600160401b038082111561261457600080fd5b6126208b838c01611f94565b909750955060608a013591508082111561263957600080fd5b506126468a828b01611f53565b989b979a50959894979596608090950135949350505050565b60006020828403121561267157600080fd5b81356001600160401b0381111561268757600080fd5b6124a08482850161234f565b600080604083850312156126a657600080fd5b82356126b181612043565b946020939093013593505050565b600080602083850312156126d257600080fd5b82356001600160401b038111156126e857600080fd5b6126f485828601611f53565b90969095509350505050565b8183823760009101908152919050565b60006001600160401b038088168352866020840152808616604084015280851660608401525060a0608083015261274a60a08301846124cc565b979650505050505050565b600082516127678184602087016124a8565b9190910192915050565b6000806040838503121561278457600080fd5b82516001600160401b038082111561279b57600080fd5b818501915085601f8301126127af57600080fd5b815160206127bf61236e83612328565b82815288828487010111156127d357600080fd5b6127e2838383018488016124a8565b878201519096509350828411156127f857600080fd5b838701935087601f85011261280c57600080fd5b8351915082821115612820576128206122b9565b8160051b92506128318184016122f8565b828152928401810192818101908985111561284b57600080fd5b948201945b84861015612875578551935061286584612080565b8382529482019490820190612850565b8096505050505050509250929050565b6000806040838503121561289857600080fd5b82516128a381612043565b60208401519092506128b481612043565b809150509250929050565b6040815260006128d260408301866124cc565b82810360208401528381526001600160fb1b038411156128f157600080fd5b8360051b808660208401370160200195945050505050565b60006020828403121561291b57600080fd5b8151801515811461110457600080fd5b8183526000602080850194508260005b8581101561296957813561294e81612080565b6001600160a01b03168752958201959082019060010161293b565b509495945050505050565b6001600160401b038416815260406020820152600061299760408301848661292b565b95945050505050565b6000602082840312156129b257600080fd5b5051919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160401b0385168152836020820152606060408201526000611c056060830184866129b9565b634e487b7160e01b600052601160045260246000fd5b808201808211156109cb576109cb612a0b565b600060408284031215612a4657600080fd5b604051604081018181106001600160401b0382111715612a6857612a686122b9565b604052825181526020928301519281019290925250919050565b6001600160401b0385168152836020820152606060408201526000611c0560608301848661292b565b634e487b7160e01b600052600160045260246000fd5b6001600160401b038616815284602082015283604082015260806060820152600061274a6080830184866129b9565b60006001600160401b03808a168352808916602084015280881660408401525085606083015284608083015260e060a0830152612b3060e08301856124cc565b82810360c084015261083e81856124cc565b600060808284031215612b5457600080fd5b604051608081018181106001600160401b0382111715612b7657612b766122b9565b80604052508251815260208301516020820152604083015160408201526060830151612ba181612080565b60608201529392505050565b85815284602082015283604082015260a060608201526000612bd260a08301856124cc565b8281036080840152612be481856124cc565b98975050505050505050565b61ffff60f01b8360f01b16815260008251612c128160028501602087016124a8565b919091016002019392505050565b6020815260006124a06020830184866129b9565b60008085851115612c4457600080fd5b83861115612c5157600080fd5b5050820193919092039150565b600080600080600060a08688031215612c7657600080fd5b85359450602086013593506040860135925060608601356001600160401b0380821115612ca257600080fd5b612cae89838a0161234f565b93506080880135915080821115612cc457600080fd5b50612cd18882890161234f565b9150509295509295909350565b6001600160a01b0392909216825280516001600160401b03908116602080850191909152820151166040808401919091520151606082015260800190565b634e487b7160e01b600052603260045260246000fd5b600060018201612d4457612d44612a0b565b506001019056fea26469706673582212207a2b1d2e71392cc68c20cddabdf5d2298bfdba2814882aa84eb28344b808dbec64736f6c634300081400330000000000000000000000008d50e833331a0d01d6f286881ce2c3a5dad12e26000000000000000000000000e7353bedc72d29f99d6ca5cde69f807cce5d57e4
Deployed Bytecode
0x6080604052600436106101355760003560e01c80638da5cb5b116100ab578063d5e788a01161006f578063d5e788a0146103c8578063e4c6124714610403578063f1a61fac14610437578063f2fde38b1461046d578063f3c66e2b1461048d578063f92a79ff146104ad57600080fd5b80638da5cb5b146102fb57806390e810771461031957806394bf49f414610359578063c8cf934814610379578063cbb3c631146103a857600080fd5b806353b67d74116100fd57806353b67d741461023b578063547efb8414610250578063695fd54f14610263578063715018a6146102915780637813cd52146102a65780638654ddd4146102ce57600080fd5b80631450c2811461013a5780632a20521e1461016f5780632e568739146101a757806335c4a191146101d55780633f34448e146101f5575b600080fd5b34801561014657600080fd5b5061015a610155366004611fd8565b6104cd565b60405190151581526020015b60405180910390f35b34801561017b57600080fd5b5060015461018f906001600160a01b031681565b6040516001600160a01b039091168152602001610166565b3480156101b357600080fd5b506101c76101c2366004612063565b61051f565b604051908152602001610166565b3480156101e157600080fd5b5061018f6101f0366004612063565b610576565b610208610203366004612095565b6105f9565b60408051825181526020808401516001600160401b03908116918301919091529282015190921690820152606001610166565b61024e610249366004612168565b610640565b005b61020861025e3660046121e1565b610810565b34801561026f57600080fd5b5061028361027e366004612221565b61084c565b60405161016692919061223e565b34801561029d57600080fd5b5061024e6109a2565b3480156102b257600080fd5b506102bb600181565b60405161ffff9091168152602001610166565b3480156102da57600080fd5b506102ee6102e936600461246c565b6109b6565b60405161016691906124f8565b34801561030757600080fd5b506000546001600160a01b031661018f565b34801561032557600080fd5b5061033961033436600461250b565b6109d1565b604080516001600160401b03938416815292909116602083015201610166565b34801561036557600080fd5b5061024e610374366004612221565b610b2f565b34801561038557600080fd5b50610399610394366004612524565b610bb2565b6040516101669392919061258c565b3480156103b457600080fd5b506101c76103c33660046125c2565b610d60565b3480156103d457600080fd5b506103e86103e336600461265f565b610eff565b60408051825181526020928301519281019290925201610166565b34801561040f57600080fd5b5061018f7f0000000000000000000000008d50e833331a0d01d6f286881ce2c3a5dad12e2681565b34801561044357600080fd5b5061018f61045236600461250b565b6000908152600360205260409020546001600160a01b031690565b34801561047957600080fd5b5061024e610488366004612221565b610f1c565b34801561049957600080fd5b5061024e6104a8366004612693565b610f5a565b3480156104b957600080fd5b5061018f6104c83660046126bf565b610fba565b6000806104da8686610ffa565b90506104e98160c0015161109b565b50600086866040516104fc929190612700565b604051809103902090506105128282878761110b565b5060019695505050505050565b600046826001600160401b03160361055a57604051636b0dc00560e11b81526001600160401b03831660048201526024015b60405180910390fd5b506001600160401b031660009081526002602052604090205490565b600046826001600160401b0316036105ac57604051636b0dc00560e11b81526001600160401b0383166004820152602401610551565b506001600160401b038116600090815260026020526040902054806001600160a01b03811681146105f35760405163ec3822b160e01b815260048101829052602401610551565b50919050565b60408051606081018252600080825260208201819052918101919091526001600160a01b0389166106318b828b8b8b8b8b8b8b61124d565b9b9a5050505050505050505050565b600061064c8585610ffa565b905060008585604051610660929190612700565b604051809103902090506106768282868661110b565b600081815260036020526040812080546001600160a01b0319163317905560c08301516106a29061109b565b9050806020015134146106d75760208101516040516366f7ba5d60e01b81523460048201526024810191909152604401610551565b80518810156106e557805197505b60005a90508881116107145760405163176b11a760e21b815260048101829052602481018a9052604401610551565b60a08401516001600160a01b0316636e9fd6098a348760000151886080015189604001518a606001518b60e001516040518863ffffffff1660e01b8152600401610762959493929190612710565b6000604051808303818589803b15801561077b57600080fd5b5088f115801561078f573d6000803e3d6000fd5b5050505050508360a001518460800151847f589f737f4049c62fcbcd8274eeacc86e17d29c6621f36e698bcc4c90525ce28f8760400151886060015189600001516040516107fd939291906001600160401b0393841681529183166020830152909116604082015260600190565b60405180910390a4505050505050505050565b604080516060810182526000808252602082018190529181019190915261083e8a8a8a8a8a8a8a8a8a61124d565b9a9950505050505050505050565b610880604051806080016040528060008152602001600081526020016000815260200160006001600160a01b031681525090565b6060826001600160a01b03163b6000036108b857604051630a293ffd60e41b81526001600160a01b0384166004820152602401610551565b60408051600481526024810182526020810180516001600160e01b031663287bc05760e01b179052905160009182916001600160a01b038716916108fb91612755565b600060405180830381855afa9150503d8060008114610936576040519150601f19603f3d011682016040523d82523d6000602084013e61093b565b606091505b509150915081158061094c57508051155b1561097557604051630a293ffd60e41b81526001600160a01b0386166004820152602401610551565b60608180602001905181019061098b9190612771565b9450905061099881611706565b9450505050915091565b6109aa61178f565b6109b460006117bc565b565b60606109cb60016109c68461180c565b6118b0565b92915050565b60008181526003602052604081205481906001600160a01b031680610a0c5760405163e99eb48d60e01b815260048101859052602401610551565b60008482604051602001610a339291909182526001600160a01b0316602082015260400190565b60408051808303601f19018152908290528051602082012063156c638360e11b8352600483015291507f0000000000000000000000008d50e833331a0d01d6f286881ce2c3a5dad12e266001600160a01b031690632ad8c7069060240160408051808303816000875af1158015610aae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad29190612885565b604080516001600160401b038085168252831660208201529296509094506001600160a01b0384169187917f1c45fee34c18589980aa86a2b9910fac2a0be9beca86376b6d93fa4ce7f010ae910160405180910390a35050915091565b610b3761178f565b6001600160a01b038116610b5e57604051633184f16960e21b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527fa42a6dc10e430cab5d4ba037ea6d7eee30240c6b6d7dd5b12a3d2acf41e7264f9060200160405180910390a150565b600080600080610bc1876109b6565b604051631450c28160e01b81529091503090631450c28190610beb9084908a908a906004016128bf565b602060405180830381865afa925050508015610c24575060408051601f3d908101601f19168201909252610c2191810190612909565b60015b610d43573d808015610c52576040519150601f19603f3d011682016040523d82523d6000602084013e610c57565b606091505b506000610c63826118dc565b909650945090506327f5146f60e01b6001600160e01b0319821601610c8b5760019550610d3c565b6357761ca160e11b6001600160e01b0319821601610cac5760029550610d3c565b6317c4157360e11b6001600160e01b0319821601610ccd5760039550610d3c565b6305d6c00360e41b6001600160e01b0319821601610cee5760049550610d3c565b6318c9944360e21b6001600160e01b0319821601610d0f5760059550610d3c565b631515fcbb60e01b6001600160e01b0319821601610d305760069550610d3c565b60079550600094508493505b5050610d55565b5060009350839250829150610d579050565b505b93509350939050565b6000610d6b88611924565b506001600160a01b038716610d935760405163146fd3c560e21b815260040160405180910390fd5b610dd284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061109b92505050565b5060405163b8ba4ba160e01b81526001600160a01b037f0000000000000000000000008d50e833331a0d01d6f286881ce2c3a5dad12e26169063b8ba4ba190610e23908b908a908a90600401612974565b602060405180830381865afa158015610e40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6491906129a0565b90506000610e7284846119a5565b604051634b7ed26d60e11b81529091506001600160a01b038916906396fda4da90610ea7908c9085908a908a906004016129e2565b602060405180830381865afa158015610ec4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee891906129a0565b610ef29083612a21565b9998505050505050505050565b60408051808201909152600080825260208201526109cb8261109b565b610f2461178f565b6001600160a01b038116610f4e57604051631e4fbdf760e01b815260006004820152602401610551565b610f57816117bc565b50565b610f6261178f565b6001600160401b038216600081815260026020908152604091829020849055815192835282018390527ffdc2498138df0de25c8fc9bd75bb8e856dac69aaf28d3dd5e0fc48e5e9f6e93f910160405180910390a15050565b6000600360008484604051610fd0929190612700565b60408051918290039091208252602082019290925201600020546001600160a01b03169392505050565b611002611f0d565b600061100e84846119cc565b905061ffff8116600114611042576040516316d8807d60e11b815261ffff8216600482015260016024820152604401610551565b61105461104f85856119fd565b611a3f565b91504682602001516001600160401b03161461109457602082015160405163eaea034560e01b81526001600160401b039091166004820152602401610551565b5092915050565b604080518082019091526000808252602082015260006110ba83611aad565b9050600161ffff821610156110e857604051632b346f3760e01b815261ffff82166004820152602401610551565b6110f183611adf565b8060200190518101906111049190612a34565b9392505050565b600061111a8560000151611924565b6000858152600360205260409020549091506001600160a01b0316156111565760405163d80aeb9160e01b815260048101859052602401610551565b6000604051806060016040528087600001516001600160401b0316815260200187604001516001600160401b0316815260200161119a84888a606001518989611b88565b815250905060006111ac8760a0015190565b90506000806111ba8361084c565b815191935091506000036111ec576040516327366bbd60e21b81526001600160a01b0384166004820152602401610551565b6111fe6111f883611c0f565b85611c49565b600061120f82868560200151611d1f565b8351909150811015611241578251604051632889e35f60e11b8152610551918391600401918252602082015260400190565b50505050505050505050565b60408051606081018252600080825260208201819052918101919091526112738a611924565b506000899003611296576040516330014e4760e21b815260040160405180910390fd5b6001600160a01b0388166112bd5760405163146fd3c560e21b815260040160405180910390fd5b6112fc85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061109b92505050565b5060405163b8ba4ba160e01b81526000906001600160a01b037f0000000000000000000000008d50e833331a0d01d6f286881ce2c3a5dad12e26169063b8ba4ba190611350908e908c908c90600401612974565b602060405180830381865afa15801561136d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139191906129a0565b9050803410156113bd5760405163457bf1e160e11b815234600482015260248101829052604401610551565b7f0000000000000000000000008d50e833331a0d01d6f286881ce2c3a5dad12e266001600160a01b031663aa2f06ae6040518163ffffffff1660e01b81526004016040805180830381865afa15801561141a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143e9190612885565b8360200184604001826001600160401b03166001600160401b0316815250826001600160401b03166001600160401b031681525050506000611507338d8d866020015187604001518c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e4992505050565b9050611512816109b6565b805190602001208360000181815250506000807f0000000000000000000000008d50e833331a0d01d6f286881ce2c3a5dad12e266001600160a01b031663eb20fbfd85856020015188600001518f8f6040518663ffffffff1660e01b81526004016115809493929190612a82565b604080518083038185885af115801561159d573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906115c29190612885565b9150915084602001516001600160401b0316826001600160401b0316148015611600575084604001516001600160401b0316816001600160401b0316145b61160c5761160c612aab565b5050602081015134839003906001600160a01b038c16906358efb47d9083906116358b8a6119a5565b88516040516001600160e01b031960e087901b16815261165e939291908f908f90600401612ac1565b6000604051808303818588803b15801561167757600080fd5b505af115801561168b573d6000803e3d6000fd5b50505050508160a00151826080015185600001517f73b3ea77e781779ca7d3bd994ecd1ad739e22cda0120925bbf4e30de70ebc7e885604001518660600151876020015189888a60c001518b60e001516040516116ee9796959493929190612af0565b60405180910390a45050509998505050505050505050565b61173a604051806080016040528060008152602001600081526020016000815260200160006001600160a01b031681525090565b600061174583611aad565b9050600161ffff8216101561177357604051635b72a46360e11b815261ffff82166004820152602401610551565b61177c83611adf565b8060200190518101906111049190612b42565b6000546001600160a01b031633146109b45760405163118cdaa760e01b8152336004820152602401610551565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606061187282600001518360200151846040015185606001516001600160c01b031960c085901b1667ffffffffffffffff60801b608085901b16176fffffffffffffffff0000000000000000604084901b16176001600160401b03821617949350505050565b82608001518360a001518460c001518560e0015160405160200161189a959493929190612bad565b6040516020818303038152906040529050919050565b606082826040516020016118c5929190612bf0565b604051602081830303815290604052905092915050565b600080600060048451106118fc5760208401516001600160e01b03191692505b602484511061190d57602484015191505b604484511061191d575060448301515b9193909250565b600046826001600160401b03160361195a57604051636b0dc00560e11b81526001600160401b0383166004820152602401610551565b506001600160401b038116600090815260026020526040812054908190036119a057604051632e3a383760e21b81526001600160401b0383166004820152602401610551565b919050565b6000601f19601f830116601f19601f8501166119c29060e2612a21565b6111049190612a21565b600060028210156119f4578282604051635840c5b160e11b8152600401610551929190612c20565b50503560f01c90565b3660006002831015611a26578383604051635840c5b160e11b8152600401610551929190612c20565b611a338360028187612c34565b915091505b9250929050565b611a47611f0d565b6000611a5583850185612c5e565b60e087015260c086015260a085015260808401529050611a838160c081901c91608082901c91604081901c91565b6001600160401b039081166060870152908116604086015290811660208501521682525092915050565b6000600282511015611ad45781604051635840c5b160e11b815260040161055191906124f8565b506020015160f01c90565b6060600282511015611b065781604051635840c5b160e11b815260040161055191906124f8565b815160011901806001600160401b03811115611b2457611b246122b9565b6040519080825280601f01601f191660200182016040528015611b4e576020820181803683370190505b50915060008160208401836022870160045afa905080611b815760405163080f227d60e11b815260040160405180910390fd5b5050919050565b60006001600160401b03841615611bbd5760405163d9c5be6160e01b81526001600160401b0385166004820152602401610551565b8115611bdc57604051631a9b90c960e11b815260040160405180910390fd5b604080516020808201899052818301889052825180830384018152606090920190925280519101205b9695505050505050565b6040810151600090611c2357506000919050565b604082015160001901611c415750506001546001600160a01b031690565b506060015190565b6001600160a01b03821615611d1b5760405163e39682c160e01b81526000906001600160a01b037f0000000000000000000000008d50e833331a0d01d6f286881ce2c3a5dad12e26169063e39682c190611ca99086908690600401612cde565b602060405180830381865afa158015611cc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cea91906129a0565b90506000198103611d195760405163683bea8d60e11b81526001600160a01b0384166004820152602401610551565b505b5050565b6000805b8451811015611e41576000858281518110611d4057611d40612d1c565b6020026020010151905060007f0000000000000000000000008d50e833331a0d01d6f286881ce2c3a5dad12e266001600160a01b031663e39682c183886040518363ffffffff1660e01b8152600401611d9a929190612cde565b602060405180830381865afa158015611db7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ddb91906129a0565b905080611de9575050611e31565b6000198103611e165760405163683bea8d60e11b81526001600160a01b0383166004820152602401610551565b42611e218683612a21565b1015611e2e578360010193505b50505b611e3a81612d32565b9050611d23565b509392505050565b611e51611f0d565b604051806101000160405280611e6646611ed3565b6001600160401b03168152602001886001600160401b03168152602001866001600160401b03168152602001856001600160401b03168152602001611eb18a6001600160a01b031690565b8152602001878152602001848152602001838152509050979650505050505050565b60006001600160401b03821115611f0957604080516306dfcc6560e41b8152600481019190915260248101839052604401610551565b5090565b604080516101008101825260008082526020820181905291810182905260608082018390526080820183905260a082019290925260c0810182905260e081019190915290565b60008083601f840112611f6557600080fd5b5081356001600160401b03811115611f7c57600080fd5b602083019150836020828501011115611a3857600080fd5b60008083601f840112611fa657600080fd5b5081356001600160401b03811115611fbd57600080fd5b6020830191508360208260051b8501011115611a3857600080fd5b60008060008060408587031215611fee57600080fd5b84356001600160401b038082111561200557600080fd5b61201188838901611f53565b9096509450602087013591508082111561202a57600080fd5b5061203787828801611f94565b95989497509550505050565b6001600160401b0381168114610f5757600080fd5b80356119a081612043565b60006020828403121561207557600080fd5b813561110481612043565b6001600160a01b0381168114610f5757600080fd5b600080600080600080600080600060c08a8c0312156120b357600080fd5b89356120be81612043565b985060208a01356120ce81612080565b975060408a01356120de81612080565b965060608a01356001600160401b03808211156120fa57600080fd5b6121068d838e01611f94565b909850965060808c013591508082111561211f57600080fd5b61212b8d838e01611f53565b909650945060a08c013591508082111561214457600080fd5b506121518c828d01611f53565b915080935050809150509295985092959850929598565b60008060008060006060868803121561218057600080fd5b8535945060208601356001600160401b038082111561219e57600080fd5b6121aa89838a01611f53565b909650945060408801359150808211156121c357600080fd5b506121d088828901611f94565b969995985093965092949392505050565b600080600080600080600080600060c08a8c0312156121ff57600080fd5b893561220a81612043565b985060208a0135975060408a01356120de81612080565b60006020828403121561223357600080fd5b813561110481612080565b600060a08201845183526020808601518185015260408601516040850152606086015160018060a01b03808216606087015260a06080870152839150865180855260c087019250838801945060005b818110156122ab57855183168452948401949284019260010161228d565b509198975050505050505050565b634e487b7160e01b600052604160045260246000fd5b60405161010081016001600160401b03811182821017156122f2576122f26122b9565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612320576123206122b9565b604052919050565b60006001600160401b03821115612341576123416122b9565b50601f01601f191660200190565b600082601f83011261236057600080fd5b813561237361236e82612328565b6122f8565b81815284602083860101111561238857600080fd5b816020850160208301376000918101602001919091529392505050565b600061010082840312156123b857600080fd5b6123c06122cf565b90506123cb82612058565b81526123d960208301612058565b60208201526123ea60408301612058565b60408201526123fb60608301612058565b60608201526080820135608082015260a082013560a082015260c08201356001600160401b038082111561242e57600080fd5b61243a8583860161234f565b60c084015260e084013591508082111561245357600080fd5b506124608482850161234f565b60e08301525092915050565b60006020828403121561247e57600080fd5b81356001600160401b0381111561249457600080fd5b6124a0848285016123a5565b949350505050565b60005b838110156124c35781810151838201526020016124ab565b50506000910152565b600081518084526124e48160208601602086016124a8565b601f01601f19169290920160200192915050565b60208152600061110460208301846124cc565b60006020828403121561251d57600080fd5b5035919050565b60008060006040848603121561253957600080fd5b83356001600160401b038082111561255057600080fd5b61255c878388016123a5565b9450602086013591508082111561257257600080fd5b5061257f86828701611f94565b9497909650939450505050565b60608101600885106125ae57634e487b7160e01b600052602160045260246000fd5b938152602081019290925260409091015290565b600080600080600080600060a0888a0312156125dd57600080fd5b87356125e881612043565b965060208801356125f881612080565b955060408801356001600160401b038082111561261457600080fd5b6126208b838c01611f94565b909750955060608a013591508082111561263957600080fd5b506126468a828b01611f53565b989b979a50959894979596608090950135949350505050565b60006020828403121561267157600080fd5b81356001600160401b0381111561268757600080fd5b6124a08482850161234f565b600080604083850312156126a657600080fd5b82356126b181612043565b946020939093013593505050565b600080602083850312156126d257600080fd5b82356001600160401b038111156126e857600080fd5b6126f485828601611f53565b90969095509350505050565b8183823760009101908152919050565b60006001600160401b038088168352866020840152808616604084015280851660608401525060a0608083015261274a60a08301846124cc565b979650505050505050565b600082516127678184602087016124a8565b9190910192915050565b6000806040838503121561278457600080fd5b82516001600160401b038082111561279b57600080fd5b818501915085601f8301126127af57600080fd5b815160206127bf61236e83612328565b82815288828487010111156127d357600080fd5b6127e2838383018488016124a8565b878201519096509350828411156127f857600080fd5b838701935087601f85011261280c57600080fd5b8351915082821115612820576128206122b9565b8160051b92506128318184016122f8565b828152928401810192818101908985111561284b57600080fd5b948201945b84861015612875578551935061286584612080565b8382529482019490820190612850565b8096505050505050509250929050565b6000806040838503121561289857600080fd5b82516128a381612043565b60208401519092506128b481612043565b809150509250929050565b6040815260006128d260408301866124cc565b82810360208401528381526001600160fb1b038411156128f157600080fd5b8360051b808660208401370160200195945050505050565b60006020828403121561291b57600080fd5b8151801515811461110457600080fd5b8183526000602080850194508260005b8581101561296957813561294e81612080565b6001600160a01b03168752958201959082019060010161293b565b509495945050505050565b6001600160401b038416815260406020820152600061299760408301848661292b565b95945050505050565b6000602082840312156129b257600080fd5b5051919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160401b0385168152836020820152606060408201526000611c056060830184866129b9565b634e487b7160e01b600052601160045260246000fd5b808201808211156109cb576109cb612a0b565b600060408284031215612a4657600080fd5b604051604081018181106001600160401b0382111715612a6857612a686122b9565b604052825181526020928301519281019290925250919050565b6001600160401b0385168152836020820152606060408201526000611c0560608301848661292b565b634e487b7160e01b600052600160045260246000fd5b6001600160401b038616815284602082015283604082015260806060820152600061274a6080830184866129b9565b60006001600160401b03808a168352808916602084015280881660408401525085606083015284608083015260e060a0830152612b3060e08301856124cc565b82810360c084015261083e81856124cc565b600060808284031215612b5457600080fd5b604051608081018181106001600160401b0382111715612b7657612b766122b9565b80604052508251815260208301516020820152604083015160408201526060830151612ba181612080565b60608201529392505050565b85815284602082015283604082015260a060608201526000612bd260a08301856124cc565b8281036080840152612be481856124cc565b98975050505050505050565b61ffff60f01b8360f01b16815260008251612c128160028501602087016124a8565b919091016002019392505050565b6020815260006124a06020830184866129b9565b60008085851115612c4457600080fd5b83861115612c5157600080fd5b5050820193919092039150565b600080600080600060a08688031215612c7657600080fd5b85359450602086013593506040860135925060608601356001600160401b0380821115612ca257600080fd5b612cae89838a0161234f565b93506080880135915080821115612cc457600080fd5b50612cd18882890161234f565b9150509295509295909350565b6001600160a01b0392909216825280516001600160401b03908116602080850191909152820151166040808401919091520151606082015260800190565b634e487b7160e01b600052603260045260246000fd5b600060018201612d4457612d44612a0b565b506001019056fea26469706673582212207a2b1d2e71392cc68c20cddabdf5d2298bfdba2814882aa84eb28344b808dbec64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000008d50e833331a0d01d6f286881ce2c3a5dad12e26000000000000000000000000e7353bedc72d29f99d6ca5cde69f807cce5d57e4
-----Decoded View---------------
Arg [0] : interchainDB (address): 0x8d50e833331A0D01d6F286881ce2C3A5DAD12e26
Arg [1] : owner_ (address): 0xE7353BEdc72D29f99D6cA5CDE69F807cCE5d57e4
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000008d50e833331a0d01d6f286881ce2c3a5dad12e26
Arg [1] : 000000000000000000000000e7353bedc72d29f99d6ca5cde69f807cce5d57e4
Loading...
Loading
[ Download: CSV Export ]
[ 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.