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 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60c06040 | 16801291 | 503 days ago | IN | 0 ETH | 0.14680409 |
Loading...
Loading
Contract Name:
PolygonMessengerWrapper
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 50000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT // @unsupported: ovm pragma solidity 0.8.9; pragma experimental ABIEncoderV2; import "../polygon/tunnel/FxBaseRootTunnel.sol"; import "./MessengerWrapper.sol"; /** * @dev A MessengerWrapper for Polygon - https://docs.matic.network/docs * @notice Deployed on layer-1 */ contract PolygonMessengerWrapper is FxBaseRootTunnel, MessengerWrapper { constructor( address _l1BridgeAddress, address _checkpointManager, address _fxRoot, address _fxChildTunnel, uint256 _l2ChainId ) public MessengerWrapper(_l1BridgeAddress, _l2ChainId) FxBaseRootTunnel(_checkpointManager, _fxRoot) { setFxChildTunnel(_fxChildTunnel); } /** * @dev Sends a message to the l2MessengerProxy from layer-1 * @param _calldata The data that l2MessengerProxy will be called with * @notice The msg.sender is sent to the L2_PolygonMessengerProxy and checked there. */ function sendCrossDomainMessage(bytes memory _calldata) public override { _sendMessageToChild( abi.encode(msg.sender, _calldata) ); } function verifySender(address l1BridgeCaller, bytes memory /*_data*/) public view override { if (isRootConfirmation) return; require(l1BridgeCaller == address(this), "L1_PLGN_WPR: Caller must be this contract"); } function _processMessageFromChild(bytes memory message) internal override { (bool success,) = l1BridgeAddress.call(message); require(success, "L1_PLGN_WPR: Call to L1 Bridge failed"); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.12 <=0.8.9; pragma experimental ABIEncoderV2; interface IMessengerWrapper { function sendCrossDomainMessage(bytes memory _calldata) external; function verifySender(address l1BridgeCaller, bytes memory _data) external; function confirmRoots( bytes32[] calldata rootHashes, uint256[] calldata destinationChainIds, uint256[] calldata totalAmounts, uint256[] calldata rootCommittedAts ) external; }
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; } // 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 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 { 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 "../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) internal virtual; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.12 <=0.8.9; pragma experimental ABIEncoderV2; import "../interfaces/IMessengerWrapper.sol"; contract IL1Bridge { struct TransferBond { address bonder; uint256 createdAt; uint256 totalAmount; uint256 challengeStartTime; address challenger; bool challengeResolved; } uint256 public challengePeriod; mapping(bytes32 => TransferBond) public transferBonds; function getIsBonder(address maybeBonder) public view returns (bool) {} function getTransferRootId(bytes32 rootHash, uint256 totalAmount) public pure returns (bytes32) {} function confirmTransferRoot( uint256 originChainId, bytes32 rootHash, uint256 destinationChainId, uint256 totalAmount, uint256 rootCommittedAt ) external {} } abstract contract MessengerWrapper is IMessengerWrapper { address public immutable l1BridgeAddress; uint256 public immutable l2ChainId; bool public isRootConfirmation = false; constructor(address _l1BridgeAddress, uint256 _l2ChainId) internal { l1BridgeAddress = _l1BridgeAddress; l2ChainId = _l2ChainId; } modifier onlyL1Bridge { require(msg.sender == l1BridgeAddress, "MW: Sender must be the L1 Bridge"); _; } modifier rootConfirmation { isRootConfirmation = true; _; isRootConfirmation = false; } /** * @dev Confirm roots that have bonded on L1 and passed the challenge period with no challenge * @param rootHashes The root hashes to confirm * @param destinationChainIds The destinationChainId of the roots to confirm * @param totalAmounts The totalAmount of the roots to confirm * @param rootCommittedAts The rootCommittedAt of the roots to confirm */ function confirmRoots ( bytes32[] calldata rootHashes, uint256[] calldata destinationChainIds, uint256[] calldata totalAmounts, uint256[] calldata rootCommittedAts ) external override rootConfirmation { IL1Bridge l1Bridge = IL1Bridge(l1BridgeAddress); require(l1Bridge.getIsBonder(msg.sender), "MW: Sender must be a bonder"); require(rootHashes.length == totalAmounts.length, "MW: rootHashes and totalAmounts must be the same length"); uint256 challengePeriod = l1Bridge.challengePeriod(); for (uint256 i = 0; i < rootHashes.length; i++) { bool canConfirm = canConfirmRoot(l1Bridge, rootHashes[i], totalAmounts[i], challengePeriod); require(canConfirm, "MW: Root cannot be confirmed"); l1Bridge.confirmTransferRoot( l2ChainId, rootHashes[i], destinationChainIds[i], totalAmounts[i], rootCommittedAts[i] ); } } function canConfirmRoot (IL1Bridge l1Bridge, bytes32 rootHash, uint256 totalAmount, uint256 challengePeriod) public view returns (bool) { bytes32 transferRootId = l1Bridge.getTransferRootId(rootHash, totalAmount); (,uint256 createdAt,,uint256 challengeStartTime,,) = l1Bridge.transferBonds(transferRootId); uint256 timeSinceBondCreation = block.timestamp - createdAt; if ( createdAt != 0 && challengeStartTime == 0 && timeSinceBondCreation > challengePeriod ) { return true; } return false; } }
{ "optimizer": { "enabled": true, "runs": 50000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_l1BridgeAddress","type":"address"},{"internalType":"address","name":"_checkpointManager","type":"address"},{"internalType":"address","name":"_fxRoot","type":"address"},{"internalType":"address","name":"_fxChildTunnel","type":"address"},{"internalType":"uint256","name":"_l2ChainId","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"SEND_MESSAGE_EVENT_SIG","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IL1Bridge","name":"l1Bridge","type":"address"},{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"challengePeriod","type":"uint256"}],"name":"canConfirmRoot","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkpointManager","outputs":[{"internalType":"contract ICheckpointManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"rootHashes","type":"bytes32[]"},{"internalType":"uint256[]","name":"destinationChainIds","type":"uint256[]"},{"internalType":"uint256[]","name":"totalAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"rootCommittedAts","type":"uint256[]"}],"name":"confirmRoots","outputs":[],"stateMutability":"nonpayable","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":"isRootConfirmation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l1BridgeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"processedExits","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"inputData","type":"bytes"}],"name":"receiveMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"sendCrossDomainMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fxChildTunnel","type":"address"}],"name":"setFxChildTunnel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"l1BridgeCaller","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"verifySender","outputs":[],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c06040526004805460ff191690553480156200001b57600080fd5b5060405162002e1e38038062002e1e8339810160408190526200003e916200013c565b600180546001600160a01b038087166001600160a01b031992831617909255600080548387169216919091179055851660805260a081905262000081826200008c565b5050505050620001a3565b6002546001600160a01b031615620000fd5760405162461bcd60e51b815260206004820152602a60248201527f467842617365526f6f7454756e6e656c3a204348494c445f54554e4e454c5f4160448201526913149150511657d4d15560b21b606482015260840160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b80516001600160a01b03811681146200013757600080fd5b919050565b600080600080600060a086880312156200015557600080fd5b62000160866200011f565b945062000170602087016200011f565b935062000180604087016200011f565b925062000190606087016200011f565b9150608086015190509295509295909350565b60805160a051612c40620001de6000396000818161025b01526107a2015260008181610166015281816104c50152610f240152612c406000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063972c49281161008c578063c0857ba011610066578063c0857ba014610236578063d6ae3cd514610256578063de9b771f1461027d578063f953cec71461029d57600080fd5b8063972c4928146101f057806399178dd814610210578063aea4e49e1461022357600080fd5b80635ab2a558116100c85780635ab2a55814610161578063607f2d42146101ad5780638b034eb8146101d05780638e58736f146101dd57600080fd5b80630e387de6146100ef5780631aae9eed14610129578063419cb5501461014c575b600080fd5b6101167f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b6040519081526020015b60405180910390f35b61013c6101373660046123a4565b6102b0565b6040519015158152602001610120565b61015f61015a3660046124f9565b61043d565b005b6101887f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610120565b61013c6101bb36600461252e565b60036020526000908152604090205460ff1681565b60045461013c9060ff1681565b61015f6101eb366004612593565b61046a565b6002546101889073ffffffffffffffffffffffffffffffffffffffff1681565b61015f61021e366004612657565b6108f2565b61015f6102313660046126a7565b6109aa565b6001546101889073ffffffffffffffffffffffffffffffffffffffff1681565b6101167f000000000000000000000000000000000000000000000000000000000000000081565b6000546101889073ffffffffffffffffffffffffffffffffffffffff1681565b61015f6102ab3660046124f9565b610a97565b6040517f960a7afa0000000000000000000000000000000000000000000000000000000081526004810184905260248101839052600090819073ffffffffffffffffffffffffffffffffffffffff87169063960a7afa9060440160206040518083038186803b15801561032257600080fd5b505afa158015610336573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035a91906126c4565b90506000808773ffffffffffffffffffffffffffffffffffffffff16635a7e1083846040518263ffffffff1660e01b815260040161039a91815260200190565b60c06040518083038186803b1580156103b257600080fd5b505afa1580156103c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ea91906126f2565b5050935050925050600082426104009190612786565b9050821580159061040f575081155b801561041a57508581115b1561042c576001945050505050610435565b60009450505050505b949350505050565b61046733826040516020016104539291906127cd565b604051602081830303815290604052610aad565b50565b600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781556040517fd5ef755100000000000000000000000000000000000000000000000000000000815233918101919091527f00000000000000000000000000000000000000000000000000000000000000009073ffffffffffffffffffffffffffffffffffffffff82169063d5ef75519060240160206040518083038186803b15801561051e57600080fd5b505afa158015610532573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610556919061283b565b6105c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4d573a2053656e646572206d757374206265206120626f6e646572000000000060448201526064015b60405180910390fd5b878414610650576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4d573a20726f6f7448617368657320616e6420746f74616c416d6f756e74732060448201527f6d757374206265207468652073616d65206c656e67746800000000000000000060648201526084016105b8565b60008173ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b815260040160206040518083038186803b15801561069857600080fd5b505afa1580156106ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d091906126c4565b905060005b898110156108bd57600061071b848d8d858181106106f5576106f5612856565b905060200201358a8a8681811061070e5761070e612856565b90506020020135866102b0565b905080610784576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4d573a20526f6f742063616e6e6f7420626520636f6e6669726d65640000000060448201526064016105b8565b8373ffffffffffffffffffffffffffffffffffffffff1663ef6ebe5e7f00000000000000000000000000000000000000000000000000000000000000008e8e868181106107d3576107d3612856565b905060200201358d8d878181106107ec576107ec612856565b905060200201358c8c8881811061080557610805612856565b905060200201358b8b8981811061081e5761081e612856565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e08a901b16815260048101979097526024870195909552506044850192909252606484015260209091020135608482015260a401600060405180830381600087803b15801561089157600080fd5b505af11580156108a5573d6000803e3d6000fd5b505050505080806108b590612885565b9150506106d5565b5050600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055505050505050505050565b60045460ff1615610901575050565b73ffffffffffffffffffffffffffffffffffffffff821630146109a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4c315f504c474e5f5750523a2043616c6c6572206d757374206265207468697360448201527f20636f6e7472616374000000000000000000000000000000000000000000000060648201526084016105b8565b5050565b60025473ffffffffffffffffffffffffffffffffffffffff1615610a50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f467842617365526f6f7454756e6e656c3a204348494c445f54554e4e454c5f4160448201527f4c52454144595f5345540000000000000000000000000000000000000000000060648201526084016105b8565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000610aa282610b3e565b90506109a681610f20565b6000546002546040517fb472047700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169263b472047792610b099291169085906004016127cd565b600060405180830381600087803b158015610b2357600080fd5b505af1158015610b37573d6000803e3d6000fd5b5050505050565b60606000610b4b8361103a565b90506000610b5882611099565b90506000610b65836110c8565b9050600081610b73846110f1565b610b7c866112df565b604051602001610b8e939291906128be565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600390935291205490915060ff1615610c63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f535345440000000000000000000000000000000000000000000000000000000060648201526084016105b8565b600081815260036020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610ca3856112fb565b90506000610cb082611445565b9050610cbb816114d5565b60025473ffffffffffffffffffffffffffffffffffffffff908116911614610d65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c00000000000000000000000000000000000000000000000000000060648201526084016105b8565b6000610d70876114fe565b9050610d90610d80846020015190565b87610d8a8a61151a565b84611536565b610e1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f46000000000000000000000000000000000000000000000000000000000060648201526084016105b8565b610e4a85610e29896117ec565b610e328a611808565b84610e3c8c611824565b610e458d611840565b61185c565b506000610e56836119d1565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036610e8c610e87836000611a0d565b611a45565b14610ef3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e41545552450060448201526064016105b8565b6000610efe84611ac0565b806020019051810190610f1191906128eb565b9b9a5050505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1682604051610f679190612962565b6000604051808303816000865af19150503d8060008114610fa4576040519150601f19603f3d011682016040523d82523d6000602084013e610fa9565b606091505b50509050806109a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4c315f504c474e5f5750523a2043616c6c20746f204c3120427269646765206660448201527f61696c656400000000000000000000000000000000000000000000000000000060648201526084016105b8565b604080516020810190915260608152600061108461107f8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b611adc565b60408051602081019091529081529392505050565b60606110c282600001516008815181106110b5576110b5612856565b6020026020010151611bf2565b92915050565b60006110c282600001516002815181106110e4576110e4612856565b6020026020010151611a45565b604080516020810190915260008152815160609190156110c257600080611119600086611c8f565b60f81c9050600181148061113057508060ff166003145b156111f057600185516002611145919061297e565b61114f9190612786565b67ffffffffffffffff811115611167576111676123df565b6040519080825280601f01601f191660200182016040528015611191576020820181803683370190505b50925060006111a1600187611c8f565b905080846000815181106111b7576111b7612856565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001925050611254565b600285516002611200919061297e565b61120a9190612786565b67ffffffffffffffff811115611222576112226123df565b6040519080825280601f01601f19166020018201604052801561124c576020820181803683370190505b509250600091505b60ff82165b83518110156112d65761128361127260ff851683612786565b61127d9060026129bb565b87611c8f565b84828151811061129557611295612856565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806112ce81612885565b915050611259565b50505092915050565b60006110c282600001516009815181106110e4576110e4612856565b61131f60405180606001604052806060815260200160608152602001600081525090565b61133982600001516006815181106110b5576110b5612856565b60208281018290526040805180820182526000808252908301528051808201909152825181529181019082015261136f81611d10565b156113845761137d81611adc565b8252611431565b6020820151805160009061139a90600190612786565b67ffffffffffffffff8111156113b2576113b26123df565b6040519080825280601f01601f1916602001820160405280156113dc576020820181803683370190505b5090506000808360210191508260200190506113fa82828551611d49565b60408051808201825260008082526020918201528151808301909252845182528085019082015261142a90611adc565b8652505050505b61143a836112df565b604083015250919050565b604080516080810182526000918101828152606080830193909352815260208101919091526000611493836000015160038151811061148657611486612856565b6020026020010151611adc565b8360400151815181106114a8576114a8612856565b6020026020010151905060405180604001604052808281526020016114cc83611adc565b90529392505050565b60006110c282602001516000815181106114f1576114f1612856565b6020026020010151611dc4565b60006110c282600001516005815181106110e4576110e4612856565b60606110c282600001516007815181106110b5576110b5612856565b60008061156a8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b9050600061157782611adc565b9050606080856000806115898b6110f1565b90508051600014156115a5576000975050505050505050610435565b60005b86518110156117dc5781518311156115cb57600098505050505050505050610435565b6115ed8782815181106115e0576115e0612856565b6020026020010151611dde565b95508580519060200120841461160e57600098505050505050505050610435565b61162387828151811061148657611486612856565b94508451601114156116f8578151831415611685578c80519060200120611656866010815181106110b5576110b5612856565b80519060200120141561167457600198505050505050505050610435565b600098505050505050505050610435565b600082848151811061169957611699612856565b016020015160f81c905060108111156116be5760009950505050505050505050610435565b6116e3868260ff16815181106116d6576116d6612856565b6020026020010151611e5e565b94506116f06001856129bb565b9350506117ca565b84516002141561167457600061172461171d876000815181106110b5576110b5612856565b8486611e8c565b835190915061173382866129bb565b1415611788578d80519060200120611757876001815181106110b5576110b5612856565b8051906020012014156117765760019950505050505050505050610435565b60009950505050505050505050610435565b8061179f5760009950505050505050505050610435565b6117a981856129bb565b93506117c1866001815181106116d6576116d6612856565b94506117ca9050565b806117d481612885565b9150506115a8565b5050505050505050949350505050565b60006110c282600001516003815181106110e4576110e4612856565b60006110c282600001516004815181106110e4576110e4612856565b60006110c282600001516000815181106110e4576110e4612856565b60606110c282600001516001815181106110b5576110b5612856565b6001546040517f41539d4a0000000000000000000000000000000000000000000000000000000081526004810184905260009182918291829173ffffffffffffffffffffffffffffffffffffffff909116906341539d4a9060240160a06040518083038186803b1580156118cf57600080fd5b505afa1580156118e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061190791906129d3565b509350509250925061195e828b61191e9190612786565b6040805160208082018f90528183018e9052606082018d905260808083018d90528351808403909101815260a09092019092528051910120908588611fc5565b6119c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f4845414445520000000060448201526064016105b8565b9998505050505050505050565b6040805160208101909152606081526040518060200160405280611a05846020015160018151811061148657611486612856565b905292915050565b60408051808201909152600080825260208201528251805183908110611a3557611a35612856565b6020026020010151905092915050565b805160009015801590611a5a57508151602110155b611a6357600080fd5b6000611a72836020015161216f565b90506000818460000151611a869190612786565b9050600080838660200151611a9b91906129bb565b9050805191506020831015611ab757826020036101000a820491505b50949350505050565b60606110c282602001516002815181106110b5576110b5612856565b6060611ae782611d10565b611af057600080fd5b6000611afb836121f1565b905060008167ffffffffffffffff811115611b1857611b186123df565b604051908082528060200260200182016040528015611b5d57816020015b6040805180820190915260008082526020820152815260200190600190039081611b365790505b5090506000611b6f856020015161216f565b8560200151611b7e91906129bb565b90506000805b84811015611be757611b9583612274565b9150604051806040016040528083815260200184815250848281518110611bbe57611bbe612856565b6020908102919091010152611bd382846129bb565b925080611bdf81612885565b915050611b84565b509195945050505050565b8051606090611c0057600080fd5b6000611c0f836020015161216f565b90506000818460000151611c239190612786565b905060008167ffffffffffffffff811115611c4057611c406123df565b6040519080825280601f01601f191660200182016040528015611c6a576020820181803683370190505b5090506000816020019050611ab7848760200151611c8891906129bb565b8285612336565b6000611c9c600284612a4f565b15611cd657601082611caf600286612a63565b81518110611cbf57611cbf612856565b0160200151611cd1919060f81c612a77565b611d06565b601082611ce4600286612a63565b81518110611cf457611cf4612856565b0160200151611d06919060f81c612a99565b60f81b9392505050565b8051600090611d2157506000919050565b6020820151805160001a9060c0821015611d3f575060009392505050565b5060019392505050565b80611d5357505050565b60208110611d8b5782518252611d6a6020846129bb565b9250611d776020836129bb565b9150611d84602082612786565b9050611d53565b60006001611d9a836020612786565b611da690610100612bdb565b611db09190612786565b935183518516941916939093179091525050565b8051600090601514611dd557600080fd5b6110c282611a45565b60606000826000015167ffffffffffffffff811115611dff57611dff6123df565b6040519080825280601f01601f191660200182016040528015611e29576020820181803683370190505b509050805160001415611e3c5792915050565b6000816020019050611e578460200151828660000151612336565b5092915050565b8051600090602114611e6f57600080fd5b60008083602001516001611e8391906129bb565b51949350505050565b60008080611e99866110f1565b90506000815167ffffffffffffffff811115611eb757611eb76123df565b6040519080825280601f01601f191660200182016040528015611ee1576020820181803683370190505b509050845b8251611ef290876129bb565b811015611f95576000878281518110611f0d57611f0d612856565b01602001517fff000000000000000000000000000000000000000000000000000000000000001690508083611f428985612786565b81518110611f5257611f52612856565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350508080611f8d90612885565b915050611ee6565b50808051906020012082805190602001201415611fb55781519250611fba565b600092505b509095945050505050565b600060208251611fd59190612a4f565b1561203c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e76616c69642070726f6f66206c656e67746800000000000000000000000060448201526064016105b8565b60006020835161204c9190612a63565b9050612059816002612bdb565b85106120c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4c65616620696e64657820697320746f6f20626967000000000000000000000060448201526064016105b8565b60008660205b85518111612161578581015192506120e0600289612a4f565b612115576040805160208101849052908101849052606001604051602081830303815290604052805190602001209150612142565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b61214d600289612a63565b975061215a6020826129bb565b90506120c7565b509094149695505050505050565b8051600090811a60808110156121885750600092915050565b60b88110806121a3575060c081108015906121a3575060f881105b156121b15750600192915050565b60c08110156121e5576121c6600160b8612be7565b6121d39060ff1682612786565b6121de9060016129bb565b9392505050565b6121c6600160f8612be7565b805160009061220257506000919050565b600080612212846020015161216f565b846020015161222191906129bb565b905060008460000151856020015161223991906129bb565b90505b8082101561226b5761224d82612274565b61225790836129bb565b91508261226381612885565b93505061223c565b50909392505050565b80516000908190811a608081101561228f5760019150611e57565b60b88110156122b5576122a3608082612786565b6122ae9060016129bb565b9150611e57565b60c08110156122e25760b78103600185019450806020036101000a85510460018201810193505050611e57565b60f88110156122f6576122a360c082612786565b60019390930151602084900360f7016101000a90049092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a0192915050565b8061234057505050565b6020811061237857825182526123576020846129bb565b92506123646020836129bb565b9150612371602082612786565b9050612340565b80611d8b57505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461046757600080fd5b600080600080608085870312156123ba57600080fd5b84356123c581612382565b966020860135965060408601359560600135945092505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612455576124556123df565b604052919050565b600067ffffffffffffffff821115612477576124776123df565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126124b457600080fd5b81356124c76124c28261245d565b61240e565b8181528460208386010111156124dc57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561250b57600080fd5b813567ffffffffffffffff81111561252257600080fd5b610435848285016124a3565b60006020828403121561254057600080fd5b5035919050565b60008083601f84011261255957600080fd5b50813567ffffffffffffffff81111561257157600080fd5b6020830191508360208260051b850101111561258c57600080fd5b9250929050565b6000806000806000806000806080898b0312156125af57600080fd5b883567ffffffffffffffff808211156125c757600080fd5b6125d38c838d01612547565b909a50985060208b01359150808211156125ec57600080fd5b6125f88c838d01612547565b909850965060408b013591508082111561261157600080fd5b61261d8c838d01612547565b909650945060608b013591508082111561263657600080fd5b506126438b828c01612547565b999c989b5096995094979396929594505050565b6000806040838503121561266a57600080fd5b823561267581612382565b9150602083013567ffffffffffffffff81111561269157600080fd5b61269d858286016124a3565b9150509250929050565b6000602082840312156126b957600080fd5b81356121de81612382565b6000602082840312156126d657600080fd5b5051919050565b805180151581146126ed57600080fd5b919050565b60008060008060008060c0878903121561270b57600080fd5b865161271681612382565b80965050602087015194506040870151935060608701519250608087015161273d81612382565b915061274b60a088016126dd565b90509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561279857612798612757565b500390565b60005b838110156127b85781810151838201526020016127a0565b838111156127c7576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000825180604084015261280881606085016020870161279d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b60006020828403121561284d57600080fd5b6121de826126dd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156128b7576128b7612757565b5060010190565b838152600083516128d681602085016020880161279d565b60209201918201929092526040019392505050565b6000602082840312156128fd57600080fd5b815167ffffffffffffffff81111561291457600080fd5b8201601f8101841361292557600080fd5b80516129336124c28261245d565b81815285602083850101111561294857600080fd5b61295982602083016020860161279d565b95945050505050565b6000825161297481846020870161279d565b9190910192915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156129b6576129b6612757565b500290565b600082198211156129ce576129ce612757565b500190565b600080600080600060a086880312156129eb57600080fd5b855194506020860151935060408601519250606086015191506080860151612a1281612382565b809150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612a5e57612a5e612a20565b500690565b600082612a7257612a72612a20565b500490565b600060ff831680612a8a57612a8a612a20565b8060ff84160691505092915050565b600060ff831680612aac57612aac612a20565b8060ff84160491505092915050565b600181815b80851115612b1457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612afa57612afa612757565b80851615612b0757918102915b93841c9390800290612ac0565b509250929050565b600082612b2b575060016110c2565b81612b38575060006110c2565b8160018114612b4e5760028114612b5857612b74565b60019150506110c2565b60ff841115612b6957612b69612757565b50506001821b6110c2565b5060208310610133831016604e8410600b8410161715612b97575081810a6110c2565b612ba18383612abb565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612bd357612bd3612757565b029392505050565b60006121de8383612b1c565b600060ff821660ff841680821015612c0157612c01612757565b9003939250505056fea26469706673582212204af704f8cf49d01eaed053f5af2f6c93da8d4992022c8ade7b711bdd27fff84864736f6c6343000809003300000000000000000000000022b1cbb8d98a01a3b71d034bb899775a76eb1cc200000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a200000000000000000000000039f8d0ccd6347052acec0a2167e5ec808d1f14940000000000000000000000000000000000000000000000000000000000000089
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063972c49281161008c578063c0857ba011610066578063c0857ba014610236578063d6ae3cd514610256578063de9b771f1461027d578063f953cec71461029d57600080fd5b8063972c4928146101f057806399178dd814610210578063aea4e49e1461022357600080fd5b80635ab2a558116100c85780635ab2a55814610161578063607f2d42146101ad5780638b034eb8146101d05780638e58736f146101dd57600080fd5b80630e387de6146100ef5780631aae9eed14610129578063419cb5501461014c575b600080fd5b6101167f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b6040519081526020015b60405180910390f35b61013c6101373660046123a4565b6102b0565b6040519015158152602001610120565b61015f61015a3660046124f9565b61043d565b005b6101887f00000000000000000000000022b1cbb8d98a01a3b71d034bb899775a76eb1cc281565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610120565b61013c6101bb36600461252e565b60036020526000908152604090205460ff1681565b60045461013c9060ff1681565b61015f6101eb366004612593565b61046a565b6002546101889073ffffffffffffffffffffffffffffffffffffffff1681565b61015f61021e366004612657565b6108f2565b61015f6102313660046126a7565b6109aa565b6001546101889073ffffffffffffffffffffffffffffffffffffffff1681565b6101167f000000000000000000000000000000000000000000000000000000000000008981565b6000546101889073ffffffffffffffffffffffffffffffffffffffff1681565b61015f6102ab3660046124f9565b610a97565b6040517f960a7afa0000000000000000000000000000000000000000000000000000000081526004810184905260248101839052600090819073ffffffffffffffffffffffffffffffffffffffff87169063960a7afa9060440160206040518083038186803b15801561032257600080fd5b505afa158015610336573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035a91906126c4565b90506000808773ffffffffffffffffffffffffffffffffffffffff16635a7e1083846040518263ffffffff1660e01b815260040161039a91815260200190565b60c06040518083038186803b1580156103b257600080fd5b505afa1580156103c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ea91906126f2565b5050935050925050600082426104009190612786565b9050821580159061040f575081155b801561041a57508581115b1561042c576001945050505050610435565b60009450505050505b949350505050565b61046733826040516020016104539291906127cd565b604051602081830303815290604052610aad565b50565b600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781556040517fd5ef755100000000000000000000000000000000000000000000000000000000815233918101919091527f00000000000000000000000022b1cbb8d98a01a3b71d034bb899775a76eb1cc29073ffffffffffffffffffffffffffffffffffffffff82169063d5ef75519060240160206040518083038186803b15801561051e57600080fd5b505afa158015610532573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610556919061283b565b6105c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4d573a2053656e646572206d757374206265206120626f6e646572000000000060448201526064015b60405180910390fd5b878414610650576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4d573a20726f6f7448617368657320616e6420746f74616c416d6f756e74732060448201527f6d757374206265207468652073616d65206c656e67746800000000000000000060648201526084016105b8565b60008173ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b815260040160206040518083038186803b15801561069857600080fd5b505afa1580156106ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d091906126c4565b905060005b898110156108bd57600061071b848d8d858181106106f5576106f5612856565b905060200201358a8a8681811061070e5761070e612856565b90506020020135866102b0565b905080610784576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4d573a20526f6f742063616e6e6f7420626520636f6e6669726d65640000000060448201526064016105b8565b8373ffffffffffffffffffffffffffffffffffffffff1663ef6ebe5e7f00000000000000000000000000000000000000000000000000000000000000898e8e868181106107d3576107d3612856565b905060200201358d8d878181106107ec576107ec612856565b905060200201358c8c8881811061080557610805612856565b905060200201358b8b8981811061081e5761081e612856565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e08a901b16815260048101979097526024870195909552506044850192909252606484015260209091020135608482015260a401600060405180830381600087803b15801561089157600080fd5b505af11580156108a5573d6000803e3d6000fd5b505050505080806108b590612885565b9150506106d5565b5050600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055505050505050505050565b60045460ff1615610901575050565b73ffffffffffffffffffffffffffffffffffffffff821630146109a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4c315f504c474e5f5750523a2043616c6c6572206d757374206265207468697360448201527f20636f6e7472616374000000000000000000000000000000000000000000000060648201526084016105b8565b5050565b60025473ffffffffffffffffffffffffffffffffffffffff1615610a50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f467842617365526f6f7454756e6e656c3a204348494c445f54554e4e454c5f4160448201527f4c52454144595f5345540000000000000000000000000000000000000000000060648201526084016105b8565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000610aa282610b3e565b90506109a681610f20565b6000546002546040517fb472047700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169263b472047792610b099291169085906004016127cd565b600060405180830381600087803b158015610b2357600080fd5b505af1158015610b37573d6000803e3d6000fd5b5050505050565b60606000610b4b8361103a565b90506000610b5882611099565b90506000610b65836110c8565b9050600081610b73846110f1565b610b7c866112df565b604051602001610b8e939291906128be565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600390935291205490915060ff1615610c63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f535345440000000000000000000000000000000000000000000000000000000060648201526084016105b8565b600081815260036020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610ca3856112fb565b90506000610cb082611445565b9050610cbb816114d5565b60025473ffffffffffffffffffffffffffffffffffffffff908116911614610d65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c00000000000000000000000000000000000000000000000000000060648201526084016105b8565b6000610d70876114fe565b9050610d90610d80846020015190565b87610d8a8a61151a565b84611536565b610e1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f46000000000000000000000000000000000000000000000000000000000060648201526084016105b8565b610e4a85610e29896117ec565b610e328a611808565b84610e3c8c611824565b610e458d611840565b61185c565b506000610e56836119d1565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036610e8c610e87836000611a0d565b611a45565b14610ef3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e41545552450060448201526064016105b8565b6000610efe84611ac0565b806020019051810190610f1191906128eb565b9b9a5050505050505050505050565b60007f00000000000000000000000022b1cbb8d98a01a3b71d034bb899775a76eb1cc273ffffffffffffffffffffffffffffffffffffffff1682604051610f679190612962565b6000604051808303816000865af19150503d8060008114610fa4576040519150601f19603f3d011682016040523d82523d6000602084013e610fa9565b606091505b50509050806109a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4c315f504c474e5f5750523a2043616c6c20746f204c3120427269646765206660448201527f61696c656400000000000000000000000000000000000000000000000000000060648201526084016105b8565b604080516020810190915260608152600061108461107f8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b611adc565b60408051602081019091529081529392505050565b60606110c282600001516008815181106110b5576110b5612856565b6020026020010151611bf2565b92915050565b60006110c282600001516002815181106110e4576110e4612856565b6020026020010151611a45565b604080516020810190915260008152815160609190156110c257600080611119600086611c8f565b60f81c9050600181148061113057508060ff166003145b156111f057600185516002611145919061297e565b61114f9190612786565b67ffffffffffffffff811115611167576111676123df565b6040519080825280601f01601f191660200182016040528015611191576020820181803683370190505b50925060006111a1600187611c8f565b905080846000815181106111b7576111b7612856565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001925050611254565b600285516002611200919061297e565b61120a9190612786565b67ffffffffffffffff811115611222576112226123df565b6040519080825280601f01601f19166020018201604052801561124c576020820181803683370190505b509250600091505b60ff82165b83518110156112d65761128361127260ff851683612786565b61127d9060026129bb565b87611c8f565b84828151811061129557611295612856565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806112ce81612885565b915050611259565b50505092915050565b60006110c282600001516009815181106110e4576110e4612856565b61131f60405180606001604052806060815260200160608152602001600081525090565b61133982600001516006815181106110b5576110b5612856565b60208281018290526040805180820182526000808252908301528051808201909152825181529181019082015261136f81611d10565b156113845761137d81611adc565b8252611431565b6020820151805160009061139a90600190612786565b67ffffffffffffffff8111156113b2576113b26123df565b6040519080825280601f01601f1916602001820160405280156113dc576020820181803683370190505b5090506000808360210191508260200190506113fa82828551611d49565b60408051808201825260008082526020918201528151808301909252845182528085019082015261142a90611adc565b8652505050505b61143a836112df565b604083015250919050565b604080516080810182526000918101828152606080830193909352815260208101919091526000611493836000015160038151811061148657611486612856565b6020026020010151611adc565b8360400151815181106114a8576114a8612856565b6020026020010151905060405180604001604052808281526020016114cc83611adc565b90529392505050565b60006110c282602001516000815181106114f1576114f1612856565b6020026020010151611dc4565b60006110c282600001516005815181106110e4576110e4612856565b60606110c282600001516007815181106110b5576110b5612856565b60008061156a8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b9050600061157782611adc565b9050606080856000806115898b6110f1565b90508051600014156115a5576000975050505050505050610435565b60005b86518110156117dc5781518311156115cb57600098505050505050505050610435565b6115ed8782815181106115e0576115e0612856565b6020026020010151611dde565b95508580519060200120841461160e57600098505050505050505050610435565b61162387828151811061148657611486612856565b94508451601114156116f8578151831415611685578c80519060200120611656866010815181106110b5576110b5612856565b80519060200120141561167457600198505050505050505050610435565b600098505050505050505050610435565b600082848151811061169957611699612856565b016020015160f81c905060108111156116be5760009950505050505050505050610435565b6116e3868260ff16815181106116d6576116d6612856565b6020026020010151611e5e565b94506116f06001856129bb565b9350506117ca565b84516002141561167457600061172461171d876000815181106110b5576110b5612856565b8486611e8c565b835190915061173382866129bb565b1415611788578d80519060200120611757876001815181106110b5576110b5612856565b8051906020012014156117765760019950505050505050505050610435565b60009950505050505050505050610435565b8061179f5760009950505050505050505050610435565b6117a981856129bb565b93506117c1866001815181106116d6576116d6612856565b94506117ca9050565b806117d481612885565b9150506115a8565b5050505050505050949350505050565b60006110c282600001516003815181106110e4576110e4612856565b60006110c282600001516004815181106110e4576110e4612856565b60006110c282600001516000815181106110e4576110e4612856565b60606110c282600001516001815181106110b5576110b5612856565b6001546040517f41539d4a0000000000000000000000000000000000000000000000000000000081526004810184905260009182918291829173ffffffffffffffffffffffffffffffffffffffff909116906341539d4a9060240160a06040518083038186803b1580156118cf57600080fd5b505afa1580156118e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061190791906129d3565b509350509250925061195e828b61191e9190612786565b6040805160208082018f90528183018e9052606082018d905260808083018d90528351808403909101815260a09092019092528051910120908588611fc5565b6119c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f4845414445520000000060448201526064016105b8565b9998505050505050505050565b6040805160208101909152606081526040518060200160405280611a05846020015160018151811061148657611486612856565b905292915050565b60408051808201909152600080825260208201528251805183908110611a3557611a35612856565b6020026020010151905092915050565b805160009015801590611a5a57508151602110155b611a6357600080fd5b6000611a72836020015161216f565b90506000818460000151611a869190612786565b9050600080838660200151611a9b91906129bb565b9050805191506020831015611ab757826020036101000a820491505b50949350505050565b60606110c282602001516002815181106110b5576110b5612856565b6060611ae782611d10565b611af057600080fd5b6000611afb836121f1565b905060008167ffffffffffffffff811115611b1857611b186123df565b604051908082528060200260200182016040528015611b5d57816020015b6040805180820190915260008082526020820152815260200190600190039081611b365790505b5090506000611b6f856020015161216f565b8560200151611b7e91906129bb565b90506000805b84811015611be757611b9583612274565b9150604051806040016040528083815260200184815250848281518110611bbe57611bbe612856565b6020908102919091010152611bd382846129bb565b925080611bdf81612885565b915050611b84565b509195945050505050565b8051606090611c0057600080fd5b6000611c0f836020015161216f565b90506000818460000151611c239190612786565b905060008167ffffffffffffffff811115611c4057611c406123df565b6040519080825280601f01601f191660200182016040528015611c6a576020820181803683370190505b5090506000816020019050611ab7848760200151611c8891906129bb565b8285612336565b6000611c9c600284612a4f565b15611cd657601082611caf600286612a63565b81518110611cbf57611cbf612856565b0160200151611cd1919060f81c612a77565b611d06565b601082611ce4600286612a63565b81518110611cf457611cf4612856565b0160200151611d06919060f81c612a99565b60f81b9392505050565b8051600090611d2157506000919050565b6020820151805160001a9060c0821015611d3f575060009392505050565b5060019392505050565b80611d5357505050565b60208110611d8b5782518252611d6a6020846129bb565b9250611d776020836129bb565b9150611d84602082612786565b9050611d53565b60006001611d9a836020612786565b611da690610100612bdb565b611db09190612786565b935183518516941916939093179091525050565b8051600090601514611dd557600080fd5b6110c282611a45565b60606000826000015167ffffffffffffffff811115611dff57611dff6123df565b6040519080825280601f01601f191660200182016040528015611e29576020820181803683370190505b509050805160001415611e3c5792915050565b6000816020019050611e578460200151828660000151612336565b5092915050565b8051600090602114611e6f57600080fd5b60008083602001516001611e8391906129bb565b51949350505050565b60008080611e99866110f1565b90506000815167ffffffffffffffff811115611eb757611eb76123df565b6040519080825280601f01601f191660200182016040528015611ee1576020820181803683370190505b509050845b8251611ef290876129bb565b811015611f95576000878281518110611f0d57611f0d612856565b01602001517fff000000000000000000000000000000000000000000000000000000000000001690508083611f428985612786565b81518110611f5257611f52612856565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350508080611f8d90612885565b915050611ee6565b50808051906020012082805190602001201415611fb55781519250611fba565b600092505b509095945050505050565b600060208251611fd59190612a4f565b1561203c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e76616c69642070726f6f66206c656e67746800000000000000000000000060448201526064016105b8565b60006020835161204c9190612a63565b9050612059816002612bdb565b85106120c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4c65616620696e64657820697320746f6f20626967000000000000000000000060448201526064016105b8565b60008660205b85518111612161578581015192506120e0600289612a4f565b612115576040805160208101849052908101849052606001604051602081830303815290604052805190602001209150612142565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b61214d600289612a63565b975061215a6020826129bb565b90506120c7565b509094149695505050505050565b8051600090811a60808110156121885750600092915050565b60b88110806121a3575060c081108015906121a3575060f881105b156121b15750600192915050565b60c08110156121e5576121c6600160b8612be7565b6121d39060ff1682612786565b6121de9060016129bb565b9392505050565b6121c6600160f8612be7565b805160009061220257506000919050565b600080612212846020015161216f565b846020015161222191906129bb565b905060008460000151856020015161223991906129bb565b90505b8082101561226b5761224d82612274565b61225790836129bb565b91508261226381612885565b93505061223c565b50909392505050565b80516000908190811a608081101561228f5760019150611e57565b60b88110156122b5576122a3608082612786565b6122ae9060016129bb565b9150611e57565b60c08110156122e25760b78103600185019450806020036101000a85510460018201810193505050611e57565b60f88110156122f6576122a360c082612786565b60019390930151602084900360f7016101000a90049092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a0192915050565b8061234057505050565b6020811061237857825182526123576020846129bb565b92506123646020836129bb565b9150612371602082612786565b9050612340565b80611d8b57505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461046757600080fd5b600080600080608085870312156123ba57600080fd5b84356123c581612382565b966020860135965060408601359560600135945092505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612455576124556123df565b604052919050565b600067ffffffffffffffff821115612477576124776123df565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126124b457600080fd5b81356124c76124c28261245d565b61240e565b8181528460208386010111156124dc57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561250b57600080fd5b813567ffffffffffffffff81111561252257600080fd5b610435848285016124a3565b60006020828403121561254057600080fd5b5035919050565b60008083601f84011261255957600080fd5b50813567ffffffffffffffff81111561257157600080fd5b6020830191508360208260051b850101111561258c57600080fd5b9250929050565b6000806000806000806000806080898b0312156125af57600080fd5b883567ffffffffffffffff808211156125c757600080fd5b6125d38c838d01612547565b909a50985060208b01359150808211156125ec57600080fd5b6125f88c838d01612547565b909850965060408b013591508082111561261157600080fd5b61261d8c838d01612547565b909650945060608b013591508082111561263657600080fd5b506126438b828c01612547565b999c989b5096995094979396929594505050565b6000806040838503121561266a57600080fd5b823561267581612382565b9150602083013567ffffffffffffffff81111561269157600080fd5b61269d858286016124a3565b9150509250929050565b6000602082840312156126b957600080fd5b81356121de81612382565b6000602082840312156126d657600080fd5b5051919050565b805180151581146126ed57600080fd5b919050565b60008060008060008060c0878903121561270b57600080fd5b865161271681612382565b80965050602087015194506040870151935060608701519250608087015161273d81612382565b915061274b60a088016126dd565b90509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561279857612798612757565b500390565b60005b838110156127b85781810151838201526020016127a0565b838111156127c7576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000825180604084015261280881606085016020870161279d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b60006020828403121561284d57600080fd5b6121de826126dd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156128b7576128b7612757565b5060010190565b838152600083516128d681602085016020880161279d565b60209201918201929092526040019392505050565b6000602082840312156128fd57600080fd5b815167ffffffffffffffff81111561291457600080fd5b8201601f8101841361292557600080fd5b80516129336124c28261245d565b81815285602083850101111561294857600080fd5b61295982602083016020860161279d565b95945050505050565b6000825161297481846020870161279d565b9190910192915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156129b6576129b6612757565b500290565b600082198211156129ce576129ce612757565b500190565b600080600080600060a086880312156129eb57600080fd5b855194506020860151935060408601519250606086015191506080860151612a1281612382565b809150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612a5e57612a5e612a20565b500690565b600082612a7257612a72612a20565b500490565b600060ff831680612a8a57612a8a612a20565b8060ff84160691505092915050565b600060ff831680612aac57612aac612a20565b8060ff84160491505092915050565b600181815b80851115612b1457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612afa57612afa612757565b80851615612b0757918102915b93841c9390800290612ac0565b509250929050565b600082612b2b575060016110c2565b81612b38575060006110c2565b8160018114612b4e5760028114612b5857612b74565b60019150506110c2565b60ff841115612b6957612b69612757565b50506001821b6110c2565b5060208310610133831016604e8410600b8410161715612b97575081810a6110c2565b612ba18383612abb565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612bd357612bd3612757565b029392505050565b60006121de8383612b1c565b600060ff821660ff841680821015612c0157612c01612757565b9003939250505056fea26469706673582212204af704f8cf49d01eaed053f5af2f6c93da8d4992022c8ade7b711bdd27fff84864736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000022b1cbb8d98a01a3b71d034bb899775a76eb1cc200000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a200000000000000000000000039f8d0ccd6347052acec0a2167e5ec808d1f14940000000000000000000000000000000000000000000000000000000000000089
-----Decoded View---------------
Arg [0] : _l1BridgeAddress (address): 0x22B1Cbb8D98a01a3B71D034BB899775A76Eb1cc2
Arg [1] : _checkpointManager (address): 0x86E4Dc95c7FBdBf52e33D563BbDB00823894C287
Arg [2] : _fxRoot (address): 0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2
Arg [3] : _fxChildTunnel (address): 0x39F8D0ccD6347052Acec0a2167e5Ec808d1F1494
Arg [4] : _l2ChainId (uint256): 137
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 00000000000000000000000022b1cbb8d98a01a3b71d034bb899775a76eb1cc2
Arg [1] : 00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287
Arg [2] : 000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a2
Arg [3] : 00000000000000000000000039f8d0ccd6347052acec0a2167e5ec808d1f1494
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000089
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 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.