More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 750 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Receive Message | 21567815 | 5 days ago | IN | 0 ETH | 0.00530217 | ||||
Receive Message | 21563124 | 6 days ago | IN | 0 ETH | 0.00184422 | ||||
Receive Message | 21547302 | 8 days ago | IN | 0 ETH | 0.00213452 | ||||
Receive Message | 21542021 | 8 days ago | IN | 0 ETH | 0.00165202 | ||||
Receive Message | 21520620 | 11 days ago | IN | 0 ETH | 0.00204166 | ||||
Receive Message | 21517166 | 12 days ago | IN | 0 ETH | 0.00327566 | ||||
Receive Message | 21506873 | 13 days ago | IN | 0 ETH | 0.00102043 | ||||
Receive Message | 21506606 | 13 days ago | IN | 0 ETH | 0.00100333 | ||||
Receive Message | 21503348 | 14 days ago | IN | 0 ETH | 0.00142793 | ||||
Receive Message | 21468099 | 19 days ago | IN | 0 ETH | 0.0031931 | ||||
Receive Message | 21462221 | 20 days ago | IN | 0 ETH | 0.00153811 | ||||
Receive Message | 21461575 | 20 days ago | IN | 0 ETH | 0.0015888 | ||||
Receive Message | 21461325 | 20 days ago | IN | 0 ETH | 0.00149623 | ||||
Receive Message | 21458160 | 20 days ago | IN | 0 ETH | 0.00195677 | ||||
Receive Message | 21458072 | 20 days ago | IN | 0 ETH | 0.00195365 | ||||
Receive Message | 21457823 | 20 days ago | IN | 0 ETH | 0.00198598 | ||||
Receive Message | 21456888 | 20 days ago | IN | 0 ETH | 0.00150615 | ||||
Receive Message | 21456888 | 20 days ago | IN | 0 ETH | 0.00192351 | ||||
Receive Message | 21449866 | 21 days ago | IN | 0 ETH | 0.00315692 | ||||
Receive Message | 21424996 | 25 days ago | IN | 0 ETH | 0.00422264 | ||||
Receive Message | 21420146 | 26 days ago | IN | 0 ETH | 0.00305902 | ||||
Receive Message | 21417851 | 26 days ago | IN | 0 ETH | 0.00512486 | ||||
Receive Message | 21413107 | 26 days ago | IN | 0 ETH | 0.00300721 | ||||
Receive Message | 21410359 | 27 days ago | IN | 0 ETH | 0.00297072 | ||||
Receive Message | 21410232 | 27 days ago | IN | 0 ETH | 0.00287276 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
P00lsBridgePolygon
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@maticnetwork/fx-portal/contracts/tunnel/FxBaseRootTunnel.sol"; import "../../tokens/interfaces.sol"; import "../../utils/convert.sol"; import "./utils.sol"; /// @custom:security-contact [email protected] contract P00lsBridgePolygon is FxBaseRootTunnel, IERC1363Receiver { IERC721 public immutable registry; mapping(address => bool) public isBridged; event ContractMigrated(address indexed token); event BridgeDeposit(address indexed token, address indexed from, address indexed to, uint256 amount); event BridgeWithdraw(address indexed token, address indexed to, uint256 amount); constructor(address _checkpointManager, address _fxRoot, IERC721 _registry) FxBaseRootTunnel(_checkpointManager, _fxRoot) { registry = _registry; } modifier onlyValidToken(address token) { require( token != address(registry) && registry.ownerOf(addressToUint256(token)) != address(0), "P00lsBridgePolygon: invalid token" ); _; } modifier onlyMigrated(address token) { if (!isBridged[token]) migrate(token); _; } /** * Deploy token contract on child (root → child) */ function migrate(address token) public onlyValidToken(token) { // mark as deployed isBridged[token] = true; IP00lsTokenCreator rootToken = IP00lsTokenCreator(token); IP00lsTokenXCreator xRootToken = rootToken.xCreatorToken(); _sendMessageToChild(encodeMigrate( token, rootToken.name(), rootToken.symbol(), xRootToken.name(), xRootToken.symbol() )); emit ContractMigrated(token); } /** * Bridge assets to child (root → child) */ function bridge(address token, address to, uint256 amount) public onlyMigrated(token) { require(to != address(0), "P00lsBridgePolygon: invalid receiver"); SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), amount); _sendMessageToChild(encodeDeposit(token, to, amount)); emit BridgeDeposit(token, msg.sender, to, amount); } function onTransferReceived(address, address from, uint256 value, bytes calldata data) public onlyMigrated(msg.sender) returns (bytes4) { address to = abi.decode(data, (address)); require(to != address(0), "P00lsBridgePolygon: invalid receiver"); _sendMessageToChild(encodeDeposit(msg.sender, to, value)); emit BridgeDeposit(msg.sender, from, to, value); return this.onTransferReceived.selector; } /** * Withdraw asset (child → root) */ function _processMessageFromChild(bytes memory message) internal override { (address rootToken, address to, uint256 amount) = abi.decode(message, (address, address, uint256)); SafeERC20.safeTransfer(IERC20(rootToken), to, amount); emit BridgeWithdraw(rootToken, to, amount); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {RLPReader} from "../lib/RLPReader.sol"; import {MerklePatriciaProof} from "../lib/MerklePatriciaProof.sol"; import {Merkle} from "../lib/Merkle.sol"; import "../lib/ExitPayloadReader.sol"; interface IFxStateSender { function sendMessageToChild(address _receiver, bytes calldata _data) external; } contract ICheckpointManager { struct HeaderBlock { bytes32 root; uint256 start; uint256 end; uint256 createdAt; address proposer; } /** * @notice mapping of checkpoint header numbers to block details * @dev These checkpoints are submited by plasma contracts */ mapping(uint256 => HeaderBlock) public headerBlocks; } abstract contract FxBaseRootTunnel { using RLPReader for RLPReader.RLPItem; using Merkle for bytes32; using ExitPayloadReader for bytes; using ExitPayloadReader for ExitPayloadReader.ExitPayload; using ExitPayloadReader for ExitPayloadReader.Log; using ExitPayloadReader for ExitPayloadReader.LogTopics; using ExitPayloadReader for ExitPayloadReader.Receipt; // keccak256(MessageSent(bytes)) bytes32 public constant SEND_MESSAGE_EVENT_SIG = 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036; // state sender contract IFxStateSender public fxRoot; // root chain manager ICheckpointManager public checkpointManager; // child tunnel contract which receives and sends messages address public fxChildTunnel; // storage to avoid duplicate exits mapping(bytes32 => bool) public processedExits; constructor(address _checkpointManager, address _fxRoot) { checkpointManager = ICheckpointManager(_checkpointManager); fxRoot = IFxStateSender(_fxRoot); } // set fxChildTunnel if not set already function setFxChildTunnel(address _fxChildTunnel) public virtual { require(fxChildTunnel == address(0x0), "FxBaseRootTunnel: CHILD_TUNNEL_ALREADY_SET"); fxChildTunnel = _fxChildTunnel; } /** * @notice Send bytes message to Child Tunnel * @param message bytes message that will be sent to Child Tunnel * some message examples - * abi.encode(tokenId); * abi.encode(tokenId, tokenMetadata); * abi.encode(messageType, messageData); */ function _sendMessageToChild(bytes memory message) internal { fxRoot.sendMessageToChild(fxChildTunnel, message); } function _validateAndExtractMessage(bytes memory inputData) internal returns (bytes memory) { ExitPayloadReader.ExitPayload memory payload = inputData.toExitPayload(); bytes memory branchMaskBytes = payload.getBranchMaskAsBytes(); uint256 blockNumber = payload.getBlockNumber(); // checking if exit has already been processed // unique exit is identified using hash of (blockNumber, branchMask, receiptLogIndex) bytes32 exitHash = keccak256( abi.encodePacked( blockNumber, // first 2 nibbles are dropped while generating nibble array // this allows branch masks that are valid but bypass exitHash check (changing first 2 nibbles only) // so converting to nibble array and then hashing it MerklePatriciaProof._getNibbleArray(branchMaskBytes), payload.getReceiptLogIndex() ) ); require(processedExits[exitHash] == false, "FxRootTunnel: EXIT_ALREADY_PROCESSED"); processedExits[exitHash] = true; ExitPayloadReader.Receipt memory receipt = payload.getReceipt(); ExitPayloadReader.Log memory log = receipt.getLog(); // check child tunnel require(fxChildTunnel == log.getEmitter(), "FxRootTunnel: INVALID_FX_CHILD_TUNNEL"); bytes32 receiptRoot = payload.getReceiptRoot(); // verify receipt inclusion require( MerklePatriciaProof.verify(receipt.toBytes(), branchMaskBytes, payload.getReceiptProof(), receiptRoot), "FxRootTunnel: INVALID_RECEIPT_PROOF" ); // verify checkpoint inclusion _checkBlockMembershipInCheckpoint( blockNumber, payload.getBlockTime(), payload.getTxRoot(), receiptRoot, payload.getHeaderNumber(), payload.getBlockProof() ); ExitPayloadReader.LogTopics memory topics = log.getTopics(); require( bytes32(topics.getField(0).toUint()) == SEND_MESSAGE_EVENT_SIG, // topic0 is event sig "FxRootTunnel: INVALID_SIGNATURE" ); // received message data bytes memory message = abi.decode(log.getData(), (bytes)); // event decodes params again, so decoding bytes to get message return message; } function _checkBlockMembershipInCheckpoint( uint256 blockNumber, uint256 blockTime, bytes32 txRoot, bytes32 receiptRoot, uint256 headerNumber, bytes memory blockProof ) private view returns (uint256) { (bytes32 headerRoot, uint256 startBlock, , uint256 createdAt, ) = checkpointManager.headerBlocks(headerNumber); require( keccak256(abi.encodePacked(blockNumber, blockTime, txRoot, receiptRoot)).checkMembership( blockNumber - startBlock, headerRoot, blockProof ), "FxRootTunnel: INVALID_HEADER" ); return createdAt; } /** * @notice receive message from L2 to L1, validated by proof * @dev This function verifies if the transaction actually happened on child chain * * @param inputData RLP encoded data of the reference tx containing following list of fields * 0 - headerNumber - Checkpoint header block number containing the reference tx * 1 - blockProof - Proof that the block header (in the child chain) is a leaf in the submitted merkle root * 2 - blockNumber - Block number containing the reference tx on child chain * 3 - blockTime - Reference tx block time * 4 - txRoot - Transactions root of block * 5 - receiptRoot - Receipts root of block * 6 - receipt - Receipt of the reference transaction * 7 - receiptProof - Merkle proof of the reference receipt * 8 - branchMask - 32 bits denoting the path of receipt in merkle tree * 9 - receiptLogIndex - Log Index to read from the receipt */ function receiveMessage(bytes memory inputData) public virtual { bytes memory message = _validateAndExtractMessage(inputData); _processMessageFromChild(message); } /** * @notice Process message received from Child Tunnel * @dev function needs to be implemented to handle message as per requirement * This is called by onStateReceive function. * Since it is called via a system call, any event will not be emitted during its execution. * @param message bytes message that was sent from Child Tunnel */ function _processMessageFromChild(bytes memory message) internal virtual; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "@openzeppelin/contracts/interfaces/IERC721.sol"; import "@openzeppelin/contracts/interfaces/draft-IERC2612.sol"; import "@openzeppelin/contracts/interfaces/IERC4626.sol"; import "@openzeppelin/contracts/governance/utils/IVotes.sol"; import "./extensions/IERC1046.sol"; import "./extensions/IERC1363.sol"; /// @custom:security-contact [email protected] interface IP00lsTokenBase is IERC20, IERC20Metadata, IERC1046, IERC1363, IERC2612, IVotes { function owner() external view returns (address); function setTokenURI(string calldata) external; function setName(address, string calldata) external; } /// @custom:security-contact [email protected] interface IP00lsTokenCreator is IP00lsTokenBase { function xCreatorToken() external view returns (IP00lsTokenXCreator); function merkleRoot() external view returns (bytes32); function isClaimed(uint256) external view returns (bool); function claim(uint256, address, uint256, bytes32[] calldata) external; } /// @custom:security-contact [email protected] interface IP00lsTokenXCreator is IP00lsTokenBase, IERC4626 { function creatorToken() external view returns (IP00lsTokenCreator); function escrow() external view returns (address); function convertToAssetsAtBlock(uint256 shares, uint256 blockNumber) external view returns (uint256); function __delegate(address, address) external; } interface IFxMessageProcessor { function processMessageFromRoot(uint256 stateId, address rootMessageSender, bytes calldata data) external; } interface IP00lsCreatorRegistry_Polygon is IFxMessageProcessor { function __withdraw(address to, uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; function addressToUint256(address a) pure returns (uint256) { return uint256(uint160(a)); } function addressToSalt(address a) pure returns (bytes32) { return bytes32(uint256(uint160(a))); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; enum BRIDGE_OP { DEPLOY, DEPOSIT } function encodeMigrate(address rootToken, string memory name, string memory symbol, string memory xname, string memory xsymbol) pure returns (bytes memory) { return abi.encode(BRIDGE_OP.DEPLOY, abi.encode(rootToken, name, symbol, xname, xsymbol)); } function decodeMigrateData(bytes memory data) pure returns (address, string memory, string memory, string memory, string memory) { return abi.decode(data, (address, string, string, string, string)); } function encodeDeposit(address rootToken, address to, uint256 amount) pure returns (bytes memory) { return abi.encode(BRIDGE_OP.DEPOSIT, abi.encode(rootToken, to, amount)); } function decodeDepositData(bytes memory data) pure returns (address, address, uint256) { return abi.decode(data, (address, address, uint256)); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
/* * @author Hamdi Allam [email protected] * Please reach out with any questions or concerns */ pragma solidity ^0.8.0; library RLPReader { uint8 constant STRING_SHORT_START = 0x80; uint8 constant STRING_LONG_START = 0xb8; uint8 constant LIST_SHORT_START = 0xc0; uint8 constant LIST_LONG_START = 0xf8; uint8 constant WORD_SIZE = 32; struct RLPItem { uint256 len; uint256 memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint256 nextPtr; // Position of the next item in the list. } /* * @dev Returns the next element in the iteration. Reverts if it has not next element. * @param self The iterator. * @return The next element in the iteration. */ function next(Iterator memory self) internal pure returns (RLPItem memory) { require(hasNext(self)); uint256 ptr = self.nextPtr; uint256 itemLength = _itemLength(ptr); self.nextPtr = ptr + itemLength; return RLPItem(itemLength, ptr); } /* * @dev Returns true if the iteration has more elements. * @param self The iterator. * @return true if the iteration has more elements. */ function hasNext(Iterator memory self) internal pure returns (bool) { RLPItem memory item = self.item; return self.nextPtr < item.memPtr + item.len; } /* * @param item RLP encoded bytes */ function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) { uint256 memPtr; assembly { memPtr := add(item, 0x20) } return RLPItem(item.length, memPtr); } /* * @dev Create an iterator. Reverts if item is not a list. * @param self The RLP item. * @return An 'Iterator' over the item. */ function iterator(RLPItem memory self) internal pure returns (Iterator memory) { require(isList(self)); uint256 ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param item RLP encoded bytes */ function rlpLen(RLPItem memory item) internal pure returns (uint256) { return item.len; } /* * @param item RLP encoded bytes */ function payloadLen(RLPItem memory item) internal pure returns (uint256) { return item.len - _payloadOffset(item.memPtr); } /* * @param item RLP encoded list in bytes */ function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item)); uint256 items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 dataLen; for (uint256 i = 0; i < items; i++) { dataLen = _itemLength(memPtr); result[i] = RLPItem(dataLen, memPtr); memPtr = memPtr + dataLen; } return result; } // @return indicator whether encoded payload is a list. negate this function call for isData. function isList(RLPItem memory item) internal pure returns (bool) { if (item.len == 0) return false; uint8 byte0; uint256 memPtr = item.memPtr; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < LIST_SHORT_START) return false; return true; } /* * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory. * @return keccak256 hash of RLP encoded bytes. */ function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) { uint256 ptr = item.memPtr; uint256 len = item.len; bytes32 result; assembly { result := keccak256(ptr, len) } return result; } function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) { uint256 offset = _payloadOffset(item.memPtr); uint256 memPtr = item.memPtr + offset; uint256 len = item.len - offset; // data length return (memPtr, len); } /* * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory. * @return keccak256 hash of the item payload. */ function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) { (uint256 memPtr, uint256 len) = payloadLocation(item); bytes32 result; assembly { result := keccak256(memPtr, len) } return result; } /** RLPItem conversions into data types **/ // @returns raw rlp encoding in bytes function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) { bytes memory result = new bytes(item.len); if (result.length == 0) return result; uint256 ptr; assembly { ptr := add(0x20, result) } copy(item.memPtr, ptr, item.len); return result; } // any non-zero byte is considered true function toBoolean(RLPItem memory item) internal pure returns (bool) { require(item.len == 1); uint256 result; uint256 memPtr = item.memPtr; assembly { result := byte(0, mload(memPtr)) } return result == 0 ? false : true; } function toAddress(RLPItem memory item) internal pure returns (address) { // 1 byte for the length prefix require(item.len == 21); return address(uint160(toUint(item))); } function toUint(RLPItem memory item) internal pure returns (uint256) { require(item.len > 0 && item.len <= 33); uint256 offset = _payloadOffset(item.memPtr); uint256 len = item.len - offset; uint256 result; uint256 memPtr = item.memPtr + offset; assembly { result := mload(memPtr) // shfit to the correct location if neccesary if lt(len, 32) { result := div(result, exp(256, sub(32, len))) } } return result; } // enforces 32 byte length function toUintStrict(RLPItem memory item) internal pure returns (uint256) { // one byte prefix require(item.len == 33); uint256 result; uint256 memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); uint256 offset = _payloadOffset(item.memPtr); uint256 len = item.len - offset; // data length bytes memory result = new bytes(len); uint256 destPtr; assembly { destPtr := add(0x20, result) } copy(item.memPtr + offset, destPtr, len); return result; } /* * Private Helpers */ // @return number of payload items inside an encoded list. function numItems(RLPItem memory item) private pure returns (uint256) { if (item.len == 0) return 0; uint256 count = 0; uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 endPtr = item.memPtr + item.len; while (currPtr < endPtr) { currPtr = currPtr + _itemLength(currPtr); // skip over an item count++; } return count; } // @return entire rlp item byte length function _itemLength(uint256 memPtr) private pure returns (uint256) { uint256 itemLen; uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) itemLen = 1; else if (byte0 < STRING_LONG_START) itemLen = byte0 - STRING_SHORT_START + 1; else if (byte0 < LIST_SHORT_START) { assembly { let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is memPtr := add(memPtr, 1) // skip over the first byte /* 32 byte word size */ let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len itemLen := add(dataLen, add(byteLen, 1)) } } else if (byte0 < LIST_LONG_START) { itemLen = byte0 - LIST_SHORT_START + 1; } else { assembly { let byteLen := sub(byte0, 0xf7) memPtr := add(memPtr, 1) let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length itemLen := add(dataLen, add(byteLen, 1)) } } return itemLen; } // @return number of bytes until the data function _payloadOffset(uint256 memPtr) private pure returns (uint256) { uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) return 0; else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) return 1; else if (byte0 < LIST_SHORT_START) // being explicit return byte0 - (STRING_LONG_START - 1) + 1; else return byte0 - (LIST_LONG_START - 1) + 1; } /* * @param src Pointer to source * @param dest Pointer to destination * @param len Amount of memory to copy from the source */ function copy( uint256 src, uint256 dest, uint256 len ) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } if (len == 0) return; // left over bytes. Mask is used to remove unwanted bytes from the word uint256 mask = 256**(WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {RLPReader} from "./RLPReader.sol"; library MerklePatriciaProof { /* * @dev Verifies a merkle patricia proof. * @param value The terminating value in the trie. * @param encodedPath The path in the trie leading to value. * @param rlpParentNodes The rlp encoded stack of nodes. * @param root The root hash of the trie. * @return The boolean validity of the proof. */ function verify( bytes memory value, bytes memory encodedPath, bytes memory rlpParentNodes, bytes32 root ) internal pure returns (bool) { RLPReader.RLPItem memory item = RLPReader.toRlpItem(rlpParentNodes); RLPReader.RLPItem[] memory parentNodes = RLPReader.toList(item); bytes memory currentNode; RLPReader.RLPItem[] memory currentNodeList; bytes32 nodeKey = root; uint256 pathPtr = 0; bytes memory path = _getNibbleArray(encodedPath); if (path.length == 0) { return false; } for (uint256 i = 0; i < parentNodes.length; i++) { if (pathPtr > path.length) { return false; } currentNode = RLPReader.toRlpBytes(parentNodes[i]); if (nodeKey != keccak256(currentNode)) { return false; } currentNodeList = RLPReader.toList(parentNodes[i]); if (currentNodeList.length == 17) { if (pathPtr == path.length) { if (keccak256(RLPReader.toBytes(currentNodeList[16])) == keccak256(value)) { return true; } else { return false; } } uint8 nextPathNibble = uint8(path[pathPtr]); if (nextPathNibble > 16) { return false; } nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[nextPathNibble])); pathPtr += 1; } else if (currentNodeList.length == 2) { uint256 traversed = _nibblesToTraverse(RLPReader.toBytes(currentNodeList[0]), path, pathPtr); if (pathPtr + traversed == path.length) { //leaf node if (keccak256(RLPReader.toBytes(currentNodeList[1])) == keccak256(value)) { return true; } else { return false; } } //extension node if (traversed == 0) { return false; } pathPtr += traversed; nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[1])); } else { return false; } } } function _nibblesToTraverse( bytes memory encodedPartialPath, bytes memory path, uint256 pathPtr ) private pure returns (uint256) { uint256 len = 0; // encodedPartialPath has elements that are each two hex characters (1 byte), but partialPath // and slicedPath have elements that are each one hex character (1 nibble) bytes memory partialPath = _getNibbleArray(encodedPartialPath); bytes memory slicedPath = new bytes(partialPath.length); // pathPtr counts nibbles in path // partialPath.length is a number of nibbles for (uint256 i = pathPtr; i < pathPtr + partialPath.length; i++) { bytes1 pathNibble = path[i]; slicedPath[i - pathPtr] = pathNibble; } if (keccak256(partialPath) == keccak256(slicedPath)) { len = partialPath.length; } else { len = 0; } return len; } // bytes b must be hp encoded function _getNibbleArray(bytes memory b) internal pure returns (bytes memory) { bytes memory nibbles = ""; if (b.length > 0) { uint8 offset; uint8 hpNibble = uint8(_getNthNibbleOfBytes(0, b)); if (hpNibble == 1 || hpNibble == 3) { nibbles = new bytes(b.length * 2 - 1); bytes1 oddNibble = _getNthNibbleOfBytes(1, b); nibbles[0] = oddNibble; offset = 1; } else { nibbles = new bytes(b.length * 2 - 2); offset = 0; } for (uint256 i = offset; i < nibbles.length; i++) { nibbles[i] = _getNthNibbleOfBytes(i - offset + 2, b); } } return nibbles; } function _getNthNibbleOfBytes(uint256 n, bytes memory str) private pure returns (bytes1) { return bytes1(n % 2 == 0 ? uint8(str[n / 2]) / 0x10 : uint8(str[n / 2]) % 0x10); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library Merkle { function checkMembership( bytes32 leaf, uint256 index, bytes32 rootHash, bytes memory proof ) internal pure returns (bool) { require(proof.length % 32 == 0, "Invalid proof length"); uint256 proofHeight = proof.length / 32; // Proof of size n means, height of the tree is n+1. // In a tree of height n+1, max #leafs possible is 2 ^ n require(index < 2**proofHeight, "Leaf index is too big"); bytes32 proofElement; bytes32 computedHash = leaf; for (uint256 i = 32; i <= proof.length; i += 32) { assembly { proofElement := mload(add(proof, i)) } if (index % 2 == 0) { computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); } else { computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); } index = index / 2; } return computedHash == rootHash; } }
pragma solidity ^0.8.0; import {RLPReader} from "./RLPReader.sol"; library ExitPayloadReader { using RLPReader for bytes; using RLPReader for RLPReader.RLPItem; uint8 constant WORD_SIZE = 32; struct ExitPayload { RLPReader.RLPItem[] data; } struct Receipt { RLPReader.RLPItem[] data; bytes raw; uint256 logIndex; } struct Log { RLPReader.RLPItem data; RLPReader.RLPItem[] list; } struct LogTopics { RLPReader.RLPItem[] data; } // copy paste of private copy() from RLPReader to avoid changing of existing contracts function copy( uint256 src, uint256 dest, uint256 len ) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } if (len == 0) return; // left over bytes. Mask is used to remove unwanted bytes from the word uint256 mask = 256**(WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } function toExitPayload(bytes memory data) internal pure returns (ExitPayload memory) { RLPReader.RLPItem[] memory payloadData = data.toRlpItem().toList(); return ExitPayload(payloadData); } function getHeaderNumber(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[0].toUint(); } function getBlockProof(ExitPayload memory payload) internal pure returns (bytes memory) { return payload.data[1].toBytes(); } function getBlockNumber(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[2].toUint(); } function getBlockTime(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[3].toUint(); } function getTxRoot(ExitPayload memory payload) internal pure returns (bytes32) { return bytes32(payload.data[4].toUint()); } function getReceiptRoot(ExitPayload memory payload) internal pure returns (bytes32) { return bytes32(payload.data[5].toUint()); } function getReceipt(ExitPayload memory payload) internal pure returns (Receipt memory receipt) { receipt.raw = payload.data[6].toBytes(); RLPReader.RLPItem memory receiptItem = receipt.raw.toRlpItem(); if (receiptItem.isList()) { // legacy tx receipt.data = receiptItem.toList(); } else { // pop first byte before parsting receipt bytes memory typedBytes = receipt.raw; bytes memory result = new bytes(typedBytes.length - 1); uint256 srcPtr; uint256 destPtr; assembly { srcPtr := add(33, typedBytes) destPtr := add(0x20, result) } copy(srcPtr, destPtr, result.length); receipt.data = result.toRlpItem().toList(); } receipt.logIndex = getReceiptLogIndex(payload); return receipt; } function getReceiptProof(ExitPayload memory payload) internal pure returns (bytes memory) { return payload.data[7].toBytes(); } function getBranchMaskAsBytes(ExitPayload memory payload) internal pure returns (bytes memory) { return payload.data[8].toBytes(); } function getBranchMaskAsUint(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[8].toUint(); } function getReceiptLogIndex(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[9].toUint(); } // Receipt methods function toBytes(Receipt memory receipt) internal pure returns (bytes memory) { return receipt.raw; } function getLog(Receipt memory receipt) internal pure returns (Log memory) { RLPReader.RLPItem memory logData = receipt.data[3].toList()[receipt.logIndex]; return Log(logData, logData.toList()); } // Log methods function getEmitter(Log memory log) internal pure returns (address) { return RLPReader.toAddress(log.list[0]); } function getTopics(Log memory log) internal pure returns (LogTopics memory) { return LogTopics(log.list[1].toList()); } function getData(Log memory log) internal pure returns (bytes memory) { return log.list[2].toBytes(); } function toRlpBytes(Log memory log) internal pure returns (bytes memory) { return log.data.toRlpBytes(); } // LogTopics methods function getField(LogTopics memory topics, uint256 index) internal pure returns (RLPReader.RLPItem memory) { return topics.data[index]; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol) pragma solidity ^0.8.0; import "../token/ERC721/IERC721.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/draft-IERC2612.sol) pragma solidity ^0.8.0; import "../token/ERC20/extensions/draft-IERC20Permit.sol"; interface IERC2612 is IERC20Permit {}
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC4626.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol"; import "../token/ERC20/extensions/IERC20Metadata.sol"; /** * @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. * * _Available since v4.7._ */ interface IERC4626 is IERC20, IERC20Metadata { event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. * * - MUST be an ERC-20 token contract. * - MUST NOT revert. */ function asset() external view returns (address assetTokenAddress); /** * @dev Returns the total amount of the underlying asset that is “managed” by Vault. * * - SHOULD include any compounding that occurs from yield. * - MUST be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT revert. */ function totalAssets() external view returns (uint256 totalManagedAssets); /** * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToShares(uint256 assets) external view returns (uint256 shares); /** * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToAssets(uint256 shares) external view returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, * through a deposit call. * * - MUST return a limited value if receiver is subject to some deposit limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. * - MUST NOT revert. */ function maxDeposit(address receiver) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given * current on-chain conditions. * * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called * in the same transaction. * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the * deposit would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewDeposit(uint256 assets) external view returns (uint256 shares); /** * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * deposit execution, and are accounted for during deposit. * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function deposit(uint256 assets, address receiver) external returns (uint256 shares); /** * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. * - MUST return a limited value if receiver is subject to some mint limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. * - MUST NOT revert. */ function maxMint(address receiver) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given * current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the * same transaction. * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint * would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by minting. */ function previewMint(uint256 shares) external view returns (uint256 assets); /** * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint * execution, and are accounted for during mint. * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function mint(uint256 shares, address receiver) external returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the * Vault, through a withdraw call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST NOT revert. */ function maxWithdraw(address owner) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, * given current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if * called * in the same transaction. * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though * the withdrawal would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewWithdraw(uint256 assets) external view returns (uint256 shares); /** * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * withdraw execution, and are accounted for during withdraw. * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function withdraw( uint256 assets, address receiver, address owner ) external returns (uint256 shares); /** * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, * through a redeem call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. * - MUST NOT revert. */ function maxRedeem(address owner) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, * given current on-chain conditions. * * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the * same transaction. * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the * redemption would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by redeeming. */ function previewRedeem(uint256 shares) external view returns (uint256 assets); /** * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * redeem execution, and are accounted for during redeem. * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function redeem( uint256 shares, address receiver, address owner ) external returns (uint256 assets); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol) pragma solidity ^0.8.0; /** * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. * * _Available since v4.5._ */ interface IVotes { /** * @dev Emitted when an account changes their delegate. */ event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /** * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. */ event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) external view returns (uint256); /** * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`). */ function getPastVotes(address account, uint256 blockNumber) external view returns (uint256); /** * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`). * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. */ function getPastTotalSupply(uint256 blockNumber) external view returns (uint256); /** * @dev Returns the delegate that `account` has chosen. */ function delegates(address account) external view returns (address); /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(address delegatee) external; /** * @dev Delegates votes from signer to `delegatee`. */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IERC1046 { function tokenURI() external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IERC1363 { /* * Note: the ERC-165 identifier for this interface is 0x4bbee2df. * 0x4bbee2df === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) */ /* * Note: the ERC-165 identifier for this interface is 0xfb9ec8ce. * 0xfb9ec8ce === * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver * @param to address The address which you want to transfer to * @param value uint256 The amount of tokens to be transferred * @return true unless throwing */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver * @param to address The address which you want to transfer to * @param value uint256 The amount of tokens to be transferred * @param data bytes Additional data with no specified format, sent in call to `to` * @return true unless throwing */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver * @param from address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param value uint256 The amount of tokens to be transferred * @return true unless throwing */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver * @param from address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param value uint256 The amount of tokens to be transferred * @param data bytes Additional data with no specified format, sent in call to `to` * @return true unless throwing */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender * and then call `onApprovalReceived` on spender. * @param spender address The address which will spend the funds * @param value uint256 The amount of tokens to be spent */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender * and then call `onApprovalReceived` on spender. * @param spender address The address which will spend the funds * @param value uint256 The amount of tokens to be spent * @param data bytes Additional data with no specified format, sent in call to `spender` */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); } /** * @title ERC1363Spender interface * @dev Interface for any contract that wants to support `approveAndCall` * from ERC1363 token contracts. */ interface IERC1363Spender { /* * Note: the ERC-165 identifier for this interface is 0x7b04a2d0. * 0x7b04a2d0 === bytes4(keccak256("onApprovalReceived(address,uint256,bytes)")) */ /** * @notice Handle the approval of ERC1363 tokens * @dev Any ERC1363 smart contract calls this function on the recipient * after an `approve`. This function MAY throw to revert and reject the * approval. Return of other than the magic value MUST result in the * transaction being reverted. * Note: the token contract address is always the message sender. * @param owner address The address which called `approveAndCall` function * @param value uint256 The amount of tokens to be spent * @param data bytes Additional data with no specified format * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` * unless throwing */ function onApprovalReceived(address owner, uint256 value, bytes calldata data) external returns (bytes4); } /** * @title ERC1363Receiver interface * @dev Interface for any contract that wants to support `transferAndCall` or `transferFromAndCall` * from ERC1363 token contracts. */ interface IERC1363Receiver { /* * Note: the ERC-165 identifier for this interface is 0x88a7ca5c. * 0x88a7ca5c === bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)")) */ /** * @notice Handle the receipt of ERC1363 tokens * @dev Any ERC1363 smart contract calls this function on the recipient * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the * transfer. Return of other than the magic value MUST result in the * transaction being reverted. * Note: the token contract address is always the message sender. * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function * @param from address The address which are token transferred from * @param value uint256 The amount of tokens transferred * @param data bytes Additional data with no specified format * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` * unless throwing */ function onTransferReceived(address operator, address from, uint256 value, bytes calldata data) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
{ "optimizer": { "enabled": true, "runs": 200 }, "viaIR": true, "debug": { "revertStrings": "strip" }, "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":"_checkpointManager","type":"address"},{"internalType":"address","name":"_fxRoot","type":"address"},{"internalType":"contract IERC721","name":"_registry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BridgeDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BridgeWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"ContractMigrated","type":"event"},{"inputs":[],"name":"SEND_MESSAGE_EVENT_SIG","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"bridge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkpointManager","outputs":[{"internalType":"contract ICheckpointManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fxChildTunnel","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fxRoot","outputs":[{"internalType":"contract IFxStateSender","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isBridged","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTransferReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","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":[],"name":"registry","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fxChildTunnel","type":"address"}],"name":"setFxChildTunnel","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a034620000c357601f6200200e38819003918201601f19168301916001600160401b03831184841017620000c857808492606094604052833981010312620000c3576200004d81620000de565b60406200005d60208401620000de565b920151916001600160a01b03908184168403620000c3578160018060a01b0319931683600154161760015516906000541617600055608052604051611f1a9081620000f482396080518181816101dc0152818161026f0152818161048d0152611c0a0152f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620000c35756fe60806040526004361015610013575b600080fd5b60003560e01c80630e387de614610103578063174e9f3b146100fa578063607f2d42146100f15780637b103999146100e857806387121759146100df57806388a7ca5c146100d6578063972c4928146100cd578063aea4e49e146100c4578063c0857ba0146100bb578063ce5494bb146100b2578063de9b771f146100a95763f953cec7146100a157600080fd5b61000e6105a9565b5061000e6104c7565b5061000e61045c565b5061000e610432565b5061000e6103ec565b5061000e6103c2565b5061000e61032f565b5061000e61020b565b5061000e6101c5565b5061000e610193565b5061000e610150565b503461000e57600036600319011261000e5760206040517f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b0368152f35b6001600160a01b0381160361000e57565b503461000e57602036600319011261000e5760043561016e8161013f565b60018060a01b03166000526004602052602060ff604060002054166040519015158152f35b503461000e57602036600319011261000e576004356000526003602052602060ff604060002054166040519015158152f35b503461000e57600036600319011261000e576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b503461000e57606036600319011261000e5761026660043561022c8161013f565b6024356102388161013f565b6001600160a01b0382811660008181526004602052604090205460ff1615610268575b505060443591611a73565b005b816102a3927f000000000000000000000000000000000000000000000000000000000000000016918281141592836102b3575b50505061061d565b6102ac826117d0565b388061025b565b6040516331a9108f60e11b8152600481019290925291925090602090829060249082905afa908115610322575b6000916102f4575b5016151538808061029b565b610315915060203d811161031b575b61030d818361054d565b8101906117bb565b386102e8565b503d610303565b61032a6115d8565b6102e0565b503461000e57608036600319011261000e5761034c60043561013f565b6024356103588161013f565b60643567ffffffffffffffff80821161000e573660238301121561000e57816004013590811161000e57366024828401011161000e576103be9260246103a393019060443590611be0565b6040516001600160e01b031990911681529081906020820190565b0390f35b503461000e57600036600319011261000e576002546040516001600160a01b039091168152602090f35b503461000e57602036600319011261000e5760043561040a8161013f565b600254906001600160a01b039081831661000e576001600160a01b0319909216911617600255005b503461000e57600036600319011261000e576001546040516001600160a01b039091168152602090f35b503461000e57602036600319011261000e5761026660043561047d8161013f565b6104c26001600160a01b038281167f0000000000000000000000000000000000000000000000000000000000000000821681811415929190836102b35750505061061d565b6117d0565b503461000e57600036600319011261000e576000546040516001600160a01b039091168152602090f35b50634e487b7160e01b600052604160045260246000fd5b6020810190811067ffffffffffffffff82111761052457604052565b61052c6104f1565b604052565b6040810190811067ffffffffffffffff82111761052457604052565b90601f8019910116810190811067ffffffffffffffff82111761052457604052565b6040519061057c82610531565b565b60209067ffffffffffffffff811161059c575b601f01601f19160190565b6105a46104f1565b610591565b503461000e57602036600319011261000e5760043567ffffffffffffffff811161000e573660238201121561000e5780600401356105e68161057e565b906105f4604051928361054d565b808252366024828501011161000e57602081600092602461026696018386013783010152610624565b1561000e57565b6107ce6107bf61063661057c9361087d565b61077661064282610c88565b9161064c8161097f565b906106d26106c561065c86611095565b61067d61068b61066b86610ca1565b60405192839160208301958a876107f6565b03601f19810183528261054d565b5190206106b56106af6106a8836000526003602052604060002090565b5460ff1690565b1561061d565b6000526003602052604060002090565b805460ff19166001179055565b602061074b6107466106e384610ab8565b6106ec81610cd3565b600254909890610728906001600160a01b031661071761070b8c610d45565b6001600160a01b031690565b6001600160a01b039091161461061d565b610731866109c7565b94859201519061074087610c6f565b91610e22565b61061d565b61075482610997565b61075d836109af565b9061077061076a85610936565b94610959565b946115e5565b506107ba7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b0366107b46107af6107aa85610d81565b610dc5565b611363565b1461061d565b610daa565b6020808251830101910161081b565b611d27565b60005b8381106107e65750506000910152565b81810151838201526020016107d6565b6040939291815261081082518093602080850191016107d3565b019060208201520190565b60208183031261000e5780519067ffffffffffffffff821161000e570181601f8201121561000e57805161084e8161057e565b9261085c604051948561054d565b8184526020828401011161000e5761087a91602080850191016107d3565b90565b61089861089d91606060405161089281610508565b526111f0565b61123d565b604051906108aa82610508565b815290565b50634e487b7160e01b600052603260045260246000fd5b60e0908051600610156108d7570190565b6108df6108af565b0190565b6020908051156108d7570190565b6040908051600110156108d7570190565b610220908051601010156108d7570190565b6020918151811015610929575b60051b010190565b6109316108af565b610921565b602061087a915180511561094c575b0151611363565b6109546108af565b610945565b604061087a9151805160011015610972575b0151611406565b61097a6108af565b61096b565b606061087a915180516002101561094c570151611363565b608061087a915180516003101561094c570151611363565b60a061087a915180516004101561094c570151611363565b60c061087a915180516005101561094c570151611363565b50634e487b7160e01b600052601160045260246000fd5b600019810191908211610a0557565b61057c6109df565b6020039060208211610a0557565b600119810191908211610a0557565b60bf19810191908211610a0557565b607f19810191908211610a0557565b60f619810191908211610a0557565b60b619810191908211610a0557565b91908203918211610a0557565b60405190610a8082610508565b60008252565b90610a908261057e565b610a9d604051918261054d565b8281528092610aae601f199161057e565b0190602036910137565b604051906060820182811067ffffffffffffffff821117610b66575b60405260608252610b2d602083019160608352604084019260008452610b0e610b06610b0084516108c6565b51611406565b8083526111f0565b610b1781611310565b15610b3257610b26915061123d565b8452610ca1565b905290565b50610898610b269151610b61610b50610b4b83516109f6565b610a86565b918251908360200190602101610bc7565b6111f0565b610b6e6104f1565b610ad4565b9060018201809211610a0557565b9060028201809211610a0557565b9060208201809211610a0557565b91908201809211610a0557565b601f8111610bba575b6101000a90565b610bc26109df565b610bb3565b929091928315610c695792915b602093848410610c335780518252848101809111610c26575b938101809111610c19575b91601f198101908111610c0c575b91610bd4565b610c146109df565b610c06565b610c216109df565b610bf8565b610c2e6109df565b610bed565b919350918015610c6457610c51610c4c610c5692610a0d565b610baa565b6109f6565b905182518216911916179052565b505050565b50915050565b61010061087a9151805160071015610972570151611406565b61012061087a9151805160081015610972570151611406565b61014061087a915180516009101561094c570151611363565b60405190610cc782610531565b60006020838281520152565b610d179060606020604051610ce781610531565b610cef610cba565b815201526040610d0e60808351805160031015610d38575b015161123d565b91015190610914565b51610d218161123d565b60405191610d2e83610531565b8252602082015290565b610d406108af565b610d07565b602080910151805115610d74575b0151601581510361000e576001600160a01b0390610d7090611363565b1690565b610d7c6108af565b610d53565b6040602061089d9260608351610d9681610508565b520151805160011015610d3857015161123d565b6060602061087a920151805160021015610972570151611406565b602090610dd0610cba565b5051805115610dde57015190565b610de66108af565b015190565b6001906000198114610dfb570190565b6108df6109df565b906020918051821015610e1557010190565b610e1d6108af565b010190565b9093600093610e356108986000956111f0565b90610e408597611095565b91825115610fc8578597915b8151891015610fbd5783518311610fb157610e70610e6a8a84610914565b51611337565b90815160208093012003610fb157610e91610e8b8a84610914565b5161123d565b90815160118114600014610f42575084518414610f12575060ff610ecf610ec9610ebb8688610e03565b516001600160f81b03191690565b60f81c90565b169060108211610f0557610ef2610eec610efe93610ef893610914565b516113de565b93610b73565b98610deb565b9791610e4c565b5050505050935050905090565b969750915050610f28929650610b009150610902565b8281519101209181519101201460001461087a5750600190565b9199939091600203610f0557610f648186610f5f610b008e6108e3565b610fd3565b91610f6f8383610b9d565b865114610f9c57508115610f0557610eec610f90610efe93610f9693610b9d565b9a6108f1565b92610deb565b979850505050505093610b00610f28916108f1565b50505050935050905090565b505050509293505050565b505050935050905090565b9091610fe0600092611095565b92610feb8451610a86565b94825b85518401808511611072575b81101561104a57611038906001600160f81b03196110188286610e03565b51166110328683039183831161103d575b881a918a610e03565b53610deb565b610fee565b6110456109df565b611029565b50949150506020928051938491012090602081519101201460001461106d575090565b905090565b61107a6109df565b610ffa565b908160011b9180830460021490151715610a0557565b61109d610a73565b9080516110a8575090565b6000915060ff6110ca600f60f81b6110bf846108e3565b5160041c1660f81c90565b169160019283811490811561117e575b501561115d57506110f1610b4b610c51835161107f565b916110fb82611189565b60001a611107846108e3565b538060ff815b1680915b61111d575b5050505090565b845181101561115857806111458561114061113b8661115296610a66565b610b81565b6111ab565b60001a6110328288610e03565b82611111565b611116565b9160ff611175610b4b611170855161107f565b610a1b565b9390829161110d565b6003915014386110da565b80511561119e575b60200151600f60f81b1690565b6111a66108af565b611191565b90600182166111d6576111c19160011c90610e03565b5160fc1c5b60f81b6001600160f81b03191690565b6111e690600f9260011c90610e03565b5160f81c166111c6565b6111f8610cba565b5060208151916040519261120b84610531565b835201602082015290565b60209067ffffffffffffffff8111611230575b60051b0190565b6112386104f1565b611229565b61124681611310565b1561000e5761125481611467565b61125d81611216565b9161126b604051938461054d565b818352601f1961127a83611216565b0160005b8181106112f957505061129f60208092015161129981611578565b90610b9d565b6000905b8382106112b1575050505090565b6112ed816112c16112f3936114f2565b906112ca61056f565b82815281878201526112dc868a610914565b526112e78589610914565b50610b9d565b91610deb565b906112a3565b602090611304610cba565b8282880101520161127e565b80511561133157602060c09101515160001a1061132c57600190565b600090565b50600090565b6113418151610a86565b9081511561135f5780602061087a9201519051908360200190610bc7565b5090565b805180151590816113d2575b501561000e5760208101906113848251611578565b9051918183039283116113c5575b519081018091116113b8575b5190602081106113ac575090565b6020036101000a900490565b6113c06109df565b61139e565b6113cd6109df565b611392565b6021915011153861136f565b602181510361000e5760200151600181018091116113fa575190565b6114026109df565b5190565b80511561000e5761087a602082019161141f8351611578565b90519080820391821161145a575b61143682610a86565b935190810180911161144d575b8360200190610bc7565b6114556109df565b611443565b6114626109df565b61142d565b805115611331576000906020810190815161148181611578565b81018091116114e5575b9151905181018091116114d8575b91905b8281106114a95750905090565b806114b66114c5926114f2565b81018091116114cb5791610deb565b9061149c565b6114d36109df565b6112ed565b6114e06109df565b611499565b6114ed6109df565b61148b565b805160001a906080821015611508575050600190565b60b8821015611523575061151e61087a91610a39565b610b73565b9060c08110156115475760b51991600160b783602003016101000a91015104010190565b9060f882101561155e575061151e61087a91610a2a565b60010151602082900360f7016101000a90040160f5190190565b5160001a608081101561158b5750600090565b60b8811080156115c2575b156115a15750600190565b60c08110156115b65761151e61087a91610a57565b61151e61087a91610a48565b5060c08110158015611596575060f88110611596565b506040513d6000823e3d90fd5b919294939060a0600180821b0360015416926024604051809581936320a9cea560e11b835260048301525afa9586156116e3575b60009485938698611674575b509261087a96949261166e92611665610746989661067d60405193849260208401968a889290916080949284526020840152604083015260608201520190565b51902092610a66565b9061170b565b935096509360a0833d82116116db575b8161169160a0938361054d565b810103126116d857509161166e8261087a9694610746969451946116656020840151966116c66080606087015196015161013f565b96939a93969850509250929496611625565b80fd5b3d9150611684565b6116eb6115d8565b611619565b60019060ff81116116ff571b90565b6117076109df565b1b90565b939091929361173461172d8651611725601f82161561061d565b60051c6116f0565b841061061d565b60209182935b865185116117b25786850151600193611780929185831661178657604080518881019384526020840192909252611774908290840161067d565b519020935b1c94610b8f565b9361173a565b906117a961067d916040519283918a830195869091604092825260208201520190565b51902093611779565b50931493505050565b9081602091031261000e575161087a8161013f565b6001600160a01b03811660009081526004602052604090206117f1906106c5565b604051634b5d3f7160e01b81526001600160a01b03828116926118cf926118ca92909190602083600481895afa9283156119c1575b6000936119a1575b506040516306fdde0360e01b808252926000826004818b5afa918215611994575b600092611979575b50604051926395d89b4160e01b958685526000856004818d5afa94851561196c575b600095611951575b501694604051948552600085600481895afa948515611944575b600095611926575b5060009060046040518098819382525afa948515611919575b6000956118f6575b50611de4565b6119f3565b7f63a3a6504840fce1914d082b35c1578e92684e2412633097b92acce038d2b1ee600080a2565b61191291953d8091833e61190a818361054d565b81019061081b565b93386118c4565b6119216115d8565b6118bc565b61193d90600092963d8091833e61190a818361054d565b94906118a3565b61194c6115d8565b61189b565b61196591953d8091833e61190a818361054d565b9338611881565b6119746115d8565b611879565b61198d91923d8091833e61190a818361054d565b9038611857565b61199c6115d8565b61184f565b6119ba91935060203d811161031b5761030d818361054d565b913861182e565b6119c96115d8565b611826565b906020916119e7815180928185528580860191016107d3565b601f01601f1916010190565b6000546002546001600160a01b0391821692911690823b1561000e57611a40926000928360405180968195829463b472047760e01b845260048401526040602484015260448301906119ce565b03925af18015611a66575b611a525750565b67ffffffffffffffff811161052457604052565b611a6e6115d8565b611a4b565b6001600160a01b038083169392841561000e576040516323b872dd60e01b60208201523360248201523060448201526064810185905291831692611ad5926118ca9286929091611ad090611aca816084810161067d565b87611b03565b611e88565b6040519182527fa471d3307473317213b3f2d8d4af8222a8db9640c4eceaa26b9161d37506123860203393a4565b604051906001600160a01b0316611b1982610531565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564602083818095520152803b1561000e57611b8a9060008481959282868195519301915af13d15611bc6573d90611b6f8261057e565b91611b7d604051938461054d565b82523d858584013e611bca565b805180611b98575b50505050565b81839181010312611bc25701519081151582036116d85750611bb99061061d565b38808080611b92565b8280fd5b6060905b15611bd25790565b805190811561000e57602001fd5b9061087a93929133600052600460205260ff60406000205416611cb457611c3e6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811633811415919082611c4c575b505061061d565b611c47336117d0565b611cb4565b6040516331a9108f60e11b8152336004820152919250602090829060249082905afa908115611ca7575b600091611c89575b501615153880611c37565b611ca1915060203d811161031b5761030d818361054d565b38611c7e565b611caf6115d8565b611c76565b92826020919392938101031261000e5735611cce8161013f565b6001600160a01b0390811692831561000e57611cee6118ca848633611e88565b60405192835216907fa471d3307473317213b3f2d8d4af8222a8db9640c4eceaa26b9161d37506123860203392a4632229f29760e21b90565b60608180518101031261000e57602081015190611d438261013f565b7f2e7354c90b91ef6d9066ab32058ee74714e5ad7686b102277fad44de9204441c60206060604084015193611d778561013f565b015160405163a9059cbb60e01b838201526001600160a01b0394851660248201819052604480830184905282529590941693611dce906080810181811067ffffffffffffffff821117611dd7575b60405285611b03565b604051908152a3565b611ddf6104f1565b611dc5565b611e5f90611e53611e7c96611e4361087a97611e33611e2060405198899760018060a01b0316602089015260a0604089015260c08801906119ce565b601f19998a8883030160608901526119ce565b90888683030160808701526119ce565b90868483030160a08501526119ce565b0383810183528261054d565b6040519384916000602084015260408084015260608301906119ce565b0390810183528261054d565b604080516001600160a01b0392831660208201529290911690820152606080820192909252908152611e7c9061087a90601f1990611ec760808261054d565b6040519384916001602084015260408084015260608301906119ce56fea2646970667358221220f1b700f6e341bdf459b8a1bd83a710158ba8ee208a2e6df6c9a2aa533725342e64736f6c6343000811003300000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a20000000000000000000000007335db10622eecdeffadaee7f2454e37aedf7002
Deployed Bytecode
0x60806040526004361015610013575b600080fd5b60003560e01c80630e387de614610103578063174e9f3b146100fa578063607f2d42146100f15780637b103999146100e857806387121759146100df57806388a7ca5c146100d6578063972c4928146100cd578063aea4e49e146100c4578063c0857ba0146100bb578063ce5494bb146100b2578063de9b771f146100a95763f953cec7146100a157600080fd5b61000e6105a9565b5061000e6104c7565b5061000e61045c565b5061000e610432565b5061000e6103ec565b5061000e6103c2565b5061000e61032f565b5061000e61020b565b5061000e6101c5565b5061000e610193565b5061000e610150565b503461000e57600036600319011261000e5760206040517f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b0368152f35b6001600160a01b0381160361000e57565b503461000e57602036600319011261000e5760043561016e8161013f565b60018060a01b03166000526004602052602060ff604060002054166040519015158152f35b503461000e57602036600319011261000e576004356000526003602052602060ff604060002054166040519015158152f35b503461000e57600036600319011261000e576040517f0000000000000000000000007335db10622eecdeffadaee7f2454e37aedf70026001600160a01b03168152602090f35b503461000e57606036600319011261000e5761026660043561022c8161013f565b6024356102388161013f565b6001600160a01b0382811660008181526004602052604090205460ff1615610268575b505060443591611a73565b005b816102a3927f0000000000000000000000007335db10622eecdeffadaee7f2454e37aedf700216918281141592836102b3575b50505061061d565b6102ac826117d0565b388061025b565b6040516331a9108f60e11b8152600481019290925291925090602090829060249082905afa908115610322575b6000916102f4575b5016151538808061029b565b610315915060203d811161031b575b61030d818361054d565b8101906117bb565b386102e8565b503d610303565b61032a6115d8565b6102e0565b503461000e57608036600319011261000e5761034c60043561013f565b6024356103588161013f565b60643567ffffffffffffffff80821161000e573660238301121561000e57816004013590811161000e57366024828401011161000e576103be9260246103a393019060443590611be0565b6040516001600160e01b031990911681529081906020820190565b0390f35b503461000e57600036600319011261000e576002546040516001600160a01b039091168152602090f35b503461000e57602036600319011261000e5760043561040a8161013f565b600254906001600160a01b039081831661000e576001600160a01b0319909216911617600255005b503461000e57600036600319011261000e576001546040516001600160a01b039091168152602090f35b503461000e57602036600319011261000e5761026660043561047d8161013f565b6104c26001600160a01b038281167f0000000000000000000000007335db10622eecdeffadaee7f2454e37aedf7002821681811415929190836102b35750505061061d565b6117d0565b503461000e57600036600319011261000e576000546040516001600160a01b039091168152602090f35b50634e487b7160e01b600052604160045260246000fd5b6020810190811067ffffffffffffffff82111761052457604052565b61052c6104f1565b604052565b6040810190811067ffffffffffffffff82111761052457604052565b90601f8019910116810190811067ffffffffffffffff82111761052457604052565b6040519061057c82610531565b565b60209067ffffffffffffffff811161059c575b601f01601f19160190565b6105a46104f1565b610591565b503461000e57602036600319011261000e5760043567ffffffffffffffff811161000e573660238201121561000e5780600401356105e68161057e565b906105f4604051928361054d565b808252366024828501011161000e57602081600092602461026696018386013783010152610624565b1561000e57565b6107ce6107bf61063661057c9361087d565b61077661064282610c88565b9161064c8161097f565b906106d26106c561065c86611095565b61067d61068b61066b86610ca1565b60405192839160208301958a876107f6565b03601f19810183528261054d565b5190206106b56106af6106a8836000526003602052604060002090565b5460ff1690565b1561061d565b6000526003602052604060002090565b805460ff19166001179055565b602061074b6107466106e384610ab8565b6106ec81610cd3565b600254909890610728906001600160a01b031661071761070b8c610d45565b6001600160a01b031690565b6001600160a01b039091161461061d565b610731866109c7565b94859201519061074087610c6f565b91610e22565b61061d565b61075482610997565b61075d836109af565b9061077061076a85610936565b94610959565b946115e5565b506107ba7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b0366107b46107af6107aa85610d81565b610dc5565b611363565b1461061d565b610daa565b6020808251830101910161081b565b611d27565b60005b8381106107e65750506000910152565b81810151838201526020016107d6565b6040939291815261081082518093602080850191016107d3565b019060208201520190565b60208183031261000e5780519067ffffffffffffffff821161000e570181601f8201121561000e57805161084e8161057e565b9261085c604051948561054d565b8184526020828401011161000e5761087a91602080850191016107d3565b90565b61089861089d91606060405161089281610508565b526111f0565b61123d565b604051906108aa82610508565b815290565b50634e487b7160e01b600052603260045260246000fd5b60e0908051600610156108d7570190565b6108df6108af565b0190565b6020908051156108d7570190565b6040908051600110156108d7570190565b610220908051601010156108d7570190565b6020918151811015610929575b60051b010190565b6109316108af565b610921565b602061087a915180511561094c575b0151611363565b6109546108af565b610945565b604061087a9151805160011015610972575b0151611406565b61097a6108af565b61096b565b606061087a915180516002101561094c570151611363565b608061087a915180516003101561094c570151611363565b60a061087a915180516004101561094c570151611363565b60c061087a915180516005101561094c570151611363565b50634e487b7160e01b600052601160045260246000fd5b600019810191908211610a0557565b61057c6109df565b6020039060208211610a0557565b600119810191908211610a0557565b60bf19810191908211610a0557565b607f19810191908211610a0557565b60f619810191908211610a0557565b60b619810191908211610a0557565b91908203918211610a0557565b60405190610a8082610508565b60008252565b90610a908261057e565b610a9d604051918261054d565b8281528092610aae601f199161057e565b0190602036910137565b604051906060820182811067ffffffffffffffff821117610b66575b60405260608252610b2d602083019160608352604084019260008452610b0e610b06610b0084516108c6565b51611406565b8083526111f0565b610b1781611310565b15610b3257610b26915061123d565b8452610ca1565b905290565b50610898610b269151610b61610b50610b4b83516109f6565b610a86565b918251908360200190602101610bc7565b6111f0565b610b6e6104f1565b610ad4565b9060018201809211610a0557565b9060028201809211610a0557565b9060208201809211610a0557565b91908201809211610a0557565b601f8111610bba575b6101000a90565b610bc26109df565b610bb3565b929091928315610c695792915b602093848410610c335780518252848101809111610c26575b938101809111610c19575b91601f198101908111610c0c575b91610bd4565b610c146109df565b610c06565b610c216109df565b610bf8565b610c2e6109df565b610bed565b919350918015610c6457610c51610c4c610c5692610a0d565b610baa565b6109f6565b905182518216911916179052565b505050565b50915050565b61010061087a9151805160071015610972570151611406565b61012061087a9151805160081015610972570151611406565b61014061087a915180516009101561094c570151611363565b60405190610cc782610531565b60006020838281520152565b610d179060606020604051610ce781610531565b610cef610cba565b815201526040610d0e60808351805160031015610d38575b015161123d565b91015190610914565b51610d218161123d565b60405191610d2e83610531565b8252602082015290565b610d406108af565b610d07565b602080910151805115610d74575b0151601581510361000e576001600160a01b0390610d7090611363565b1690565b610d7c6108af565b610d53565b6040602061089d9260608351610d9681610508565b520151805160011015610d3857015161123d565b6060602061087a920151805160021015610972570151611406565b602090610dd0610cba565b5051805115610dde57015190565b610de66108af565b015190565b6001906000198114610dfb570190565b6108df6109df565b906020918051821015610e1557010190565b610e1d6108af565b010190565b9093600093610e356108986000956111f0565b90610e408597611095565b91825115610fc8578597915b8151891015610fbd5783518311610fb157610e70610e6a8a84610914565b51611337565b90815160208093012003610fb157610e91610e8b8a84610914565b5161123d565b90815160118114600014610f42575084518414610f12575060ff610ecf610ec9610ebb8688610e03565b516001600160f81b03191690565b60f81c90565b169060108211610f0557610ef2610eec610efe93610ef893610914565b516113de565b93610b73565b98610deb565b9791610e4c565b5050505050935050905090565b969750915050610f28929650610b009150610902565b8281519101209181519101201460001461087a5750600190565b9199939091600203610f0557610f648186610f5f610b008e6108e3565b610fd3565b91610f6f8383610b9d565b865114610f9c57508115610f0557610eec610f90610efe93610f9693610b9d565b9a6108f1565b92610deb565b979850505050505093610b00610f28916108f1565b50505050935050905090565b505050509293505050565b505050935050905090565b9091610fe0600092611095565b92610feb8451610a86565b94825b85518401808511611072575b81101561104a57611038906001600160f81b03196110188286610e03565b51166110328683039183831161103d575b881a918a610e03565b53610deb565b610fee565b6110456109df565b611029565b50949150506020928051938491012090602081519101201460001461106d575090565b905090565b61107a6109df565b610ffa565b908160011b9180830460021490151715610a0557565b61109d610a73565b9080516110a8575090565b6000915060ff6110ca600f60f81b6110bf846108e3565b5160041c1660f81c90565b169160019283811490811561117e575b501561115d57506110f1610b4b610c51835161107f565b916110fb82611189565b60001a611107846108e3565b538060ff815b1680915b61111d575b5050505090565b845181101561115857806111458561114061113b8661115296610a66565b610b81565b6111ab565b60001a6110328288610e03565b82611111565b611116565b9160ff611175610b4b611170855161107f565b610a1b565b9390829161110d565b6003915014386110da565b80511561119e575b60200151600f60f81b1690565b6111a66108af565b611191565b90600182166111d6576111c19160011c90610e03565b5160fc1c5b60f81b6001600160f81b03191690565b6111e690600f9260011c90610e03565b5160f81c166111c6565b6111f8610cba565b5060208151916040519261120b84610531565b835201602082015290565b60209067ffffffffffffffff8111611230575b60051b0190565b6112386104f1565b611229565b61124681611310565b1561000e5761125481611467565b61125d81611216565b9161126b604051938461054d565b818352601f1961127a83611216565b0160005b8181106112f957505061129f60208092015161129981611578565b90610b9d565b6000905b8382106112b1575050505090565b6112ed816112c16112f3936114f2565b906112ca61056f565b82815281878201526112dc868a610914565b526112e78589610914565b50610b9d565b91610deb565b906112a3565b602090611304610cba565b8282880101520161127e565b80511561133157602060c09101515160001a1061132c57600190565b600090565b50600090565b6113418151610a86565b9081511561135f5780602061087a9201519051908360200190610bc7565b5090565b805180151590816113d2575b501561000e5760208101906113848251611578565b9051918183039283116113c5575b519081018091116113b8575b5190602081106113ac575090565b6020036101000a900490565b6113c06109df565b61139e565b6113cd6109df565b611392565b6021915011153861136f565b602181510361000e5760200151600181018091116113fa575190565b6114026109df565b5190565b80511561000e5761087a602082019161141f8351611578565b90519080820391821161145a575b61143682610a86565b935190810180911161144d575b8360200190610bc7565b6114556109df565b611443565b6114626109df565b61142d565b805115611331576000906020810190815161148181611578565b81018091116114e5575b9151905181018091116114d8575b91905b8281106114a95750905090565b806114b66114c5926114f2565b81018091116114cb5791610deb565b9061149c565b6114d36109df565b6112ed565b6114e06109df565b611499565b6114ed6109df565b61148b565b805160001a906080821015611508575050600190565b60b8821015611523575061151e61087a91610a39565b610b73565b9060c08110156115475760b51991600160b783602003016101000a91015104010190565b9060f882101561155e575061151e61087a91610a2a565b60010151602082900360f7016101000a90040160f5190190565b5160001a608081101561158b5750600090565b60b8811080156115c2575b156115a15750600190565b60c08110156115b65761151e61087a91610a57565b61151e61087a91610a48565b5060c08110158015611596575060f88110611596565b506040513d6000823e3d90fd5b919294939060a0600180821b0360015416926024604051809581936320a9cea560e11b835260048301525afa9586156116e3575b60009485938698611674575b509261087a96949261166e92611665610746989661067d60405193849260208401968a889290916080949284526020840152604083015260608201520190565b51902092610a66565b9061170b565b935096509360a0833d82116116db575b8161169160a0938361054d565b810103126116d857509161166e8261087a9694610746969451946116656020840151966116c66080606087015196015161013f565b96939a93969850509250929496611625565b80fd5b3d9150611684565b6116eb6115d8565b611619565b60019060ff81116116ff571b90565b6117076109df565b1b90565b939091929361173461172d8651611725601f82161561061d565b60051c6116f0565b841061061d565b60209182935b865185116117b25786850151600193611780929185831661178657604080518881019384526020840192909252611774908290840161067d565b519020935b1c94610b8f565b9361173a565b906117a961067d916040519283918a830195869091604092825260208201520190565b51902093611779565b50931493505050565b9081602091031261000e575161087a8161013f565b6001600160a01b03811660009081526004602052604090206117f1906106c5565b604051634b5d3f7160e01b81526001600160a01b03828116926118cf926118ca92909190602083600481895afa9283156119c1575b6000936119a1575b506040516306fdde0360e01b808252926000826004818b5afa918215611994575b600092611979575b50604051926395d89b4160e01b958685526000856004818d5afa94851561196c575b600095611951575b501694604051948552600085600481895afa948515611944575b600095611926575b5060009060046040518098819382525afa948515611919575b6000956118f6575b50611de4565b6119f3565b7f63a3a6504840fce1914d082b35c1578e92684e2412633097b92acce038d2b1ee600080a2565b61191291953d8091833e61190a818361054d565b81019061081b565b93386118c4565b6119216115d8565b6118bc565b61193d90600092963d8091833e61190a818361054d565b94906118a3565b61194c6115d8565b61189b565b61196591953d8091833e61190a818361054d565b9338611881565b6119746115d8565b611879565b61198d91923d8091833e61190a818361054d565b9038611857565b61199c6115d8565b61184f565b6119ba91935060203d811161031b5761030d818361054d565b913861182e565b6119c96115d8565b611826565b906020916119e7815180928185528580860191016107d3565b601f01601f1916010190565b6000546002546001600160a01b0391821692911690823b1561000e57611a40926000928360405180968195829463b472047760e01b845260048401526040602484015260448301906119ce565b03925af18015611a66575b611a525750565b67ffffffffffffffff811161052457604052565b611a6e6115d8565b611a4b565b6001600160a01b038083169392841561000e576040516323b872dd60e01b60208201523360248201523060448201526064810185905291831692611ad5926118ca9286929091611ad090611aca816084810161067d565b87611b03565b611e88565b6040519182527fa471d3307473317213b3f2d8d4af8222a8db9640c4eceaa26b9161d37506123860203393a4565b604051906001600160a01b0316611b1982610531565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564602083818095520152803b1561000e57611b8a9060008481959282868195519301915af13d15611bc6573d90611b6f8261057e565b91611b7d604051938461054d565b82523d858584013e611bca565b805180611b98575b50505050565b81839181010312611bc25701519081151582036116d85750611bb99061061d565b38808080611b92565b8280fd5b6060905b15611bd25790565b805190811561000e57602001fd5b9061087a93929133600052600460205260ff60406000205416611cb457611c3e6001600160a01b037f0000000000000000000000007335db10622eecdeffadaee7f2454e37aedf7002811633811415919082611c4c575b505061061d565b611c47336117d0565b611cb4565b6040516331a9108f60e11b8152336004820152919250602090829060249082905afa908115611ca7575b600091611c89575b501615153880611c37565b611ca1915060203d811161031b5761030d818361054d565b38611c7e565b611caf6115d8565b611c76565b92826020919392938101031261000e5735611cce8161013f565b6001600160a01b0390811692831561000e57611cee6118ca848633611e88565b60405192835216907fa471d3307473317213b3f2d8d4af8222a8db9640c4eceaa26b9161d37506123860203392a4632229f29760e21b90565b60608180518101031261000e57602081015190611d438261013f565b7f2e7354c90b91ef6d9066ab32058ee74714e5ad7686b102277fad44de9204441c60206060604084015193611d778561013f565b015160405163a9059cbb60e01b838201526001600160a01b0394851660248201819052604480830184905282529590941693611dce906080810181811067ffffffffffffffff821117611dd7575b60405285611b03565b604051908152a3565b611ddf6104f1565b611dc5565b611e5f90611e53611e7c96611e4361087a97611e33611e2060405198899760018060a01b0316602089015260a0604089015260c08801906119ce565b601f19998a8883030160608901526119ce565b90888683030160808701526119ce565b90868483030160a08501526119ce565b0383810183528261054d565b6040519384916000602084015260408084015260608301906119ce565b0390810183528261054d565b604080516001600160a01b0392831660208201529290911690820152606080820192909252908152611e7c9061087a90601f1990611ec760808261054d565b6040519384916001602084015260408084015260608301906119ce56fea2646970667358221220f1b700f6e341bdf459b8a1bd83a710158ba8ee208a2e6df6c9a2aa533725342e64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a20000000000000000000000007335db10622eecdeffadaee7f2454e37aedf7002
-----Decoded View---------------
Arg [0] : _checkpointManager (address): 0x86E4Dc95c7FBdBf52e33D563BbDB00823894C287
Arg [1] : _fxRoot (address): 0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2
Arg [2] : _registry (address): 0x7335dB10622eeCdEFfAdAee7F2454e37aedf7002
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287
Arg [1] : 000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a2
Arg [2] : 0000000000000000000000007335db10622eecdeffadaee7f2454e37aedf7002
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.04063 | 110,659,645.6142 | $4,496,134.6 |
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.