Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 737 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Propagate Root | 20936732 | 19 hrs ago | IN | 0 ETH | 0.00104006 | ||||
Propagate Root | 20929557 | 43 hrs ago | IN | 0 ETH | 0.00226411 | ||||
Propagate Root | 20922383 | 2 days ago | IN | 0 ETH | 0.00259978 | ||||
Propagate Root | 20915202 | 3 days ago | IN | 0 ETH | 0.00207085 | ||||
Propagate Root | 20908030 | 4 days ago | IN | 0 ETH | 0.00046082 | ||||
Propagate Root | 20900855 | 5 days ago | IN | 0 ETH | 0.00033711 | ||||
Propagate Root | 20893685 | 6 days ago | IN | 0 ETH | 0.00059249 | ||||
Propagate Root | 20886502 | 7 days ago | IN | 0 ETH | 0.00048605 | ||||
Propagate Root | 20879336 | 8 days ago | IN | 0 ETH | 0.00239484 | ||||
Propagate Root | 20872163 | 9 days ago | IN | 0 ETH | 0.00304351 | ||||
Propagate Root | 20864993 | 10 days ago | IN | 0 ETH | 0.00092992 | ||||
Propagate Root | 20857817 | 11 days ago | IN | 0 ETH | 0.000452 | ||||
Propagate Root | 20850653 | 12 days ago | IN | 0 ETH | 0.00041357 | ||||
Propagate Root | 20843479 | 13 days ago | IN | 0 ETH | 0.00095331 | ||||
Propagate Root | 20836314 | 14 days ago | IN | 0 ETH | 0.001965 | ||||
Propagate Root | 20829139 | 15 days ago | IN | 0 ETH | 0.00173152 | ||||
Propagate Root | 20821977 | 16 days ago | IN | 0 ETH | 0.00271254 | ||||
Propagate Root | 20814801 | 17 days ago | IN | 0 ETH | 0.00132629 | ||||
Propagate Root | 20807639 | 18 days ago | IN | 0 ETH | 0.00169979 | ||||
Propagate Root | 20800470 | 19 days ago | IN | 0 ETH | 0.00062018 | ||||
Propagate Root | 20793320 | 20 days ago | IN | 0 ETH | 0.00118713 | ||||
Propagate Root | 20786159 | 21 days ago | IN | 0 ETH | 0.00116768 | ||||
Propagate Root | 20778997 | 22 days ago | IN | 0 ETH | 0.00058216 | ||||
Propagate Root | 20771844 | 23 days ago | IN | 0 ETH | 0.00128077 | ||||
Propagate Root | 20764691 | 24 days ago | IN | 0 ETH | 0.00037148 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
PolygonStateBridge
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 10000 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; // Optimism interface for cross domain messaging import {IPolygonWorldID} from "./interfaces/IPolygonWorldID.sol"; import {IWorldIDIdentityManager} from "./interfaces/IWorldIDIdentityManager.sol"; import {IRootHistory} from "./interfaces/IRootHistory.sol"; import {Ownable2Step} from "openzeppelin-contracts/access/Ownable2Step.sol"; import {FxBaseRootTunnel} from "fx-portal/contracts/tunnel/FxBaseRootTunnel.sol"; /// @title Polygon World ID State Bridge /// @author Worldcoin /// @notice Distributes new World ID Identity Manager roots to World ID supported networks /// @dev This contract lives on Ethereum mainnet and is called by the World ID Identity Manager contract /// in the registerIdentities method contract PolygonStateBridge is FxBaseRootTunnel, Ownable2Step { /////////////////////////////////////////////////////////////////// /// STORAGE /// /////////////////////////////////////////////////////////////////// /// @notice WorldID Identity Manager contract IWorldIDIdentityManager public immutable worldID; /////////////////////////////////////////////////////////////////// /// EVENTS /// /////////////////////////////////////////////////////////////////// /// @notice Emitted when the StateBridge sets the root history expiry for OpWorldID and PolygonWorldID /// @param rootHistoryExpiry The new root history expiry event SetRootHistoryExpiry(uint256 rootHistoryExpiry); /// @notice Emitted when the owner calls setFxChildTunnel for the first time event SetFxChildTunnel(address fxChildTunnel); /// @notice Emitted when a root is sent to PolygonWorldID /// @param root The latest WorldID Identity Manager root. event RootPropagated(uint256 root); /////////////////////////////////////////////////////////////////// /// ERRORS /// /////////////////////////////////////////////////////////////////// /// @notice Emitted when an attempt is made to renounce ownership. error CannotRenounceOwnership(); /// @notice Emitted when an attempt is made to set the FxBaseRootTunnel, /// FxChildTunnel, CheckpointManager or WorldIDIdentityManager addresses to the zero address. error AddressZero(); /// @notice Emitted when an attempt is made to set the FxBaseRootTunnel's /// fxChildTunnel when it has already been set. error FxBaseRootChildTunnelAlreadySet(); /////////////////////////////////////////////////////////////////// /// CONSTRUCTOR /// /////////////////////////////////////////////////////////////////// /// @notice constructor /// @param _checkpointManager address of the checkpoint manager contract /// @param _fxRoot address of Polygon's fxRoot contract, part of the FxPortal bridge (Goerli or Mainnet) /// @param _worldIDIdentityManager Deployment address of the WorldID Identity Manager contract /// @custom:reverts AddressZero If any of the constructor arguments are the zero address constructor(address _checkpointManager, address _fxRoot, address _worldIDIdentityManager) FxBaseRootTunnel(_checkpointManager, _fxRoot) { if ( _checkpointManager == address(0) || _fxRoot == address(0) || _worldIDIdentityManager == address(0) ) { revert AddressZero(); } worldID = IWorldIDIdentityManager(_worldIDIdentityManager); } /////////////////////////////////////////////////////////////////// /// PUBLIC API /// /////////////////////////////////////////////////////////////////// /// @notice Sends the latest WorldIDIdentityManager root /// to Polygon's StateChild contract (PolygonWorldID) function propagateRoot() external { uint256 latestRoot = worldID.latestRoot(); bytes memory message = abi.encodeCall(IPolygonWorldID.receiveRoot, (latestRoot)); /// @notice FxBaseRootTunnel method to send bytes payload to FxBaseChildTunnel contract _sendMessageToChild(message); emit RootPropagated(latestRoot); } /// @notice Sets the root history expiry for PolygonWorldID /// @param _rootHistoryExpiry The new root history expiry function setRootHistoryExpiryPolygon(uint256 _rootHistoryExpiry) external onlyOwner { bytes memory message = abi.encodeCall(IRootHistory.setRootHistoryExpiry, (_rootHistoryExpiry)); /// @notice FxBaseRootTunnel method to send bytes payload to FxBaseChildTunnel contract _sendMessageToChild(message); emit SetRootHistoryExpiry(_rootHistoryExpiry); } /// @notice boilerplate function to satisfy FxBaseRootTunnel inheritance (not going to be used) function _processMessageFromChild(bytes memory) internal override { /// WorldID 🌎🆔 State Bridge } /////////////////////////////////////////////////////////////////////////////// /// ADDRESS MANAGEMENT /// /////////////////////////////////////////////////////////////////////////////// /// @notice Sets the `fxChildTunnel` address if not already set. /// @dev This implementation replicates the logic from `FxBaseRootTunnel` due to the inability /// to call `external` superclass methods when overriding them. /// /// @param _fxChildTunnel The address of the child (non-L1) tunnel contract. /// /// @custom:reverts string If the root tunnel has already been set. /// @custom:reverts AddressZero If the `_fxChildTunnel` is the zero address. function setFxChildTunnel(address _fxChildTunnel) public virtual override onlyOwner { if (fxChildTunnel != address(0x0)) { revert FxBaseRootChildTunnelAlreadySet(); } if (_fxChildTunnel == address(0x0)) { revert AddressZero(); } fxChildTunnel = _fxChildTunnel; emit SetFxChildTunnel(_fxChildTunnel); } /////////////////////////////////////////////////////////////////// /// OWNERSHIP /// /////////////////////////////////////////////////////////////////// /// @notice Ensures that ownership of WorldID implementations cannot be renounced. /// @dev This function is intentionally not `virtual` as we do not want it to be possible to /// renounce ownership for any WorldID implementation. /// @dev This function is marked as `onlyOwner` to maintain the access restriction from the base /// contract. function renounceOwnership() public view override onlyOwner { revert CannotRenounceOwnership(); } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.15; /// @title Interface for the PolygonWorldID contract /// @author Worldcoin /// @notice Interface for the CrossDomainOwnable contract for the Optimism L2 /// @custom:usage abi.encodeCall(IPolygonWorldID.receiveRoot, (_newRoot, _supersedeTimestamp)); interface IPolygonWorldID { //////////////////////////////////////////////////////////////////////////////// /// ROOT MIRRORING /// /////////////////////////////////////////////////////////////////////////////// /// @notice This function is called by the state bridge contract when it forwards a new root to /// the bridged WorldID. /// /// @param newRoot The value of the new root. /// /// @custom:reverts CannotOverwriteRoot If the root already exists in the root history. /// @custom:reverts string If the caller is not the owner. function receiveRoot(uint256 newRoot) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; /// @title IWorldIDIdentityManager /// @author Worldcoin /// @dev used to fetch the latest root from the WorldIDIdentityManager interface IWorldIDIdentityManager { /// @notice returns the latest root function latestRoot() external view returns (uint256); }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.15; /// @title Interface for WorldID setRooHistoryExpiry /// @author Worldcoin /// @notice Interface for WorldID setRooHistoryExpiry /// @dev Used in StateBridge to set the root history expiry time on Optimism (OPWorldID) /// @custom:usage abi.encodeCall(IRootHistory.setRootHistoryExpiry, (_expiryTime)); interface IRootHistory { /// @notice Sets the amount of time it takes for a root in the root history to expire. /// /// @param expiryTime The new amount of time it takes for a root to expire. /// /// @custom:reverts string If the caller is not the owner. function setRootHistoryExpiry(uint256 expiryTime) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (access/Ownable2Step.sol) pragma solidity ^0.8.0; import "./Ownable.sol"; /** * @dev Contract module which provides access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() external { address sender = _msgSender(); require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); _transferOwnership(sender); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {RLPReader} from "../lib/RLPReader.sol"; import {MerklePatriciaProof} from "../lib/MerklePatriciaProof.sol"; import {Merkle} from "../lib/Merkle.sol"; import "../lib/ExitPayloadReader.sol"; interface IFxStateSender { function sendMessageToChild(address _receiver, bytes calldata _data) external; } contract ICheckpointManager { struct HeaderBlock { bytes32 root; uint256 start; uint256 end; uint256 createdAt; address proposer; } /** * @notice mapping of checkpoint header numbers to block details * @dev These checkpoints are submited by plasma contracts */ mapping(uint256 => HeaderBlock) public headerBlocks; } abstract contract FxBaseRootTunnel { using RLPReader for RLPReader.RLPItem; using Merkle for bytes32; using ExitPayloadReader for bytes; using ExitPayloadReader for ExitPayloadReader.ExitPayload; using ExitPayloadReader for ExitPayloadReader.Log; using ExitPayloadReader for ExitPayloadReader.LogTopics; using ExitPayloadReader for ExitPayloadReader.Receipt; // keccak256(MessageSent(bytes)) bytes32 public constant SEND_MESSAGE_EVENT_SIG = 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036; // state sender contract IFxStateSender public fxRoot; // root chain manager ICheckpointManager public checkpointManager; // child tunnel contract which receives and sends messages address public fxChildTunnel; // storage to avoid duplicate exits mapping(bytes32 => bool) public processedExits; constructor(address _checkpointManager, address _fxRoot) { checkpointManager = ICheckpointManager(_checkpointManager); fxRoot = IFxStateSender(_fxRoot); } // set fxChildTunnel if not set already function setFxChildTunnel(address _fxChildTunnel) public virtual { require(fxChildTunnel == address(0x0), "FxBaseRootTunnel: CHILD_TUNNEL_ALREADY_SET"); fxChildTunnel = _fxChildTunnel; } /** * @notice Send bytes message to Child Tunnel * @param message bytes message that will be sent to Child Tunnel * some message examples - * abi.encode(tokenId); * abi.encode(tokenId, tokenMetadata); * abi.encode(messageType, messageData); */ function _sendMessageToChild(bytes memory message) internal { fxRoot.sendMessageToChild(fxChildTunnel, message); } function _validateAndExtractMessage(bytes memory inputData) internal returns (bytes memory) { ExitPayloadReader.ExitPayload memory payload = inputData.toExitPayload(); bytes memory branchMaskBytes = payload.getBranchMaskAsBytes(); uint256 blockNumber = payload.getBlockNumber(); // checking if exit has already been processed // unique exit is identified using hash of (blockNumber, branchMask, receiptLogIndex) bytes32 exitHash = keccak256( abi.encodePacked( blockNumber, // first 2 nibbles are dropped while generating nibble array // this allows branch masks that are valid but bypass exitHash check (changing first 2 nibbles only) // so converting to nibble array and then hashing it MerklePatriciaProof._getNibbleArray(branchMaskBytes), payload.getReceiptLogIndex() ) ); require(processedExits[exitHash] == false, "FxRootTunnel: EXIT_ALREADY_PROCESSED"); processedExits[exitHash] = true; ExitPayloadReader.Receipt memory receipt = payload.getReceipt(); ExitPayloadReader.Log memory log = receipt.getLog(); // check child tunnel require(fxChildTunnel == log.getEmitter(), "FxRootTunnel: INVALID_FX_CHILD_TUNNEL"); bytes32 receiptRoot = payload.getReceiptRoot(); // verify receipt inclusion require( MerklePatriciaProof.verify(receipt.toBytes(), branchMaskBytes, payload.getReceiptProof(), receiptRoot), "FxRootTunnel: INVALID_RECEIPT_PROOF" ); // verify checkpoint inclusion _checkBlockMembershipInCheckpoint( blockNumber, payload.getBlockTime(), payload.getTxRoot(), receiptRoot, payload.getHeaderNumber(), payload.getBlockProof() ); ExitPayloadReader.LogTopics memory topics = log.getTopics(); require( bytes32(topics.getField(0).toUint()) == SEND_MESSAGE_EVENT_SIG, // topic0 is event sig "FxRootTunnel: INVALID_SIGNATURE" ); // received message data bytes memory message = abi.decode(log.getData(), (bytes)); // event decodes params again, so decoding bytes to get message return message; } function _checkBlockMembershipInCheckpoint( uint256 blockNumber, uint256 blockTime, bytes32 txRoot, bytes32 receiptRoot, uint256 headerNumber, bytes memory blockProof ) private view returns (uint256) { (bytes32 headerRoot, uint256 startBlock, , uint256 createdAt, ) = checkpointManager.headerBlocks(headerNumber); require( keccak256(abi.encodePacked(blockNumber, blockTime, txRoot, receiptRoot)).checkMembership( blockNumber - startBlock, headerRoot, blockProof ), "FxRootTunnel: INVALID_HEADER" ); return createdAt; } /** * @notice receive message from L2 to L1, validated by proof * @dev This function verifies if the transaction actually happened on child chain * * @param inputData RLP encoded data of the reference tx containing following list of fields * 0 - headerNumber - Checkpoint header block number containing the reference tx * 1 - blockProof - Proof that the block header (in the child chain) is a leaf in the submitted merkle root * 2 - blockNumber - Block number containing the reference tx on child chain * 3 - blockTime - Reference tx block time * 4 - txRoot - Transactions root of block * 5 - receiptRoot - Receipts root of block * 6 - receipt - Receipt of the reference transaction * 7 - receiptProof - Merkle proof of the reference receipt * 8 - branchMask - 32 bits denoting the path of receipt in merkle tree * 9 - receiptLogIndex - Log Index to read from the receipt */ function receiveMessage(bytes memory inputData) public virtual { bytes memory message = _validateAndExtractMessage(inputData); _processMessageFromChild(message); } /** * @notice Process message received from Child Tunnel * @dev function needs to be implemented to handle message as per requirement * This is called by onStateReceive function. * Since it is called via a system call, any event will not be emitted during its execution. * @param message bytes message that was sent from Child Tunnel */ function _processMessageFromChild(bytes memory message) internal virtual; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../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. * * By default, the owner account will be the one that deploys the contract. 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; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @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 { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing 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 { require(newOwner != address(0), "Ownable: new owner is the zero address"); _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); } }
/* * @author Hamdi Allam [email protected] * Please reach out with any questions or concerns */ pragma solidity ^0.8.0; library RLPReader { uint8 constant STRING_SHORT_START = 0x80; uint8 constant STRING_LONG_START = 0xb8; uint8 constant LIST_SHORT_START = 0xc0; uint8 constant LIST_LONG_START = 0xf8; uint8 constant WORD_SIZE = 32; struct RLPItem { uint256 len; uint256 memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint256 nextPtr; // Position of the next item in the list. } /* * @dev Returns the next element in the iteration. Reverts if it has not next element. * @param self The iterator. * @return The next element in the iteration. */ function next(Iterator memory self) internal pure returns (RLPItem memory) { require(hasNext(self)); uint256 ptr = self.nextPtr; uint256 itemLength = _itemLength(ptr); self.nextPtr = ptr + itemLength; return RLPItem(itemLength, ptr); } /* * @dev Returns true if the iteration has more elements. * @param self The iterator. * @return true if the iteration has more elements. */ function hasNext(Iterator memory self) internal pure returns (bool) { RLPItem memory item = self.item; return self.nextPtr < item.memPtr + item.len; } /* * @param item RLP encoded bytes */ function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) { uint256 memPtr; assembly { memPtr := add(item, 0x20) } return RLPItem(item.length, memPtr); } /* * @dev Create an iterator. Reverts if item is not a list. * @param self The RLP item. * @return An 'Iterator' over the item. */ function iterator(RLPItem memory self) internal pure returns (Iterator memory) { require(isList(self)); uint256 ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param item RLP encoded bytes */ function rlpLen(RLPItem memory item) internal pure returns (uint256) { return item.len; } /* * @param item RLP encoded bytes */ function payloadLen(RLPItem memory item) internal pure returns (uint256) { return item.len - _payloadOffset(item.memPtr); } /* * @param item RLP encoded list in bytes */ function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item)); uint256 items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 dataLen; for (uint256 i = 0; i < items; i++) { dataLen = _itemLength(memPtr); result[i] = RLPItem(dataLen, memPtr); memPtr = memPtr + dataLen; } return result; } // @return indicator whether encoded payload is a list. negate this function call for isData. function isList(RLPItem memory item) internal pure returns (bool) { if (item.len == 0) return false; uint8 byte0; uint256 memPtr = item.memPtr; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < LIST_SHORT_START) return false; return true; } /* * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory. * @return keccak256 hash of RLP encoded bytes. */ function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) { uint256 ptr = item.memPtr; uint256 len = item.len; bytes32 result; assembly { result := keccak256(ptr, len) } return result; } function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) { uint256 offset = _payloadOffset(item.memPtr); uint256 memPtr = item.memPtr + offset; uint256 len = item.len - offset; // data length return (memPtr, len); } /* * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory. * @return keccak256 hash of the item payload. */ function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) { (uint256 memPtr, uint256 len) = payloadLocation(item); bytes32 result; assembly { result := keccak256(memPtr, len) } return result; } /** RLPItem conversions into data types **/ // @returns raw rlp encoding in bytes function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) { bytes memory result = new bytes(item.len); if (result.length == 0) return result; uint256 ptr; assembly { ptr := add(0x20, result) } copy(item.memPtr, ptr, item.len); return result; } // any non-zero byte is considered true function toBoolean(RLPItem memory item) internal pure returns (bool) { require(item.len == 1); uint256 result; uint256 memPtr = item.memPtr; assembly { result := byte(0, mload(memPtr)) } return result == 0 ? false : true; } function toAddress(RLPItem memory item) internal pure returns (address) { // 1 byte for the length prefix require(item.len == 21); return address(uint160(toUint(item))); } function toUint(RLPItem memory item) internal pure returns (uint256) { require(item.len > 0 && item.len <= 33); uint256 offset = _payloadOffset(item.memPtr); uint256 len = item.len - offset; uint256 result; uint256 memPtr = item.memPtr + offset; assembly { result := mload(memPtr) // shfit to the correct location if neccesary if lt(len, 32) { result := div(result, exp(256, sub(32, len))) } } return result; } // enforces 32 byte length function toUintStrict(RLPItem memory item) internal pure returns (uint256) { // one byte prefix require(item.len == 33); uint256 result; uint256 memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); uint256 offset = _payloadOffset(item.memPtr); uint256 len = item.len - offset; // data length bytes memory result = new bytes(len); uint256 destPtr; assembly { destPtr := add(0x20, result) } copy(item.memPtr + offset, destPtr, len); return result; } /* * Private Helpers */ // @return number of payload items inside an encoded list. function numItems(RLPItem memory item) private pure returns (uint256) { if (item.len == 0) return 0; uint256 count = 0; uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 endPtr = item.memPtr + item.len; while (currPtr < endPtr) { currPtr = currPtr + _itemLength(currPtr); // skip over an item count++; } return count; } // @return entire rlp item byte length function _itemLength(uint256 memPtr) private pure returns (uint256) { uint256 itemLen; uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) itemLen = 1; else if (byte0 < STRING_LONG_START) itemLen = byte0 - STRING_SHORT_START + 1; else if (byte0 < LIST_SHORT_START) { assembly { let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is memPtr := add(memPtr, 1) // skip over the first byte /* 32 byte word size */ let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len itemLen := add(dataLen, add(byteLen, 1)) } } else if (byte0 < LIST_LONG_START) { itemLen = byte0 - LIST_SHORT_START + 1; } else { assembly { let byteLen := sub(byte0, 0xf7) memPtr := add(memPtr, 1) let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length itemLen := add(dataLen, add(byteLen, 1)) } } return itemLen; } // @return number of bytes until the data function _payloadOffset(uint256 memPtr) private pure returns (uint256) { uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) return 0; else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) return 1; else if (byte0 < LIST_SHORT_START) // being explicit return byte0 - (STRING_LONG_START - 1) + 1; else return byte0 - (LIST_LONG_START - 1) + 1; } /* * @param src Pointer to source * @param dest Pointer to destination * @param len Amount of memory to copy from the source */ function copy( uint256 src, uint256 dest, uint256 len ) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } if (len == 0) return; // left over bytes. Mask is used to remove unwanted bytes from the word uint256 mask = 256**(WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {RLPReader} from "./RLPReader.sol"; library MerklePatriciaProof { /* * @dev Verifies a merkle patricia proof. * @param value The terminating value in the trie. * @param encodedPath The path in the trie leading to value. * @param rlpParentNodes The rlp encoded stack of nodes. * @param root The root hash of the trie. * @return The boolean validity of the proof. */ function verify( bytes memory value, bytes memory encodedPath, bytes memory rlpParentNodes, bytes32 root ) internal pure returns (bool) { RLPReader.RLPItem memory item = RLPReader.toRlpItem(rlpParentNodes); RLPReader.RLPItem[] memory parentNodes = RLPReader.toList(item); bytes memory currentNode; RLPReader.RLPItem[] memory currentNodeList; bytes32 nodeKey = root; uint256 pathPtr = 0; bytes memory path = _getNibbleArray(encodedPath); if (path.length == 0) { return false; } for (uint256 i = 0; i < parentNodes.length; i++) { if (pathPtr > path.length) { return false; } currentNode = RLPReader.toRlpBytes(parentNodes[i]); if (nodeKey != keccak256(currentNode)) { return false; } currentNodeList = RLPReader.toList(parentNodes[i]); if (currentNodeList.length == 17) { if (pathPtr == path.length) { if (keccak256(RLPReader.toBytes(currentNodeList[16])) == keccak256(value)) { return true; } else { return false; } } uint8 nextPathNibble = uint8(path[pathPtr]); if (nextPathNibble > 16) { return false; } nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[nextPathNibble])); pathPtr += 1; } else if (currentNodeList.length == 2) { uint256 traversed = _nibblesToTraverse(RLPReader.toBytes(currentNodeList[0]), path, pathPtr); if (pathPtr + traversed == path.length) { //leaf node if (keccak256(RLPReader.toBytes(currentNodeList[1])) == keccak256(value)) { return true; } else { return false; } } //extension node if (traversed == 0) { return false; } pathPtr += traversed; nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[1])); } else { return false; } } } function _nibblesToTraverse( bytes memory encodedPartialPath, bytes memory path, uint256 pathPtr ) private pure returns (uint256) { uint256 len = 0; // encodedPartialPath has elements that are each two hex characters (1 byte), but partialPath // and slicedPath have elements that are each one hex character (1 nibble) bytes memory partialPath = _getNibbleArray(encodedPartialPath); bytes memory slicedPath = new bytes(partialPath.length); // pathPtr counts nibbles in path // partialPath.length is a number of nibbles for (uint256 i = pathPtr; i < pathPtr + partialPath.length; i++) { bytes1 pathNibble = path[i]; slicedPath[i - pathPtr] = pathNibble; } if (keccak256(partialPath) == keccak256(slicedPath)) { len = partialPath.length; } else { len = 0; } return len; } // bytes b must be hp encoded function _getNibbleArray(bytes memory b) internal pure returns (bytes memory) { bytes memory nibbles = ""; if (b.length > 0) { uint8 offset; uint8 hpNibble = uint8(_getNthNibbleOfBytes(0, b)); if (hpNibble == 1 || hpNibble == 3) { nibbles = new bytes(b.length * 2 - 1); bytes1 oddNibble = _getNthNibbleOfBytes(1, b); nibbles[0] = oddNibble; offset = 1; } else { nibbles = new bytes(b.length * 2 - 2); offset = 0; } for (uint256 i = offset; i < nibbles.length; i++) { nibbles[i] = _getNthNibbleOfBytes(i - offset + 2, b); } } return nibbles; } function _getNthNibbleOfBytes(uint256 n, bytes memory str) private pure returns (bytes1) { return bytes1(n % 2 == 0 ? uint8(str[n / 2]) / 0x10 : uint8(str[n / 2]) % 0x10); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library Merkle { function checkMembership( bytes32 leaf, uint256 index, bytes32 rootHash, bytes memory proof ) internal pure returns (bool) { require(proof.length % 32 == 0, "Invalid proof length"); uint256 proofHeight = proof.length / 32; // Proof of size n means, height of the tree is n+1. // In a tree of height n+1, max #leafs possible is 2 ^ n require(index < 2**proofHeight, "Leaf index is too big"); bytes32 proofElement; bytes32 computedHash = leaf; for (uint256 i = 32; i <= proof.length; i += 32) { assembly { proofElement := mload(add(proof, i)) } if (index % 2 == 0) { computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); } else { computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); } index = index / 2; } return computedHash == rootHash; } }
pragma solidity ^0.8.0; import {RLPReader} from "./RLPReader.sol"; library ExitPayloadReader { using RLPReader for bytes; using RLPReader for RLPReader.RLPItem; uint8 constant WORD_SIZE = 32; struct ExitPayload { RLPReader.RLPItem[] data; } struct Receipt { RLPReader.RLPItem[] data; bytes raw; uint256 logIndex; } struct Log { RLPReader.RLPItem data; RLPReader.RLPItem[] list; } struct LogTopics { RLPReader.RLPItem[] data; } // copy paste of private copy() from RLPReader to avoid changing of existing contracts function copy( uint256 src, uint256 dest, uint256 len ) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } if (len == 0) return; // left over bytes. Mask is used to remove unwanted bytes from the word uint256 mask = 256**(WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } function toExitPayload(bytes memory data) internal pure returns (ExitPayload memory) { RLPReader.RLPItem[] memory payloadData = data.toRlpItem().toList(); return ExitPayload(payloadData); } function getHeaderNumber(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[0].toUint(); } function getBlockProof(ExitPayload memory payload) internal pure returns (bytes memory) { return payload.data[1].toBytes(); } function getBlockNumber(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[2].toUint(); } function getBlockTime(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[3].toUint(); } function getTxRoot(ExitPayload memory payload) internal pure returns (bytes32) { return bytes32(payload.data[4].toUint()); } function getReceiptRoot(ExitPayload memory payload) internal pure returns (bytes32) { return bytes32(payload.data[5].toUint()); } function getReceipt(ExitPayload memory payload) internal pure returns (Receipt memory receipt) { receipt.raw = payload.data[6].toBytes(); RLPReader.RLPItem memory receiptItem = receipt.raw.toRlpItem(); if (receiptItem.isList()) { // legacy tx receipt.data = receiptItem.toList(); } else { // pop first byte before parsting receipt bytes memory typedBytes = receipt.raw; bytes memory result = new bytes(typedBytes.length - 1); uint256 srcPtr; uint256 destPtr; assembly { srcPtr := add(33, typedBytes) destPtr := add(0x20, result) } copy(srcPtr, destPtr, result.length); receipt.data = result.toRlpItem().toList(); } receipt.logIndex = getReceiptLogIndex(payload); return receipt; } function getReceiptProof(ExitPayload memory payload) internal pure returns (bytes memory) { return payload.data[7].toBytes(); } function getBranchMaskAsBytes(ExitPayload memory payload) internal pure returns (bytes memory) { return payload.data[8].toBytes(); } function getBranchMaskAsUint(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[8].toUint(); } function getReceiptLogIndex(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[9].toUint(); } // Receipt methods function toBytes(Receipt memory receipt) internal pure returns (bytes memory) { return receipt.raw; } function getLog(Receipt memory receipt) internal pure returns (Log memory) { RLPReader.RLPItem memory logData = receipt.data[3].toList()[receipt.logIndex]; return Log(logData, logData.toList()); } // Log methods function getEmitter(Log memory log) internal pure returns (address) { return RLPReader.toAddress(log.list[0]); } function getTopics(Log memory log) internal pure returns (LogTopics memory) { return LogTopics(log.list[1].toList()); } function getData(Log memory log) internal pure returns (bytes memory) { return log.list[2].toBytes(); } function toRlpBytes(Log memory log) internal pure returns (bytes memory) { return log.data.toRlpBytes(); } // LogTopics methods function getField(LogTopics memory topics, uint256 index) internal pure returns (RLPReader.RLPItem memory) { return topics.data[index]; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @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; } }
{ "remappings": [ "@prb/test/=lib/prb-test/src/", "forge-std/=lib/forge-std/src/", "src/=src/", "semaphore/=lib/semaphore-v3/packages/contracts/contracts/", "solmate/=lib/solmate/", "@rari-capital/solmate/=lib/solmate/", "@eth-optimism/contracts/=node_modules/@eth-optimism/contracts/", "@eth-optimism/contracts-bedrock/=node_modules/@eth-optimism/contracts-bedrock/", "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "fx-portal/contracts/=lib/contracts/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "prb-test/=lib/prb-test/src/", "semaphore-v3/=lib/semaphore-v3/" ], "optimizer": { "enabled": true, "runs": 10000, "details": { "peephole": true, "inliner": true, "deduplicate": true, "cse": true, "yul": true } }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_checkpointManager","type":"address"},{"internalType":"address","name":"_fxRoot","type":"address"},{"internalType":"address","name":"_worldIDIdentityManager","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressZero","type":"error"},{"inputs":[],"name":"CannotRenounceOwnership","type":"error"},{"inputs":[],"name":"FxBaseRootChildTunnelAlreadySet","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"root","type":"uint256"}],"name":"RootPropagated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"fxChildTunnel","type":"address"}],"name":"SetFxChildTunnel","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rootHistoryExpiry","type":"uint256"}],"name":"SetRootHistoryExpiry","type":"event"},{"inputs":[],"name":"SEND_MESSAGE_EVENT_SIG","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkpointManager","outputs":[{"internalType":"contract ICheckpointManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fxChildTunnel","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fxRoot","outputs":[{"internalType":"contract IFxStateSender","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"processedExits","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"propagateRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"inputData","type":"bytes"}],"name":"receiveMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fxChildTunnel","type":"address"}],"name":"setFxChildTunnel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rootHistoryExpiry","type":"uint256"}],"name":"setRootHistoryExpiryPolygon","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"worldID","outputs":[{"internalType":"contract IWorldIDIdentityManager","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b506040516200280238038062002802833981016040819052620000349162000174565b600180546001600160a01b038086166001600160a01b031992831617909255600080549285169290911691909117905562000076620000703390565b620000db565b6001600160a01b03831615806200009457506001600160a01b038216155b80620000a757506001600160a01b038116155b15620000c657604051639fabe1c160e01b815260040160405180910390fd5b6001600160a01b031660805250620001be9050565b600580546001600160a01b0319169055620001028162000105602090811b6200077a17901c565b50565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200016f57600080fd5b919050565b6000806000606084860312156200018a57600080fd5b620001958462000157565b9250620001a56020850162000157565b9150620001b56040850162000157565b90509250925092565b608051612621620001e160003960008181610139015261037101526126216000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638da5cb5b11610097578063de9b771f11610066578063de9b771f14610251578063e30c397814610271578063f2fde38b1461028f578063f953cec7146102a257600080fd5b80638da5cb5b146101e0578063972c4928146101fe578063aea4e49e1461021e578063c0857ba01461023157600080fd5b8063380db829116100d3578063380db82914610195578063607f2d421461019d578063715018a6146101d057806379ba5097146101d857600080fd5b80630e387de6146100fa5780631213c3ef146101345780633398b74714610180575b600080fd5b6101217f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b6040519081526020015b60405180910390f35b61015b7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161012b565b61019361018e36600461203e565b6102b5565b005b61019361036d565b6101c06101ab36600461203e565b60036020526000908152604090205460ff1681565b604051901515815260200161012b565b6101936104a8565b6101936104e2565b60045473ffffffffffffffffffffffffffffffffffffffff1661015b565b60025461015b9073ffffffffffffffffffffffffffffffffffffffff1681565b61019361022c366004612079565b61059c565b60015461015b9073ffffffffffffffffffffffffffffffffffffffff1681565b60005461015b9073ffffffffffffffffffffffffffffffffffffffff1681565b60055473ffffffffffffffffffffffffffffffffffffffff1661015b565b61019361029d366004612079565b6106ba565b6101936102b036600461211e565b61076a565b6102bd6107f1565b6000816040516024016102d291815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc70aa72700000000000000000000000000000000000000000000000000000000179052905061033581610874565b6040518281527f9036872f40830f3909d8006c77be543a639ad4ebb34aff720498fcd12656a292906020015b60405180910390a15050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d7b0fef16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fe919061219e565b905060008160405160240161041591815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ffbde929b00000000000000000000000000000000000000000000000000000000179052905061047881610874565b6040518281527fd8f3e639501c4b5e551a948a2930f1215556bcde417c94d45746a8ec6418366f90602001610361565b6104b06107f1565b6040517f77aeb0ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554339073ffffffffffffffffffffffffffffffffffffffff168114610590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f74207468652060448201527f6e6577206f776e6572000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61059981610905565b50565b6105a46107f1565b60025473ffffffffffffffffffffffffffffffffffffffff16156105f4576040517f88105e2600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610641576040517f9fabe1c100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f051af90fc70cf37c96b5cf1dedc6626a60cedb18b3f13bb71fb082d0d13be3ea9060200160405180910390a150565b6106c26107f1565b6005805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915561072560045473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600061077582610936565b505050565b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60045473ffffffffffffffffffffffffffffffffffffffff163314610872576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610587565b565b6000546002546040517fb472047700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169263b4720477926108d09291169085906004016121e7565b600060405180830381600087803b1580156108ea57600080fd5b505af11580156108fe573d6000803e3d6000fd5b5050505050565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556105998161077a565b6060600061094383610cfa565b9050600061095082610d59565b9050600061095d83610d88565b905060008161096b84610db1565b61097486610f9f565b60405160200161098693929190612237565b60408051601f1981840301815291815281516020928301206000818152600390935291205490915060ff1615610a3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f53534544000000000000000000000000000000000000000000000000000000006064820152608401610587565b600081815260036020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610a7d85610fbb565b90506000610a8a82611105565b9050610a9581611195565b60025473ffffffffffffffffffffffffffffffffffffffff908116911614610b3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c0000000000000000000000000000000000000000000000000000006064820152608401610587565b6000610b4a876111be565b9050610b6a610b5a846020015190565b87610b648a6111da565b846111f6565b610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f4600000000000000000000000000000000000000000000000000000000006064820152608401610587565b610c2485610c03896114a9565b610c0c8a6114c5565b84610c168c6114e1565b610c1f8d6114fd565b611519565b506000610c308361167f565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036610c66610c618360006116bb565b6116f3565b14610ccd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e4154555245006044820152606401610587565b6000610cd88461176e565b806020019051810190610ceb9190612264565b9b9a5050505050505050505050565b6040805160208101909152606081526000610d44610d3f8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b61178a565b60408051602081019091529081529392505050565b6060610d828260000151600881518110610d7557610d756122db565b60200260200101516118a0565b92915050565b6000610d828260000151600281518110610da457610da46122db565b60200260200101516116f3565b60408051602081019091526000815281516060919015610d8257600080610dd960008661193d565b60f81c90506001811480610df057508060ff166003145b15610eb057600185516002610e059190612339565b610e0f9190612376565b67ffffffffffffffff811115610e2757610e27612096565b6040519080825280601f01601f191660200182016040528015610e51576020820181803683370190505b5092506000610e6160018761193d565b90508084600081518110610e7757610e776122db565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001925050610f14565b600285516002610ec09190612339565b610eca9190612376565b67ffffffffffffffff811115610ee257610ee2612096565b6040519080825280601f01601f191660200182016040528015610f0c576020820181803683370190505b509250600091505b60ff82165b8351811015610f9657610f43610f3260ff851683612376565b610f3d90600261238d565b8761193d565b848281518110610f5557610f556122db565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080610f8e816123a5565b915050610f19565b50505092915050565b6000610d828260000151600981518110610da457610da46122db565b610fdf60405180606001604052806060815260200160608152602001600081525090565b610ff98260000151600681518110610d7557610d756122db565b60208281018290526040805180820182526000808252908301528051808201909152825181529181019082015261102f816119be565b156110445761103d8161178a565b82526110f1565b6020820151805160009061105a90600190612376565b67ffffffffffffffff81111561107257611072612096565b6040519080825280601f01601f19166020018201604052801561109c576020820181803683370190505b5090506000808360210191508260200190506110ba828285516119f9565b6040805180820182526000808252602091820152815180830190925284518252808501908201526110ea9061178a565b8652505050505b6110fa83610f9f565b604083015250919050565b6040805160808101825260009181018281526060808301939093528152602081019190915260006111538360000151600381518110611146576111466122db565b602002602001015161178a565b836040015181518110611168576111686122db565b60200260200101519050604051806040016040528082815260200161118c8361178a565b90529392505050565b6000610d8282602001516000815181106111b1576111b16122db565b6020026020010151611a84565b6000610d828260000151600581518110610da457610da46122db565b6060610d828260000151600781518110610d7557610d756122db565b60008061122a8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b905060006112378261178a565b9050606080856000806112498b610db1565b905080516000036112645760009750505050505050506114a1565b60005b865181101561149857815183111561128a576000985050505050505050506114a1565b6112ac87828151811061129f5761129f6122db565b6020026020010151611a9e565b9550858051906020012084146112cd576000985050505050505050506114a1565b6112e2878281518110611146576111466122db565b945084516011036113b45781518303611341578c8051906020012061131386601081518110610d7557610d756122db565b8051906020012003611330576001985050505050505050506114a1565b6000985050505050505050506114a1565b6000828481518110611355576113556122db565b016020015160f81c9050601081111561137a57600099505050505050505050506114a1565b61139f868260ff1681518110611392576113926122db565b6020026020010151611b1d565b94506113ac60018561238d565b935050611486565b84516002036113305760006113df6113d887600081518110610d7557610d756122db565b8486611b4b565b83519091506113ee828661238d565b03611441578d8051906020012061141187600181518110610d7557610d756122db565b805190602001200361142f57600199505050505050505050506114a1565b600099505050505050505050506114a1565b8060000361145b57600099505050505050505050506114a1565b611465818561238d565b935061147d86600181518110611392576113926122db565b94506114869050565b80611490816123a5565b915050611267565b50505050505050505b949350505050565b6000610d828260000151600381518110610da457610da46122db565b6000610d828260000151600481518110610da457610da46122db565b6000610d828260000151600081518110610da457610da46122db565b6060610d828260000151600181518110610d7557610d756122db565b6001546040517f41539d4a0000000000000000000000000000000000000000000000000000000081526004810184905260009182918291829173ffffffffffffffffffffffffffffffffffffffff909116906341539d4a9060240160a060405180830381865afa158015611591573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b591906123dd565b509350509250925061160c828b6115cc9190612376565b6040805160208082018f90528183018e9052606082018d905260808083018d90528351808403909101815260a09092019092528051910120908588611c83565b611672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f484541444552000000006044820152606401610587565b9998505050505050505050565b60408051602081019091526060815260405180602001604052806116b38460200151600181518110611146576111466122db565b905292915050565b604080518082019091526000808252602082015282518051839081106116e3576116e36122db565b6020026020010151905092915050565b80516000901580159061170857508151602110155b61171157600080fd5b60006117208360200151611e30565b905060008184600001516117349190612376565b9050600080838660200151611749919061238d565b905080519150602083101561176557826020036101000a820491505b50949350505050565b6060610d828260200151600281518110610d7557610d756122db565b6060611795826119be565b61179e57600080fd5b60006117a983611eb2565b905060008167ffffffffffffffff8111156117c6576117c6612096565b60405190808252806020026020018201604052801561180b57816020015b60408051808201909152600080825260208201528152602001906001900390816117e45790505b509050600061181d8560200151611e30565b856020015161182c919061238d565b90506000805b848110156118955761184383611f37565b915060405180604001604052808381526020018481525084828151811061186c5761186c6122db565b6020908102919091010152611881828461238d565b92508061188d816123a5565b915050611832565b509195945050505050565b80516060906118ae57600080fd5b60006118bd8360200151611e30565b905060008184600001516118d19190612376565b905060008167ffffffffffffffff8111156118ee576118ee612096565b6040519080825280601f01601f191660200182016040528015611918576020820181803683370190505b5090506000816020019050611765848760200151611936919061238d565b8285611ff9565b600061194a600284612459565b156119845760108261195d60028661246d565b8151811061196d5761196d6122db565b016020015161197f919060f81c612481565b6119b4565b60108261199260028661246d565b815181106119a2576119a26122db565b01602001516119b4919060f81c6124a3565b60f81b9392505050565b805160009081036119d157506000919050565b6020820151805160001a9060c08210156119ef575060009392505050565b5060019392505050565b80600003611a0657505050565b60208110611a3e5782518252611a1d60208461238d565b9250611a2a60208361238d565b9150611a37602082612376565b9050611a06565b80600003611a4b57505050565b60006001611a5a836020612376565b611a66906101006125e5565b611a709190612376565b935183518516941916939093179091525050565b8051600090601514611a9557600080fd5b610d82826116f3565b60606000826000015167ffffffffffffffff811115611abf57611abf612096565b6040519080825280601f01601f191660200182016040528015611ae9576020820181803683370190505b5090508051600003611afb5792915050565b6000816020019050611b168460200151828660000151611ff9565b5092915050565b8051600090602114611b2e57600080fd5b60008083602001516001611b42919061238d565b51949350505050565b60008080611b5886610db1565b90506000815167ffffffffffffffff811115611b7657611b76612096565b6040519080825280601f01601f191660200182016040528015611ba0576020820181803683370190505b509050845b8251611bb1908761238d565b811015611c54576000878281518110611bcc57611bcc6122db565b01602001517fff000000000000000000000000000000000000000000000000000000000000001690508083611c018985612376565b81518110611c1157611c116122db565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350508080611c4c906123a5565b915050611ba5565b508080519060200120828051906020012003611c735781519250611c78565b600092505b509095945050505050565b600060208251611c939190612459565b15611cfa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e76616c69642070726f6f66206c656e6774680000000000000000000000006044820152606401610587565b600060208351611d0a919061246d565b9050611d178160026125e5565b8510611d7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4c65616620696e64657820697320746f6f2062696700000000000000000000006044820152606401610587565b60008660205b85518111611e2257858101519250611d9e600289612459565b600003611dd6576040805160208101849052908101849052606001604051602081830303815290604052805190602001209150611e03565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b611e0e60028961246d565b9750611e1b60208261238d565b9050611d85565b509094149695505050505050565b8051600090811a6080811015611e495750600092915050565b60b8811080611e64575060c08110801590611e64575060f881105b15611e725750600192915050565b60c0811015611ea657611e87600160b86125f1565b611e949060ff1682612376565b611e9f90600161238d565b9392505050565b611e87600160f86125f1565b80516000908103611ec557506000919050565b600080611ed58460200151611e30565b8460200151611ee4919061238d565b9050600084600001518560200151611efc919061238d565b90505b80821015611f2e57611f1082611f37565b611f1a908361238d565b915082611f26816123a5565b935050611eff565b50909392505050565b80516000908190811a6080811015611f525760019150611b16565b60b8811015611f7857611f66608082612376565b611f7190600161238d565b9150611b16565b60c0811015611fa55760b78103600185019450806020036101000a85510460018201810193505050611b16565b60f8811015611fb957611f6660c082612376565b60019390930151602084900360f7016101000a90049092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a0192915050565b8060000361200657505050565b60208110611a3e578251825261201d60208461238d565b925061202a60208361238d565b9150612037602082612376565b9050612006565b60006020828403121561205057600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461059957600080fd5b60006020828403121561208b57600080fd5b8135611e9f81612057565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156120ee576120ee612096565b604052919050565b600067ffffffffffffffff82111561211057612110612096565b50601f01601f191660200190565b60006020828403121561213057600080fd5b813567ffffffffffffffff81111561214757600080fd5b8201601f8101841361215857600080fd5b803561216b612166826120f6565b6120c5565b81815285602083850101111561218057600080fd5b81602084016020830137600091810160200191909152949350505050565b6000602082840312156121b057600080fd5b5051919050565b60005b838110156121d25781810151838201526020016121ba565b838111156121e1576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600082518060408401526122228160608501602087016121b7565b601f01601f1916919091016060019392505050565b8381526000835161224f8160208501602088016121b7565b60209201918201929092526040019392505050565b60006020828403121561227657600080fd5b815167ffffffffffffffff81111561228d57600080fd5b8201601f8101841361229e57600080fd5b80516122ac612166826120f6565b8181528560208385010111156122c157600080fd5b6122d28260208301602086016121b7565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156123715761237161230a565b500290565b6000828210156123885761238861230a565b500390565b600082198211156123a0576123a061230a565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036123d6576123d661230a565b5060010190565b600080600080600060a086880312156123f557600080fd5b85519450602086015193506040860151925060608601519150608086015161241c81612057565b809150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826124685761246861242a565b500690565b60008261247c5761247c61242a565b500490565b600060ff8316806124945761249461242a565b8060ff84160691505092915050565b600060ff8316806124b6576124b661242a565b8060ff84160491505092915050565b600181815b8085111561251e57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156125045761250461230a565b8085161561251157918102915b93841c93908002906124ca565b509250929050565b60008261253557506001610d82565b8161254257506000610d82565b816001811461255857600281146125625761257e565b6001915050610d82565b60ff8411156125735761257361230a565b50506001821b610d82565b5060208310610133831016604e8410600b84101617156125a1575081810a610d82565b6125ab83836124c5565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156125dd576125dd61230a565b029392505050565b6000611e9f8383612526565b600060ff821660ff84168082101561260b5761260b61230a565b9003939250505056fea164736f6c634300080f000a00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a2000000000000000000000000f7134ce138832c1456f2a91d64621ee90c2bddea
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80638da5cb5b11610097578063de9b771f11610066578063de9b771f14610251578063e30c397814610271578063f2fde38b1461028f578063f953cec7146102a257600080fd5b80638da5cb5b146101e0578063972c4928146101fe578063aea4e49e1461021e578063c0857ba01461023157600080fd5b8063380db829116100d3578063380db82914610195578063607f2d421461019d578063715018a6146101d057806379ba5097146101d857600080fd5b80630e387de6146100fa5780631213c3ef146101345780633398b74714610180575b600080fd5b6101217f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b6040519081526020015b60405180910390f35b61015b7f000000000000000000000000f7134ce138832c1456f2a91d64621ee90c2bddea81565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161012b565b61019361018e36600461203e565b6102b5565b005b61019361036d565b6101c06101ab36600461203e565b60036020526000908152604090205460ff1681565b604051901515815260200161012b565b6101936104a8565b6101936104e2565b60045473ffffffffffffffffffffffffffffffffffffffff1661015b565b60025461015b9073ffffffffffffffffffffffffffffffffffffffff1681565b61019361022c366004612079565b61059c565b60015461015b9073ffffffffffffffffffffffffffffffffffffffff1681565b60005461015b9073ffffffffffffffffffffffffffffffffffffffff1681565b60055473ffffffffffffffffffffffffffffffffffffffff1661015b565b61019361029d366004612079565b6106ba565b6101936102b036600461211e565b61076a565b6102bd6107f1565b6000816040516024016102d291815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc70aa72700000000000000000000000000000000000000000000000000000000179052905061033581610874565b6040518281527f9036872f40830f3909d8006c77be543a639ad4ebb34aff720498fcd12656a292906020015b60405180910390a15050565b60007f000000000000000000000000f7134ce138832c1456f2a91d64621ee90c2bddea73ffffffffffffffffffffffffffffffffffffffff1663d7b0fef16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fe919061219e565b905060008160405160240161041591815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ffbde929b00000000000000000000000000000000000000000000000000000000179052905061047881610874565b6040518281527fd8f3e639501c4b5e551a948a2930f1215556bcde417c94d45746a8ec6418366f90602001610361565b6104b06107f1565b6040517f77aeb0ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554339073ffffffffffffffffffffffffffffffffffffffff168114610590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f74207468652060448201527f6e6577206f776e6572000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61059981610905565b50565b6105a46107f1565b60025473ffffffffffffffffffffffffffffffffffffffff16156105f4576040517f88105e2600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610641576040517f9fabe1c100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f051af90fc70cf37c96b5cf1dedc6626a60cedb18b3f13bb71fb082d0d13be3ea9060200160405180910390a150565b6106c26107f1565b6005805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915561072560045473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600061077582610936565b505050565b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60045473ffffffffffffffffffffffffffffffffffffffff163314610872576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610587565b565b6000546002546040517fb472047700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169263b4720477926108d09291169085906004016121e7565b600060405180830381600087803b1580156108ea57600080fd5b505af11580156108fe573d6000803e3d6000fd5b5050505050565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556105998161077a565b6060600061094383610cfa565b9050600061095082610d59565b9050600061095d83610d88565b905060008161096b84610db1565b61097486610f9f565b60405160200161098693929190612237565b60408051601f1981840301815291815281516020928301206000818152600390935291205490915060ff1615610a3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f53534544000000000000000000000000000000000000000000000000000000006064820152608401610587565b600081815260036020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610a7d85610fbb565b90506000610a8a82611105565b9050610a9581611195565b60025473ffffffffffffffffffffffffffffffffffffffff908116911614610b3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c0000000000000000000000000000000000000000000000000000006064820152608401610587565b6000610b4a876111be565b9050610b6a610b5a846020015190565b87610b648a6111da565b846111f6565b610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f4600000000000000000000000000000000000000000000000000000000006064820152608401610587565b610c2485610c03896114a9565b610c0c8a6114c5565b84610c168c6114e1565b610c1f8d6114fd565b611519565b506000610c308361167f565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036610c66610c618360006116bb565b6116f3565b14610ccd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e4154555245006044820152606401610587565b6000610cd88461176e565b806020019051810190610ceb9190612264565b9b9a5050505050505050505050565b6040805160208101909152606081526000610d44610d3f8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b61178a565b60408051602081019091529081529392505050565b6060610d828260000151600881518110610d7557610d756122db565b60200260200101516118a0565b92915050565b6000610d828260000151600281518110610da457610da46122db565b60200260200101516116f3565b60408051602081019091526000815281516060919015610d8257600080610dd960008661193d565b60f81c90506001811480610df057508060ff166003145b15610eb057600185516002610e059190612339565b610e0f9190612376565b67ffffffffffffffff811115610e2757610e27612096565b6040519080825280601f01601f191660200182016040528015610e51576020820181803683370190505b5092506000610e6160018761193d565b90508084600081518110610e7757610e776122db565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001925050610f14565b600285516002610ec09190612339565b610eca9190612376565b67ffffffffffffffff811115610ee257610ee2612096565b6040519080825280601f01601f191660200182016040528015610f0c576020820181803683370190505b509250600091505b60ff82165b8351811015610f9657610f43610f3260ff851683612376565b610f3d90600261238d565b8761193d565b848281518110610f5557610f556122db565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080610f8e816123a5565b915050610f19565b50505092915050565b6000610d828260000151600981518110610da457610da46122db565b610fdf60405180606001604052806060815260200160608152602001600081525090565b610ff98260000151600681518110610d7557610d756122db565b60208281018290526040805180820182526000808252908301528051808201909152825181529181019082015261102f816119be565b156110445761103d8161178a565b82526110f1565b6020820151805160009061105a90600190612376565b67ffffffffffffffff81111561107257611072612096565b6040519080825280601f01601f19166020018201604052801561109c576020820181803683370190505b5090506000808360210191508260200190506110ba828285516119f9565b6040805180820182526000808252602091820152815180830190925284518252808501908201526110ea9061178a565b8652505050505b6110fa83610f9f565b604083015250919050565b6040805160808101825260009181018281526060808301939093528152602081019190915260006111538360000151600381518110611146576111466122db565b602002602001015161178a565b836040015181518110611168576111686122db565b60200260200101519050604051806040016040528082815260200161118c8361178a565b90529392505050565b6000610d8282602001516000815181106111b1576111b16122db565b6020026020010151611a84565b6000610d828260000151600581518110610da457610da46122db565b6060610d828260000151600781518110610d7557610d756122db565b60008061122a8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b905060006112378261178a565b9050606080856000806112498b610db1565b905080516000036112645760009750505050505050506114a1565b60005b865181101561149857815183111561128a576000985050505050505050506114a1565b6112ac87828151811061129f5761129f6122db565b6020026020010151611a9e565b9550858051906020012084146112cd576000985050505050505050506114a1565b6112e2878281518110611146576111466122db565b945084516011036113b45781518303611341578c8051906020012061131386601081518110610d7557610d756122db565b8051906020012003611330576001985050505050505050506114a1565b6000985050505050505050506114a1565b6000828481518110611355576113556122db565b016020015160f81c9050601081111561137a57600099505050505050505050506114a1565b61139f868260ff1681518110611392576113926122db565b6020026020010151611b1d565b94506113ac60018561238d565b935050611486565b84516002036113305760006113df6113d887600081518110610d7557610d756122db565b8486611b4b565b83519091506113ee828661238d565b03611441578d8051906020012061141187600181518110610d7557610d756122db565b805190602001200361142f57600199505050505050505050506114a1565b600099505050505050505050506114a1565b8060000361145b57600099505050505050505050506114a1565b611465818561238d565b935061147d86600181518110611392576113926122db565b94506114869050565b80611490816123a5565b915050611267565b50505050505050505b949350505050565b6000610d828260000151600381518110610da457610da46122db565b6000610d828260000151600481518110610da457610da46122db565b6000610d828260000151600081518110610da457610da46122db565b6060610d828260000151600181518110610d7557610d756122db565b6001546040517f41539d4a0000000000000000000000000000000000000000000000000000000081526004810184905260009182918291829173ffffffffffffffffffffffffffffffffffffffff909116906341539d4a9060240160a060405180830381865afa158015611591573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b591906123dd565b509350509250925061160c828b6115cc9190612376565b6040805160208082018f90528183018e9052606082018d905260808083018d90528351808403909101815260a09092019092528051910120908588611c83565b611672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f484541444552000000006044820152606401610587565b9998505050505050505050565b60408051602081019091526060815260405180602001604052806116b38460200151600181518110611146576111466122db565b905292915050565b604080518082019091526000808252602082015282518051839081106116e3576116e36122db565b6020026020010151905092915050565b80516000901580159061170857508151602110155b61171157600080fd5b60006117208360200151611e30565b905060008184600001516117349190612376565b9050600080838660200151611749919061238d565b905080519150602083101561176557826020036101000a820491505b50949350505050565b6060610d828260200151600281518110610d7557610d756122db565b6060611795826119be565b61179e57600080fd5b60006117a983611eb2565b905060008167ffffffffffffffff8111156117c6576117c6612096565b60405190808252806020026020018201604052801561180b57816020015b60408051808201909152600080825260208201528152602001906001900390816117e45790505b509050600061181d8560200151611e30565b856020015161182c919061238d565b90506000805b848110156118955761184383611f37565b915060405180604001604052808381526020018481525084828151811061186c5761186c6122db565b6020908102919091010152611881828461238d565b92508061188d816123a5565b915050611832565b509195945050505050565b80516060906118ae57600080fd5b60006118bd8360200151611e30565b905060008184600001516118d19190612376565b905060008167ffffffffffffffff8111156118ee576118ee612096565b6040519080825280601f01601f191660200182016040528015611918576020820181803683370190505b5090506000816020019050611765848760200151611936919061238d565b8285611ff9565b600061194a600284612459565b156119845760108261195d60028661246d565b8151811061196d5761196d6122db565b016020015161197f919060f81c612481565b6119b4565b60108261199260028661246d565b815181106119a2576119a26122db565b01602001516119b4919060f81c6124a3565b60f81b9392505050565b805160009081036119d157506000919050565b6020820151805160001a9060c08210156119ef575060009392505050565b5060019392505050565b80600003611a0657505050565b60208110611a3e5782518252611a1d60208461238d565b9250611a2a60208361238d565b9150611a37602082612376565b9050611a06565b80600003611a4b57505050565b60006001611a5a836020612376565b611a66906101006125e5565b611a709190612376565b935183518516941916939093179091525050565b8051600090601514611a9557600080fd5b610d82826116f3565b60606000826000015167ffffffffffffffff811115611abf57611abf612096565b6040519080825280601f01601f191660200182016040528015611ae9576020820181803683370190505b5090508051600003611afb5792915050565b6000816020019050611b168460200151828660000151611ff9565b5092915050565b8051600090602114611b2e57600080fd5b60008083602001516001611b42919061238d565b51949350505050565b60008080611b5886610db1565b90506000815167ffffffffffffffff811115611b7657611b76612096565b6040519080825280601f01601f191660200182016040528015611ba0576020820181803683370190505b509050845b8251611bb1908761238d565b811015611c54576000878281518110611bcc57611bcc6122db565b01602001517fff000000000000000000000000000000000000000000000000000000000000001690508083611c018985612376565b81518110611c1157611c116122db565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350508080611c4c906123a5565b915050611ba5565b508080519060200120828051906020012003611c735781519250611c78565b600092505b509095945050505050565b600060208251611c939190612459565b15611cfa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e76616c69642070726f6f66206c656e6774680000000000000000000000006044820152606401610587565b600060208351611d0a919061246d565b9050611d178160026125e5565b8510611d7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4c65616620696e64657820697320746f6f2062696700000000000000000000006044820152606401610587565b60008660205b85518111611e2257858101519250611d9e600289612459565b600003611dd6576040805160208101849052908101849052606001604051602081830303815290604052805190602001209150611e03565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b611e0e60028961246d565b9750611e1b60208261238d565b9050611d85565b509094149695505050505050565b8051600090811a6080811015611e495750600092915050565b60b8811080611e64575060c08110801590611e64575060f881105b15611e725750600192915050565b60c0811015611ea657611e87600160b86125f1565b611e949060ff1682612376565b611e9f90600161238d565b9392505050565b611e87600160f86125f1565b80516000908103611ec557506000919050565b600080611ed58460200151611e30565b8460200151611ee4919061238d565b9050600084600001518560200151611efc919061238d565b90505b80821015611f2e57611f1082611f37565b611f1a908361238d565b915082611f26816123a5565b935050611eff565b50909392505050565b80516000908190811a6080811015611f525760019150611b16565b60b8811015611f7857611f66608082612376565b611f7190600161238d565b9150611b16565b60c0811015611fa55760b78103600185019450806020036101000a85510460018201810193505050611b16565b60f8811015611fb957611f6660c082612376565b60019390930151602084900360f7016101000a90049092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a0192915050565b8060000361200657505050565b60208110611a3e578251825261201d60208461238d565b925061202a60208361238d565b9150612037602082612376565b9050612006565b60006020828403121561205057600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461059957600080fd5b60006020828403121561208b57600080fd5b8135611e9f81612057565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156120ee576120ee612096565b604052919050565b600067ffffffffffffffff82111561211057612110612096565b50601f01601f191660200190565b60006020828403121561213057600080fd5b813567ffffffffffffffff81111561214757600080fd5b8201601f8101841361215857600080fd5b803561216b612166826120f6565b6120c5565b81815285602083850101111561218057600080fd5b81602084016020830137600091810160200191909152949350505050565b6000602082840312156121b057600080fd5b5051919050565b60005b838110156121d25781810151838201526020016121ba565b838111156121e1576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600082518060408401526122228160608501602087016121b7565b601f01601f1916919091016060019392505050565b8381526000835161224f8160208501602088016121b7565b60209201918201929092526040019392505050565b60006020828403121561227657600080fd5b815167ffffffffffffffff81111561228d57600080fd5b8201601f8101841361229e57600080fd5b80516122ac612166826120f6565b8181528560208385010111156122c157600080fd5b6122d28260208301602086016121b7565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156123715761237161230a565b500290565b6000828210156123885761238861230a565b500390565b600082198211156123a0576123a061230a565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036123d6576123d661230a565b5060010190565b600080600080600060a086880312156123f557600080fd5b85519450602086015193506040860151925060608601519150608086015161241c81612057565b809150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826124685761246861242a565b500690565b60008261247c5761247c61242a565b500490565b600060ff8316806124945761249461242a565b8060ff84160691505092915050565b600060ff8316806124b6576124b661242a565b8060ff84160491505092915050565b600181815b8085111561251e57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156125045761250461230a565b8085161561251157918102915b93841c93908002906124ca565b509250929050565b60008261253557506001610d82565b8161254257506000610d82565b816001811461255857600281146125625761257e565b6001915050610d82565b60ff8411156125735761257361230a565b50506001821b610d82565b5060208310610133831016604e8410600b84101617156125a1575081810a610d82565b6125ab83836124c5565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156125dd576125dd61230a565b029392505050565b6000611e9f8383612526565b600060ff821660ff84168082101561260b5761260b61230a565b9003939250505056fea164736f6c634300080f000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a2000000000000000000000000f7134ce138832c1456f2a91d64621ee90c2bddea
-----Decoded View---------------
Arg [0] : _checkpointManager (address): 0x86E4Dc95c7FBdBf52e33D563BbDB00823894C287
Arg [1] : _fxRoot (address): 0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2
Arg [2] : _worldIDIdentityManager (address): 0xf7134CE138832c1456F2a91D64621eE90c2bddEa
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287
Arg [1] : 000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a2
Arg [2] : 000000000000000000000000f7134ce138832c1456f2a91d64621ee90c2bddea
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.