Source Code
Overview
ETH Balance
288.093349570805518458 ETH
Token Holdings
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 475,385 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Submit Message | 7492973 | 2 days ago | IN | 0 ETH | 0.00012945 | ||||
Submit Message | 7490333 | 2 days ago | IN | 0 ETH | 0.00078593 | ||||
Submit Message | 7490331 | 2 days ago | IN | 0 ETH | 0.00077044 | ||||
Submit Message | 7489623 | 2 days ago | IN | 0 ETH | 0.00071511 | ||||
Submit Message | 7454179 | 7 days ago | IN | 0 ETH | 0.00107288 | ||||
Submit Message | 7446646 | 8 days ago | IN | 0 ETH | 0.00063689 | ||||
Submit Message | 7428061 | 11 days ago | IN | 0 ETH | 0.00039432 | ||||
Submit Message | 7425480 | 11 days ago | IN | 0 ETH | 0.0007004 | ||||
Submit Message | 7319497 | 27 days ago | IN | 0.0001 ETH | 0.00042481 | ||||
Submit Message | 7294155 | 31 days ago | IN | 0 ETH | 0.00011703 | ||||
Submit Message | 7284758 | 32 days ago | IN | 0 ETH | 0.00203152 | ||||
Submit Message | 7278464 | 33 days ago | IN | 0 ETH | 0.00041979 | ||||
Submit Message | 7272281 | 34 days ago | IN | 0 ETH | 0.00034978 | ||||
Submit Message | 7270861 | 34 days ago | IN | 0 ETH | 0.0009284 | ||||
Submit Message | 7262146 | 35 days ago | IN | 0 ETH | 0.00010862 | ||||
Submit Message | 7258511 | 36 days ago | IN | 0 ETH | 0.00021098 | ||||
Submit Message | 7252068 | 37 days ago | IN | 0 ETH | 0.00047173 | ||||
Submit Message | 7245378 | 38 days ago | IN | 0 ETH | 0.00015268 | ||||
Submit Message | 7210366 | 43 days ago | IN | 0 ETH | 0.0002589 | ||||
Submit Message | 7205755 | 44 days ago | IN | 0 ETH | 0.00004941 | ||||
Submit Message | 7202201 | 44 days ago | IN | 0 ETH | 0.00014558 | ||||
Submit Message | 7110717 | 58 days ago | IN | 0 ETH | 0.00013174 | ||||
Submit Message | 7103832 | 59 days ago | IN | 0 ETH | 0.00006033 | ||||
Submit Message | 7098751 | 60 days ago | IN | 0 ETH | 0.00004974 | ||||
Submit Message | 7081121 | 62 days ago | IN | 0 ETH | 0.00012884 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
6056069 | 224 days ago | 0 ETH | ||||
6053867 | 224 days ago | 0 ETH | ||||
6053866 | 224 days ago | 0 ETH | ||||
6053767 | 224 days ago | 0 ETH | ||||
6051133 | 224 days ago | 0 ETH | ||||
6051009 | 224 days ago | 0 ETH | ||||
5855201 | 254 days ago | 0.00372265 ETH | ||||
5855201 | 254 days ago | 0.0037222 ETH | ||||
5855201 | 254 days ago | 0.0037222 ETH | ||||
5855199 | 254 days ago | 0.00427895 ETH | ||||
5855198 | 254 days ago | 0.00442058 ETH | ||||
5855194 | 254 days ago | 0.00444673 ETH | ||||
5855194 | 254 days ago | 0.00444673 ETH | ||||
5855194 | 254 days ago | 0.00444673 ETH | ||||
5855194 | 254 days ago | 0.00444673 ETH | ||||
5855194 | 254 days ago | 0.00444673 ETH | ||||
5855194 | 254 days ago | 0.00444619 ETH | ||||
5855194 | 254 days ago | 0.00444619 ETH | ||||
5855194 | 254 days ago | 0.00444619 ETH | ||||
5855194 | 254 days ago | 0.00444673 ETH | ||||
5855193 | 254 days ago | 0.00458246 ETH | ||||
5855193 | 254 days ago | 0.00458302 ETH | ||||
5855193 | 254 days ago | 0.00458302 ETH | ||||
5855193 | 254 days ago | 0.00458302 ETH | ||||
5855193 | 254 days ago | 0.00458246 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Gateway
Compiler Version
v0.8.25+commit.b61c2a91
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; import "frost-evm/sol/Schnorr.sol"; import "./BranchlessMath.sol"; /** * @dev Required interface of an GMP compliant contract */ interface IGmpReceiver { /** * @dev Handles the receipt of a single GMP message. * The contract must verify the msg.sender, it must be the Gateway Contract address. * * @param id The EIP-712 hash of the message payload, used as GMP unique identifier * @param network The chain_id of the source chain who send the message * @param source The pubkey/address which sent the GMP message * @param payload The message payload with no specified format * @return 32 byte result which will be stored together with GMP message */ function onGmpReceived(bytes32 id, uint128 network, bytes32 source, bytes calldata payload) external payable returns (bytes32); } /** * @dev Required interface of an Gateway compliant contract */ interface IGateway { /** * @dev Emitted when `GmpMessage` is executed. * - `id` EIP-712 hash of the `GmpPayload`, which is it's unique identifier * - `source` sender pubkey/address (the format depends on src chain) * - `dest` recipient address * - `status` GMP message execution status * - `result` GMP result */ event GmpExecuted(bytes32 indexed id, bytes32 indexed source, address indexed dest, uint256 status, bytes32 result); /** * @dev Emitted when `UpdateShardsMessage` is executed. * - `id` EIP-712 hash of the UpdateShardsMessage, zero for sudo * - `revoked` shards with keys revoked * - `registered` new shards registered */ event KeySetChanged(bytes32 indexed id, TssKey[] revoked, TssKey[] registered); /** * @dev New GMP submitted by calling the `submitMessage` method. * - `id` EIP-712 hash of the `GmpPayload`, which is it's unique identifier * - `sender` sender account, with an extra flag indicating if it is a contract or an EOA * - `recipient` address or pubkey, the format depends on the destination network. * - `network` recipient network identifier * - `gasLimit` maximum gas limit for the GMP call * - `salt` salt is equal to the previous message id (EIP-712 hash). * - `data` message data with no specified format */ event GmpCreated( bytes32 indexed id, bytes32 indexed sender, address indexed recipient, uint16 network, uint256 gasLimit, uint256 salt, bytes data ); function deposit(bytes32 source, uint16 network) external payable; /** * Returns the deposit of a source against its network id */ function depositOf(bytes32 source, uint16 networkId) external view returns (uint256); /** * Execute GMP message */ function execute(Signature memory signature, GmpMessage memory message) external returns (uint8 status, bytes32 result); /** * Update TSS key set */ function updateKeys(Signature memory signature, UpdateKeysMessage memory message) external; function submitMessage(address recipient, uint16 network, uint256 gasLimit, bytes memory data) external payable; } /** * @dev Tss public key */ struct TssKey { uint8 yParity; // public key y-coord parity, the contract converts it to 27/28 uint256 xCoord; // affine x-coordinate } /** * @dev Message payload used to revoke or/and register new shards */ struct UpdateKeysMessage { TssKey[] revoke; // Keys to revoke TssKey[] register; // Keys to add } /** * @dev GMP payload, this is what the timechain creates as task payload */ struct GmpMessage { bytes32 source; // Pubkey/Address of who send the GMP message uint16 srcNetwork; // Source chain identifier (for ethereum networks it is the EIP-155 chain id) address dest; // Destination/Recipient contract address uint16 destNetwork; // Destination chain identifier (it's the EIP-155 chain_id for ethereum networks) uint256 gasLimit; // gas limit of the GMP call uint256 salt; // Message salt, useful for sending two messages with same content bytes data; // message data with no specified format } /** * @dev this is what must be signed using the schnorr signature, * OBS: what is actually signed is: keccak256(abi.encodePacked(R, parity, px, nonce, message)) * Where `parity` is the public key y coordinate stored in the contract, and `R` is computed from `e` and `s` parameters. */ struct Signature { uint256 xCoord; // public key x coordinates, y-parity is stored in the contract uint256 e; // Schnorr signature e parameter uint256 s; // Schnorr signature s parameter } /** * @dev Shard info stored in the Gateway Contract * OBS: the order of the attributes matters! ethereum storage is 256bit aligned, try to keep * the shard info below 256 bit, so it can be stored in one single storage slot. * reference: https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html * */ struct KeyInfo { uint216 _gap; // gap, so we can use later for store more information about a shard uint8 status; // status, 0 = unregisted, 1 = active, 3 = revoked uint32 nonce; // shard nonce } /** * @dev GMP info stored in the Gateway Contract * OBS: the order of the attributes matters! ethereum storage is 256bit aligned, try to keep * the attributes 256 bit aligned, ex: nonce, block and status can be read in one storage access. * reference: https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html * */ struct GmpInfo { uint184 _gap; // gap to keep status and blocknumber 256bit aligned uint8 status; // message status: NOT_FOUND | PENDING | SUCCESS | REVERT uint64 blockNumber; // block in which the message was processed bytes32 result; // the result of the GMP message } contract SigUtils { // EIP-712: Typed structured data hashing and signing // https://eips.ethereum.org/EIPS/eip-712 uint16 internal immutable NETWORK_ID; bytes32 internal immutable DOMAIN_SEPARATOR; constructor(uint16 networkId, address gateway) { NETWORK_ID = networkId; DOMAIN_SEPARATOR = computeDomainSeparator(networkId, gateway); } // Computes the EIP-712 domain separador function computeDomainSeparator(uint256 networkId, address addr) private pure returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256("Analog Gateway Contract"), keccak256("0.1.0"), uint256(networkId), address(addr) ) ); } // computes the hash of an array of tss keys function _getTssKeyHash(TssKey memory tssKey) private pure returns (bytes32) { return keccak256(abi.encode(keccak256("TssKey(uint8 yParity,uint256 xCoord)"), tssKey.yParity, tssKey.xCoord)); } // computes the hash of an array of tss keys function _getTssKeyArrayHash(TssKey[] memory tssKeys) private pure returns (bytes32) { bytes memory keysHashed = new bytes(tssKeys.length * 32); uint256 ptr; assembly { ptr := keysHashed } for (uint256 i = 0; i < tssKeys.length; i++) { bytes32 hash = _getTssKeyHash(tssKeys[i]); assembly { ptr := add(ptr, 32) mstore(ptr, hash) } } return keccak256(keysHashed); } // computes the hash of the fully encoded EIP-712 message for the domain, which can be used to recover the signer function _getUpdateKeysHash(UpdateKeysMessage memory message) private pure returns (bytes32) { return keccak256( abi.encode( keccak256("UpdateKeysMessage(TssKey[] revoke,TssKey[] register)TssKey(uint8 yParity,uint256 xCoord)"), _getTssKeyArrayHash(message.revoke), _getTssKeyArrayHash(message.register) ) ); } function getUpdateKeysTypedHash(UpdateKeysMessage memory message) internal view returns (bytes memory) { return abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, _getUpdateKeysHash(message)); } // computes the hash of an array of tss keys function _getGmpHash(GmpMessage memory gmp) private pure returns (bytes32) { return keccak256( abi.encode( keccak256( "GmpMessage(bytes32 source,uint16 srcNetwork,address dest,uint16 destNetwork,uint256 gasLimit,uint256 salt,bytes data)" ), gmp.source, gmp.srcNetwork, gmp.dest, gmp.destNetwork, gmp.gasLimit, gmp.salt, keccak256(gmp.data) ) ); } // computes the hash of the fully encoded EIP-712 message for the domain, which can be used to recover the signer function getGmpTypedHash(GmpMessage memory message) public view returns (bytes memory) { return abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, _getGmpHash(message)); } } contract Gateway is IGateway, SigUtils { uint8 internal constant GMP_STATUS_NOT_FOUND = 0; // GMP message not processed uint8 internal constant GMP_STATUS_SUCCESS = 1; // GMP message executed successfully uint8 internal constant GMP_STATUS_REVERTED = 2; // GMP message executed, but reverted uint8 internal constant GMP_STATUS_PENDING = 128; // GMP message is pending (used in case of reetrancy) uint8 internal constant SHARD_ACTIVE = (1 << 0); // Shard active bitflag uint8 internal constant SHARD_Y_PARITY = (1 << 1); // Pubkey y parity bitflag uint256 internal constant EXECUTE_GAS_DIFF = 9081; // Measured gas cost difference for `execute` // Non-zero value used to initialize the `prevMessageHash` storage bytes32 internal constant FIRST_MESSAGE_PLACEHOLDER = bytes32(uint256(2 ** 256 - 1)); // Shard data, maps the pubkey coordX (which is already collision resistant) to shard info. mapping(bytes32 => KeyInfo) _shards; // GMP message status mapping(bytes32 => GmpInfo) _messages; // Source address => Source network => Deposit Amount mapping(bytes32 => mapping(uint16 => uint256)) _deposits; // Hash of the previous GMP message submitted. bytes32 public prevMessageHash; constructor(uint16 networkId, TssKey[] memory keys) payable SigUtils(networkId, address(this)) { // Initialize the prevMessageHash with a non-zero value to avoid the first GMP to spent more gas, // once initialize the storage cost 21k gas, while alter it cost just 2800 gas. prevMessageHash = FIRST_MESSAGE_PLACEHOLDER; _registerKeys(keys); // emit event TssKey[] memory revoked = new TssKey[](0); emit KeySetChanged(bytes32(0), revoked, keys); } function gmpInfo(bytes32 id) external view returns (GmpInfo memory) { return _messages[id]; } function depositOf(bytes32 source, uint16 networkId) external view returns (uint256) { return _deposits[source][networkId]; } function keyInfo(bytes32 id) external view returns (KeyInfo memory) { return _shards[id]; } // Check if shard exists, verify TSS signature and increment shard nonce function _verifySignature(Signature memory signature, bytes32 message) private view { // Load shard from storage KeyInfo storage signer = _shards[bytes32(signature.xCoord)]; // Verify if shard is active uint8 status = signer.status; require((status & SHARD_ACTIVE) > 0, "shard key revoked or not exists"); // Load y parity bit, it must be 27 (even), or 28 (odd) // ref: https://ethereum.github.io/yellowpaper/paper.pdf uint8 yParity; if ((status & SHARD_Y_PARITY) > 0) { yParity = 28; } else { yParity = 27; } // Verify Signature require( Schnorr.verify(yParity, signature.xCoord, uint256(message), signature.e, signature.s), "invalid tss signature" ); } // Converts a `TssKey` into an `KeyInfo` unique identifier function _tssKeyToShardId(TssKey memory tssKey) private pure returns (bytes32) { // The tssKey coord x is already collision resistant // if we are unsure about it, we can hash the coord and parity bit return bytes32(tssKey.xCoord); } function _registerKeys(TssKey[] memory keys) private { // We don't perform any arithmetic operation, except iterate a loop unchecked { // Register or activate tss key (revoked keys keep the previous nonce) for (uint256 i = 0; i < keys.length; i++) { TssKey memory newKey = keys[i]; // Read shard from storage bytes32 shardId = _tssKeyToShardId(newKey); KeyInfo storage shard = _shards[shardId]; uint8 status = shard.status; uint32 nonce = shard.nonce; // Check if the shard is not active require((status & SHARD_ACTIVE) == 0, "already active, cannot register again"); // Check y-parity uint8 yParity = newKey.yParity; require(yParity == (yParity & 1), "y parity bit must be 0 or 1, cannot register shard"); // If nonce is zero, it's a new shard, otherwise it is an existing shard which was previously revoked. if (nonce == 0) { // if is a new shard shard, set its initial nonce to 1 shard.nonce = 1; } else { // If the shard exists, the provided y-parity must match the original one uint8 actualYParity = (status & SHARD_Y_PARITY) > 0 ? 1 : 0; require( actualYParity == yParity, "the provided y-parity doesn't match the existing y-parity, cannot register shard" ); } // store the y-parity in the `KeyInfo` if (yParity > 0) { // enable SHARD_Y_PARITY bitflag status |= SHARD_Y_PARITY; } else { // disable SHARD_Y_PARITY bitflag status &= ~SHARD_Y_PARITY; } // enable SHARD_ACTIVE bitflag status |= SHARD_ACTIVE; // Save new status in the storage shard.status = status; } } } function _revokeKeys(TssKey[] memory keys) private { // We don't perform any arithmetic operation, except iterate a loop unchecked { // Revoke tss keys for (uint256 i = 0; i < keys.length; i++) { TssKey memory revokedKey = keys[i]; // Read shard from storage bytes32 shardId = _tssKeyToShardId(revokedKey); KeyInfo storage shard = _shards[shardId]; // Check if the shard exists and is active require(shard.nonce > 0, "shard doesn't exists, cannot revoke key"); require((shard.status & SHARD_ACTIVE) > 0, "cannot revoke a shard key already revoked"); // Check y-parity { uint8 yParity = (shard.status & SHARD_Y_PARITY) > 0 ? 1 : 0; require(yParity == revokedKey.yParity, "invalid y parity bit, cannot revoke key"); } // Disable SHARD_ACTIVE bitflag shard.status = shard.status & (~SHARD_ACTIVE); // Disable active flag } } } // Register/Revoke TSS keys and emits [`KeySetChanged`] event function _updateKeys(bytes32 messageHash, TssKey[] memory keysToRevoke, TssKey[] memory newKeys) private { // We don't perform any arithmetic operation, except iterate a loop unchecked { // Revoke tss keys (revoked keys can be registred again keeping the previous nonce) _revokeKeys(keysToRevoke); // Register or activate revoked keys _registerKeys(newKeys); } emit KeySetChanged(messageHash, keysToRevoke, newKeys); } // Register/Revoke TSS keys using shard TSS signature function updateKeys(Signature memory signature, UpdateKeysMessage memory message) public { bytes memory payload = getUpdateKeysTypedHash(message); bytes32 messageHash = keccak256(payload); _verifySignature(signature, messageHash); // Register shards pubkeys _updateKeys(messageHash, message.revoke, message.register); } // Deposit balance to refund callers of execute function deposit(bytes32 source, uint16 network) public payable { uint256 depositBefore = _deposits[source][network]; _deposits[source][network] = depositBefore + msg.value; } // Execute GMP message function _execute(bytes32 payloadHash, GmpMessage memory message) private returns (uint8 status, bytes32 result) { // Verify if this GMP message was already executed GmpInfo storage gmp = _messages[payloadHash]; require(gmp.status == GMP_STATUS_NOT_FOUND, "message already executed"); // Update status to `pending` to prevent reentrancy attacks. gmp.status = GMP_STATUS_PENDING; gmp.blockNumber = uint64(block.number); // The encoded onGmpReceived call bytes memory data = abi.encodeCall(IGmpReceiver.onGmpReceived, (payloadHash, message.srcNetwork, message.source, message.data)); // Execute GMP call bytes32[1] memory output = [bytes32(0)]; bool success; address dest = message.dest; // Cap the GMP gas limit to 80% of the block gas limit // OBS: we assume the remaining 20% is enough for the Gateway execution, which is a safe assumption // once most EVM blockchains have gas limits above 10M and don't need more than 60k gas for the Gateway execution. uint256 maxGasLimit = (block.gaslimit / 5) * 4; // 80% of the block gas limit uint256 gasLimit = BranchlessMath.min(message.gasLimit, maxGasLimit); // Make sure the gas left is enough to execute the GMP message unchecked { // Subtract 5000 gas, 2600 (CALL) + 2400 (other instructions with some margin) uint256 gasAvailable = BranchlessMath.saturatingSub(gasleft(), 5000); // “all but one 64th", reference: https://eips.ethereum.org/EIPS/eip-150 gasAvailable -= gasAvailable >> 6; require(gasAvailable > gasLimit, "gas left below message.gasLimit"); } assembly ("memory-safe") { // Using low-level assembly because the GMP is considered executed // regardless if the call reverts or not. let ptr := add(data, 32) let size := mload(data) // returns 1 if the call succeed, and 0 if it reverted success := call( gasLimit, // call gas limit (defined in the GMP message) dest, // dest address 0, // value in wei to transfer (always zero for GMP) ptr, // input memory pointer size, // input size output, // output memory pointer 32 // output size (fixed 32 bytes) ) } // Get Result result = output[0]; // Update GMP status status = uint8(BranchlessMath.choice(success, GMP_STATUS_SUCCESS, GMP_STATUS_REVERTED)); // Persist result and status on storage gmp.result = result; gmp.status = status; // Emit event emit GmpExecuted(payloadHash, message.source, message.dest, status, result); } // Send GMP message using sudo account function execute( Signature memory signature, // coordinate x, nonce, e, s GmpMessage memory message ) public returns (uint8 status, bytes32 result) { uint256 initialGas = gasleft(); // Theoretically we could remove the destination network field // and fill it up with the network id of the contract, then the signature will fail. require(message.destNetwork == NETWORK_ID, "invalid gmp network"); bytes memory payload = getGmpTypedHash(message); bytes32 messageHash = keccak256(payload); _verifySignature(signature, messageHash); (status, result) = _execute(messageHash, message); uint256 deposited = _deposits[message.source][message.srcNetwork]; // TODO: we must reimburse the tx base gas cost, we don't have access to it because it // is deducted before the contract is executed, currently it is calculated as: // base_gas = 21_000 + 4 * zeros + 16 * nonZeros uint256 refund = ((initialGas - gasleft()) + EXECUTE_GAS_DIFF) * tx.gasprice; require(deposited >= refund, "deposit below max refund"); _deposits[message.source][message.srcNetwork] = deposited - refund; payable(tx.origin).transfer(refund); } // Submit a new GMP message function submitMessage(address recipient, uint16 network, uint256 gasLimit, bytes memory data) external payable { // TODO: charge the gas cost of the Gateway execution // Check if the msg.sender is a contract or an EOA uint256 isContract = BranchlessMath.choice(tx.origin != msg.sender, 1, 0); // We use 20 bytes for the address and 1 bit for contract flag bytes32 source = bytes32(isContract << 160) | bytes32(uint256(uint160(msg.sender))); // Salt is equal to the previous message id (EIP-712 hash), this allows us to establish a sequence and eaily query the message history. bytes32 prevHash = prevMessageHash; // if the messageHash is the first message, we use a zero salt uint256 salt = BranchlessMath.choice(prevHash == FIRST_MESSAGE_PLACEHOLDER, 0, uint256(prevHash)); // Create GMP message and update prevMessageHash { GmpMessage memory message = GmpMessage(source, NETWORK_ID, recipient, network, gasLimit, salt, data); prevHash = keccak256(getGmpTypedHash(message)); prevMessageHash = prevHash; } emit GmpCreated(prevHash, source, recipient, network, gasLimit, salt, data); } }
//SPDX-License-Identifier: LGPLv3 pragma solidity ^0.8.0; library Schnorr { // secp256k1 group order uint256 internal constant Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141; // parity := public key y-coord parity (27 or 28) // px := public key x-coord // message := 32-byte message // e := schnorr signature challenge // s := schnorr signature function verify(uint8 parity, uint256 px, uint256 message, uint256 e, uint256 s) internal pure returns (bool) { // ecrecover = (m, v, r, s); uint256 sp = Q - mulmod(s, px, Q); uint256 ep = Q - mulmod(e, px, Q); require(sp != 0); // the ecrecover precompile implementation checks that the `r` and `s` // inputs are non-zero (in this case, `px` and `ep`), thus we don't need to // check if they're zero. address R = ecrecover(bytes32(sp), parity, bytes32(px), bytes32(ep)); require(R != address(0), "ecrecover failed"); return bytes32(e) == keccak256(abi.encodePacked(R, parity, px, message)); } }
pragma solidity >=0.7.0 <0.9.0; /** * @dev Utilities for branchless operations, useful when a constant gas cost is required. */ library BranchlessMath { /** * @dev Returns the smallest of two numbers. */ function min(uint256 x, uint256 y) internal pure returns (uint256 result) { assembly ("memory-safe") { // gas efficient branchless min function: // min(x,y) = y ^ ((x ^ y) * (x < y)) // Reference: https://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax result := xor(y, mul(xor(x, y), lt(x, y))) } } /** * @dev Returns the largest of two numbers. */ function max(uint256 x, uint256 y) internal pure returns (uint256 result) { assembly ("memory-safe") { // gas efficient branchless max function: // max(x,y) = x ^ ((x ^ y) * (x < y)) // Reference: https://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax result := xor(x, mul(xor(x, y), lt(x, y))) } } /** * @dev If `cond` is true, use `x`, otherwise use `y`. */ function choice(bool cond, uint256 x, uint256 y) internal pure returns (uint256 result) { assembly ("memory-safe") { // gas efficient branchless choice function: // choice(c,x,y) = x ^ ((x ^ y) * (c == 0)) result := xor(x, mul(xor(x, y), iszero(cond))) } } /** * @dev Unsigned saturating addition, bounds to UINT256 MAX instead of overflowing. * equivalent to: * uint256 r = x + y; * return r >= x ? r : UINT256_MAX; */ function saturatingAdd(uint256 x, uint256 y) internal pure returns (uint256 result) { assembly ("memory-safe") { // add(x,y) = (x + y) | -(y > (x + y)) x := add(x, y) y := sub(0, gt(y, x)) result := or(x, y) } } /** * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing. * equivalent to: x > y ? x - y : 0 */ function saturatingSub(uint256 x, uint256 y) internal pure returns (uint256 result) { assembly ("memory-safe") { // sub(x,y) = (x - y) * (x > y) result := mul(sub(x, y), gt(x, y)) } } }
{ "remappings": [ "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "frost-evm/=lib/frost-evm/" ], "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":"uint16","name":"networkId","type":"uint16"},{"components":[{"internalType":"uint8","name":"yParity","type":"uint8"},{"internalType":"uint256","name":"xCoord","type":"uint256"}],"internalType":"struct TssKey[]","name":"keys","type":"tuple[]"}],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"sender","type":"bytes32"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint16","name":"network","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"gasLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"salt","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"GmpCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"source","type":"bytes32"},{"indexed":true,"internalType":"address","name":"dest","type":"address"},{"indexed":false,"internalType":"uint256","name":"status","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"result","type":"bytes32"}],"name":"GmpExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"components":[{"internalType":"uint8","name":"yParity","type":"uint8"},{"internalType":"uint256","name":"xCoord","type":"uint256"}],"indexed":false,"internalType":"struct TssKey[]","name":"revoked","type":"tuple[]"},{"components":[{"internalType":"uint8","name":"yParity","type":"uint8"},{"internalType":"uint256","name":"xCoord","type":"uint256"}],"indexed":false,"internalType":"struct TssKey[]","name":"registered","type":"tuple[]"}],"name":"KeySetChanged","type":"event"},{"inputs":[{"internalType":"bytes32","name":"source","type":"bytes32"},{"internalType":"uint16","name":"network","type":"uint16"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"source","type":"bytes32"},{"internalType":"uint16","name":"networkId","type":"uint16"}],"name":"depositOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"xCoord","type":"uint256"},{"internalType":"uint256","name":"e","type":"uint256"},{"internalType":"uint256","name":"s","type":"uint256"}],"internalType":"struct Signature","name":"signature","type":"tuple"},{"components":[{"internalType":"bytes32","name":"source","type":"bytes32"},{"internalType":"uint16","name":"srcNetwork","type":"uint16"},{"internalType":"address","name":"dest","type":"address"},{"internalType":"uint16","name":"destNetwork","type":"uint16"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct GmpMessage","name":"message","type":"tuple"}],"name":"execute","outputs":[{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"bytes32","name":"result","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"source","type":"bytes32"},{"internalType":"uint16","name":"srcNetwork","type":"uint16"},{"internalType":"address","name":"dest","type":"address"},{"internalType":"uint16","name":"destNetwork","type":"uint16"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct GmpMessage","name":"message","type":"tuple"}],"name":"getGmpTypedHash","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"gmpInfo","outputs":[{"components":[{"internalType":"uint184","name":"_gap","type":"uint184"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"uint64","name":"blockNumber","type":"uint64"},{"internalType":"bytes32","name":"result","type":"bytes32"}],"internalType":"struct GmpInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"keyInfo","outputs":[{"components":[{"internalType":"uint216","name":"_gap","type":"uint216"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"uint32","name":"nonce","type":"uint32"}],"internalType":"struct KeyInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prevMessageHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint16","name":"network","type":"uint16"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"submitMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"xCoord","type":"uint256"},{"internalType":"uint256","name":"e","type":"uint256"},{"internalType":"uint256","name":"s","type":"uint256"}],"internalType":"struct Signature","name":"signature","type":"tuple"},{"components":[{"components":[{"internalType":"uint8","name":"yParity","type":"uint8"},{"internalType":"uint256","name":"xCoord","type":"uint256"}],"internalType":"struct TssKey[]","name":"revoke","type":"tuple[]"},{"components":[{"internalType":"uint8","name":"yParity","type":"uint8"},{"internalType":"uint256","name":"xCoord","type":"uint256"}],"internalType":"struct TssKey[]","name":"register","type":"tuple[]"}],"internalType":"struct UpdateKeysMessage","name":"message","type":"tuple"}],"name":"updateKeys","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c0604052604051611eab380380611eab83398101604081905261002291610436565b61ffff82166080818152604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527f9af41c8827b204ef75a7e66226328d17ead3ef661cad3235f0653f0d6fe6ae01828401527faa7cdbe2cce2ec7b606b0e199ddd9b264a6e645e767fb8479a7917dcd1b8693f6060830152928101939093523060a08085019190915281518085038201815260c09094019091528251929091019190912090526000196003556100e281610167565b604080516000808252602082019092528161011f565b60408051808201909152600080825260208201528152602001906001900390816100f85790505b5090506000801b7f08280779918718ff44abb0d69be5f2219690cd1c4155aa887ba7c2423a921e658284604051610157929190610579565b60405180910390a25050506105bd565b60005b81518110156103bd576000828281518110610187576101876105a7565b6020026020010151905060006101a2826103c160201b60201c565b6000818152602081905260409020805491925090600160d81b810460ff811691600160e01b900463ffffffff1690600116156102335760405162461bcd60e51b815260206004820152602560248201527f616c7265616479206163746976652c2063616e6e6f742072656769737465722060448201526430b3b0b4b760d91b60648201526084015b60405180910390fd5b845160ff811660018216146102a55760405162461bcd60e51b815260206004820152603260248201527f792070617269747920626974206d7573742062652030206f7220312c2063616e6044820152711b9bdd081c9959da5cdd195c881cda185c9960721b606482015260840161022a565b8163ffffffff166000036102cb5783546001600160e01b0316600160e01b178455610377565b6000600284166102dc5760006102df565b60015b90508160ff168160ff16146103755760405162461bcd60e51b815260206004820152605060248201527f7468652070726f766964656420792d70617269747920646f65736e2774206d6160448201527f74636820746865206578697374696e6720792d7061726974792c2063616e6e6f60648201526f1d081c9959da5cdd195c881cda185c9960821b608482015260a40161022a565b505b60ff81161561038b57600283179250610393565b600219831692505b5050815460ff60d81b1916600160d81b600192831760ff16021790915592909201915061016a9050565b5050565b6020015190565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715610400576104006103c8565b60405290565b604051601f8201601f191681016001600160401b038111828210171561042e5761042e6103c8565b604052919050565b600080604080848603121561044a57600080fd5b835161ffff8116811461045c57600080fd5b602085810151919450906001600160401b038082111561047b57600080fd5b818701915087601f83011261048f57600080fd5b8151818111156104a1576104a16103c8565b6104af848260051b01610406565b818152848101925060069190911b8301840190898211156104cf57600080fd5b928401925b8184101561051f5785848b0312156104ec5760008081fd5b6104f46103de565b845160ff811681146105065760008081fd5b81528486015186820152835292850192918401916104d4565b8096505050505050509250929050565b60008151808452602080850194506020840160005b8381101561056e578151805160ff1688528301518388015260409096019590820190600101610544565b509495945050505050565b60408152600061058c604083018561052f565b828103602084015261059e818561052f565b95945050505050565b634e487b7160e01b600052603260045260246000fd5b60805160a0516118bb6105f06000396000818161035601526106cb01526000818161045a015261052401526118bb6000f3fe6080604052600436106100865760003560e01c80638d3f97a6116100595780638d3f97a614610124578063a7ef4ebd146101d4578063b9d81984146101e7578063bdfbbea6146102cb578063d67929461461030457600080fd5b80631498212f1461008b5780632a1cf452146100ad5780634e9a2db5146100e357806379e293a814610111575b600080fd5b34801561009757600080fd5b506100ab6100a63660046113b7565b61031a565b005b3480156100b957600080fd5b506100cd6100c8366004611590565b610352565b6040516100da9190611612565b60405180910390f35b3480156100ef57600080fd5b506101036100fe36600461162c565b6103b2565b6040519081526020016100da565b6100ab61011f36600461162c565b6103d7565b34801561013057600080fd5b506101a061013f366004611658565b6040805160608082018352600080835260208084018290529284018190529384528382529282902082519384018352546001600160d81b0381168452600160d81b810460ff1691840191909152600160e01b900463ffffffff169082015290565b6040805182516001600160d81b0316815260208084015160ff16908201529181015163ffffffff16908201526060016100da565b6100ab6101e2366004611671565b610423565b3480156101f357600080fd5b50610283610202366004611658565b60408051608081018252600080825260208201819052918101829052606081019190915250600090815260016020818152604092839020835160808101855281546001600160b81b0381168252600160b81b810460ff1693820193909352600160c01b9092046001600160401b031693820193909352910154606082015290565b6040516100da919081516001600160b81b0316815260208083015160ff16908201526040808301516001600160401b0316908201526060918201519181019190915260800190565b3480156102d757600080fd5b506102eb6102e63660046116d8565b61051a565b6040805160ff90931683526020830191909152016100da565b34801561031057600080fd5b5061010360035481565b6000610325826106c7565b8051602082012090915061033984826106f3565b61034c81846000015185602001516107de565b50505050565b60607f000000000000000000000000000000000000000000000000000000000000000061037e8361082f565b60405161190160f01b6020820152602281019290925260428201526062016040516020818303038152906040529050919050565b600082815260026020908152604080832061ffff851684529091529020545b92915050565b600082815260026020908152604080832061ffff851684529091529020546103ff348261173c565b600093845260026020908152604080862061ffff9095168652939052919092205550565b60006001333214186003549091503360a083901b179060006000198214158202905060006040518060e001604052808581526020017f000000000000000000000000000000000000000000000000000000000000000061ffff1681526020018a6001600160a01b031681526020018961ffff1681526020018881526020018381526020018781525090506104b681610352565b8051906020012092508260038190555050876001600160a01b031683837f0114885f90b5168242aa31b7afb9c2e9f88e90ce329c893d3e6c56021c4c03a58a8a868b604051610508949392919061174f565b60405180910390a45050505050505050565b60008060005a90507f000000000000000000000000000000000000000000000000000000000000000061ffff16846060015161ffff16146105985760405162461bcd60e51b8152602060048201526013602482015272696e76616c696420676d70206e6574776f726b60681b60448201526064015b60405180910390fd5b60006105a385610352565b805160208201209091506105b787826106f3565b6105c181876108f2565b87516000908152600260209081526040808320828c015161ffff1684529091528120549297509095503a6123795a6105f99088611782565b610603919061173c565b61060d9190611795565b90508082101561065f5760405162461bcd60e51b815260206004820152601860248201527f6465706f7369742062656c6f77206d617820726566756e640000000000000000604482015260640161058f565b6106698183611782565b88516000908152600260209081526040808320828d015161ffff168452909152808220929092559051329183156108fc02918491818181858888f193505050501580156106ba573d6000803e3d6000fd5b5050505050509250929050565b60607f000000000000000000000000000000000000000000000000000000000000000061037e83610b19565b815160009081526020819052604090208054600160d81b900460ff8116906001166107605760405162461bcd60e51b815260206004820152601f60248201527f7368617264206b6579207265766f6b6564206f72206e6f742065786973747300604482015260640161058f565b600060028216156107735750601c610777565b50601b5b6107938186600001518660001c88602001518960400151610b75565b6107d75760405162461bcd60e51b8152602060048201526015602482015274696e76616c696420747373207369676e617475726560581b604482015260640161058f565b5050505050565b6107e782610d03565b6107f081610ed4565b827f08280779918718ff44abb0d69be5f2219690cd1c4155aa887ba7c2423a921e6583836040516108229291906117f6565b60405180910390a2505050565b60007feb1e0a6b8c4db87ab3beb15e5ae24e7c880703e1b9ee466077096eaeba83623b826000015183602001518460400151856060015186608001518760a001518860c00151805190602001206040516020016108d5989796959493929190978852602088019690965261ffff94851660408801526001600160a01b039390931660608701529216608085015260a084019190915260c083015260e08201526101000190565b604051602081830303815290604052805190602001209050919050565b60008281526001602052604081208054829190600160b81b900460ff161561095c5760405162461bcd60e51b815260206004820152601860248201527f6d65737361676520616c72656164792065786563757465640000000000000000604482015260640161058f565b80546001600160401b034316600160c01b026001600160b81b0390911617600160bf1b1781556020840151845160c08601516040516000936109a7938a939192909190602401611824565b60408051601f19818403018152918152602080830180516001600160e01b0316630190093760e01b1790528151908101825260008082529188015192935091816109f260054561184d565b6109fd906004611795565b60808a01519091508181189082110281186000610a205a61138880820391110290565b600681901c90039050818111610a785760405162461bcd60e51b815260206004820152601f60248201527f676173206c6566742062656c6f77206d6573736167652e6761734c696d697400604482015260640161058f565b50602086018651602087828460008988f187519a509550506001600386150218905060018801899055875460ff60b81b1916600160b81b60ff831690810291909117895560408c8101518d518251938452602084018d9052939c506001600160a01b031692918e917f29f318d7f9b869de8987630235eb1a1ea9d870133c3092af2510a9fed3e3da21910160405180910390a4505050505050509250929050565b60007f20196ac379740f17512afd999063959b8bfeee674b5db6c6c6f934a8fa3f1074610b498360000151611121565b610b568460200151611121565b60408051602081019490945283019190915260608201526080016108d5565b60008070014551231950b75fc4402da1732fc9bebe19868409610baa9070014551231950b75fc4402da1732fc9bebe19611782565b9050600070014551231950b75fc4402da1732fc9bebe19878609610be09070014551231950b75fc4402da1732fc9bebe19611782565b905081600003610bef57600080fd5b6040805160008082526020820180845285905260ff8b1692820192909252606081018990526080810183905260019060a0016020604051602081039080840390855afa158015610c43573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610c995760405162461bcd60e51b815260206004820152601060248201526f1958dc9958dbdd995c8819985a5b195960821b604482015260640161058f565b6040516bffffffffffffffffffffffff19606083901b1660208201526001600160f81b031960f88b901b1660348201526035810189905260558101889052607501604051602081830303815290604052805190602001208660001b14935050505095945050505050565b60005b8151811015610ed0576000828281518110610d2357610d2361186f565b602002602001015190506000610d3a826020015190565b6000818152602081905260409020805491925090600160e01b900463ffffffff16610db75760405162461bcd60e51b815260206004820152602760248201527f736861726420646f65736e2774206578697374732c2063616e6e6f74207265766044820152666f6b65206b657960c81b606482015260840161058f565b8054600160d81b9004600116610e215760405162461bcd60e51b815260206004820152602960248201527f63616e6e6f74207265766f6b652061207368617264206b657920616c726561646044820152681e481c995d9bdad95960ba1b606482015260840161058f565b8054600090600160d81b9004600216610e3b576000610e3e565b60015b9050836000015160ff168160ff1614610ea95760405162461bcd60e51b815260206004820152602760248201527f696e76616c6964207920706172697479206269742c2063616e6e6f74207265766044820152666f6b65206b657960c81b606482015260840161058f565b50805460ff60d81b198116600160d81b9182900460fe169091021790555050600101610d06565b5050565b60005b8151811015610ed0576000828281518110610ef457610ef461186f565b602002602001015190506000610f0b826020015190565b6000818152602081905260409020805491925090600160d81b810460ff811691600160e01b900463ffffffff169060011615610f975760405162461bcd60e51b815260206004820152602560248201527f616c7265616479206163746976652c2063616e6e6f742072656769737465722060448201526430b3b0b4b760d91b606482015260840161058f565b845160ff811660018216146110095760405162461bcd60e51b815260206004820152603260248201527f792070617269747920626974206d7573742062652030206f7220312c2063616e6044820152711b9bdd081c9959da5cdd195c881cda185c9960721b606482015260840161058f565b8163ffffffff1660000361102f5783546001600160e01b0316600160e01b1784556110db565b600060028416611040576000611043565b60015b90508160ff168160ff16146110d95760405162461bcd60e51b815260206004820152605060248201527f7468652070726f766964656420792d70617269747920646f65736e2774206d6160448201527f74636820746865206578697374696e6720792d7061726974792c2063616e6e6f60648201526f1d081c9959da5cdd195c881cda185c9960821b608482015260a40161058f565b505b60ff8116156110ef576002831792506110f7565b600219831692505b5050815460ff60d81b1916600160d81b600192831760ff160217909155929092019150610ed79050565b600080825160206111329190611795565b6001600160401b0381111561114957611149611219565b6040519080825280601f01601f191660200182016040528015611173576020820181803683370190505b5090508060005b84518110156111b95760006111a786838151811061119a5761119a61186f565b60200260200101516111c9565b6020939093019283525060010161117a565b5050805160209091012092915050565b80516020808301516040516000936108d5937f811c696df5f31d44fda354b9ceaa10237015e73b631a3eb69dbca953eac4a5009391920192835260ff919091166020830152604082015260600190565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561125157611251611219565b60405290565b60405160e081016001600160401b038111828210171561125157611251611219565b604051601f8201601f191681016001600160401b03811182821017156112a1576112a1611219565b604052919050565b6000606082840312156112bb57600080fd5b604051606081018181106001600160401b03821117156112dd576112dd611219565b80604052508091508235815260208301356020820152604083013560408201525092915050565b600082601f83011261131557600080fd5b813560206001600160401b0382111561133057611330611219565b61133e818360051b01611279565b82815260069290921b8401810191818101908684111561135d57600080fd5b8286015b848110156113ac576040818903121561137a5760008081fd5b61138261122f565b813560ff811681146113945760008081fd5b81528185013585820152835291830191604001611361565b509695505050505050565b600080608083850312156113ca57600080fd5b6113d484846112a9565b915060608301356001600160401b03808211156113f057600080fd5b908401906040828703121561140457600080fd5b61140c61122f565b82358281111561141b57600080fd5b61142788828601611304565b82525060208301358281111561143c57600080fd5b61144888828601611304565b6020830152508093505050509250929050565b803561ffff8116811461146d57600080fd5b919050565b80356001600160a01b038116811461146d57600080fd5b600082601f83011261149a57600080fd5b81356001600160401b038111156114b3576114b3611219565b6114c6601f8201601f1916602001611279565b8181528460208386010111156114db57600080fd5b816020850160208301376000918101602001919091529392505050565b600060e0828403121561150a57600080fd5b611512611257565b9050813581526115246020830161145b565b602082015261153560408301611472565b60408201526115466060830161145b565b60608201526080820135608082015260a082013560a082015260c08201356001600160401b0381111561157857600080fd5b61158484828501611489565b60c08301525092915050565b6000602082840312156115a257600080fd5b81356001600160401b038111156115b857600080fd5b6115c4848285016114f8565b949350505050565b6000815180845260005b818110156115f2576020818501810151868301820152016115d6565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061162560208301846115cc565b9392505050565b6000806040838503121561163f57600080fd5b8235915061164f6020840161145b565b90509250929050565b60006020828403121561166a57600080fd5b5035919050565b6000806000806080858703121561168757600080fd5b61169085611472565b935061169e6020860161145b565b92506040850135915060608501356001600160401b038111156116c057600080fd5b6116cc87828801611489565b91505092959194509250565b600080608083850312156116eb57600080fd5b6116f584846112a9565b915060608301356001600160401b0381111561171057600080fd5b61171c858286016114f8565b9150509250929050565b634e487b7160e01b600052601160045260246000fd5b808201808211156103d1576103d1611726565b61ffff8516815283602082015282604082015260806060820152600061177860808301846115cc565b9695505050505050565b818103818111156103d1576103d1611726565b80820281158282048414176103d1576103d1611726565b60008151808452602080850194506020840160005b838110156117eb578151805160ff16885283015183880152604090960195908201906001016117c1565b509495945050505050565b60408152600061180960408301856117ac565b828103602084015261181b81856117ac565b95945050505050565b84815261ffff8416602082015282604082015260806060820152600061177860808301846115cc565b60008261186a57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e597ea991356b942c3027ae1235720bad340395d40fe5e7a2cb48a74f6436b5564736f6c634300081900330000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ea799c7abe5e749b5e7c180ea319eee79c36cc89cae50ba26aeae11d2f1ce54d
Deployed Bytecode
0x6080604052600436106100865760003560e01c80638d3f97a6116100595780638d3f97a614610124578063a7ef4ebd146101d4578063b9d81984146101e7578063bdfbbea6146102cb578063d67929461461030457600080fd5b80631498212f1461008b5780632a1cf452146100ad5780634e9a2db5146100e357806379e293a814610111575b600080fd5b34801561009757600080fd5b506100ab6100a63660046113b7565b61031a565b005b3480156100b957600080fd5b506100cd6100c8366004611590565b610352565b6040516100da9190611612565b60405180910390f35b3480156100ef57600080fd5b506101036100fe36600461162c565b6103b2565b6040519081526020016100da565b6100ab61011f36600461162c565b6103d7565b34801561013057600080fd5b506101a061013f366004611658565b6040805160608082018352600080835260208084018290529284018190529384528382529282902082519384018352546001600160d81b0381168452600160d81b810460ff1691840191909152600160e01b900463ffffffff169082015290565b6040805182516001600160d81b0316815260208084015160ff16908201529181015163ffffffff16908201526060016100da565b6100ab6101e2366004611671565b610423565b3480156101f357600080fd5b50610283610202366004611658565b60408051608081018252600080825260208201819052918101829052606081019190915250600090815260016020818152604092839020835160808101855281546001600160b81b0381168252600160b81b810460ff1693820193909352600160c01b9092046001600160401b031693820193909352910154606082015290565b6040516100da919081516001600160b81b0316815260208083015160ff16908201526040808301516001600160401b0316908201526060918201519181019190915260800190565b3480156102d757600080fd5b506102eb6102e63660046116d8565b61051a565b6040805160ff90931683526020830191909152016100da565b34801561031057600080fd5b5061010360035481565b6000610325826106c7565b8051602082012090915061033984826106f3565b61034c81846000015185602001516107de565b50505050565b60607f42487e60b8430b462aaec984dbc48065224b826d2de7f497b18c3fd5578fe77761037e8361082f565b60405161190160f01b6020820152602281019290925260428201526062016040516020818303038152906040529050919050565b600082815260026020908152604080832061ffff851684529091529020545b92915050565b600082815260026020908152604080832061ffff851684529091529020546103ff348261173c565b600093845260026020908152604080862061ffff9095168652939052919092205550565b60006001333214186003549091503360a083901b179060006000198214158202905060006040518060e001604052808581526020017f000000000000000000000000000000000000000000000000000000000000000561ffff1681526020018a6001600160a01b031681526020018961ffff1681526020018881526020018381526020018781525090506104b681610352565b8051906020012092508260038190555050876001600160a01b031683837f0114885f90b5168242aa31b7afb9c2e9f88e90ce329c893d3e6c56021c4c03a58a8a868b604051610508949392919061174f565b60405180910390a45050505050505050565b60008060005a90507f000000000000000000000000000000000000000000000000000000000000000561ffff16846060015161ffff16146105985760405162461bcd60e51b8152602060048201526013602482015272696e76616c696420676d70206e6574776f726b60681b60448201526064015b60405180910390fd5b60006105a385610352565b805160208201209091506105b787826106f3565b6105c181876108f2565b87516000908152600260209081526040808320828c015161ffff1684529091528120549297509095503a6123795a6105f99088611782565b610603919061173c565b61060d9190611795565b90508082101561065f5760405162461bcd60e51b815260206004820152601860248201527f6465706f7369742062656c6f77206d617820726566756e640000000000000000604482015260640161058f565b6106698183611782565b88516000908152600260209081526040808320828d015161ffff168452909152808220929092559051329183156108fc02918491818181858888f193505050501580156106ba573d6000803e3d6000fd5b5050505050509250929050565b60607f42487e60b8430b462aaec984dbc48065224b826d2de7f497b18c3fd5578fe77761037e83610b19565b815160009081526020819052604090208054600160d81b900460ff8116906001166107605760405162461bcd60e51b815260206004820152601f60248201527f7368617264206b6579207265766f6b6564206f72206e6f742065786973747300604482015260640161058f565b600060028216156107735750601c610777565b50601b5b6107938186600001518660001c88602001518960400151610b75565b6107d75760405162461bcd60e51b8152602060048201526015602482015274696e76616c696420747373207369676e617475726560581b604482015260640161058f565b5050505050565b6107e782610d03565b6107f081610ed4565b827f08280779918718ff44abb0d69be5f2219690cd1c4155aa887ba7c2423a921e6583836040516108229291906117f6565b60405180910390a2505050565b60007feb1e0a6b8c4db87ab3beb15e5ae24e7c880703e1b9ee466077096eaeba83623b826000015183602001518460400151856060015186608001518760a001518860c00151805190602001206040516020016108d5989796959493929190978852602088019690965261ffff94851660408801526001600160a01b039390931660608701529216608085015260a084019190915260c083015260e08201526101000190565b604051602081830303815290604052805190602001209050919050565b60008281526001602052604081208054829190600160b81b900460ff161561095c5760405162461bcd60e51b815260206004820152601860248201527f6d65737361676520616c72656164792065786563757465640000000000000000604482015260640161058f565b80546001600160401b034316600160c01b026001600160b81b0390911617600160bf1b1781556020840151845160c08601516040516000936109a7938a939192909190602401611824565b60408051601f19818403018152918152602080830180516001600160e01b0316630190093760e01b1790528151908101825260008082529188015192935091816109f260054561184d565b6109fd906004611795565b60808a01519091508181189082110281186000610a205a61138880820391110290565b600681901c90039050818111610a785760405162461bcd60e51b815260206004820152601f60248201527f676173206c6566742062656c6f77206d6573736167652e6761734c696d697400604482015260640161058f565b50602086018651602087828460008988f187519a509550506001600386150218905060018801899055875460ff60b81b1916600160b81b60ff831690810291909117895560408c8101518d518251938452602084018d9052939c506001600160a01b031692918e917f29f318d7f9b869de8987630235eb1a1ea9d870133c3092af2510a9fed3e3da21910160405180910390a4505050505050509250929050565b60007f20196ac379740f17512afd999063959b8bfeee674b5db6c6c6f934a8fa3f1074610b498360000151611121565b610b568460200151611121565b60408051602081019490945283019190915260608201526080016108d5565b60008070014551231950b75fc4402da1732fc9bebe19868409610baa9070014551231950b75fc4402da1732fc9bebe19611782565b9050600070014551231950b75fc4402da1732fc9bebe19878609610be09070014551231950b75fc4402da1732fc9bebe19611782565b905081600003610bef57600080fd5b6040805160008082526020820180845285905260ff8b1692820192909252606081018990526080810183905260019060a0016020604051602081039080840390855afa158015610c43573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610c995760405162461bcd60e51b815260206004820152601060248201526f1958dc9958dbdd995c8819985a5b195960821b604482015260640161058f565b6040516bffffffffffffffffffffffff19606083901b1660208201526001600160f81b031960f88b901b1660348201526035810189905260558101889052607501604051602081830303815290604052805190602001208660001b14935050505095945050505050565b60005b8151811015610ed0576000828281518110610d2357610d2361186f565b602002602001015190506000610d3a826020015190565b6000818152602081905260409020805491925090600160e01b900463ffffffff16610db75760405162461bcd60e51b815260206004820152602760248201527f736861726420646f65736e2774206578697374732c2063616e6e6f74207265766044820152666f6b65206b657960c81b606482015260840161058f565b8054600160d81b9004600116610e215760405162461bcd60e51b815260206004820152602960248201527f63616e6e6f74207265766f6b652061207368617264206b657920616c726561646044820152681e481c995d9bdad95960ba1b606482015260840161058f565b8054600090600160d81b9004600216610e3b576000610e3e565b60015b9050836000015160ff168160ff1614610ea95760405162461bcd60e51b815260206004820152602760248201527f696e76616c6964207920706172697479206269742c2063616e6e6f74207265766044820152666f6b65206b657960c81b606482015260840161058f565b50805460ff60d81b198116600160d81b9182900460fe169091021790555050600101610d06565b5050565b60005b8151811015610ed0576000828281518110610ef457610ef461186f565b602002602001015190506000610f0b826020015190565b6000818152602081905260409020805491925090600160d81b810460ff811691600160e01b900463ffffffff169060011615610f975760405162461bcd60e51b815260206004820152602560248201527f616c7265616479206163746976652c2063616e6e6f742072656769737465722060448201526430b3b0b4b760d91b606482015260840161058f565b845160ff811660018216146110095760405162461bcd60e51b815260206004820152603260248201527f792070617269747920626974206d7573742062652030206f7220312c2063616e6044820152711b9bdd081c9959da5cdd195c881cda185c9960721b606482015260840161058f565b8163ffffffff1660000361102f5783546001600160e01b0316600160e01b1784556110db565b600060028416611040576000611043565b60015b90508160ff168160ff16146110d95760405162461bcd60e51b815260206004820152605060248201527f7468652070726f766964656420792d70617269747920646f65736e2774206d6160448201527f74636820746865206578697374696e6720792d7061726974792c2063616e6e6f60648201526f1d081c9959da5cdd195c881cda185c9960821b608482015260a40161058f565b505b60ff8116156110ef576002831792506110f7565b600219831692505b5050815460ff60d81b1916600160d81b600192831760ff160217909155929092019150610ed79050565b600080825160206111329190611795565b6001600160401b0381111561114957611149611219565b6040519080825280601f01601f191660200182016040528015611173576020820181803683370190505b5090508060005b84518110156111b95760006111a786838151811061119a5761119a61186f565b60200260200101516111c9565b6020939093019283525060010161117a565b5050805160209091012092915050565b80516020808301516040516000936108d5937f811c696df5f31d44fda354b9ceaa10237015e73b631a3eb69dbca953eac4a5009391920192835260ff919091166020830152604082015260600190565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561125157611251611219565b60405290565b60405160e081016001600160401b038111828210171561125157611251611219565b604051601f8201601f191681016001600160401b03811182821017156112a1576112a1611219565b604052919050565b6000606082840312156112bb57600080fd5b604051606081018181106001600160401b03821117156112dd576112dd611219565b80604052508091508235815260208301356020820152604083013560408201525092915050565b600082601f83011261131557600080fd5b813560206001600160401b0382111561133057611330611219565b61133e818360051b01611279565b82815260069290921b8401810191818101908684111561135d57600080fd5b8286015b848110156113ac576040818903121561137a5760008081fd5b61138261122f565b813560ff811681146113945760008081fd5b81528185013585820152835291830191604001611361565b509695505050505050565b600080608083850312156113ca57600080fd5b6113d484846112a9565b915060608301356001600160401b03808211156113f057600080fd5b908401906040828703121561140457600080fd5b61140c61122f565b82358281111561141b57600080fd5b61142788828601611304565b82525060208301358281111561143c57600080fd5b61144888828601611304565b6020830152508093505050509250929050565b803561ffff8116811461146d57600080fd5b919050565b80356001600160a01b038116811461146d57600080fd5b600082601f83011261149a57600080fd5b81356001600160401b038111156114b3576114b3611219565b6114c6601f8201601f1916602001611279565b8181528460208386010111156114db57600080fd5b816020850160208301376000918101602001919091529392505050565b600060e0828403121561150a57600080fd5b611512611257565b9050813581526115246020830161145b565b602082015261153560408301611472565b60408201526115466060830161145b565b60608201526080820135608082015260a082013560a082015260c08201356001600160401b0381111561157857600080fd5b61158484828501611489565b60c08301525092915050565b6000602082840312156115a257600080fd5b81356001600160401b038111156115b857600080fd5b6115c4848285016114f8565b949350505050565b6000815180845260005b818110156115f2576020818501810151868301820152016115d6565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061162560208301846115cc565b9392505050565b6000806040838503121561163f57600080fd5b8235915061164f6020840161145b565b90509250929050565b60006020828403121561166a57600080fd5b5035919050565b6000806000806080858703121561168757600080fd5b61169085611472565b935061169e6020860161145b565b92506040850135915060608501356001600160401b038111156116c057600080fd5b6116cc87828801611489565b91505092959194509250565b600080608083850312156116eb57600080fd5b6116f584846112a9565b915060608301356001600160401b0381111561171057600080fd5b61171c858286016114f8565b9150509250929050565b634e487b7160e01b600052601160045260246000fd5b808201808211156103d1576103d1611726565b61ffff8516815283602082015282604082015260806060820152600061177860808301846115cc565b9695505050505050565b818103818111156103d1576103d1611726565b80820281158282048414176103d1576103d1611726565b60008151808452602080850194506020840160005b838110156117eb578151805160ff16885283015183880152604090960195908201906001016117c1565b509495945050505050565b60408152600061180960408301856117ac565b828103602084015261181b81856117ac565b95945050505050565b84815261ffff8416602082015282604082015260806060820152600061177860808301846115cc565b60008261186a57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e597ea991356b942c3027ae1235720bad340395d40fe5e7a2cb48a74f6436b5564736f6c63430008190033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ea799c7abe5e749b5e7c180ea319eee79c36cc89cae50ba26aeae11d2f1ce54d
-----Decoded View---------------
Arg [0] : networkId (uint16): 5
Arg [1] : keys (tuple[]): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : ea799c7abe5e749b5e7c180ea319eee79c36cc89cae50ba26aeae11d2f1ce54d
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.