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 682 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Receive Message | 20952351 | 5 hrs ago | IN | 0 ETH | 0.01300444 | ||||
Receive Message | 20945701 | 28 hrs ago | IN | 0 ETH | 0.02474542 | ||||
Receive Message | 20945700 | 28 hrs ago | IN | 0 ETH | 0.02183428 | ||||
Receive Message | 20931919 | 3 days ago | IN | 0 ETH | 0.02155503 | ||||
Publish Price | 20931498 | 3 days ago | IN | 0 ETH | 0.00164958 | ||||
Publish Price | 20931497 | 3 days ago | IN | 0 ETH | 0.0018536 | ||||
Publish Price | 20931496 | 3 days ago | IN | 0 ETH | 0.0018292 | ||||
Publish Price | 20931495 | 3 days ago | IN | 0 ETH | 0.0019434 | ||||
Publish Price | 20931494 | 3 days ago | IN | 0 ETH | 0.00170843 | ||||
Publish Price | 20917144 | 5 days ago | IN | 0 ETH | 0.0014344 | ||||
Publish Price | 20917143 | 5 days ago | IN | 0 ETH | 0.00166218 | ||||
Receive Message | 20912632 | 5 days ago | IN | 0 ETH | 0.01577636 | ||||
Receive Message | 20912184 | 5 days ago | IN | 0 ETH | 0.01339961 | ||||
Receive Message | 20906309 | 6 days ago | IN | 0 ETH | 0.01500778 | ||||
Receive Message | 20905267 | 6 days ago | IN | 0 ETH | 0.00998754 | ||||
Receive Message | 20905266 | 6 days ago | IN | 0 ETH | 0.0121636 | ||||
Publish Price | 20902799 | 7 days ago | IN | 0 ETH | 0.00093233 | ||||
Publish Price | 20902798 | 7 days ago | IN | 0 ETH | 0.0009394 | ||||
Publish Price | 20902797 | 7 days ago | IN | 0 ETH | 0.00081378 | ||||
Publish Price | 20902796 | 7 days ago | IN | 0 ETH | 0.00089588 | ||||
Receive Message | 20898583 | 7 days ago | IN | 0 ETH | 0.00878101 | ||||
Receive Message | 20889236 | 9 days ago | IN | 0 ETH | 0.00828068 | ||||
Publish Price | 20888448 | 9 days ago | IN | 0 ETH | 0.00095004 | ||||
Publish Price | 20888447 | 9 days ago | IN | 0 ETH | 0.00098233 | ||||
Publish Price | 20888446 | 9 days ago | IN | 0 ETH | 0.00099302 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
OracleRootTunnel
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@maticnetwork/fx-portal/contracts/tunnel/FxBaseRootTunnel.sol"; import "./OracleBaseTunnel.sol"; import "../oracle/interfaces/OracleAncillaryInterface.sol"; import "../common/implementation/Lockable.sol"; /** * @title Adapter deployed on mainnet that validates and sends price requests from sidechain to the DVM on mainnet. * @dev This contract must be a registered financial contract in order to make DVM price requests. */ contract OracleRootTunnel is OracleBaseTunnel, FxBaseRootTunnel, Lockable { constructor( address _checkpointManager, address _fxRoot, address _finderAddress ) OracleBaseTunnel(_finderAddress) FxBaseRootTunnel(_checkpointManager, _fxRoot) {} /** * @notice This is the first method that should be called in order to publish a price request to the sidechain. * @dev Publishes the DVM resolved price for the price request, or reverts if not resolved yet. This contract must * be registered with the DVM to query price requests. * @param identifier Identifier of price request to resolve. * @param time Timestamp of price request to resolve. * @param ancillaryData extra data of price request to resolve. */ function publishPrice( bytes32 identifier, uint256 time, bytes memory ancillaryData ) public nonReentrant() { // `getPrice` will revert if there is no price. int256 price = _getOracle().getPrice(identifier, time, ancillaryData); // This implementation allows duplicate MessageSent events via _sendMessageToRoot. The child tunnel on the // sidechain will not have a problem handling duplicate price resolutions (it will just ignore them). This is // potentially a fallback in case the automatic state sync to the sidechain is missing the `publishPrice` // transaction for some reason. There is little risk in duplicating MessageSent emissions because the sidechain // bridge does not impose any rate-limiting. _publishPrice(identifier, time, ancillaryData, price); _sendMessageToChild(abi.encode(identifier, time, ancillaryData, price)); } /** * @notice Submits a price request. * @dev This internal method will be called inside `receiveMessage(bytes memory inputData)`. The `inputData` is a * proof of transaction that is derived from the transaction hash of the transaction on the child chain that * originated the cross-chain price request via _sendMessageToRoot. This contract must be registered with the DVM * to submit price requests. * @param data ABI encoded params with which to call `requestPrice`. */ function _processMessageFromChild(bytes memory data) internal override { (bytes32 identifier, uint256 time, bytes memory ancillaryData) = abi.decode(data, (bytes32, uint256, bytes)); _requestPrice(identifier, time, ancillaryData); _getOracle().requestPrice(identifier, time, ancillaryData); } /** * @notice Return DVM for this network. */ function _getOracle() internal view returns (OracleAncillaryInterface) { return OracleAncillaryInterface(finder.getImplementationAddress(OracleInterfaces.Oracle)); } }
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(uint src, uint dest, uint 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; } // left over bytes. Mask is used to remove unwanted bytes from the word uint 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 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; } }
// 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 ); } }
/* * @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 { uint len; uint memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint 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)); uint ptr = self.nextPtr; uint 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) { uint 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)); uint ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param item RLP encoded bytes */ function rlpLen(RLPItem memory item) internal pure returns (uint) { return item.len; } /* * @param item RLP encoded bytes */ function payloadLen(RLPItem memory item) internal pure returns (uint) { 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)); uint items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint memPtr = item.memPtr + _payloadOffset(item.memPtr); uint dataLen; for (uint 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; uint 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 (uint, uint) { uint offset = _payloadOffset(item.memPtr); uint memPtr = item.memPtr + offset; uint 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) { (uint memPtr, uint 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; uint 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); uint result; uint 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 (uint) { require(item.len > 0 && item.len <= 33); uint offset = _payloadOffset(item.memPtr); uint len = item.len - offset; uint result; uint 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 (uint) { // one byte prefix require(item.len == 33); uint result; uint memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); uint offset = _payloadOffset(item.memPtr); uint len = item.len - offset; // data length bytes memory result = new bytes(len); uint 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 (uint) { if (item.len == 0) return 0; uint count = 0; uint currPtr = item.memPtr + _payloadOffset(item.memPtr); uint 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(uint memPtr) private pure returns (uint) { uint itemLen; uint 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(uint memPtr) private pure returns (uint) { uint 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(uint src, uint dest, uint 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 uint 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 "../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 { 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) virtual internal; }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; /** * @title A contract that provides modifiers to prevent reentrancy to state-changing and view-only methods. This contract * is inspired by https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/ReentrancyGuard.sol * and https://github.com/balancer-labs/balancer-core/blob/master/contracts/BPool.sol. */ contract Lockable { bool private _notEntered; constructor() { // Storing an initial non-zero value makes deployment a bit more expensive, but in exchange the refund on every // call to nonReentrant will be lower in amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to increase the likelihood of the full // refund coming into effect. _notEntered = true; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` function is not supported. It is possible to * prevent this from happening by making the `nonReentrant` function external, and making it call a `private` * function that does the actual state modification. */ modifier nonReentrant() { _preEntranceCheck(); _preEntranceSet(); _; _postEntranceReset(); } /** * @dev Designed to prevent a view-only method from being re-entered during a call to a `nonReentrant()` state-changing method. */ modifier nonReentrantView() { _preEntranceCheck(); _; } // Internal methods are used to avoid copying the require statement's bytecode to every `nonReentrant()` method. // On entry into a function, `_preEntranceCheck()` should always be called to check if the function is being // re-entered. Then, if the function modifies state, it should call `_postEntranceSet()`, perform its logic, and // then call `_postEntranceReset()`. // View-only methods can simply call `_preEntranceCheck()` to make sure that it is not being re-entered. function _preEntranceCheck() internal view { // On the first call to nonReentrant, _notEntered will be true require(_notEntered, "ReentrancyGuard: reentrant call"); } function _preEntranceSet() internal { // Any calls to nonReentrant after this point will fail _notEntered = false; } function _postEntranceReset() internal { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _notEntered = true; } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; /** * @title Stores common interface names used throughout the DVM by registration in the Finder. */ library OracleInterfaces { bytes32 public constant Oracle = "Oracle"; bytes32 public constant IdentifierWhitelist = "IdentifierWhitelist"; bytes32 public constant Store = "Store"; bytes32 public constant FinancialContractsAdmin = "FinancialContractsAdmin"; bytes32 public constant Registry = "Registry"; bytes32 public constant CollateralWhitelist = "CollateralWhitelist"; bytes32 public constant OptimisticOracle = "OptimisticOracle"; bytes32 public constant Bridge = "Bridge"; bytes32 public constant GenericHandler = "GenericHandler"; bytes32 public constant SkinnyOptimisticOracle = "SkinnyOptimisticOracle"; bytes32 public constant ChildMessenger = "ChildMessenger"; bytes32 public constant OracleHub = "OracleHub"; bytes32 public constant OracleSpoke = "OracleSpoke"; } /** * @title Commonly re-used values for contracts associated with the OptimisticOracle. */ library OptimisticOracleConstraints { // Any price request submitted to the OptimisticOracle must contain ancillary data no larger than this value. // This value must be <= the Voting contract's `ancillaryBytesLimit` constant value otherwise it is possible // that a price can be requested to the OptimisticOracle successfully, but cannot be resolved by the DVM which // refuses to accept a price request made with ancillary data length over a certain size. uint256 public constant ancillaryBytesLimit = 8192; }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; /** * @title Provides addresses of the live contracts implementing certain interfaces. * @dev Examples are the Oracle or Store interfaces. */ interface FinderInterface { /** * @notice Updates the address of the contract that implements `interfaceName`. * @param interfaceName bytes32 encoding of the interface name that is either changed or registered. * @param implementationAddress address of the deployed contract that implements the interface. */ function changeImplementationAddress(bytes32 interfaceName, address implementationAddress) external; /** * @notice Gets the address of the contract that implements the given `interfaceName`. * @param interfaceName queried interface. * @return implementationAddress address of the deployed contract that implements the interface. */ function getImplementationAddress(bytes32 interfaceName) external view returns (address); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; /** * @title Financial contract facing Oracle interface. * @dev Interface used by financial contracts to interact with the Oracle. Voters will use a different interface. */ abstract contract OracleAncillaryInterface { /** * @notice Enqueues a request (if a request isn't already present) for the given `identifier`, `time` pair. * @dev Time must be in the past and the identifier must be supported. * @param identifier uniquely identifies the price requested. eg BTC/USD (encoded as bytes32) could be requested. * @param ancillaryData arbitrary data appended to a price request to give the voters more info from the caller. * @param time unix timestamp for the price request. */ function requestPrice( bytes32 identifier, uint256 time, bytes memory ancillaryData ) public virtual; /** * @notice Whether the price for `identifier` and `time` is available. * @dev Time must be in the past and the identifier must be supported. * @param identifier uniquely identifies the price requested. eg BTC/USD (encoded as bytes32) could be requested. * @param time unix timestamp for the price request. * @param ancillaryData arbitrary data appended to a price request to give the voters more info from the caller. * @return bool if the DVM has resolved to a price for the given identifier and timestamp. */ function hasPrice( bytes32 identifier, uint256 time, bytes memory ancillaryData ) public view virtual returns (bool); /** * @notice Gets the price for `identifier` and `time` if it has already been requested and resolved. * @dev If the price is not available, the method reverts. * @param identifier uniquely identifies the price requested. eg BTC/USD (encoded as bytes32) could be requested. * @param time unix timestamp for the price request. * @param ancillaryData arbitrary data appended to a price request to give the voters more info from the caller. * @return int256 representing the resolved price for the given identifier and timestamp. */ function getPrice( bytes32 identifier, uint256 time, bytes memory ancillaryData ) public view virtual returns (int256); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; import "../oracle/interfaces/FinderInterface.sol"; import "../oracle/implementation/Constants.sol"; /** * @notice Enforces lifecycle of price requests for deriving contract. */ abstract contract OracleBaseTunnel { enum RequestState { NeverRequested, Requested, Resolved } struct Price { RequestState state; int256 price; } // This value must be <= the Voting contract's `ancillaryBytesLimit` value otherwise it is possible // that a price can be requested to this contract successfully, but cannot be resolved by the DVM which refuses // to accept a price request made with ancillary data length over a certain size. uint256 public constant ancillaryBytesLimit = 8192; // Mapping of encoded price requests {identifier, time, ancillaryData} to Price objects. mapping(bytes32 => Price) internal prices; // Finder to provide addresses for DVM system contracts. FinderInterface public finder; event PriceRequestAdded(bytes32 indexed identifier, uint256 time, bytes ancillaryData, bytes32 indexed requestHash); event PushedPrice( bytes32 indexed identifier, uint256 time, bytes ancillaryData, int256 price, bytes32 indexed requestHash ); /** * @notice Constructor. * @param _finderAddress finder to use to get addresses of DVM contracts. */ constructor(address _finderAddress) { finder = FinderInterface(_finderAddress); } /** * @notice Enqueues a request (if a request isn't already present) for the given (identifier, time, * ancillary data) combination. Will only emit an event if the request has never been requested. */ function _requestPrice( bytes32 identifier, uint256 time, bytes memory ancillaryData ) internal { require(ancillaryData.length <= ancillaryBytesLimit, "Invalid ancillary data"); bytes32 priceRequestId = _encodePriceRequest(identifier, time, ancillaryData); Price storage lookup = prices[priceRequestId]; if (lookup.state == RequestState.NeverRequested) { lookup.state = RequestState.Requested; emit PriceRequestAdded(identifier, time, ancillaryData, priceRequestId); } } /** * @notice Publishes price for a requested query. Will only emit an event if the request has never been resolved. */ function _publishPrice( bytes32 identifier, uint256 time, bytes memory ancillaryData, int256 price ) internal { bytes32 priceRequestId = _encodePriceRequest(identifier, time, ancillaryData); Price storage lookup = prices[priceRequestId]; if (lookup.state == RequestState.Requested) { lookup.price = price; lookup.state = RequestState.Resolved; emit PushedPrice(identifier, time, ancillaryData, lookup.price, priceRequestId); } } /** * @notice Returns the convenient way to store price requests, uniquely identified by {identifier, time, * ancillaryData }. */ function _encodePriceRequest( bytes32 identifier, uint256 time, bytes memory ancillaryData ) internal pure returns (bytes32) { return keccak256(abi.encode(identifier, time, ancillaryData)); } }
{ "evmVersion": "london", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 1000000 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
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":"_finderAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"identifier","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"ancillaryData","type":"bytes"},{"indexed":true,"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"name":"PriceRequestAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"identifier","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"ancillaryData","type":"bytes"},{"indexed":false,"internalType":"int256","name":"price","type":"int256"},{"indexed":true,"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"name":"PushedPrice","type":"event"},{"inputs":[],"name":"SEND_MESSAGE_EVENT_SIG","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ancillaryBytesLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkpointManager","outputs":[{"internalType":"contract ICheckpointManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finder","outputs":[{"internalType":"contract FinderInterface","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":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"processedExits","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"identifier","type":"bytes32"},{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"bytes","name":"ancillaryData","type":"bytes"}],"name":"publishPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"inputData","type":"bytes"}],"name":"receiveMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fxChildTunnel","type":"address"}],"name":"setFxChildTunnel","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620028f4380380620028f48339810160408190526200003491620000a2565b600180546001600160a01b039283166001600160a01b031991821617825560038054958416958216959095179094556002805492909316919093161790556006805460ff19169091179055620000ec565b80516001600160a01b03811681146200009d57600080fd5b919050565b600080600060608486031215620000b857600080fd5b620000c38462000085565b9250620000d36020850162000085565b9150620000e36040850162000085565b90509250925092565b6127f880620000fc6000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063c0857ba011610076578063de9b771f1161005b578063de9b771f146101d3578063deda381b146101f3578063f953cec71461020657600080fd5b8063c0857ba0146101aa578063c371dda7146101ca57600080fd5b8063972c4928116100a7578063972c492814610130578063aea4e49e14610175578063b9a3c84c1461018a57600080fd5b80630e387de6146100c3578063607f2d42146100fd575b600080fd5b6100ea7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b6040519081526020015b60405180910390f35b61012061010b366004611ff9565b60056020526000908152604090205460ff1681565b60405190151581526020016100f4565b6004546101509073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f4565b610188610183366004612037565b610219565b005b6001546101509073ffffffffffffffffffffffffffffffffffffffff1681565b6003546101509073ffffffffffffffffffffffffffffffffffffffff1681565b6100ea61200081565b6002546101509073ffffffffffffffffffffffffffffffffffffffff1681565b61018861020136600461216e565b61030b565b6101886102143660046121be565b610448565b60045473ffffffffffffffffffffffffffffffffffffffff16156102c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f467842617365526f6f7454756e6e656c3a204348494c445f54554e4e454c5f4160448201527f4c52454144595f5345540000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610313610462565b610340600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600061034a6104d0565b73ffffffffffffffffffffffffffffffffffffffff1663719c6d568585856040518463ffffffff1660e01b81526004016103869392919061226d565b60206040518083038186803b15801561039e57600080fd5b505afa1580156103b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d69190612295565b90506103e484848484610597565b610412848484846040516020016103fe94939291906122ae565b60405160208183030381529060405261064c565b50610443600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b505050565b6000610453826106dd565b905061045e81610abf565b5050565b60065460ff166104ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102bb565b565b6001546040517faafd5e400000000000000000000000000000000000000000000000000000000081527f4f7261636c650000000000000000000000000000000000000000000000000000600482015260009173ffffffffffffffffffffffffffffffffffffffff169063aafd5e409060240160206040518083038186803b15801561055a57600080fd5b505afa15801561056e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059291906122de565b905090565b60006105a4858585610b65565b60008181526020819052604090209091506001815460ff1660028111156105cd576105cd6122fb565b1415610644576001810183905580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166002178155604051829087907ffd38de8c79c8c3c553ecd154c6b11b67511ec8dee573c8a488a056d7335b34e89061063b9089908990899061232a565b60405180910390a35b505050505050565b600254600480546040517fb472047700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384169363b4720477936106a89390911691869101612353565b600060405180830381600087803b1580156106c257600080fd5b505af11580156106d6573d6000803e3d6000fd5b5050505050565b606060006106ea83610b9b565b905060006106f782610bfa565b9050600061070483610c29565b905060008161071284610c52565b61071b86610e40565b60405160200161072d93929190612382565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600590935291205490915060ff1615610802576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f535345440000000000000000000000000000000000000000000000000000000060648201526084016102bb565b600081815260056020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561084285610e5c565b9050600061084f82610fa6565b905061085a81611036565b60045473ffffffffffffffffffffffffffffffffffffffff908116911614610904576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c00000000000000000000000000000000000000000000000000000060648201526084016102bb565b600061090f8761105f565b905061092f61091f846020015190565b876109298a61107b565b84611097565b6109bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f46000000000000000000000000000000000000000000000000000000000060648201526084016102bb565b6109e9856109c88961134e565b6109d18a61136a565b846109db8c611386565b6109e48d6113a2565b6113be565b5060006109f583611533565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036610a2b610a2683600061156f565b6115a7565b14610a92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e41545552450060448201526064016102bb565b6000610a9d84611622565b806020019051810190610ab091906123f4565b9b9a5050505050505050505050565b600080600083806020019051810190610ad89190612429565b925092509250610ae983838361163e565b610af16104d0565b73ffffffffffffffffffffffffffffffffffffffff1663216666a48484846040518463ffffffff1660e01b8152600401610b2d9392919061226d565b600060405180830381600087803b158015610b4757600080fd5b505af1158015610b5b573d6000803e3d6000fd5b5050505050505050565b6000838383604051602001610b7c9392919061226d565b6040516020818303038152906040528051906020012090509392505050565b6040805160208101909152606081526000610be5610be08460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b611753565b60408051602081019091529081529392505050565b6060610c238260000151600881518110610c1657610c1661246f565b6020026020010151611869565b92915050565b6000610c238260000151600281518110610c4557610c4561246f565b60200260200101516115a7565b60408051602081019091526000815281516060919015610c2357600080610c7a600086611906565b60f81c90506001811480610c9157508060ff166003145b15610d5157600185516002610ca691906124cd565b610cb0919061250a565b67ffffffffffffffff811115610cc857610cc8612054565b6040519080825280601f01601f191660200182016040528015610cf2576020820181803683370190505b5092506000610d02600187611906565b90508084600081518110610d1857610d1861246f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001925050610db5565b600285516002610d6191906124cd565b610d6b919061250a565b67ffffffffffffffff811115610d8357610d83612054565b6040519080825280601f01601f191660200182016040528015610dad576020820181803683370190505b509250600091505b60ff82165b8351811015610e3757610de4610dd360ff85168361250a565b610dde906002612521565b87611906565b848281518110610df657610df661246f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080610e2f81612539565b915050610dba565b50505092915050565b6000610c238260000151600981518110610c4557610c4561246f565b610e8060405180606001604052806060815260200160608152602001600081525090565b610e9a8260000151600681518110610c1657610c1661246f565b602082810182905260408051808201825260008082529083015280518082019091528251815291810190820152610ed081611987565b15610ee557610ede81611753565b8252610f92565b60208201518051600090610efb9060019061250a565b67ffffffffffffffff811115610f1357610f13612054565b6040519080825280601f01601f191660200182016040528015610f3d576020820181803683370190505b509050600080836021019150826020019050610f5b828285516119c0565b604080518082018252600080825260209182015281518083019092528451825280850190820152610f8b90611753565b8652505050505b610f9b83610e40565b604083015250919050565b604080516080810182526000918101828152606080830193909352815260208101919091526000610ff48360000151600381518110610fe757610fe761246f565b6020026020010151611753565b8360400151815181106110095761100961246f565b60200260200101519050604051806040016040528082815260200161102d83611753565b90529392505050565b6000610c2382602001516000815181106110525761105261246f565b6020026020010151611a3b565b6000610c238260000151600581518110610c4557610c4561246f565b6060610c238260000151600781518110610c1657610c1661246f565b6000806110cb8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b905060006110d882611753565b9050606080856000806110ea8b610c52565b9050805160001415611106576000975050505050505050611346565b60005b865181101561133d57815183111561112c57600098505050505050505050611346565b61114e8782815181106111415761114161246f565b6020026020010151611a55565b95508580519060200120841461116f57600098505050505050505050611346565b611184878281518110610fe757610fe761246f565b94508451601114156112595781518314156111e6578c805190602001206111b786601081518110610c1657610c1661246f565b8051906020012014156111d557600198505050505050505050611346565b600098505050505050505050611346565b60008284815181106111fa576111fa61246f565b016020015160f81c9050601081111561121f5760009950505050505050505050611346565b611244868260ff16815181106112375761123761246f565b6020026020010151611ad5565b9450611251600185612521565b93505061132b565b8451600214156111d557600061128561127e87600081518110610c1657610c1661246f565b8486611b03565b83519091506112948286612521565b14156112e9578d805190602001206112b887600181518110610c1657610c1661246f565b8051906020012014156112d75760019950505050505050505050611346565b60009950505050505050505050611346565b806113005760009950505050505050505050611346565b61130a8185612521565b9350611322866001815181106112375761123761246f565b945061132b9050565b8061133581612539565b915050611109565b50505050505050505b949350505050565b6000610c238260000151600381518110610c4557610c4561246f565b6000610c238260000151600481518110610c4557610c4561246f565b6000610c238260000151600081518110610c4557610c4561246f565b6060610c238260000151600181518110610c1657610c1661246f565b6003546040517f41539d4a0000000000000000000000000000000000000000000000000000000081526004810184905260009182918291829173ffffffffffffffffffffffffffffffffffffffff909116906341539d4a9060240160a06040518083038186803b15801561143157600080fd5b505afa158015611445573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114699190612572565b50935050925092506114c0828b611480919061250a565b6040805160208082018f90528183018e9052606082018d905260808083018d90528351808403909101815260a09092019092528051910120908588611c3c565b611526576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f4845414445520000000060448201526064016102bb565b9998505050505050505050565b60408051602081019091526060815260405180602001604052806115678460200151600181518110610fe757610fe761246f565b905292915050565b604080518082019091526000808252602082015282518051839081106115975761159761246f565b6020026020010151905092915050565b8051600090158015906115bc57508151602110155b6115c557600080fd5b60006115d48360200151611de6565b905060008184600001516115e8919061250a565b90506000808386602001516115fd9190612521565b905080519150602083101561161957826020036101000a820491505b50949350505050565b6060610c238260200151600281518110610c1657610c1661246f565b612000815111156116ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c696420616e63696c6c61727920646174610000000000000000000060448201526064016102bb565b60006116b8848484610b65565b6000818152602081905260408120919250815460ff1660028111156116df576116df6122fb565b14156106d65780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001178155604051829086907f55ad1db144341b8105784dba37a7cb1c3088262f75ea638cfb7c8ecfb73751c69061174490889088906125bf565b60405180910390a35050505050565b606061175e82611987565b61176757600080fd5b600061177283611e68565b905060008167ffffffffffffffff81111561178f5761178f612054565b6040519080825280602002602001820160405280156117d457816020015b60408051808201909152600080825260208201528152602001906001900390816117ad5790505b50905060006117e68560200151611de6565b85602001516117f59190612521565b90506000805b8481101561185e5761180c83611eeb565b91506040518060400160405280838152602001848152508482815181106118355761183561246f565b602090810291909101015261184a8284612521565b92508061185681612539565b9150506117fb565b509195945050505050565b805160609061187757600080fd5b60006118868360200151611de6565b9050600081846000015161189a919061250a565b905060008167ffffffffffffffff8111156118b7576118b7612054565b6040519080825280601f01601f1916602001820160405280156118e1576020820181803683370190505b50905060008160200190506116198487602001516118ff9190612521565b8285611fad565b6000611913600284612607565b1561194d5760108261192660028661261b565b815181106119365761193661246f565b0160200151611948919060f81c61262f565b61197d565b60108261195b60028661261b565b8151811061196b5761196b61246f565b016020015161197d919060f81c612651565b60f81b9392505050565b805160009061199857506000919050565b6020820151805160001a9060c08210156119b6575060009392505050565b5060019392505050565b806119ca57505050565b60208110611a0257825182526119e1602084612521565b92506119ee602083612521565b91506119fb60208261250a565b90506119ca565b60006001611a1183602061250a565b611a1d90610100612793565b611a27919061250a565b935183518516941916939093179091525050565b8051600090601514611a4c57600080fd5b610c23826115a7565b60606000826000015167ffffffffffffffff811115611a7657611a76612054565b6040519080825280601f01601f191660200182016040528015611aa0576020820181803683370190505b509050805160001415611ab35792915050565b6000816020019050611ace8460200151828660000151611fad565b5092915050565b8051600090602114611ae657600080fd5b60008083602001516001611afa9190612521565b51949350505050565b60008080611b1086610c52565b90506000815167ffffffffffffffff811115611b2e57611b2e612054565b6040519080825280601f01601f191660200182016040528015611b58576020820181803683370190505b509050845b8251611b699087612521565b811015611c0c576000878281518110611b8457611b8461246f565b01602001517fff000000000000000000000000000000000000000000000000000000000000001690508083611bb9898561250a565b81518110611bc957611bc961246f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350508080611c0490612539565b915050611b5d565b50808051906020012082805190602001201415611c2c5781519250611c31565b600092505b509095945050505050565b600060208251611c4c9190612607565b15611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e76616c69642070726f6f66206c656e67746800000000000000000000000060448201526064016102bb565b600060208351611cc3919061261b565b9050611cd0816002612793565b8510611d38576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4c65616620696e64657820697320746f6f20626967000000000000000000000060448201526064016102bb565b60008660205b85518111611dd857858101519250611d57600289612607565b611d8c576040805160208101849052908101849052606001604051602081830303815290604052805190602001209150611db9565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b611dc460028961261b565b9750611dd1602082612521565b9050611d3e565b509094149695505050505050565b8051600090811a6080811015611dff5750600092915050565b60b8811080611e1a575060c08110801590611e1a575060f881105b15611e285750600192915050565b60c0811015611e5c57611e3d600160b861279f565b611e4a9060ff168261250a565b611e55906001612521565b9392505050565b611e3d600160f861279f565b8051600090611e7957506000919050565b600080611e898460200151611de6565b8460200151611e989190612521565b9050600084600001518560200151611eb09190612521565b90505b80821015611ee257611ec482611eeb565b611ece9083612521565b915082611eda81612539565b935050611eb3565b50909392505050565b80516000908190811a6080811015611f065760019150611ace565b60b8811015611f2c57611f1a60808261250a565b611f25906001612521565b9150611ace565b60c0811015611f595760b78103600185019450806020036101000a85510460018201810193505050611ace565b60f8811015611f6d57611f1a60c08261250a565b60019390930151602084900360f7016101000a90049092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a0192915050565b80611fb757505050565b60208110611fef5782518252611fce602084612521565b9250611fdb602083612521565b9150611fe860208261250a565b9050611fb7565b80611a0257505050565b60006020828403121561200b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461203457600080fd5b50565b60006020828403121561204957600080fd5b8135611e5581612012565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156120ca576120ca612054565b604052919050565b600067ffffffffffffffff8211156120ec576120ec612054565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261212957600080fd5b813561213c612137826120d2565b612083565b81815284602083860101111561215157600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561218357600080fd5b8335925060208401359150604084013567ffffffffffffffff8111156121a857600080fd5b6121b486828701612118565b9150509250925092565b6000602082840312156121d057600080fd5b813567ffffffffffffffff8111156121e757600080fd5b61134684828501612118565b60005b8381101561220e5781810151838201526020016121f6565b8381111561221d576000848401525b50505050565b6000815180845261223b8160208601602086016121f3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b83815282602082015260606040820152600061228c6060830184612223565b95945050505050565b6000602082840312156122a757600080fd5b5051919050565b8481528360208201526080604082015260006122cd6080830185612223565b905082606083015295945050505050565b6000602082840312156122f057600080fd5b8151611e5581612012565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8381526060602082015260006123436060830185612223565b9050826040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006113466040830184612223565b8381526000835161239a8160208501602088016121f3565b60209201918201929092526040019392505050565b600082601f8301126123c057600080fd5b81516123ce612137826120d2565b8181528460208386010111156123e357600080fd5b6113468260208301602087016121f3565b60006020828403121561240657600080fd5b815167ffffffffffffffff81111561241d57600080fd5b611346848285016123af565b60008060006060848603121561243e57600080fd5b8351925060208401519150604084015167ffffffffffffffff81111561246357600080fd5b6121b4868287016123af565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156125055761250561249e565b500290565b60008282101561251c5761251c61249e565b500390565b600082198211156125345761253461249e565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561256b5761256b61249e565b5060010190565b600080600080600060a0868803121561258a57600080fd5b8551945060208601519350604086015192506060860151915060808601516125b181612012565b809150509295509295909350565b8281526040602082015260006113466040830184612223565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612616576126166125d8565b500690565b60008261262a5761262a6125d8565b500490565b600060ff831680612642576126426125d8565b8060ff84160691505092915050565b600060ff831680612664576126646125d8565b8060ff84160491505092915050565b600181815b808511156126cc57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156126b2576126b261249e565b808516156126bf57918102915b93841c9390800290612678565b509250929050565b6000826126e357506001610c23565b816126f057506000610c23565b816001811461270657600281146127105761272c565b6001915050610c23565b60ff8411156127215761272161249e565b50506001821b610c23565b5060208310610133831016604e8410600b841016171561274f575081810a610c23565b6127598383612673565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561278b5761278b61249e565b029392505050565b6000611e5583836126d4565b600060ff821660ff8416808210156127b9576127b961249e565b9003939250505056fea264697066735822122082be973be98f6756b7fe5738f4fe5e3731ce3859968ba58db7f855b95a6030c264736f6c6343000809003300000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a200000000000000000000000040f941e48a552bf496b154af6bf55725f18d77c3
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100be5760003560e01c8063c0857ba011610076578063de9b771f1161005b578063de9b771f146101d3578063deda381b146101f3578063f953cec71461020657600080fd5b8063c0857ba0146101aa578063c371dda7146101ca57600080fd5b8063972c4928116100a7578063972c492814610130578063aea4e49e14610175578063b9a3c84c1461018a57600080fd5b80630e387de6146100c3578063607f2d42146100fd575b600080fd5b6100ea7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b6040519081526020015b60405180910390f35b61012061010b366004611ff9565b60056020526000908152604090205460ff1681565b60405190151581526020016100f4565b6004546101509073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f4565b610188610183366004612037565b610219565b005b6001546101509073ffffffffffffffffffffffffffffffffffffffff1681565b6003546101509073ffffffffffffffffffffffffffffffffffffffff1681565b6100ea61200081565b6002546101509073ffffffffffffffffffffffffffffffffffffffff1681565b61018861020136600461216e565b61030b565b6101886102143660046121be565b610448565b60045473ffffffffffffffffffffffffffffffffffffffff16156102c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f467842617365526f6f7454756e6e656c3a204348494c445f54554e4e454c5f4160448201527f4c52454144595f5345540000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610313610462565b610340600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600061034a6104d0565b73ffffffffffffffffffffffffffffffffffffffff1663719c6d568585856040518463ffffffff1660e01b81526004016103869392919061226d565b60206040518083038186803b15801561039e57600080fd5b505afa1580156103b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d69190612295565b90506103e484848484610597565b610412848484846040516020016103fe94939291906122ae565b60405160208183030381529060405261064c565b50610443600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b505050565b6000610453826106dd565b905061045e81610abf565b5050565b60065460ff166104ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102bb565b565b6001546040517faafd5e400000000000000000000000000000000000000000000000000000000081527f4f7261636c650000000000000000000000000000000000000000000000000000600482015260009173ffffffffffffffffffffffffffffffffffffffff169063aafd5e409060240160206040518083038186803b15801561055a57600080fd5b505afa15801561056e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059291906122de565b905090565b60006105a4858585610b65565b60008181526020819052604090209091506001815460ff1660028111156105cd576105cd6122fb565b1415610644576001810183905580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166002178155604051829087907ffd38de8c79c8c3c553ecd154c6b11b67511ec8dee573c8a488a056d7335b34e89061063b9089908990899061232a565b60405180910390a35b505050505050565b600254600480546040517fb472047700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384169363b4720477936106a89390911691869101612353565b600060405180830381600087803b1580156106c257600080fd5b505af11580156106d6573d6000803e3d6000fd5b5050505050565b606060006106ea83610b9b565b905060006106f782610bfa565b9050600061070483610c29565b905060008161071284610c52565b61071b86610e40565b60405160200161072d93929190612382565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600590935291205490915060ff1615610802576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f535345440000000000000000000000000000000000000000000000000000000060648201526084016102bb565b600081815260056020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561084285610e5c565b9050600061084f82610fa6565b905061085a81611036565b60045473ffffffffffffffffffffffffffffffffffffffff908116911614610904576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c00000000000000000000000000000000000000000000000000000060648201526084016102bb565b600061090f8761105f565b905061092f61091f846020015190565b876109298a61107b565b84611097565b6109bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f46000000000000000000000000000000000000000000000000000000000060648201526084016102bb565b6109e9856109c88961134e565b6109d18a61136a565b846109db8c611386565b6109e48d6113a2565b6113be565b5060006109f583611533565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036610a2b610a2683600061156f565b6115a7565b14610a92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e41545552450060448201526064016102bb565b6000610a9d84611622565b806020019051810190610ab091906123f4565b9b9a5050505050505050505050565b600080600083806020019051810190610ad89190612429565b925092509250610ae983838361163e565b610af16104d0565b73ffffffffffffffffffffffffffffffffffffffff1663216666a48484846040518463ffffffff1660e01b8152600401610b2d9392919061226d565b600060405180830381600087803b158015610b4757600080fd5b505af1158015610b5b573d6000803e3d6000fd5b5050505050505050565b6000838383604051602001610b7c9392919061226d565b6040516020818303038152906040528051906020012090509392505050565b6040805160208101909152606081526000610be5610be08460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b611753565b60408051602081019091529081529392505050565b6060610c238260000151600881518110610c1657610c1661246f565b6020026020010151611869565b92915050565b6000610c238260000151600281518110610c4557610c4561246f565b60200260200101516115a7565b60408051602081019091526000815281516060919015610c2357600080610c7a600086611906565b60f81c90506001811480610c9157508060ff166003145b15610d5157600185516002610ca691906124cd565b610cb0919061250a565b67ffffffffffffffff811115610cc857610cc8612054565b6040519080825280601f01601f191660200182016040528015610cf2576020820181803683370190505b5092506000610d02600187611906565b90508084600081518110610d1857610d1861246f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001925050610db5565b600285516002610d6191906124cd565b610d6b919061250a565b67ffffffffffffffff811115610d8357610d83612054565b6040519080825280601f01601f191660200182016040528015610dad576020820181803683370190505b509250600091505b60ff82165b8351811015610e3757610de4610dd360ff85168361250a565b610dde906002612521565b87611906565b848281518110610df657610df661246f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080610e2f81612539565b915050610dba565b50505092915050565b6000610c238260000151600981518110610c4557610c4561246f565b610e8060405180606001604052806060815260200160608152602001600081525090565b610e9a8260000151600681518110610c1657610c1661246f565b602082810182905260408051808201825260008082529083015280518082019091528251815291810190820152610ed081611987565b15610ee557610ede81611753565b8252610f92565b60208201518051600090610efb9060019061250a565b67ffffffffffffffff811115610f1357610f13612054565b6040519080825280601f01601f191660200182016040528015610f3d576020820181803683370190505b509050600080836021019150826020019050610f5b828285516119c0565b604080518082018252600080825260209182015281518083019092528451825280850190820152610f8b90611753565b8652505050505b610f9b83610e40565b604083015250919050565b604080516080810182526000918101828152606080830193909352815260208101919091526000610ff48360000151600381518110610fe757610fe761246f565b6020026020010151611753565b8360400151815181106110095761100961246f565b60200260200101519050604051806040016040528082815260200161102d83611753565b90529392505050565b6000610c2382602001516000815181106110525761105261246f565b6020026020010151611a3b565b6000610c238260000151600581518110610c4557610c4561246f565b6060610c238260000151600781518110610c1657610c1661246f565b6000806110cb8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b905060006110d882611753565b9050606080856000806110ea8b610c52565b9050805160001415611106576000975050505050505050611346565b60005b865181101561133d57815183111561112c57600098505050505050505050611346565b61114e8782815181106111415761114161246f565b6020026020010151611a55565b95508580519060200120841461116f57600098505050505050505050611346565b611184878281518110610fe757610fe761246f565b94508451601114156112595781518314156111e6578c805190602001206111b786601081518110610c1657610c1661246f565b8051906020012014156111d557600198505050505050505050611346565b600098505050505050505050611346565b60008284815181106111fa576111fa61246f565b016020015160f81c9050601081111561121f5760009950505050505050505050611346565b611244868260ff16815181106112375761123761246f565b6020026020010151611ad5565b9450611251600185612521565b93505061132b565b8451600214156111d557600061128561127e87600081518110610c1657610c1661246f565b8486611b03565b83519091506112948286612521565b14156112e9578d805190602001206112b887600181518110610c1657610c1661246f565b8051906020012014156112d75760019950505050505050505050611346565b60009950505050505050505050611346565b806113005760009950505050505050505050611346565b61130a8185612521565b9350611322866001815181106112375761123761246f565b945061132b9050565b8061133581612539565b915050611109565b50505050505050505b949350505050565b6000610c238260000151600381518110610c4557610c4561246f565b6000610c238260000151600481518110610c4557610c4561246f565b6000610c238260000151600081518110610c4557610c4561246f565b6060610c238260000151600181518110610c1657610c1661246f565b6003546040517f41539d4a0000000000000000000000000000000000000000000000000000000081526004810184905260009182918291829173ffffffffffffffffffffffffffffffffffffffff909116906341539d4a9060240160a06040518083038186803b15801561143157600080fd5b505afa158015611445573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114699190612572565b50935050925092506114c0828b611480919061250a565b6040805160208082018f90528183018e9052606082018d905260808083018d90528351808403909101815260a09092019092528051910120908588611c3c565b611526576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f4845414445520000000060448201526064016102bb565b9998505050505050505050565b60408051602081019091526060815260405180602001604052806115678460200151600181518110610fe757610fe761246f565b905292915050565b604080518082019091526000808252602082015282518051839081106115975761159761246f565b6020026020010151905092915050565b8051600090158015906115bc57508151602110155b6115c557600080fd5b60006115d48360200151611de6565b905060008184600001516115e8919061250a565b90506000808386602001516115fd9190612521565b905080519150602083101561161957826020036101000a820491505b50949350505050565b6060610c238260200151600281518110610c1657610c1661246f565b612000815111156116ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c696420616e63696c6c61727920646174610000000000000000000060448201526064016102bb565b60006116b8848484610b65565b6000818152602081905260408120919250815460ff1660028111156116df576116df6122fb565b14156106d65780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001178155604051829086907f55ad1db144341b8105784dba37a7cb1c3088262f75ea638cfb7c8ecfb73751c69061174490889088906125bf565b60405180910390a35050505050565b606061175e82611987565b61176757600080fd5b600061177283611e68565b905060008167ffffffffffffffff81111561178f5761178f612054565b6040519080825280602002602001820160405280156117d457816020015b60408051808201909152600080825260208201528152602001906001900390816117ad5790505b50905060006117e68560200151611de6565b85602001516117f59190612521565b90506000805b8481101561185e5761180c83611eeb565b91506040518060400160405280838152602001848152508482815181106118355761183561246f565b602090810291909101015261184a8284612521565b92508061185681612539565b9150506117fb565b509195945050505050565b805160609061187757600080fd5b60006118868360200151611de6565b9050600081846000015161189a919061250a565b905060008167ffffffffffffffff8111156118b7576118b7612054565b6040519080825280601f01601f1916602001820160405280156118e1576020820181803683370190505b50905060008160200190506116198487602001516118ff9190612521565b8285611fad565b6000611913600284612607565b1561194d5760108261192660028661261b565b815181106119365761193661246f565b0160200151611948919060f81c61262f565b61197d565b60108261195b60028661261b565b8151811061196b5761196b61246f565b016020015161197d919060f81c612651565b60f81b9392505050565b805160009061199857506000919050565b6020820151805160001a9060c08210156119b6575060009392505050565b5060019392505050565b806119ca57505050565b60208110611a0257825182526119e1602084612521565b92506119ee602083612521565b91506119fb60208261250a565b90506119ca565b60006001611a1183602061250a565b611a1d90610100612793565b611a27919061250a565b935183518516941916939093179091525050565b8051600090601514611a4c57600080fd5b610c23826115a7565b60606000826000015167ffffffffffffffff811115611a7657611a76612054565b6040519080825280601f01601f191660200182016040528015611aa0576020820181803683370190505b509050805160001415611ab35792915050565b6000816020019050611ace8460200151828660000151611fad565b5092915050565b8051600090602114611ae657600080fd5b60008083602001516001611afa9190612521565b51949350505050565b60008080611b1086610c52565b90506000815167ffffffffffffffff811115611b2e57611b2e612054565b6040519080825280601f01601f191660200182016040528015611b58576020820181803683370190505b509050845b8251611b699087612521565b811015611c0c576000878281518110611b8457611b8461246f565b01602001517fff000000000000000000000000000000000000000000000000000000000000001690508083611bb9898561250a565b81518110611bc957611bc961246f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350508080611c0490612539565b915050611b5d565b50808051906020012082805190602001201415611c2c5781519250611c31565b600092505b509095945050505050565b600060208251611c4c9190612607565b15611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e76616c69642070726f6f66206c656e67746800000000000000000000000060448201526064016102bb565b600060208351611cc3919061261b565b9050611cd0816002612793565b8510611d38576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4c65616620696e64657820697320746f6f20626967000000000000000000000060448201526064016102bb565b60008660205b85518111611dd857858101519250611d57600289612607565b611d8c576040805160208101849052908101849052606001604051602081830303815290604052805190602001209150611db9565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b611dc460028961261b565b9750611dd1602082612521565b9050611d3e565b509094149695505050505050565b8051600090811a6080811015611dff5750600092915050565b60b8811080611e1a575060c08110801590611e1a575060f881105b15611e285750600192915050565b60c0811015611e5c57611e3d600160b861279f565b611e4a9060ff168261250a565b611e55906001612521565b9392505050565b611e3d600160f861279f565b8051600090611e7957506000919050565b600080611e898460200151611de6565b8460200151611e989190612521565b9050600084600001518560200151611eb09190612521565b90505b80821015611ee257611ec482611eeb565b611ece9083612521565b915082611eda81612539565b935050611eb3565b50909392505050565b80516000908190811a6080811015611f065760019150611ace565b60b8811015611f2c57611f1a60808261250a565b611f25906001612521565b9150611ace565b60c0811015611f595760b78103600185019450806020036101000a85510460018201810193505050611ace565b60f8811015611f6d57611f1a60c08261250a565b60019390930151602084900360f7016101000a90049092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a0192915050565b80611fb757505050565b60208110611fef5782518252611fce602084612521565b9250611fdb602083612521565b9150611fe860208261250a565b9050611fb7565b80611a0257505050565b60006020828403121561200b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461203457600080fd5b50565b60006020828403121561204957600080fd5b8135611e5581612012565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156120ca576120ca612054565b604052919050565b600067ffffffffffffffff8211156120ec576120ec612054565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261212957600080fd5b813561213c612137826120d2565b612083565b81815284602083860101111561215157600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561218357600080fd5b8335925060208401359150604084013567ffffffffffffffff8111156121a857600080fd5b6121b486828701612118565b9150509250925092565b6000602082840312156121d057600080fd5b813567ffffffffffffffff8111156121e757600080fd5b61134684828501612118565b60005b8381101561220e5781810151838201526020016121f6565b8381111561221d576000848401525b50505050565b6000815180845261223b8160208601602086016121f3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b83815282602082015260606040820152600061228c6060830184612223565b95945050505050565b6000602082840312156122a757600080fd5b5051919050565b8481528360208201526080604082015260006122cd6080830185612223565b905082606083015295945050505050565b6000602082840312156122f057600080fd5b8151611e5581612012565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8381526060602082015260006123436060830185612223565b9050826040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006113466040830184612223565b8381526000835161239a8160208501602088016121f3565b60209201918201929092526040019392505050565b600082601f8301126123c057600080fd5b81516123ce612137826120d2565b8181528460208386010111156123e357600080fd5b6113468260208301602087016121f3565b60006020828403121561240657600080fd5b815167ffffffffffffffff81111561241d57600080fd5b611346848285016123af565b60008060006060848603121561243e57600080fd5b8351925060208401519150604084015167ffffffffffffffff81111561246357600080fd5b6121b4868287016123af565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156125055761250561249e565b500290565b60008282101561251c5761251c61249e565b500390565b600082198211156125345761253461249e565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561256b5761256b61249e565b5060010190565b600080600080600060a0868803121561258a57600080fd5b8551945060208601519350604086015192506060860151915060808601516125b181612012565b809150509295509295909350565b8281526040602082015260006113466040830184612223565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612616576126166125d8565b500690565b60008261262a5761262a6125d8565b500490565b600060ff831680612642576126426125d8565b8060ff84160691505092915050565b600060ff831680612664576126646125d8565b8060ff84160491505092915050565b600181815b808511156126cc57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156126b2576126b261249e565b808516156126bf57918102915b93841c9390800290612678565b509250929050565b6000826126e357506001610c23565b816126f057506000610c23565b816001811461270657600281146127105761272c565b6001915050610c23565b60ff8411156127215761272161249e565b50506001821b610c23565b5060208310610133831016604e8410600b841016171561274f575081810a610c23565b6127598383612673565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561278b5761278b61249e565b029392505050565b6000611e5583836126d4565b600060ff821660ff8416808210156127b9576127b961249e565b9003939250505056fea264697066735822122082be973be98f6756b7fe5738f4fe5e3731ce3859968ba58db7f855b95a6030c264736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a200000000000000000000000040f941e48a552bf496b154af6bf55725f18d77c3
-----Decoded View---------------
Arg [0] : _checkpointManager (address): 0x86E4Dc95c7FBdBf52e33D563BbDB00823894C287
Arg [1] : _fxRoot (address): 0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2
Arg [2] : _finderAddress (address): 0x40f941E48A552bF496B154Af6bf55725f18D77c3
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287
Arg [1] : 000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a2
Arg [2] : 00000000000000000000000040f941e48a552bf496b154af6bf55725f18d77c3
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.