More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 586 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Unstake | 20482262 | 71 days ago | IN | 0 ETH | 0.00027549 | ||||
Unstake | 20246953 | 104 days ago | IN | 0 ETH | 0.00078075 | ||||
Unstake | 20246948 | 104 days ago | IN | 0 ETH | 0.00066742 | ||||
Unstake | 20207198 | 109 days ago | IN | 0 ETH | 0.00188558 | ||||
Unstake | 19942013 | 146 days ago | IN | 0 ETH | 0.00139597 | ||||
Unstake | 19859563 | 158 days ago | IN | 0 ETH | 0.00074611 | ||||
Unstake | 19784464 | 168 days ago | IN | 0 ETH | 0.0025148 | ||||
Unstake | 19756539 | 172 days ago | IN | 0 ETH | 0.0010702 | ||||
Unstake | 19736042 | 175 days ago | IN | 0 ETH | 0.00244378 | ||||
Bulk Unstake | 19718214 | 178 days ago | IN | 0 ETH | 0.00497431 | ||||
Unstake | 19715470 | 178 days ago | IN | 0 ETH | 0.00299398 | ||||
Unstake | 19714792 | 178 days ago | IN | 0 ETH | 0.00067812 | ||||
Unstake | 19714787 | 178 days ago | IN | 0 ETH | 0.00100512 | ||||
Unstake | 19624887 | 191 days ago | IN | 0 ETH | 0.00596786 | ||||
Unstake | 19624884 | 191 days ago | IN | 0 ETH | 0.00588795 | ||||
Unstake | 19624881 | 191 days ago | IN | 0 ETH | 0.00644933 | ||||
Bulk Unstake | 19610598 | 193 days ago | IN | 0 ETH | 0.01995148 | ||||
Bulk Unstake | 19586848 | 196 days ago | IN | 0 ETH | 0.00590111 | ||||
Unstake | 19583361 | 197 days ago | IN | 0 ETH | 0.01516722 | ||||
Unstake | 19565907 | 199 days ago | IN | 0 ETH | 0.0020256 | ||||
Unstake | 19565905 | 199 days ago | IN | 0 ETH | 0.00324347 | ||||
Unstake | 19558151 | 200 days ago | IN | 0 ETH | 0.00671374 | ||||
Unstake | 19553583 | 201 days ago | IN | 0 ETH | 0.00670002 | ||||
Unstake | 19553581 | 201 days ago | IN | 0 ETH | 0.00227984 | ||||
Unstake | 19553580 | 201 days ago | IN | 0 ETH | 0.002342 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
NuCyberStaking
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 10000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; import "@lambdalf-dev/ethereum-contracts/contracts/interfaces/IArrayErrors.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/utils/ContractState.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/utils/ERC173.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC721.sol"; import { FxBaseRootTunnel } from "fx-portal/contracts/tunnel/FxBaseRootTunnel.sol"; contract NuCyberStaking is IArrayErrors, ContractState, ERC173, FxBaseRootTunnel { // ************************************** // ***** CUSTOM TYPES ***** // ************************************** struct StakedToken { uint64 tokenId; address beneficiary; } // ************************************** // ************************************** // ***** ERRORS ***** // ************************************** /** * @dev Thrown when user tries to unstake a token they don't own * * @param tokenId the token being unstaked */ error NCS_TOKEN_NOT_OWNED(uint256 tokenId); /** * @dev Thrown when trying to stake while rewards are not set */ error NCS_REWARDS_NOT_SET(); // ************************************** // ************************************** // ***** EVENTS ***** // ************************************** /** * @dev Emitted when a user sets a beneficiary address * * @param tokenId the token being unstaked * @param beneficiary the address benefitting from the token */ event BenefitStarted(uint256 indexed tokenId, address indexed beneficiary); /** * @dev Emitted when a user sets a beneficiary address * * @param tokenId the token being unstaked * @param beneficiary the address benefitting from the token */ event BenefitEnded(uint256 indexed tokenId, address indexed beneficiary); // ************************************** // ************************************** // ***** BYTECODE VARIABLES ***** // ************************************** uint8 public constant ACTIVE = 1; // ************************************** // ************************************** // ***** STORAGE VARIABLES ***** // ************************************** IERC721 public nuCyber; // Wallet address mapped to list of token Ids mapping(address => StakedToken[]) private _stakedTokens; // Beneficiary wallet address mapped to list of token Ids mapping(address => uint256[]) private _benefitTokens; // ************************************** constructor(address nucyberContractAddress_, address cpManager_, address fxRoot_) FxBaseRootTunnel(cpManager_, fxRoot_) { nuCyber = IERC721(nucyberContractAddress_); _setOwner(msg.sender); } // ************************************** // ***** INTERNAL ***** // ************************************** /** * @dev Internal function returning the benefit balance of `account_`. * * @param account_ the beneficiary address */ function _balanceOfBenefit(address account_) internal view returns (uint256) { return _benefitTokens[account_].length; } /** * @dev Internal function returning the staking balance of `account_`. * * @param account_ the beneficiary address */ function _balanceOfStaked(address account_) internal view returns (uint256) { return _stakedTokens[account_].length; } /** * @dev Internal function that ends a benefit. * * @param beneficiary_ the beneficiary address * @param tokenId_ the token being unstaked * * Requirements: * * - Emits a {BenefitEnded} event */ function _endBenefit(address beneficiary_, uint256 tokenId_) internal { uint256 _last_ = _benefitTokens[beneficiary_].length; uint256 _count_ = _last_; bool _deleted_; while(_count_ > 0) { unchecked { --_count_; } if (_benefitTokens[beneficiary_][_count_] == tokenId_) { if (_count_ != _last_ - 1) { _benefitTokens[beneficiary_][_count_] = _benefitTokens[beneficiary_][_last_ - 1]; } _benefitTokens[beneficiary_].pop(); _deleted_ = true; } } if(! _deleted_) { revert NCS_TOKEN_NOT_OWNED(tokenId_); } emit BenefitEnded(tokenId_, beneficiary_); } /** * @dev Internal function that returns a specific staked token and its index * * @param tokenOwner_ the token owner * @param tokenId_ the token being unstaked * * Requirements: * * - `tokenOwner_` must own `tokenId_` */ function _findToken(address tokenOwner_, uint256 tokenId_) internal view returns (StakedToken memory, uint256) { uint256 _count_ = _stakedTokens[tokenOwner_].length; while(_count_ > 0) { unchecked { --_count_; } if (_stakedTokens[tokenOwner_][_count_].tokenId == tokenId_) { return (_stakedTokens[tokenOwner_][_count_], _count_); } } revert NCS_TOKEN_NOT_OWNED(tokenId_); } /** * @dev Internal function to process a message sent by the child contract on Polygon * Note: In our situation, we do not expect to receive any message from the child contract. * * @param message the message sent by the child contract */ function _processMessageFromChild(bytes memory message) internal override { // We don't need a message from child } /** * @dev Internal function to send a message to the child contract on Polygon * * @param sender_ the address staking or unstaking one or more token * @param amount_ the number of token being staked or unstaked * @param isStake_ whether the token are being staked or unstaked */ function _sendMessage(address sender_, uint16 amount_, bool isStake_) internal { if (amount_ > 0) { _sendMessageToChild( abi.encode(sender_, uint8(1), amount_, isStake_) ); } } /** * @dev Internal function that stakes `tokenId_` for `tokenOwner_`. * * @param tokenOwner_ the token owner * @param tokenId_ the token being staked * @param beneficiary_ an address that will benefit from the token being staked * * Requirements: * * - `tokenOwner_` must own `tokenId_` * - This contract must be allowed to transfer NuCyber tokens on behalf of `tokenOwner_` * - Emits a {BenefitStarted} event if `beneficiary_` is not null */ function _stakeToken(address tokenOwner_, uint256 tokenId_, address beneficiary_) internal { _stakedTokens[tokenOwner_].push(StakedToken(uint64(tokenId_),beneficiary_)); if (beneficiary_ != address(0)) { _benefitTokens[beneficiary_].push(tokenId_); emit BenefitStarted(tokenId_, beneficiary_); } try nuCyber.transferFrom(tokenOwner_, address(this), tokenId_) {} catch Error(string memory reason) { revert(reason); } } /** * @dev Internal function that unstakes `tokenId_` for `tokenOwner_`. * * @param tokenOwner_ the token owner * @param tokenId_ the token being unstaked * * Requirements: * * - `tokenOwner_` must own `tokenId_` * - Emits a {BenefitEnded} event if `tokenId_` had a beneficiary */ function _unstakeToken(address tokenOwner_, uint256 tokenId_) internal { uint256 _last_ = _stakedTokens[tokenOwner_].length; uint256 _count_ = _last_; bool _deleted_; while(_count_ > 0) { unchecked { --_count_; } if (_stakedTokens[tokenOwner_][_count_].tokenId == tokenId_) { address _beneficiary_ = _stakedTokens[tokenOwner_][_count_].beneficiary; if(_beneficiary_ != address(0)) { _endBenefit(_beneficiary_, tokenId_); } if (_count_ != _last_ - 1) { _stakedTokens[tokenOwner_][_count_] = _stakedTokens[tokenOwner_][_last_ - 1]; } _stakedTokens[tokenOwner_].pop(); _deleted_ = true; } } if(! _deleted_) { revert NCS_TOKEN_NOT_OWNED(tokenId_); } try nuCyber.transferFrom(address(this), tokenOwner_, tokenId_) {} catch Error(string memory reason) { revert(reason); } } // ************************************** // ************************************** // ***** PUBLIC ***** // ************************************** /** * @dev Stakes a batch of NuCyber at once. * * @param tokenIds_ the tokens being staked * @param beneficiaries_ a list of addresses that will benefit from the tokens being staked * * Requirements: * * - Caller must own all of `tokenIds_` * - Emits one or more {BenefitStarted} events if `beneficiaries_` is not null * - This contract must be allowed to transfer NuCyber tokens on behalf of the caller */ function bulkStake(uint256[] memory tokenIds_, address[] memory beneficiaries_) public isState(ACTIVE) { if (fxChildTunnel == address(0)) { revert NCS_REWARDS_NOT_SET(); } uint256 _len_ = tokenIds_.length; if ( beneficiaries_.length != _len_ ) { revert ARRAY_LENGTH_MISMATCH(); } while (_len_ > 0) { unchecked { --_len_; } _stakeToken(msg.sender, tokenIds_[_len_], beneficiaries_[_len_]); } _sendMessage(msg.sender, uint16(tokenIds_.length), true); } /** * @dev Unstakes a batch of NuCyber at once. * * @param tokenIds_ the tokens being unstaked * * Requirements: * * - Caller must own all of `tokenIds_` * - Emits one or more {BenefitEnded} events if `tokenIds_` had beneficiaries */ function bulkUnstake(uint256[] memory tokenIds_) public { uint256 _len_ = tokenIds_.length; while (_len_ > 0) { unchecked { --_len_; } _unstakeToken(msg.sender, tokenIds_[_len_]); } _sendMessage(msg.sender, uint16(tokenIds_.length), false); } /** * @dev Stakes a NuCyber token. * * @param tokenId_ the token being staked * @param beneficiary_ an address that will benefit from the token being staked * * Requirements: * * - Caller must own `tokenId_` * - Emits a {BenefitStarted} event if `beneficiary_` is not null * - This contract must be allowed to transfer NuCyber tokens on behalf of the caller */ function stake(uint256 tokenId_, address beneficiary_) public isState(ACTIVE) { if (fxChildTunnel == address(0)) { revert NCS_REWARDS_NOT_SET(); } _stakeToken(msg.sender, tokenId_, beneficiary_); _sendMessage(msg.sender, 1, true); } /** * @dev Unstakes a NuCyber token. * * @param tokenId_ the token being unstaked * * Requirements: * * - Caller must own `tokenId_` * - Emits a {BenefitEnded} event if `tokenId_` had a beneficiary */ function unstake(uint256 tokenId_) public { _unstakeToken(msg.sender, tokenId_); _sendMessage(msg.sender, 1, false); } /** * @dev Updates the beneficiary of a staked token. * * @param tokenId_ the staked token * @param newBeneficiary_ the address that will benefit from the staked token * * Requirements: * * - Caller must own `tokenId_` * - Emits a {BenefitEnded} event if `tokenId_` had a beneficiary * - Emits a {BenefitStarted} event if `newBeneficiary_` is not null */ function updateBeneficiary(uint256 tokenId_, address newBeneficiary_) public { (StakedToken memory _stakedToken_, uint256 _index_) = _findToken(msg.sender, tokenId_); _stakedTokens[msg.sender][_index_].beneficiary = newBeneficiary_; if (_stakedToken_.beneficiary != address(0)) { _endBenefit(_stakedToken_.beneficiary, tokenId_); } if (newBeneficiary_ != address(0)) { _benefitTokens[newBeneficiary_].push(tokenId_); emit BenefitStarted(tokenId_, newBeneficiary_); } } // ************************************** // ************************************** // ***** CONTRACT OWNER ***** // ************************************** /** * @dev Sets the NuCyber contract address * * @param contractAddress_ the address of the NuCyber contract * * Requirements: * * - Caller must be the contract owner */ function setNuCyberContract(address contractAddress_) external onlyOwner { nuCyber = IERC721(contractAddress_); } /** * @dev Updates the contract state. * * @param newState_ the new sale state * * Requirements: * * - Caller must be the contract owner. * - `newState_` must be a valid state. */ function setContractState(uint8 newState_) external onlyOwner { if (newState_ > ACTIVE) { revert ContractState_INVALID_STATE(newState_); } _setContractState(newState_); } /** * @dev Updates the child contract on Polygon * * @param fxChildTunnel_ the new child contract on Polygon * * Requirements: * * - Caller must be the contract owner. */ function updateFxChildTunnel(address fxChildTunnel_) external onlyOwner { fxChildTunnel = fxChildTunnel_; } // ************************************** // ************************************** // ***** VIEW ***** // ************************************** /** * @dev Returns the number oof NuCyber staked and owned by `tokenOwner_`. * Note: We need this function for collab.land to successfully give out token ownership roles * * @param tokenOwner_ address owning tokens */ function balanceOf(address tokenOwner_) public view returns (uint256) { return nuCyber.balanceOf(tokenOwner_) + _balanceOfStaked(tokenOwner_) + _balanceOfBenefit(tokenOwner_); } /** * @dev Returns the benefit balance of `account_`. * * @param account_ the address to check */ function balanceOfBenefit(address account_) external view returns (uint256) { return _balanceOfBenefit(account_); } /** * @dev Returns the staking balance of `account_`. * * @param account_ the address to check */ function balanceOfStaked(address account_) external view returns (uint256) { return _balanceOfStaked(account_); } /** * @dev Returns the list of tokens owned by `tokenOwner_`. * * @param tokenOwner_ address owning tokens */ function stakedTokens(address tokenOwner_) public view returns (StakedToken[] memory) { return _stakedTokens[tokenOwner_]; } // ************************************** }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; interface IArrayErrors { /** * @dev Thrown when two related arrays have different lengths */ error ARRAY_LENGTH_MISMATCH(); }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; interface IContractState { /** * @dev Thrown when a function is called with the wrong contract state. * * @param currentState the current state of the contract */ error ContractState_INCORRECT_STATE(uint8 currentState); /** * @dev Thrown when trying to set the contract state to an invalid value. * * @param invalidState the invalid contract state */ error ContractState_INVALID_STATE(uint8 invalidState); /** * @dev Emitted when the sale state changes * * @param previousState the previous state of the contract * @param newState the new state of the contract */ event ContractStateChanged(uint8 indexed previousState, uint8 indexed newState); /** * @dev Returns the current contract state. */ function getContractState() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; // import "./IERC165.sol"; /** * @dev Required interface of an ERC173 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-173[EIP]. */ interface IERC173 /* is IERC165 */ { /** * @dev This emits when ownership of a contract changes. * * @param previousOwner the previous contract owner * @param newOwner the new contract owner */ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @notice Set the address of the new owner of the contract. * @dev Set newOwner_ to address(0) to renounce any ownership. */ function transferOwnership(address newOwner_) external; /** * @notice Returns the address of the owner. */ function owner() external view returns(address); }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; interface IERC173Errors { /** * @dev Thrown when `operator` is not the contract owner. * * @param operator address trying to use a function reserved to contract owner without authorization */ error IERC173_NOT_OWNER(address operator); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; // import "./IERC165.sol"; /** * @title ERC-721 Non-Fungible Token Standard * @dev See https://eips.ethereum.org/EIPS/eip-721 * Note: the ERC-165 identifier for this interface is 0x80ac58cd. */ interface IERC721 /* is IERC165 */ { /** * @dev This emits when the approved address for an NFT is changed or reaffirmed. * The zero address indicates there is no approved address. * When a Transfer event emits, this also indicates that the approved address for that NFT (if any) is reset to none. * * @param owner address that owns the token * @param approved address that is allowed to manage the token * @param tokenId identifier of the token being approved */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev This emits when an operator is enabled or disabled for an owner. The operator can manage all NFTs of the owner. * * @param owner address that owns the tokens * @param operator address that is allowed or not to manage the tokens * @param approved whether the operator is allowed or not */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev This emits when ownership of any NFT changes by any mechanism. * This event emits when NFTs are created (`from` == 0) and destroyed (`to` == 0). * Exception: during contract creation, any number of NFTs may be created and assigned without emitting Transfer. * At the time of any transfer, the approved address for that NFT (if any) is reset to none. * * @param from address the token is being transferred from * @param to address the token is being transferred to * @param tokenId identifier of the token being transferred */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @notice Change or reaffirm the approved address for an NFT * @dev The zero address indicates there is no approved address. * Throws unless `msg.sender` is the current NFT owner, or an authorized operator of the current owner. */ function approve(address approved_, uint256 tokenId_) external; /** * @notice Transfers the ownership of an NFT from one address to another address * @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved address for this NFT. * Throws if `from_` is not the current owner. * Throws if `to_` is the zero address. * Throws if `tokenId_` is not a valid NFT. * When transfer is complete, this function checks if `to_` is a smart contract (code size > 0). * If so, it calls {onERC721Received} on `to_` and throws if the return value is not * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. */ function safeTransferFrom(address from_, address to_, uint256 tokenId_, bytes calldata data_) external; /** * @notice Transfers the ownership of an NFT from one address to another address * @dev This works identically to the other function with an extra data parameter, * except this function just sets data to "". */ function safeTransferFrom(address from_, address to_, uint256 tokenId_) external; /** * @notice Enable or disable approval for a third party ("operator") to manage all of `msg.sender`'s assets. * @dev Emits the ApprovalForAll event. The contract MUST allow multiple operators per owner. */ function setApprovalForAll(address operator_, bool approved_) external; /** * @notice Transfer ownership of an NFT. * The caller is responsible to confirm that `to_` is capable of receiving nfts or * else they may be permanently lost * @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved address for this NFT. * Throws if `from_` is not the current owner. * Throws if `to_` is the zero address. * Throws if `tokenId_` is not a valid NFT. */ function transferFrom(address from_, address to_, uint256 tokenId_) external; /** * @notice Count all NFTs assigned to an owner * @dev NFTs assigned to the zero address are considered invalid. Throws for queries about the zero address. */ function balanceOf(address owner_) external view returns (uint256); /** * @notice Get the approved address for a single NFT * @dev Throws if `tokenId_` is not a valid NFT. */ function getApproved(uint256 tokenId_) external view returns (address); /** * @notice Query if an address is an authorized operator for another address */ function isApprovedForAll(address owner_, address operator_) external view returns (bool); /** * @notice Find the owner of an NFT * @dev NFTs assigned to zero address are considered invalid, and queries * about them do throw. */ function ownerOf(uint256 tokenId_) external view returns (address); }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; import "../interfaces/IContractState.sol"; abstract contract ContractState is IContractState { // Enum to represent the sale state, defaults to ``PAUSED``. uint8 public constant PAUSED = 0; // The current state of the contract uint8 private _contractState; // ************************************** // ***** MODIFIER ***** // ************************************** /** * @dev Ensures that contract state is `expectedState_`. * * @param expectedState_ : the desirable contract state */ modifier isState(uint8 expectedState_) { if (_contractState != expectedState_) { revert ContractState_INCORRECT_STATE(_contractState); } _; } /** * @dev Ensures that contract state is not `unexpectedState_`. * * @param unexpectedState_ : the undesirable contract state */ modifier isNotState(uint8 unexpectedState_) { if (_contractState == unexpectedState_) { revert ContractState_INCORRECT_STATE(_contractState); } _; } // ************************************** // ************************************** // ***** INTERNAL ***** // ************************************** /** * @dev Internal function setting the contract state to `newState_`. * * Note: Contract state defaults to ``PAUSED``. * To maintain extendability, this value kept as uint8 instead of enum. * As a result, it is possible to set the state to an incorrect value. * To avoid issues, `newState_` should be validated before calling this function */ function _setContractState(uint8 newState_) internal virtual { uint8 _previousState_ = _contractState; _contractState = newState_; emit ContractStateChanged(_previousState_, newState_); } // ************************************** // ************************************** // ***** VIEW ***** // ************************************** /** * @dev Returns the current contract state. * * @return uint8 : the current contract state */ function getContractState() public virtual view override returns (uint8) { return _contractState; } // ************************************** }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; import "../interfaces/IERC173.sol"; import "../interfaces/IERC173Errors.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract ERC173 is IERC173, IERC173Errors { // The owner of the contract address private _owner; // ************************************** // ***** MODIFIER ***** // ************************************** /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { if (owner() != msg.sender) { revert IERC173_NOT_OWNER(msg.sender); } _; } // ************************************** // ************************************** // ***** INTERNAL ***** // ************************************** /** * @dev Sets the contract owner. * * Note: This function needs to be called in the contract constructor to initialize the contract owner, * if it is not, then parts of the contract might be non functional * * @param owner_ : address that owns the contract */ function _setOwner(address owner_) internal { _owner = owner_; } // ************************************** // ************************************** // ***** CONTRACT OWNER ***** // ************************************** /** * @dev Transfers ownership of the contract to `newOwner_`. * * @param newOwner_ : address of the new contract owner * * Requirements: * * - Caller must be the contract owner. */ function transferOwnership(address newOwner_) public virtual onlyOwner { address _oldOwner_ = _owner; _owner = newOwner_; emit OwnershipTransferred(_oldOwner_, newOwner_); } // ************************************** // ************************************** // ***** VIEW ***** // ************************************** /** * @dev Returns the address of the current contract owner. * * @return address : the current contract owner */ function owner() public view virtual returns (address) { return _owner; } // ************************************** }
pragma solidity ^0.8.0; import { RLPReader } from "./RLPReader.sol"; library ExitPayloadReader { using RLPReader for bytes; using RLPReader for RLPReader.RLPItem; uint8 constant WORD_SIZE = 32; struct ExitPayload { RLPReader.RLPItem[] data; } struct Receipt { RLPReader.RLPItem[] data; bytes raw; uint256 logIndex; } struct Log { RLPReader.RLPItem data; RLPReader.RLPItem[] list; } struct LogTopics { RLPReader.RLPItem[] data; } // copy paste of private copy() from RLPReader to avoid changing of existing contracts function copy(uint src, uint dest, uint len) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } // left over bytes. Mask is used to remove unwanted bytes from the word uint mask = 256 ** (WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } function toExitPayload(bytes memory data) internal pure returns (ExitPayload memory) { RLPReader.RLPItem[] memory payloadData = data .toRlpItem() .toList(); return ExitPayload(payloadData); } function getHeaderNumber(ExitPayload memory payload) internal pure returns(uint256) { return payload.data[0].toUint(); } function getBlockProof(ExitPayload memory payload) internal pure returns(bytes memory) { return payload.data[1].toBytes(); } function getBlockNumber(ExitPayload memory payload) internal pure returns(uint256) { return payload.data[2].toUint(); } function getBlockTime(ExitPayload memory payload) internal pure returns(uint256) { return payload.data[3].toUint(); } function getTxRoot(ExitPayload memory payload) internal pure returns(bytes32) { return bytes32(payload.data[4].toUint()); } function getReceiptRoot(ExitPayload memory payload) internal pure returns(bytes32) { return bytes32(payload.data[5].toUint()); } function getReceipt(ExitPayload memory payload) internal pure returns(Receipt memory receipt) { receipt.raw = payload.data[6].toBytes(); RLPReader.RLPItem memory receiptItem = receipt.raw.toRlpItem(); if (receiptItem.isList()) { // legacy tx receipt.data = receiptItem.toList(); } else { // pop first byte before parsting receipt bytes memory typedBytes = receipt.raw; bytes memory result = new bytes(typedBytes.length - 1); uint256 srcPtr; uint256 destPtr; assembly { srcPtr := add(33, typedBytes) destPtr := add(0x20, result) } copy(srcPtr, destPtr, result.length); receipt.data = result.toRlpItem().toList(); } receipt.logIndex = getReceiptLogIndex(payload); return receipt; } function getReceiptProof(ExitPayload memory payload) internal pure returns(bytes memory) { return payload.data[7].toBytes(); } function getBranchMaskAsBytes(ExitPayload memory payload) internal pure returns(bytes memory) { return payload.data[8].toBytes(); } function getBranchMaskAsUint(ExitPayload memory payload) internal pure returns(uint256) { return payload.data[8].toUint(); } function getReceiptLogIndex(ExitPayload memory payload) internal pure returns(uint256) { return payload.data[9].toUint(); } // Receipt methods function toBytes(Receipt memory receipt) internal pure returns(bytes memory) { return receipt.raw; } function getLog(Receipt memory receipt) internal pure returns(Log memory) { RLPReader.RLPItem memory logData = receipt.data[3].toList()[receipt.logIndex]; return Log(logData, logData.toList()); } // Log methods function getEmitter(Log memory log) internal pure returns(address) { return RLPReader.toAddress(log.list[0]); } function getTopics(Log memory log) internal pure returns(LogTopics memory) { return LogTopics(log.list[1].toList()); } function getData(Log memory log) internal pure returns(bytes memory) { return log.list[2].toBytes(); } function toRlpBytes(Log memory log) internal pure returns(bytes memory) { return log.data.toRlpBytes(); } // LogTopics methods function getField(LogTopics memory topics, uint256 index) internal pure returns(RLPReader.RLPItem memory) { return topics.data[index]; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library Merkle { function checkMembership( bytes32 leaf, uint256 index, bytes32 rootHash, bytes memory proof ) internal pure returns (bool) { require(proof.length % 32 == 0, "Invalid proof length"); uint256 proofHeight = proof.length / 32; // Proof of size n means, height of the tree is n+1. // In a tree of height n+1, max #leafs possible is 2 ^ n require(index < 2 ** proofHeight, "Leaf index is too big"); bytes32 proofElement; bytes32 computedHash = leaf; for (uint256 i = 32; i <= proof.length; i += 32) { assembly { proofElement := mload(add(proof, i)) } if (index % 2 == 0) { computedHash = keccak256( abi.encodePacked(computedHash, proofElement) ); } else { computedHash = keccak256( abi.encodePacked(proofElement, computedHash) ); } index = index / 2; } return computedHash == rootHash; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {RLPReader} from "./RLPReader.sol"; library MerklePatriciaProof { /* * @dev Verifies a merkle patricia proof. * @param value The terminating value in the trie. * @param encodedPath The path in the trie leading to value. * @param rlpParentNodes The rlp encoded stack of nodes. * @param root The root hash of the trie. * @return The boolean validity of the proof. */ function verify( bytes memory value, bytes memory encodedPath, bytes memory rlpParentNodes, bytes32 root ) internal pure returns (bool) { RLPReader.RLPItem memory item = RLPReader.toRlpItem(rlpParentNodes); RLPReader.RLPItem[] memory parentNodes = RLPReader.toList(item); bytes memory currentNode; RLPReader.RLPItem[] memory currentNodeList; bytes32 nodeKey = root; uint256 pathPtr = 0; bytes memory path = _getNibbleArray(encodedPath); if (path.length == 0) { return false; } for (uint256 i = 0; i < parentNodes.length; i++) { if (pathPtr > path.length) { return false; } currentNode = RLPReader.toRlpBytes(parentNodes[i]); if (nodeKey != keccak256(currentNode)) { return false; } currentNodeList = RLPReader.toList(parentNodes[i]); if (currentNodeList.length == 17) { if (pathPtr == path.length) { if ( keccak256(RLPReader.toBytes(currentNodeList[16])) == keccak256(value) ) { return true; } else { return false; } } uint8 nextPathNibble = uint8(path[pathPtr]); if (nextPathNibble > 16) { return false; } nodeKey = bytes32( RLPReader.toUintStrict(currentNodeList[nextPathNibble]) ); pathPtr += 1; } else if (currentNodeList.length == 2) { uint256 traversed = _nibblesToTraverse( RLPReader.toBytes(currentNodeList[0]), path, pathPtr ); if (pathPtr + traversed == path.length) { //leaf node if ( keccak256(RLPReader.toBytes(currentNodeList[1])) == keccak256(value) ) { return true; } else { return false; } } //extension node if (traversed == 0) { return false; } pathPtr += traversed; nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[1])); } else { return false; } } } function _nibblesToTraverse( bytes memory encodedPartialPath, bytes memory path, uint256 pathPtr ) private pure returns (uint256) { uint256 len = 0; // encodedPartialPath has elements that are each two hex characters (1 byte), but partialPath // and slicedPath have elements that are each one hex character (1 nibble) bytes memory partialPath = _getNibbleArray(encodedPartialPath); bytes memory slicedPath = new bytes(partialPath.length); // pathPtr counts nibbles in path // partialPath.length is a number of nibbles for (uint256 i = pathPtr; i < pathPtr + partialPath.length; i++) { bytes1 pathNibble = path[i]; slicedPath[i - pathPtr] = pathNibble; } if (keccak256(partialPath) == keccak256(slicedPath)) { len = partialPath.length; } else { len = 0; } return len; } // bytes b must be hp encoded function _getNibbleArray(bytes memory b) internal pure returns (bytes memory) { bytes memory nibbles = ""; if (b.length > 0) { uint8 offset; uint8 hpNibble = uint8(_getNthNibbleOfBytes(0, b)); if (hpNibble == 1 || hpNibble == 3) { nibbles = new bytes(b.length * 2 - 1); bytes1 oddNibble = _getNthNibbleOfBytes(1, b); nibbles[0] = oddNibble; offset = 1; } else { nibbles = new bytes(b.length * 2 - 2); offset = 0; } for (uint256 i = offset; i < nibbles.length; i++) { nibbles[i] = _getNthNibbleOfBytes(i - offset + 2, b); } } return nibbles; } function _getNthNibbleOfBytes(uint256 n, bytes memory str) private pure returns (bytes1) { return bytes1( n % 2 == 0 ? uint8(str[n / 2]) / 0x10 : uint8(str[n / 2]) % 0x10 ); } }
/* * @author Hamdi Allam [email protected] * Please reach out with any questions or concerns */ pragma solidity ^0.8.0; library RLPReader { uint8 constant STRING_SHORT_START = 0x80; uint8 constant STRING_LONG_START = 0xb8; uint8 constant LIST_SHORT_START = 0xc0; uint8 constant LIST_LONG_START = 0xf8; uint8 constant WORD_SIZE = 32; struct RLPItem { uint len; uint memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint nextPtr; // Position of the next item in the list. } /* * @dev Returns the next element in the iteration. Reverts if it has not next element. * @param self The iterator. * @return The next element in the iteration. */ function next(Iterator memory self) internal pure returns (RLPItem memory) { require(hasNext(self)); uint ptr = self.nextPtr; uint itemLength = _itemLength(ptr); self.nextPtr = ptr + itemLength; return RLPItem(itemLength, ptr); } /* * @dev Returns true if the iteration has more elements. * @param self The iterator. * @return true if the iteration has more elements. */ function hasNext(Iterator memory self) internal pure returns (bool) { RLPItem memory item = self.item; return self.nextPtr < item.memPtr + item.len; } /* * @param item RLP encoded bytes */ function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) { uint memPtr; assembly { memPtr := add(item, 0x20) } return RLPItem(item.length, memPtr); } /* * @dev Create an iterator. Reverts if item is not a list. * @param self The RLP item. * @return An 'Iterator' over the item. */ function iterator(RLPItem memory self) internal pure returns (Iterator memory) { require(isList(self)); uint ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param item RLP encoded bytes */ function rlpLen(RLPItem memory item) internal pure returns (uint) { return item.len; } /* * @param item RLP encoded bytes */ function payloadLen(RLPItem memory item) internal pure returns (uint) { return item.len - _payloadOffset(item.memPtr); } /* * @param item RLP encoded list in bytes */ function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item)); uint items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint memPtr = item.memPtr + _payloadOffset(item.memPtr); uint dataLen; for (uint i = 0; i < items; i++) { dataLen = _itemLength(memPtr); result[i] = RLPItem(dataLen, memPtr); memPtr = memPtr + dataLen; } return result; } // @return indicator whether encoded payload is a list. negate this function call for isData. function isList(RLPItem memory item) internal pure returns (bool) { if (item.len == 0) return false; uint8 byte0; uint memPtr = item.memPtr; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < LIST_SHORT_START) return false; return true; } /* * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory. * @return keccak256 hash of RLP encoded bytes. */ function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) { uint256 ptr = item.memPtr; uint256 len = item.len; bytes32 result; assembly { result := keccak256(ptr, len) } return result; } function payloadLocation(RLPItem memory item) internal pure returns (uint, uint) { uint offset = _payloadOffset(item.memPtr); uint memPtr = item.memPtr + offset; uint len = item.len - offset; // data length return (memPtr, len); } /* * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory. * @return keccak256 hash of the item payload. */ function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) { (uint memPtr, uint len) = payloadLocation(item); bytes32 result; assembly { result := keccak256(memPtr, len) } return result; } /** RLPItem conversions into data types **/ // @returns raw rlp encoding in bytes function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) { bytes memory result = new bytes(item.len); if (result.length == 0) return result; uint ptr; assembly { ptr := add(0x20, result) } copy(item.memPtr, ptr, item.len); return result; } // any non-zero byte is considered true function toBoolean(RLPItem memory item) internal pure returns (bool) { require(item.len == 1); uint result; uint memPtr = item.memPtr; assembly { result := byte(0, mload(memPtr)) } return result == 0 ? false : true; } function toAddress(RLPItem memory item) internal pure returns (address) { // 1 byte for the length prefix require(item.len == 21); return address(uint160(toUint(item))); } function toUint(RLPItem memory item) internal pure returns (uint) { require(item.len > 0 && item.len <= 33); uint offset = _payloadOffset(item.memPtr); uint len = item.len - offset; uint result; uint memPtr = item.memPtr + offset; assembly { result := mload(memPtr) // shfit to the correct location if neccesary if lt(len, 32) { result := div(result, exp(256, sub(32, len))) } } return result; } // enforces 32 byte length function toUintStrict(RLPItem memory item) internal pure returns (uint) { // one byte prefix require(item.len == 33); uint result; uint memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); uint offset = _payloadOffset(item.memPtr); uint len = item.len - offset; // data length bytes memory result = new bytes(len); uint destPtr; assembly { destPtr := add(0x20, result) } copy(item.memPtr + offset, destPtr, len); return result; } /* * Private Helpers */ // @return number of payload items inside an encoded list. function numItems(RLPItem memory item) private pure returns (uint) { if (item.len == 0) return 0; uint count = 0; uint currPtr = item.memPtr + _payloadOffset(item.memPtr); uint endPtr = item.memPtr + item.len; while (currPtr < endPtr) { currPtr = currPtr + _itemLength(currPtr); // skip over an item count++; } return count; } // @return entire rlp item byte length function _itemLength(uint memPtr) private pure returns (uint) { uint itemLen; uint byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) itemLen = 1; else if (byte0 < STRING_LONG_START) itemLen = byte0 - STRING_SHORT_START + 1; else if (byte0 < LIST_SHORT_START) { assembly { let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is memPtr := add(memPtr, 1) // skip over the first byte /* 32 byte word size */ let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len itemLen := add(dataLen, add(byteLen, 1)) } } else if (byte0 < LIST_LONG_START) { itemLen = byte0 - LIST_SHORT_START + 1; } else { assembly { let byteLen := sub(byte0, 0xf7) memPtr := add(memPtr, 1) let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length itemLen := add(dataLen, add(byteLen, 1)) } } return itemLen; } // @return number of bytes until the data function _payloadOffset(uint memPtr) private pure returns (uint) { uint byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) return 0; else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) return 1; else if (byte0 < LIST_SHORT_START) // being explicit return byte0 - (STRING_LONG_START - 1) + 1; else return byte0 - (LIST_LONG_START - 1) + 1; } /* * @param src Pointer to source * @param dest Pointer to destination * @param len Amount of memory to copy from the source */ function copy(uint src, uint dest, uint len) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } if (len == 0) return; // left over bytes. Mask is used to remove unwanted bytes from the word uint mask = 256 ** (WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {RLPReader} from "../lib/RLPReader.sol"; import {MerklePatriciaProof} from "../lib/MerklePatriciaProof.sol"; import {Merkle} from "../lib/Merkle.sol"; import "../lib/ExitPayloadReader.sol"; interface IFxStateSender { function sendMessageToChild(address _receiver, bytes calldata _data) external; } contract ICheckpointManager { struct HeaderBlock { bytes32 root; uint256 start; uint256 end; uint256 createdAt; address proposer; } /** * @notice mapping of checkpoint header numbers to block details * @dev These checkpoints are submited by plasma contracts */ mapping(uint256 => HeaderBlock) public headerBlocks; } abstract contract FxBaseRootTunnel { using RLPReader for RLPReader.RLPItem; using Merkle for bytes32; using ExitPayloadReader for bytes; using ExitPayloadReader for ExitPayloadReader.ExitPayload; using ExitPayloadReader for ExitPayloadReader.Log; using ExitPayloadReader for ExitPayloadReader.LogTopics; using ExitPayloadReader for ExitPayloadReader.Receipt; // keccak256(MessageSent(bytes)) bytes32 public constant SEND_MESSAGE_EVENT_SIG = 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036; // state sender contract IFxStateSender public fxRoot; // root chain manager ICheckpointManager public checkpointManager; // child tunnel contract which receives and sends messages address public fxChildTunnel; // storage to avoid duplicate exits mapping(bytes32 => bool) public processedExits; constructor(address _checkpointManager, address _fxRoot) { checkpointManager = ICheckpointManager(_checkpointManager); fxRoot = IFxStateSender(_fxRoot); } // set fxChildTunnel if not set already function setFxChildTunnel(address _fxChildTunnel) public { require(fxChildTunnel == address(0x0), "FxBaseRootTunnel: CHILD_TUNNEL_ALREADY_SET"); fxChildTunnel = _fxChildTunnel; } /** * @notice Send bytes message to Child Tunnel * @param message bytes message that will be sent to Child Tunnel * some message examples - * abi.encode(tokenId); * abi.encode(tokenId, tokenMetadata); * abi.encode(messageType, messageData); */ function _sendMessageToChild(bytes memory message) internal { fxRoot.sendMessageToChild(fxChildTunnel, message); } function _validateAndExtractMessage(bytes memory inputData) internal returns (bytes memory) { ExitPayloadReader.ExitPayload memory payload = inputData.toExitPayload(); bytes memory branchMaskBytes = payload.getBranchMaskAsBytes(); uint256 blockNumber = payload.getBlockNumber(); // checking if exit has already been processed // unique exit is identified using hash of (blockNumber, branchMask, receiptLogIndex) bytes32 exitHash = keccak256( abi.encodePacked( blockNumber, // first 2 nibbles are dropped while generating nibble array // this allows branch masks that are valid but bypass exitHash check (changing first 2 nibbles only) // so converting to nibble array and then hashing it MerklePatriciaProof._getNibbleArray(branchMaskBytes), payload.getReceiptLogIndex() ) ); require( processedExits[exitHash] == false, "FxRootTunnel: EXIT_ALREADY_PROCESSED" ); processedExits[exitHash] = true; ExitPayloadReader.Receipt memory receipt = payload.getReceipt(); ExitPayloadReader.Log memory log = receipt.getLog(); // check child tunnel require(fxChildTunnel == log.getEmitter(), "FxRootTunnel: INVALID_FX_CHILD_TUNNEL"); bytes32 receiptRoot = payload.getReceiptRoot(); // verify receipt inclusion require( MerklePatriciaProof.verify( receipt.toBytes(), branchMaskBytes, payload.getReceiptProof(), receiptRoot ), "FxRootTunnel: INVALID_RECEIPT_PROOF" ); // verify checkpoint inclusion _checkBlockMembershipInCheckpoint( blockNumber, payload.getBlockTime(), payload.getTxRoot(), receiptRoot, payload.getHeaderNumber(), payload.getBlockProof() ); ExitPayloadReader.LogTopics memory topics = log.getTopics(); require( bytes32(topics.getField(0).toUint()) == SEND_MESSAGE_EVENT_SIG, // topic0 is event sig "FxRootTunnel: INVALID_SIGNATURE" ); // received message data (bytes memory message) = abi.decode(log.getData(), (bytes)); // event decodes params again, so decoding bytes to get message return message; } function _checkBlockMembershipInCheckpoint( uint256 blockNumber, uint256 blockTime, bytes32 txRoot, bytes32 receiptRoot, uint256 headerNumber, bytes memory blockProof ) private view returns (uint256) { ( bytes32 headerRoot, uint256 startBlock, , uint256 createdAt, ) = checkpointManager.headerBlocks(headerNumber); require( keccak256( abi.encodePacked(blockNumber, blockTime, txRoot, receiptRoot) ) .checkMembership( blockNumber-startBlock, headerRoot, blockProof ), "FxRootTunnel: INVALID_HEADER" ); return createdAt; } /** * @notice receive message from L2 to L1, validated by proof * @dev This function verifies if the transaction actually happened on child chain * * @param inputData RLP encoded data of the reference tx containing following list of fields * 0 - headerNumber - Checkpoint header block number containing the reference tx * 1 - blockProof - Proof that the block header (in the child chain) is a leaf in the submitted merkle root * 2 - blockNumber - Block number containing the reference tx on child chain * 3 - blockTime - Reference tx block time * 4 - txRoot - Transactions root of block * 5 - receiptRoot - Receipts root of block * 6 - receipt - Receipt of the reference transaction * 7 - receiptProof - Merkle proof of the reference receipt * 8 - branchMask - 32 bits denoting the path of receipt in merkle tree * 9 - receiptLogIndex - Log Index to read from the receipt */ function receiveMessage(bytes memory inputData) public virtual { bytes memory message = _validateAndExtractMessage(inputData); _processMessageFromChild(message); } /** * @notice Process message received from Child Tunnel * @dev function needs to be implemented to handle message as per requirement * This is called by onStateReceive function. * Since it is called via a system call, any event will not be emitted during its execution. * @param message bytes message that was sent from Child Tunnel */ function _processMessageFromChild(bytes memory message) virtual internal; }
{ "viaIR": false, "optimizer": { "enabled": true, "runs": 10000 }, "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":"nucyberContractAddress_","type":"address"},{"internalType":"address","name":"cpManager_","type":"address"},{"internalType":"address","name":"fxRoot_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ARRAY_LENGTH_MISMATCH","type":"error"},{"inputs":[{"internalType":"uint8","name":"currentState","type":"uint8"}],"name":"ContractState_INCORRECT_STATE","type":"error"},{"inputs":[{"internalType":"uint8","name":"invalidState","type":"uint8"}],"name":"ContractState_INVALID_STATE","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"IERC173_NOT_OWNER","type":"error"},{"inputs":[],"name":"NCS_REWARDS_NOT_SET","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"NCS_TOKEN_NOT_OWNED","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"}],"name":"BenefitEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"}],"name":"BenefitStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"previousState","type":"uint8"},{"indexed":true,"internalType":"uint8","name":"newState","type":"uint8"}],"name":"ContractStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"ACTIVE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSED","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEND_MESSAGE_EVENT_SIG","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner_","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"balanceOfBenefit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"balanceOfStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds_","type":"uint256[]"},{"internalType":"address[]","name":"beneficiaries_","type":"address[]"}],"name":"bulkStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds_","type":"uint256[]"}],"name":"bulkUnstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkpointManager","outputs":[{"internalType":"contract ICheckpointManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fxChildTunnel","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fxRoot","outputs":[{"internalType":"contract IFxStateSender","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractState","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nuCyber","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"processedExits","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"inputData","type":"bytes"}],"name":"receiveMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"newState_","type":"uint8"}],"name":"setContractState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fxChildTunnel","type":"address"}],"name":"setFxChildTunnel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress_","type":"address"}],"name":"setNuCyberContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"address","name":"beneficiary_","type":"address"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner_","type":"address"}],"name":"stakedTokens","outputs":[{"components":[{"internalType":"uint64","name":"tokenId","type":"uint64"},{"internalType":"address","name":"beneficiary","type":"address"}],"internalType":"struct NuCyberStaking.StakedToken[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner_","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"address","name":"newBeneficiary_","type":"address"}],"name":"updateBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fxChildTunnel_","type":"address"}],"name":"updateFxChildTunnel","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620035df380380620035df8339810160408190526200003491620000af565b600280546001600160a01b03199081166001600160a01b03858116919091179092556001805482168484161790556005805490911691851691909117905560008054610100600160a81b0319166101003302179055505050620000f9565b80516001600160a01b0381168114620000aa57600080fd5b919050565b600080600060608486031215620000c557600080fd5b620000d08462000092565b9250620000e06020850162000092565b9150620000f06040850162000092565b90509250925092565b6134d680620001096000396000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c8063972c4928116100ee578063c0857ba011610097578063de9b771f11610071578063de9b771f14610394578063f2fde38b146103a7578063f7b4c187146103ba578063f953cec7146103cd57600080fd5b8063c0857ba014610366578063c10ce94d14610379578063c90bd0471461038c57600080fd5b8063ab563dc5116100c8578063ab563dc51461032d578063aea4e49e14610340578063aeb339131461035357600080fd5b8063972c4928146102f2578063a5b39cfb14610305578063a9aad58c1461032557600080fd5b8063607f2d42116101505780637acb77571161012a5780637acb77571461029c5780637f4e4849146102af5780638da5cb5b146102c857600080fd5b8063607f2d42146102435780636e0777411461027657806370a082311461028957600080fd5b80633455f41e116101815780633455f41e1461020a5780633e8eb5a41461021d578063568fae8a1461023057600080fd5b80630292199f146101a85780630e387de6146101bd5780632e17de78146101f7575b600080fd5b6101bb6101b6366004612bdd565b6103e0565b005b6101e47f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b6040519081526020015b60405180910390f35b6101bb610205366004612bfa565b61046b565b6101e4610218366004612bdd565b610485565b6101bb61022b366004612c13565b6104a5565b6101bb61023e366004612d52565b6105a6565b610266610251366004612bfa565b60046020526000908152604090205460ff1681565b60405190151581526020016101ee565b6101bb610284366004612bdd565b6105ef565b6101e4610297366004612bdd565b610675565b6101bb6102aa366004612c13565b610742565b60005460ff165b60405160ff90911681526020016101ee565b60005461010090046001600160a01b03165b6040516001600160a01b0390911681526020016101ee565b6003546102da906001600160a01b031681565b610318610313366004612bdd565b6107ea565b6040516101ee9190612d87565b6102b6600081565b6101bb61033b366004612de9565b610882565b6101bb61034e366004612bdd565b6109a6565b6101e4610361366004612bdd565b610a3f565b6002546102da906001600160a01b031681565b6005546102da906001600160a01b031681565b6102b6600181565b6001546102da906001600160a01b031681565b6101bb6103b5366004612bdd565b610a5d565b6101bb6103c8366004612eb8565b610b19565b6101bb6103db366004612f21565b610bb1565b6000546001600160a01b03610100909104163314610431576040517f55932a1b0000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6104753382610bbc565b6104823360016000610f2f565b50565b6001600160a01b0381166000908152600660205260408120545b92915050565b6000806104b23385610f82565b33600090815260066020526040902080549294509092508491839081106104db576104db612fa7565b60009182526020918290200180547fffffffff0000000000000000000000000000000000000000ffffffffffffffff16680100000000000000006001600160a01b0394851602179055830151161561053b5761053b8260200151856110ba565b6001600160a01b038316156105a0576001600160a01b038316600081815260076020908152604080832080546001810182559084529183209091018790555186917fe0e8b8961e9f558e2bc7536b6a59f335a7c0a95e001d7332b1f707962d07a76891a35b50505050565b80515b80156105de57806001900390506105d9338383815181106105cc576105cc612fa7565b6020026020010151610bbc565b6105a9565b6105eb3383516000610f2f565b5050565b6000546001600160a01b0361010090910416331461063b576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610428565b600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6001600160a01b0381166000908152600760205260408120546001600160a01b0383166000908152600660205260409020546005546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152909116906370a0823190602401602060405180830381865afa15801561070a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072e9190612fd6565b610738919061301e565b61049f919061301e565b60005460019060ff16811461078c576000546040517f5d80b9ec00000000000000000000000000000000000000000000000000000000815260ff9091166004820152602401610428565b6003546001600160a01b03166107ce576040517f31cd21c000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107d9338484611271565b6107e533600180610f2f565b505050565b6001600160a01b0381166000908152600660209081526040808320805482518185028101850190935280835260609492939192909184015b82821015610877576000848152602090819020604080518082019091529084015467ffffffffffffffff811682526801000000000000000090046001600160a01b031681830152825260019092019101610822565b505050509050919050565b60005460019060ff1681146108cc576000546040517f5d80b9ec00000000000000000000000000000000000000000000000000000000815260ff9091166004820152602401610428565b6003546001600160a01b031661090e576040517f31cd21c000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82518251811461094a576040517f88adebd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801561099957806001900390506109943385838151811061096d5761096d612fa7565b602002602001015185848151811061098757610987612fa7565b6020026020010151611271565b61094a565b6105a03385516001610f2f565b6003546001600160a01b031615610431576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f467842617365526f6f7454756e6e656c3a204348494c445f54554e4e454c5f4160448201527f4c52454144595f534554000000000000000000000000000000000000000000006064820152608401610428565b6001600160a01b03811660009081526007602052604081205461049f565b6000546001600160a01b03610100909104163314610aa9576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610428565b600080546001600160a01b038381166101008181027fffffffffffffffffffffff0000000000000000000000000000000000000000ff851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b6000546001600160a01b03610100909104163314610b65576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610428565b600160ff82161115610ba8576040517fb81f899300000000000000000000000000000000000000000000000000000000815260ff82166004820152602401610428565b610482816113e3565b60006107e582611445565b6001600160a01b0382166000908152600660205260408120549081905b8115610e05576001600160a01b038516600090815260066020526040902080546000199093019285919084908110610c1357610c13612fa7565b60009182526020909120015467ffffffffffffffff1603610e00576001600160a01b0385166000908152600660205260408120805484908110610c5857610c58612fa7565b6000918252602090912001546801000000000000000090046001600160a01b031690508015610c8b57610c8b81866110ba565b610c96600185613031565b8314610d99576001600160a01b0386166000908152600660205260409020610cbf600186613031565b81548110610ccf57610ccf612fa7565b9060005260206000200160066000886001600160a01b03166001600160a01b031681526020019081526020016000208481548110610d0f57610d0f612fa7565b6000918252602090912082549101805467ffffffffffffffff9092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000083168117825592547fffffffff0000000000000000000000000000000000000000000000000000000090921690921768010000000000000000918290046001600160a01b03169091021790555b6001600160a01b0386166000908152600660205260409020805480610dc057610dc0613044565b600082815260209020810160001990810180547fffffffff0000000000000000000000000000000000000000000000000000000016905501905550600190505b610bd9565b80610e3f576040517fb8cd55d500000000000000000000000000000000000000000000000000000000815260048101859052602401610428565b6005546040517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03878116602483015260448201879052909116906323b872dd90606401600060405180830381600087803b158015610eac57600080fd5b505af1925050508015610ebd575060015b610f2857610ec9613073565b806308c379a003610f1c5750610edd61308f565b80610ee85750610f1e565b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610428919061319a565b505b3d6000803e3d6000fd5b5050505050565b61ffff8216156107e557604080516001600160a01b038516602082015260019181019190915261ffff8316606082015281151560808201526107e59060a00160405160208183030381529060405261181a565b60408051808201909152600080825260208201526001600160a01b0383166000908152600660205260408120545b801561107e576001600160a01b038516600090815260066020526040902080546000199092019185919083908110610fea57610fea612fa7565b60009182526020909120015467ffffffffffffffff1603611079576001600160a01b038516600090815260066020526040902080548290811061102f5761102f612fa7565b60009182526020918290206040805180820190915291015467ffffffffffffffff811682526801000000000000000090046001600160a01b031691810191909152925090506110b3565b610fb0565b6040517fb8cd55d500000000000000000000000000000000000000000000000000000000815260048101859052602401610428565b9250929050565b6001600160a01b0382166000908152600760205260408120549081905b81156111fa576001600160a01b03851660009081526007602052604090208054600019909301928591908490811061111157611111612fa7565b9060005260206000200154036111f55761112c600184613031565b82146111b3576001600160a01b0385166000908152600760205260409020611155600185613031565b8154811061116557611165612fa7565b906000526020600020015460076000876001600160a01b03166001600160a01b0316815260200190815260200160002083815481106111a6576111a6612fa7565b6000918252602090912001555b6001600160a01b03851660009081526007602052604090208054806111da576111da613044565b60019003818190600052602060002001600090559055600190505b6110d7565b80611234576040517fb8cd55d500000000000000000000000000000000000000000000000000000000815260048101859052602401610428565b6040516001600160a01b0386169085907f137032969b3eef1e583f6869378c3ae25f0497c0b96ca1bce52b708782fb49cc90600090a35050505050565b6001600160a01b038084166000908152600660209081526040808320815180830190925267ffffffffffffffff80881683528686168385018181528354600181018555938752949095209251929091018054935190951668010000000000000000027fffffffff000000000000000000000000000000000000000000000000000000009093169116171790915515611359576001600160a01b038116600081815260076020908152604080832080546001810182559084529183209091018590555184917fe0e8b8961e9f558e2bc7536b6a59f335a7c0a95e001d7332b1f707962d07a76891a35b6005546040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015230602483015260448201859052909116906323b872dd90606401600060405180830381600087803b1580156113c657600080fd5b505af19250505080156113d7575060015b6107e557610ec9613073565b6000805460ff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00831681178455604051919092169283917f7285522ec93a20dcefa1a1d057094a227073a5463b91c0c19a23c6ef5c9c1fe49190a35050565b6060600061145283611897565b9050600061145f826118f6565b9050600061146c8361191f565b905060008161147a84611948565b61148386611b36565b604051602001611495939291906131ad565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff161561156a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f53534544000000000000000000000000000000000000000000000000000000006064820152608401610428565b600081815260046020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556115aa85611b52565b905060006115b782611c9c565b90506115c281611d2c565b6003546001600160a01b0390811691161461165f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c0000000000000000000000000000000000000000000000000000006064820152608401610428565b600061166a87611d55565b905061168a61167a846020015190565b876116848a611d71565b84611d8d565b611716576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f4600000000000000000000000000000000000000000000000000000000006064820152608401610428565b6117448561172389612040565b61172c8a61205c565b846117368c612078565b61173f8d612094565b6120b0565b50600061175083612209565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036611786611781836000612245565b61227d565b146117ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e4154555245006044820152606401610428565b60006117f8846122f8565b80602001905181019061180b91906131da565b9b9a5050505050505050505050565b6001546003546040517fb47204770000000000000000000000000000000000000000000000000000000081526001600160a01b039283169263b47204779261186992911690859060040161325c565b600060405180830381600087803b15801561188357600080fd5b505af1158015610f28573d6000803e3d6000fd5b60408051602081019091526060815260006118e16118dc8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b612314565b60408051602081019091529081529392505050565b606061049f826000015160088151811061191257611912612fa7565b602002602001015161242a565b600061049f826000015160028151811061193b5761193b612fa7565b602002602001015161227d565b6040805160208101909152600081528151606091901561049f576000806119706000866124c7565b60f81c9050600181148061198757508060ff166003145b15611a475760018551600261199c919061327e565b6119a69190613031565b67ffffffffffffffff8111156119be576119be612c43565b6040519080825280601f01601f1916602001820160405280156119e8576020820181803683370190505b50925060006119f86001876124c7565b90508084600081518110611a0e57611a0e612fa7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001925050611aab565b600285516002611a57919061327e565b611a619190613031565b67ffffffffffffffff811115611a7957611a79612c43565b6040519080825280601f01601f191660200182016040528015611aa3576020820181803683370190505b509250600091505b60ff82165b8351811015611b2d57611ada611ac960ff851683613031565b611ad490600261301e565b876124c7565b848281518110611aec57611aec612fa7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080611b2581613295565b915050611ab0565b50505092915050565b600061049f826000015160098151811061193b5761193b612fa7565b611b7660405180606001604052806060815260200160608152602001600081525090565b611b90826000015160068151811061191257611912612fa7565b602082810182905260408051808201825260008082529083015280518082019091528251815291810190820152611bc681612548565b15611bdb57611bd481612314565b8252611c88565b60208201518051600090611bf190600190613031565b67ffffffffffffffff811115611c0957611c09612c43565b6040519080825280601f01601f191660200182016040528015611c33576020820181803683370190505b509050600080836021019150826020019050611c5182828551612583565b604080518082018252600080825260209182015281518083019092528451825280850190820152611c8190612314565b8652505050505b611c9183611b36565b604083015250919050565b604080516080810182526000918101828152606080830193909352815260208101919091526000611cea8360000151600381518110611cdd57611cdd612fa7565b6020026020010151612314565b836040015181518110611cff57611cff612fa7565b602002602001015190506040518060400160405280828152602001611d2383612314565b90529392505050565b600061049f8260200151600081518110611d4857611d48612fa7565b6020026020010151612601565b600061049f826000015160058151811061193b5761193b612fa7565b606061049f826000015160078151811061191257611912612fa7565b600080611dc18460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b90506000611dce82612314565b905060608085600080611de08b611948565b90508051600003611dfb576000975050505050505050612038565b60005b865181101561202f578151831115611e2157600098505050505050505050612038565b611e43878281518110611e3657611e36612fa7565b602002602001015161261b565b955085805190602001208414611e6457600098505050505050505050612038565b611e79878281518110611cdd57611cdd612fa7565b94508451601103611f4b5781518303611ed8578c80519060200120611eaa8660108151811061191257611912612fa7565b8051906020012003611ec757600198505050505050505050612038565b600098505050505050505050612038565b6000828481518110611eec57611eec612fa7565b016020015160f81c90506010811115611f115760009950505050505050505050612038565b611f36868260ff1681518110611f2957611f29612fa7565b602002602001015161269a565b9450611f4360018561301e565b93505061201d565b8451600203611ec7576000611f76611f6f8760008151811061191257611912612fa7565b84866126c8565b8351909150611f85828661301e565b03611fd8578d80519060200120611fa88760018151811061191257611912612fa7565b8051906020012003611fc65760019950505050505050505050612038565b60009950505050505050505050612038565b80600003611ff25760009950505050505050505050612038565b611ffc818561301e565b935061201486600181518110611f2957611f29612fa7565b945061201d9050565b8061202781613295565b915050611dfe565b50505050505050505b949350505050565b600061049f826000015160038151811061193b5761193b612fa7565b600061049f826000015160048151811061193b5761193b612fa7565b600061049f826000015160008151811061193b5761193b612fa7565b606061049f826000015160018151811061191257611912612fa7565b6002546040517f41539d4a000000000000000000000000000000000000000000000000000000008152600481018490526000918291829182916001600160a01b03909116906341539d4a9060240160a060405180830381865afa15801561211b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061213f91906132af565b5093505092509250612196828b6121569190613031565b6040805160208082018f90528183018e9052606082018d905260808083018d90528351808403909101815260a09092019092528051910120908588612800565b6121fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f484541444552000000006044820152606401610428565b9998505050505050505050565b604080516020810190915260608152604051806020016040528061223d8460200151600181518110611cdd57611cdd612fa7565b905292915050565b6040805180820190915260008082526020820152825180518390811061226d5761226d612fa7565b6020026020010151905092915050565b80516000901580159061229257508151602110155b61229b57600080fd5b60006122aa83602001516129ad565b905060008184600001516122be9190613031565b90506000808386602001516122d3919061301e565b90508051915060208310156122ef57826020036101000a820491505b50949350505050565b606061049f826020015160028151811061191257611912612fa7565b606061231f82612548565b61232857600080fd5b600061233383612a2f565b905060008167ffffffffffffffff81111561235057612350612c43565b60405190808252806020026020018201604052801561239557816020015b604080518082019091526000808252602082015281526020019060019003908161236e5790505b50905060006123a785602001516129ad565b85602001516123b6919061301e565b90506000805b8481101561241f576123cd83612ab4565b91506040518060400160405280838152602001848152508482815181106123f6576123f6612fa7565b602090810291909101015261240b828461301e565b92508061241781613295565b9150506123bc565b509195945050505050565b805160609061243857600080fd5b600061244783602001516129ad565b9050600081846000015161245b9190613031565b905060008167ffffffffffffffff81111561247857612478612c43565b6040519080825280601f01601f1916602001820160405280156124a2576020820181803683370190505b50905060008160200190506122ef8487602001516124c0919061301e565b8285612b76565b60006124d460028461332b565b1561250e576010826124e760028661333f565b815181106124f7576124f7612fa7565b0160200151612509919060f81c613353565b61253e565b60108261251c60028661333f565b8151811061252c5761252c612fa7565b016020015161253e919060f81c613375565b60f81b9392505050565b8051600090810361255b57506000919050565b6020820151805160001a9060c0821015612579575060009392505050565b5060019392505050565b8060000361259057505050565b602081106125c857825182526125a760208461301e565b92506125b460208361301e565b91506125c1602082613031565b9050612590565b600060016125d7836020613031565b6125e39061010061347b565b6125ed9190613031565b935183518516941916939093179091525050565b805160009060151461261257600080fd5b61049f8261227d565b60606000826000015167ffffffffffffffff81111561263c5761263c612c43565b6040519080825280601f01601f191660200182016040528015612666576020820181803683370190505b50905080516000036126785792915050565b60008160200190506126938460200151828660000151612b76565b5092915050565b80516000906021146126ab57600080fd5b600080836020015160016126bf919061301e565b51949350505050565b600080806126d586611948565b90506000815167ffffffffffffffff8111156126f3576126f3612c43565b6040519080825280601f01601f19166020018201604052801561271d576020820181803683370190505b509050845b825161272e908761301e565b8110156127d157600087828151811061274957612749612fa7565b01602001517fff00000000000000000000000000000000000000000000000000000000000000169050808361277e8985613031565b8151811061278e5761278e612fa7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505080806127c990613295565b915050612722565b5080805190602001208280519060200120036127f057815192506127f5565b600092505b509095945050505050565b600060208251612810919061332b565b15612877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e76616c69642070726f6f66206c656e6774680000000000000000000000006044820152606401610428565b600060208351612887919061333f565b905061289481600261347b565b85106128fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4c65616620696e64657820697320746f6f2062696700000000000000000000006044820152606401610428565b60008660205b8551811161299f5785810151925061291b60028961332b565b600003612953576040805160208101849052908101849052606001604051602081830303815290604052805190602001209150612980565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b61298b60028961333f565b975061299860208261301e565b9050612902565b509094149695505050505050565b8051600090811a60808110156129c65750600092915050565b60b88110806129e1575060c081108015906129e1575060f881105b156129ef5750600192915050565b60c0811015612a2357612a04600160b8613487565b612a119060ff1682613031565b612a1c90600161301e565b9392505050565b612a04600160f8613487565b80516000908103612a4257506000919050565b600080612a5284602001516129ad565b8460200151612a61919061301e565b9050600084600001518560200151612a79919061301e565b90505b80821015612aab57612a8d82612ab4565b612a97908361301e565b915082612aa381613295565b935050612a7c565b50909392505050565b80516000908190811a6080811015612acf5760019150612693565b60b8811015612af557612ae3608082613031565b612aee90600161301e565b9150612693565b60c0811015612b225760b78103600185019450806020036101000a85510460018201810193505050612693565b60f8811015612b3657612ae360c082613031565b60019390930151602084900360f7016101000a90049092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a0192915050565b80600003612b8357505050565b60208110612bbb5782518252612b9a60208461301e565b9250612ba760208361301e565b9150612bb4602082613031565b9050612b83565b806000036125c857505050565b6001600160a01b038116811461048257600080fd5b600060208284031215612bef57600080fd5b8135612a1c81612bc8565b600060208284031215612c0c57600080fd5b5035919050565b60008060408385031215612c2657600080fd5b823591506020830135612c3881612bc8565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116810181811067ffffffffffffffff82111715612cb657612cb6612c43565b6040525050565b600067ffffffffffffffff821115612cd757612cd7612c43565b5060051b60200190565b600082601f830112612cf257600080fd5b81356020612cff82612cbd565b604051612d0c8282612c72565b83815260059390931b8501820192828101915086841115612d2c57600080fd5b8286015b84811015612d475780358352918301918301612d30565b509695505050505050565b600060208284031215612d6457600080fd5b813567ffffffffffffffff811115612d7b57600080fd5b61203884828501612ce1565b602080825282518282018190526000919060409081850190868401855b82811015612ddc578151805167ffffffffffffffff1685528601516001600160a01b0316868501529284019290850190600101612da4565b5091979650505050505050565b60008060408385031215612dfc57600080fd5b823567ffffffffffffffff80821115612e1457600080fd5b612e2086838701612ce1565b9350602091508185013581811115612e3757600080fd5b85019050601f81018613612e4a57600080fd5b8035612e5581612cbd565b604051612e628282612c72565b82815260059290921b8301840191848101915088831115612e8257600080fd5b928401925b82841015612ea9578335612e9a81612bc8565b82529284019290840190612e87565b80955050505050509250929050565b600060208284031215612eca57600080fd5b813560ff81168114612a1c57600080fd5b600067ffffffffffffffff821115612ef557612ef5612c43565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600060208284031215612f3357600080fd5b813567ffffffffffffffff811115612f4a57600080fd5b8201601f81018413612f5b57600080fd5b8035612f6681612edb565b604051612f738282612c72565b828152866020848601011115612f8857600080fd5b8260208501602083013760009281016020019290925250949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215612fe857600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561049f5761049f612fef565b8181038181111561049f5761049f612fef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060033d111561308c5760046000803e5060005160e01c5b90565b600060443d101561309d5790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff81602484011181841117156130eb57505050505090565b82850191508151818111156131035750505050505090565b843d870101602082850101111561311d5750505050505090565b6127f560208286010187612c72565b60005b8381101561314757818101518382015260200161312f565b50506000910152565b6000815180845261316881602086016020860161312c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612a1c6020830184613150565b838152600083516131c581602085016020880161312c565b60209201918201929092526040019392505050565b6000602082840312156131ec57600080fd5b815167ffffffffffffffff81111561320357600080fd5b8201601f8101841361321457600080fd5b805161321f81612edb565b60405161322c8282612c72565b82815286602084860101111561324157600080fd5b61325283602083016020870161312c565b9695505050505050565b6001600160a01b03831681526040602082015260006120386040830184613150565b808202811582820484141761049f5761049f612fef565b600060001982036132a8576132a8612fef565b5060010190565b600080600080600060a086880312156132c757600080fd5b8551945060208601519350604086015192506060860151915060808601516132ee81612bc8565b809150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261333a5761333a6132fc565b500690565b60008261334e5761334e6132fc565b500490565b600060ff831680613366576133666132fc565b8060ff84160691505092915050565b600060ff831680613388576133886132fc565b8060ff84160491505092915050565b600181815b808511156133d25781600019048211156133b8576133b8612fef565b808516156133c557918102915b93841c939080029061339c565b509250929050565b6000826133e95750600161049f565b816133f65750600061049f565b816001811461340c576002811461341657613432565b600191505061049f565b60ff84111561342757613427612fef565b50506001821b61049f565b5060208310610133831016604e8410600b8410161715613455575081810a61049f565b61345f8383613397565b806000190482111561347357613473612fef565b029392505050565b6000612a1c83836133da565b60ff828116828216039081111561049f5761049f612fef56fea26469706673582212209e639d97bd5501c8292a8916fa3a156081e2e3a688a9415ddea8a5009528d3dd64736f6c63430008110033000000000000000000000000e5c7d9a18df4fdc12db723761a862845612917ba00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a2
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101a35760003560e01c8063972c4928116100ee578063c0857ba011610097578063de9b771f11610071578063de9b771f14610394578063f2fde38b146103a7578063f7b4c187146103ba578063f953cec7146103cd57600080fd5b8063c0857ba014610366578063c10ce94d14610379578063c90bd0471461038c57600080fd5b8063ab563dc5116100c8578063ab563dc51461032d578063aea4e49e14610340578063aeb339131461035357600080fd5b8063972c4928146102f2578063a5b39cfb14610305578063a9aad58c1461032557600080fd5b8063607f2d42116101505780637acb77571161012a5780637acb77571461029c5780637f4e4849146102af5780638da5cb5b146102c857600080fd5b8063607f2d42146102435780636e0777411461027657806370a082311461028957600080fd5b80633455f41e116101815780633455f41e1461020a5780633e8eb5a41461021d578063568fae8a1461023057600080fd5b80630292199f146101a85780630e387de6146101bd5780632e17de78146101f7575b600080fd5b6101bb6101b6366004612bdd565b6103e0565b005b6101e47f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b6040519081526020015b60405180910390f35b6101bb610205366004612bfa565b61046b565b6101e4610218366004612bdd565b610485565b6101bb61022b366004612c13565b6104a5565b6101bb61023e366004612d52565b6105a6565b610266610251366004612bfa565b60046020526000908152604090205460ff1681565b60405190151581526020016101ee565b6101bb610284366004612bdd565b6105ef565b6101e4610297366004612bdd565b610675565b6101bb6102aa366004612c13565b610742565b60005460ff165b60405160ff90911681526020016101ee565b60005461010090046001600160a01b03165b6040516001600160a01b0390911681526020016101ee565b6003546102da906001600160a01b031681565b610318610313366004612bdd565b6107ea565b6040516101ee9190612d87565b6102b6600081565b6101bb61033b366004612de9565b610882565b6101bb61034e366004612bdd565b6109a6565b6101e4610361366004612bdd565b610a3f565b6002546102da906001600160a01b031681565b6005546102da906001600160a01b031681565b6102b6600181565b6001546102da906001600160a01b031681565b6101bb6103b5366004612bdd565b610a5d565b6101bb6103c8366004612eb8565b610b19565b6101bb6103db366004612f21565b610bb1565b6000546001600160a01b03610100909104163314610431576040517f55932a1b0000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6104753382610bbc565b6104823360016000610f2f565b50565b6001600160a01b0381166000908152600660205260408120545b92915050565b6000806104b23385610f82565b33600090815260066020526040902080549294509092508491839081106104db576104db612fa7565b60009182526020918290200180547fffffffff0000000000000000000000000000000000000000ffffffffffffffff16680100000000000000006001600160a01b0394851602179055830151161561053b5761053b8260200151856110ba565b6001600160a01b038316156105a0576001600160a01b038316600081815260076020908152604080832080546001810182559084529183209091018790555186917fe0e8b8961e9f558e2bc7536b6a59f335a7c0a95e001d7332b1f707962d07a76891a35b50505050565b80515b80156105de57806001900390506105d9338383815181106105cc576105cc612fa7565b6020026020010151610bbc565b6105a9565b6105eb3383516000610f2f565b5050565b6000546001600160a01b0361010090910416331461063b576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610428565b600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6001600160a01b0381166000908152600760205260408120546001600160a01b0383166000908152600660205260409020546005546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152909116906370a0823190602401602060405180830381865afa15801561070a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072e9190612fd6565b610738919061301e565b61049f919061301e565b60005460019060ff16811461078c576000546040517f5d80b9ec00000000000000000000000000000000000000000000000000000000815260ff9091166004820152602401610428565b6003546001600160a01b03166107ce576040517f31cd21c000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107d9338484611271565b6107e533600180610f2f565b505050565b6001600160a01b0381166000908152600660209081526040808320805482518185028101850190935280835260609492939192909184015b82821015610877576000848152602090819020604080518082019091529084015467ffffffffffffffff811682526801000000000000000090046001600160a01b031681830152825260019092019101610822565b505050509050919050565b60005460019060ff1681146108cc576000546040517f5d80b9ec00000000000000000000000000000000000000000000000000000000815260ff9091166004820152602401610428565b6003546001600160a01b031661090e576040517f31cd21c000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82518251811461094a576040517f88adebd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801561099957806001900390506109943385838151811061096d5761096d612fa7565b602002602001015185848151811061098757610987612fa7565b6020026020010151611271565b61094a565b6105a03385516001610f2f565b6003546001600160a01b031615610431576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f467842617365526f6f7454756e6e656c3a204348494c445f54554e4e454c5f4160448201527f4c52454144595f534554000000000000000000000000000000000000000000006064820152608401610428565b6001600160a01b03811660009081526007602052604081205461049f565b6000546001600160a01b03610100909104163314610aa9576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610428565b600080546001600160a01b038381166101008181027fffffffffffffffffffffff0000000000000000000000000000000000000000ff851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b6000546001600160a01b03610100909104163314610b65576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610428565b600160ff82161115610ba8576040517fb81f899300000000000000000000000000000000000000000000000000000000815260ff82166004820152602401610428565b610482816113e3565b60006107e582611445565b6001600160a01b0382166000908152600660205260408120549081905b8115610e05576001600160a01b038516600090815260066020526040902080546000199093019285919084908110610c1357610c13612fa7565b60009182526020909120015467ffffffffffffffff1603610e00576001600160a01b0385166000908152600660205260408120805484908110610c5857610c58612fa7565b6000918252602090912001546801000000000000000090046001600160a01b031690508015610c8b57610c8b81866110ba565b610c96600185613031565b8314610d99576001600160a01b0386166000908152600660205260409020610cbf600186613031565b81548110610ccf57610ccf612fa7565b9060005260206000200160066000886001600160a01b03166001600160a01b031681526020019081526020016000208481548110610d0f57610d0f612fa7565b6000918252602090912082549101805467ffffffffffffffff9092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000083168117825592547fffffffff0000000000000000000000000000000000000000000000000000000090921690921768010000000000000000918290046001600160a01b03169091021790555b6001600160a01b0386166000908152600660205260409020805480610dc057610dc0613044565b600082815260209020810160001990810180547fffffffff0000000000000000000000000000000000000000000000000000000016905501905550600190505b610bd9565b80610e3f576040517fb8cd55d500000000000000000000000000000000000000000000000000000000815260048101859052602401610428565b6005546040517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03878116602483015260448201879052909116906323b872dd90606401600060405180830381600087803b158015610eac57600080fd5b505af1925050508015610ebd575060015b610f2857610ec9613073565b806308c379a003610f1c5750610edd61308f565b80610ee85750610f1e565b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610428919061319a565b505b3d6000803e3d6000fd5b5050505050565b61ffff8216156107e557604080516001600160a01b038516602082015260019181019190915261ffff8316606082015281151560808201526107e59060a00160405160208183030381529060405261181a565b60408051808201909152600080825260208201526001600160a01b0383166000908152600660205260408120545b801561107e576001600160a01b038516600090815260066020526040902080546000199092019185919083908110610fea57610fea612fa7565b60009182526020909120015467ffffffffffffffff1603611079576001600160a01b038516600090815260066020526040902080548290811061102f5761102f612fa7565b60009182526020918290206040805180820190915291015467ffffffffffffffff811682526801000000000000000090046001600160a01b031691810191909152925090506110b3565b610fb0565b6040517fb8cd55d500000000000000000000000000000000000000000000000000000000815260048101859052602401610428565b9250929050565b6001600160a01b0382166000908152600760205260408120549081905b81156111fa576001600160a01b03851660009081526007602052604090208054600019909301928591908490811061111157611111612fa7565b9060005260206000200154036111f55761112c600184613031565b82146111b3576001600160a01b0385166000908152600760205260409020611155600185613031565b8154811061116557611165612fa7565b906000526020600020015460076000876001600160a01b03166001600160a01b0316815260200190815260200160002083815481106111a6576111a6612fa7565b6000918252602090912001555b6001600160a01b03851660009081526007602052604090208054806111da576111da613044565b60019003818190600052602060002001600090559055600190505b6110d7565b80611234576040517fb8cd55d500000000000000000000000000000000000000000000000000000000815260048101859052602401610428565b6040516001600160a01b0386169085907f137032969b3eef1e583f6869378c3ae25f0497c0b96ca1bce52b708782fb49cc90600090a35050505050565b6001600160a01b038084166000908152600660209081526040808320815180830190925267ffffffffffffffff80881683528686168385018181528354600181018555938752949095209251929091018054935190951668010000000000000000027fffffffff000000000000000000000000000000000000000000000000000000009093169116171790915515611359576001600160a01b038116600081815260076020908152604080832080546001810182559084529183209091018590555184917fe0e8b8961e9f558e2bc7536b6a59f335a7c0a95e001d7332b1f707962d07a76891a35b6005546040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015230602483015260448201859052909116906323b872dd90606401600060405180830381600087803b1580156113c657600080fd5b505af19250505080156113d7575060015b6107e557610ec9613073565b6000805460ff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00831681178455604051919092169283917f7285522ec93a20dcefa1a1d057094a227073a5463b91c0c19a23c6ef5c9c1fe49190a35050565b6060600061145283611897565b9050600061145f826118f6565b9050600061146c8361191f565b905060008161147a84611948565b61148386611b36565b604051602001611495939291906131ad565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff161561156a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f53534544000000000000000000000000000000000000000000000000000000006064820152608401610428565b600081815260046020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556115aa85611b52565b905060006115b782611c9c565b90506115c281611d2c565b6003546001600160a01b0390811691161461165f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c0000000000000000000000000000000000000000000000000000006064820152608401610428565b600061166a87611d55565b905061168a61167a846020015190565b876116848a611d71565b84611d8d565b611716576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f4600000000000000000000000000000000000000000000000000000000006064820152608401610428565b6117448561172389612040565b61172c8a61205c565b846117368c612078565b61173f8d612094565b6120b0565b50600061175083612209565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036611786611781836000612245565b61227d565b146117ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e4154555245006044820152606401610428565b60006117f8846122f8565b80602001905181019061180b91906131da565b9b9a5050505050505050505050565b6001546003546040517fb47204770000000000000000000000000000000000000000000000000000000081526001600160a01b039283169263b47204779261186992911690859060040161325c565b600060405180830381600087803b15801561188357600080fd5b505af1158015610f28573d6000803e3d6000fd5b60408051602081019091526060815260006118e16118dc8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b612314565b60408051602081019091529081529392505050565b606061049f826000015160088151811061191257611912612fa7565b602002602001015161242a565b600061049f826000015160028151811061193b5761193b612fa7565b602002602001015161227d565b6040805160208101909152600081528151606091901561049f576000806119706000866124c7565b60f81c9050600181148061198757508060ff166003145b15611a475760018551600261199c919061327e565b6119a69190613031565b67ffffffffffffffff8111156119be576119be612c43565b6040519080825280601f01601f1916602001820160405280156119e8576020820181803683370190505b50925060006119f86001876124c7565b90508084600081518110611a0e57611a0e612fa7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001925050611aab565b600285516002611a57919061327e565b611a619190613031565b67ffffffffffffffff811115611a7957611a79612c43565b6040519080825280601f01601f191660200182016040528015611aa3576020820181803683370190505b509250600091505b60ff82165b8351811015611b2d57611ada611ac960ff851683613031565b611ad490600261301e565b876124c7565b848281518110611aec57611aec612fa7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080611b2581613295565b915050611ab0565b50505092915050565b600061049f826000015160098151811061193b5761193b612fa7565b611b7660405180606001604052806060815260200160608152602001600081525090565b611b90826000015160068151811061191257611912612fa7565b602082810182905260408051808201825260008082529083015280518082019091528251815291810190820152611bc681612548565b15611bdb57611bd481612314565b8252611c88565b60208201518051600090611bf190600190613031565b67ffffffffffffffff811115611c0957611c09612c43565b6040519080825280601f01601f191660200182016040528015611c33576020820181803683370190505b509050600080836021019150826020019050611c5182828551612583565b604080518082018252600080825260209182015281518083019092528451825280850190820152611c8190612314565b8652505050505b611c9183611b36565b604083015250919050565b604080516080810182526000918101828152606080830193909352815260208101919091526000611cea8360000151600381518110611cdd57611cdd612fa7565b6020026020010151612314565b836040015181518110611cff57611cff612fa7565b602002602001015190506040518060400160405280828152602001611d2383612314565b90529392505050565b600061049f8260200151600081518110611d4857611d48612fa7565b6020026020010151612601565b600061049f826000015160058151811061193b5761193b612fa7565b606061049f826000015160078151811061191257611912612fa7565b600080611dc18460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b90506000611dce82612314565b905060608085600080611de08b611948565b90508051600003611dfb576000975050505050505050612038565b60005b865181101561202f578151831115611e2157600098505050505050505050612038565b611e43878281518110611e3657611e36612fa7565b602002602001015161261b565b955085805190602001208414611e6457600098505050505050505050612038565b611e79878281518110611cdd57611cdd612fa7565b94508451601103611f4b5781518303611ed8578c80519060200120611eaa8660108151811061191257611912612fa7565b8051906020012003611ec757600198505050505050505050612038565b600098505050505050505050612038565b6000828481518110611eec57611eec612fa7565b016020015160f81c90506010811115611f115760009950505050505050505050612038565b611f36868260ff1681518110611f2957611f29612fa7565b602002602001015161269a565b9450611f4360018561301e565b93505061201d565b8451600203611ec7576000611f76611f6f8760008151811061191257611912612fa7565b84866126c8565b8351909150611f85828661301e565b03611fd8578d80519060200120611fa88760018151811061191257611912612fa7565b8051906020012003611fc65760019950505050505050505050612038565b60009950505050505050505050612038565b80600003611ff25760009950505050505050505050612038565b611ffc818561301e565b935061201486600181518110611f2957611f29612fa7565b945061201d9050565b8061202781613295565b915050611dfe565b50505050505050505b949350505050565b600061049f826000015160038151811061193b5761193b612fa7565b600061049f826000015160048151811061193b5761193b612fa7565b600061049f826000015160008151811061193b5761193b612fa7565b606061049f826000015160018151811061191257611912612fa7565b6002546040517f41539d4a000000000000000000000000000000000000000000000000000000008152600481018490526000918291829182916001600160a01b03909116906341539d4a9060240160a060405180830381865afa15801561211b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061213f91906132af565b5093505092509250612196828b6121569190613031565b6040805160208082018f90528183018e9052606082018d905260808083018d90528351808403909101815260a09092019092528051910120908588612800565b6121fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f484541444552000000006044820152606401610428565b9998505050505050505050565b604080516020810190915260608152604051806020016040528061223d8460200151600181518110611cdd57611cdd612fa7565b905292915050565b6040805180820190915260008082526020820152825180518390811061226d5761226d612fa7565b6020026020010151905092915050565b80516000901580159061229257508151602110155b61229b57600080fd5b60006122aa83602001516129ad565b905060008184600001516122be9190613031565b90506000808386602001516122d3919061301e565b90508051915060208310156122ef57826020036101000a820491505b50949350505050565b606061049f826020015160028151811061191257611912612fa7565b606061231f82612548565b61232857600080fd5b600061233383612a2f565b905060008167ffffffffffffffff81111561235057612350612c43565b60405190808252806020026020018201604052801561239557816020015b604080518082019091526000808252602082015281526020019060019003908161236e5790505b50905060006123a785602001516129ad565b85602001516123b6919061301e565b90506000805b8481101561241f576123cd83612ab4565b91506040518060400160405280838152602001848152508482815181106123f6576123f6612fa7565b602090810291909101015261240b828461301e565b92508061241781613295565b9150506123bc565b509195945050505050565b805160609061243857600080fd5b600061244783602001516129ad565b9050600081846000015161245b9190613031565b905060008167ffffffffffffffff81111561247857612478612c43565b6040519080825280601f01601f1916602001820160405280156124a2576020820181803683370190505b50905060008160200190506122ef8487602001516124c0919061301e565b8285612b76565b60006124d460028461332b565b1561250e576010826124e760028661333f565b815181106124f7576124f7612fa7565b0160200151612509919060f81c613353565b61253e565b60108261251c60028661333f565b8151811061252c5761252c612fa7565b016020015161253e919060f81c613375565b60f81b9392505050565b8051600090810361255b57506000919050565b6020820151805160001a9060c0821015612579575060009392505050565b5060019392505050565b8060000361259057505050565b602081106125c857825182526125a760208461301e565b92506125b460208361301e565b91506125c1602082613031565b9050612590565b600060016125d7836020613031565b6125e39061010061347b565b6125ed9190613031565b935183518516941916939093179091525050565b805160009060151461261257600080fd5b61049f8261227d565b60606000826000015167ffffffffffffffff81111561263c5761263c612c43565b6040519080825280601f01601f191660200182016040528015612666576020820181803683370190505b50905080516000036126785792915050565b60008160200190506126938460200151828660000151612b76565b5092915050565b80516000906021146126ab57600080fd5b600080836020015160016126bf919061301e565b51949350505050565b600080806126d586611948565b90506000815167ffffffffffffffff8111156126f3576126f3612c43565b6040519080825280601f01601f19166020018201604052801561271d576020820181803683370190505b509050845b825161272e908761301e565b8110156127d157600087828151811061274957612749612fa7565b01602001517fff00000000000000000000000000000000000000000000000000000000000000169050808361277e8985613031565b8151811061278e5761278e612fa7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505080806127c990613295565b915050612722565b5080805190602001208280519060200120036127f057815192506127f5565b600092505b509095945050505050565b600060208251612810919061332b565b15612877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e76616c69642070726f6f66206c656e6774680000000000000000000000006044820152606401610428565b600060208351612887919061333f565b905061289481600261347b565b85106128fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4c65616620696e64657820697320746f6f2062696700000000000000000000006044820152606401610428565b60008660205b8551811161299f5785810151925061291b60028961332b565b600003612953576040805160208101849052908101849052606001604051602081830303815290604052805190602001209150612980565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b61298b60028961333f565b975061299860208261301e565b9050612902565b509094149695505050505050565b8051600090811a60808110156129c65750600092915050565b60b88110806129e1575060c081108015906129e1575060f881105b156129ef5750600192915050565b60c0811015612a2357612a04600160b8613487565b612a119060ff1682613031565b612a1c90600161301e565b9392505050565b612a04600160f8613487565b80516000908103612a4257506000919050565b600080612a5284602001516129ad565b8460200151612a61919061301e565b9050600084600001518560200151612a79919061301e565b90505b80821015612aab57612a8d82612ab4565b612a97908361301e565b915082612aa381613295565b935050612a7c565b50909392505050565b80516000908190811a6080811015612acf5760019150612693565b60b8811015612af557612ae3608082613031565b612aee90600161301e565b9150612693565b60c0811015612b225760b78103600185019450806020036101000a85510460018201810193505050612693565b60f8811015612b3657612ae360c082613031565b60019390930151602084900360f7016101000a90049092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a0192915050565b80600003612b8357505050565b60208110612bbb5782518252612b9a60208461301e565b9250612ba760208361301e565b9150612bb4602082613031565b9050612b83565b806000036125c857505050565b6001600160a01b038116811461048257600080fd5b600060208284031215612bef57600080fd5b8135612a1c81612bc8565b600060208284031215612c0c57600080fd5b5035919050565b60008060408385031215612c2657600080fd5b823591506020830135612c3881612bc8565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116810181811067ffffffffffffffff82111715612cb657612cb6612c43565b6040525050565b600067ffffffffffffffff821115612cd757612cd7612c43565b5060051b60200190565b600082601f830112612cf257600080fd5b81356020612cff82612cbd565b604051612d0c8282612c72565b83815260059390931b8501820192828101915086841115612d2c57600080fd5b8286015b84811015612d475780358352918301918301612d30565b509695505050505050565b600060208284031215612d6457600080fd5b813567ffffffffffffffff811115612d7b57600080fd5b61203884828501612ce1565b602080825282518282018190526000919060409081850190868401855b82811015612ddc578151805167ffffffffffffffff1685528601516001600160a01b0316868501529284019290850190600101612da4565b5091979650505050505050565b60008060408385031215612dfc57600080fd5b823567ffffffffffffffff80821115612e1457600080fd5b612e2086838701612ce1565b9350602091508185013581811115612e3757600080fd5b85019050601f81018613612e4a57600080fd5b8035612e5581612cbd565b604051612e628282612c72565b82815260059290921b8301840191848101915088831115612e8257600080fd5b928401925b82841015612ea9578335612e9a81612bc8565b82529284019290840190612e87565b80955050505050509250929050565b600060208284031215612eca57600080fd5b813560ff81168114612a1c57600080fd5b600067ffffffffffffffff821115612ef557612ef5612c43565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600060208284031215612f3357600080fd5b813567ffffffffffffffff811115612f4a57600080fd5b8201601f81018413612f5b57600080fd5b8035612f6681612edb565b604051612f738282612c72565b828152866020848601011115612f8857600080fd5b8260208501602083013760009281016020019290925250949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215612fe857600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561049f5761049f612fef565b8181038181111561049f5761049f612fef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060033d111561308c5760046000803e5060005160e01c5b90565b600060443d101561309d5790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff81602484011181841117156130eb57505050505090565b82850191508151818111156131035750505050505090565b843d870101602082850101111561311d5750505050505090565b6127f560208286010187612c72565b60005b8381101561314757818101518382015260200161312f565b50506000910152565b6000815180845261316881602086016020860161312c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612a1c6020830184613150565b838152600083516131c581602085016020880161312c565b60209201918201929092526040019392505050565b6000602082840312156131ec57600080fd5b815167ffffffffffffffff81111561320357600080fd5b8201601f8101841361321457600080fd5b805161321f81612edb565b60405161322c8282612c72565b82815286602084860101111561324157600080fd5b61325283602083016020870161312c565b9695505050505050565b6001600160a01b03831681526040602082015260006120386040830184613150565b808202811582820484141761049f5761049f612fef565b600060001982036132a8576132a8612fef565b5060010190565b600080600080600060a086880312156132c757600080fd5b8551945060208601519350604086015192506060860151915060808601516132ee81612bc8565b809150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261333a5761333a6132fc565b500690565b60008261334e5761334e6132fc565b500490565b600060ff831680613366576133666132fc565b8060ff84160691505092915050565b600060ff831680613388576133886132fc565b8060ff84160491505092915050565b600181815b808511156133d25781600019048211156133b8576133b8612fef565b808516156133c557918102915b93841c939080029061339c565b509250929050565b6000826133e95750600161049f565b816133f65750600061049f565b816001811461340c576002811461341657613432565b600191505061049f565b60ff84111561342757613427612fef565b50506001821b61049f565b5060208310610133831016604e8410600b8410161715613455575081810a61049f565b61345f8383613397565b806000190482111561347357613473612fef565b029392505050565b6000612a1c83836133da565b60ff828116828216039081111561049f5761049f612fef56fea26469706673582212209e639d97bd5501c8292a8916fa3a156081e2e3a688a9415ddea8a5009528d3dd64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e5c7d9a18df4fdc12db723761a862845612917ba00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a2
-----Decoded View---------------
Arg [0] : nucyberContractAddress_ (address): 0xE5C7D9A18df4fDc12DB723761A862845612917bA
Arg [1] : cpManager_ (address): 0x86E4Dc95c7FBdBf52e33D563BbDB00823894C287
Arg [2] : fxRoot_ (address): 0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000e5c7d9a18df4fdc12db723761a862845612917ba
Arg [1] : 00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287
Arg [2] : 000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a2
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.