Overview
POL Balance
0 POL
POL Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 374 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Exit | 59628194 | 134 days ago | IN | 0 POL | 0.00281035 | ||||
Harvest | 58205294 | 170 days ago | IN | 0 POL | 0.00547642 | ||||
Withdraw | 58205260 | 170 days ago | IN | 0 POL | 0.00335683 | ||||
Harvest | 57702119 | 183 days ago | IN | 0 POL | 0.00392034 | ||||
Withdraw | 57702086 | 183 days ago | IN | 0 POL | 0.00321633 | ||||
Harvest | 57514218 | 188 days ago | IN | 0 POL | 0.00300111 | ||||
Withdraw | 56943972 | 203 days ago | IN | 0 POL | 0.00071454 | ||||
Withdraw | 56943965 | 203 days ago | IN | 0 POL | 0.00277341 | ||||
Harvest | 56943893 | 203 days ago | IN | 0 POL | 0.0047514 | ||||
Harvest | 56942866 | 203 days ago | IN | 0 POL | 0.003213 | ||||
Withdraw | 56942823 | 203 days ago | IN | 0 POL | 0.00277341 | ||||
Withdraw | 56935722 | 203 days ago | IN | 0 POL | 0.0032166 | ||||
Harvest | 56935701 | 203 days ago | IN | 0 POL | 0.00443502 | ||||
Withdraw | 56885560 | 204 days ago | IN | 0 POL | 0.0029649 | ||||
Withdraw | 56854812 | 205 days ago | IN | 0 POL | 0.0007149 | ||||
Withdraw | 56854810 | 205 days ago | IN | 0 POL | 0.0032169 | ||||
Harvest | 56772816 | 207 days ago | IN | 0 POL | 0.00648774 | ||||
Harvest | 56734506 | 208 days ago | IN | 0 POL | 0.00443442 | ||||
Withdraw | 56711763 | 209 days ago | IN | 0 POL | 0.00071418 | ||||
Withdraw | 56711680 | 209 days ago | IN | 0 POL | 0.00523919 | ||||
Harvest | 56711504 | 209 days ago | IN | 0 POL | 0.00843082 | ||||
Withdraw | 56709408 | 209 days ago | IN | 0 POL | 0.00077066 | ||||
Withdraw | 56709357 | 209 days ago | IN | 0 POL | 0.0066518 | ||||
Harvest | 56709122 | 209 days ago | IN | 0 POL | 0.00089999 | ||||
Withdraw | 56688458 | 209 days ago | IN | 0 POL | 0.0032166 |
Loading...
Loading
Contract Name:
GemPool
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import "./EnumerableSet.sol"; import "./Pausable.sol"; import "./SafeERC20.sol"; import "./IERC1271.sol"; import "./draft-EIP712.sol"; error NotAuthorized(); error EmptyAmount(); error StakeFailed(); error RewardFailed(); error BonusFailed(); error WithdrawFailed(); error EmptyStaked(); error AccountMismatched(); error InvalidClaim(); error ClaimExpired(); error InvalidSignature(); error PoolStarted(); error PoolNotStart(); error PoolEnded(); error PoolOngoing(); contract GemPool is Pausable, EIP712 { using SafeERC20 for IERC20; using EnumerableSet for EnumerableSet.UintSet; using EnumerableSet for EnumerableSet.AddressSet; bytes32 private constant REWARD_HASH = keccak256( "Reward(uint256 timestamp,uint256 rewardAmount,uint256 bonusAmount)" ); bytes32 private constant CLAIM_HASH = keccak256( "Claim(address account,Reward[] rewards,uint256 salt,uint256 expire)Reward(uint256 timestamp,uint256 rewardAmount,uint256 bonusAmount)" ); struct Reward { uint256 timestamp; uint256 rewardAmount; uint256 bonusAmount; } struct Claim { address account; Reward[] rewards; uint256 salt; uint256 expire; } struct StakeInfo { uint256 initial; uint256 balance; uint256 reward; // Claimed amount uint256 bonus; // Claimed amount } IERC20 public immutable stakingToken; IERC20 public immutable rewardToken; IERC20 public immutable bonusToken; uint256 public immutable duration = 540 days; address public owner; address public claimSigner; mapping(bytes32 => bool) private claimExecuted; // Start timestamp uint256 public start; // Total staked uint256 public totalSupply; // User address => total staked amount mapping(address => uint256) public balanceOf; // User address => staked timestamps mapping(address => EnumerableSet.UintSet) private stakes; // User address => staked timestamp => StakeInfo mapping(address => mapping(uint256 => StakeInfo)) private stakeInfos; EnumerableSet.AddressSet private participants; event Stake(address indexed account, uint256 timestamp); event Harvest( address indexed account, uint256 timestamp, uint256 reward, uint256 bonus ); event Withdraw(address indexed account, uint256 amount); constructor( address _claimSigner, address _stakingToken, address _rewardToken, address _bonusToken ) EIP712("Alchemist", "1.0.0") { owner = msg.sender; claimSigner = _claimSigner; stakingToken = IERC20(_stakingToken); rewardToken = IERC20(_rewardToken); bonusToken = IERC20(_bonusToken); } modifier onlyOwner() { if (msg.sender != owner) revert NotAuthorized(); _; } modifier ongoing() { if (start == 0 || block.timestamp < start) revert PoolNotStart(); if (block.timestamp > start + duration) revert PoolEnded(); _; } function stake(uint256 _amount) external whenNotPaused ongoing { if (_amount == 0) revert EmptyAmount(); address account = msg.sender; uint256 timestamp = block.timestamp; StakeInfo storage stakeInfo = stakeInfos[account][timestamp]; bool success = stakingToken.transferFrom(account, address(this), _amount); if (!success) revert StakeFailed(); balanceOf[account] += _amount; if (stakes[account].contains(timestamp)) { stakeInfo.initial += _amount; stakeInfo.balance += _amount; } else { stakes[account].add(timestamp); stakeInfo.initial = _amount; stakeInfo.balance = _amount; } totalSupply += _amount; participants.add(account); emit Stake(account, timestamp); } function _harvest( address _account, uint256 _timestamp, Reward calldata _reward ) private { StakeInfo storage stakeInfo = stakeInfos[_account][_timestamp]; if (_reward.rewardAmount > 0) { stakeInfo.reward += _reward.rewardAmount; bool success = rewardToken.transfer(_account, _reward.rewardAmount); if (!success) revert RewardFailed(); } if (_reward.bonusAmount > 0) { stakeInfo.bonus += _reward.bonusAmount; bool success = bonusToken.transfer(_account, _reward.bonusAmount); if (!success) revert BonusFailed(); } emit Harvest( _account, _timestamp, _reward.rewardAmount, _reward.bonusAmount ); } function harvest(Claim calldata _claim, bytes calldata _signature) external whenNotPaused { if (msg.sender != _claim.account) revert AccountMismatched(); bytes32 claimHash = hash(_claim); if (block.timestamp > _claim.expire) revert ClaimExpired(); if (claimExecuted[claimHash]) revert InvalidClaim(); claimExecuted[claimHash] = true; if (ECDSA.recover(_hashTypedDataV4(claimHash), _signature) != claimSigner) revert InvalidSignature(); uint256 len = _claim.rewards.length; for (uint256 i; i < len; ) { _harvest(_claim.account, _claim.rewards[i].timestamp, _claim.rewards[i]); unchecked { ++i; } } } function getStakes(address _account) external view returns (uint256[] memory) { return stakes[_account].values(); } function getStakeOf(address _account, uint256 _timestamp) external view returns ( uint256, uint256, uint256, uint256, uint256 ) { StakeInfo memory stakeInfo = stakeInfos[_account][_timestamp]; return ( balanceOf[_account], stakeInfo.initial, stakeInfo.balance, stakeInfo.reward, stakeInfo.bonus ); } function _removeTimestamps( uint256[] memory timestampToRemove, address account ) private { uint256 count = 0; for (uint256 i; i < timestampToRemove.length; ) { if (timestampToRemove[i] != 0) { count++; stakes[account].remove(timestampToRemove[i]); } unchecked { ++i; } } if (timestampToRemove.length == count) { participants.remove(account); } } function withdraw(uint256 _amount) external { if (_amount == 0) revert EmptyAmount(); address account = msg.sender; if (balanceOf[account] == 0) revert EmptyStaked(); uint256 len = stakes[account].length(); uint256[] memory timestampToRemove = new uint256[](len); for (uint256 i; i < len; ) { uint256 timestamp = stakes[account].at(i); StakeInfo storage stakeInfo = stakeInfos[account][timestamp]; stakeInfo.balance -= (stakeInfo.balance * _amount) / balanceOf[account]; if (stakeInfo.balance == 0) { timestampToRemove[i] = timestamp; } unchecked { ++i; } } _removeTimestamps(timestampToRemove, account); balanceOf[account] -= _amount; totalSupply -= _amount; bool success = stakingToken.transfer(msg.sender, _amount); if (!success) revert WithdrawFailed(); emit Withdraw(account, _amount); } function getParticipants() external view returns (address[] memory) { return participants.values(); } function exit() external { address account = msg.sender; if (balanceOf[account] == 0) revert EmptyStaked(); uint256 amount = balanceOf[account]; uint256 len = stakes[account].length(); uint256[] memory timestampToRemove = new uint256[](len); for (uint256 i; i < len; ) { uint256 timestamp = stakes[account].at(i); StakeInfo storage stakeInfo = stakeInfos[account][timestamp]; stakeInfo.balance = 0; timestampToRemove[i] = timestamp; unchecked { ++i; } } _removeTimestamps(timestampToRemove, account); balanceOf[account] = 0; totalSupply -= amount; bool success = stakingToken.transfer(msg.sender, amount); if (!success) revert WithdrawFailed(); participants.remove(account); emit Withdraw(account, amount); } function hash(Reward[] memory rewards) private pure returns (bytes32) { bytes32[] memory rewardBytes = new bytes32[](rewards.length); for (uint256 i = 0; i < rewards.length; ) { rewardBytes[i] = keccak256( abi.encode( REWARD_HASH, rewards[i].timestamp, rewards[i].rewardAmount, rewards[i].bonusAmount ) ); unchecked { ++i; } } return keccak256(abi.encodePacked(rewardBytes)); } function hash(Claim memory claim) private pure returns (bytes32) { return keccak256( abi.encode( CLAIM_HASH, claim.account, hash(claim.rewards), claim.salt, claim.expire ) ); } function launch(uint256 _start) external onlyOwner { if (start != 0) revert PoolStarted(); start = _start; } function flipPause() external onlyOwner { if (paused()) { _unpause(); } else { _pause(); } } function pullToken() external onlyOwner { if (block.timestamp < start + duration) revert PoolOngoing(); uint256 rewardBalance = rewardToken.balanceOf(address(this)); uint256 bonusBalance = bonusToken.balanceOf(address(this)); if (rewardBalance > 0) { bool success = rewardToken.transfer( owner, rewardToken.balanceOf(address(this)) ); if (!success) revert RewardFailed(); } if (bonusBalance > 0) { bool success = bonusToken.transfer( owner, bonusToken.balanceOf(address(this)) ); if (!success) revert BonusFailed(); } } function updateSigner(address _claimSigner) external onlyOwner { claimSigner = _claimSigner; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol) pragma solidity ^0.8.0; import "./ECDSA.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * _Available since v3.4._ */ abstract contract EIP712 { /* solhint-disable var-name-mixedcase */ // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _CACHED_DOMAIN_SEPARATOR; uint256 private immutable _CACHED_CHAIN_ID; address private immutable _CACHED_THIS; bytes32 private immutable _HASHED_NAME; bytes32 private immutable _HASHED_VERSION; bytes32 private immutable _TYPE_HASH; /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); bytes32 typeHash = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; _CACHED_CHAIN_ID = block.chainid; _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); _CACHED_THIS = address(this); _TYPE_HASH = typeHash; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) { return _CACHED_DOMAIN_SEPARATOR; } else { return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); } } function _buildDomainSeparator( bytes32 typeHash, bytes32 nameHash, bytes32 versionHash ) private view returns (bytes32) { return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "./Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC1271 standard signature validation method for * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. * * _Available since v4.1._ */ interface IERC1271 { /** * @dev Should return whether the signature provided is valid for the provided data * @param hash Hash of the data to be signed * @param signature Signature byte array associated with _data */ function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "./Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./draft-IERC20Permit.sol"; import "./Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_claimSigner","type":"address"},{"internalType":"address","name":"_stakingToken","type":"address"},{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_bonusToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountMismatched","type":"error"},{"inputs":[],"name":"BonusFailed","type":"error"},{"inputs":[],"name":"ClaimExpired","type":"error"},{"inputs":[],"name":"EmptyAmount","type":"error"},{"inputs":[],"name":"EmptyStaked","type":"error"},{"inputs":[],"name":"InvalidClaim","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"PoolEnded","type":"error"},{"inputs":[],"name":"PoolNotStart","type":"error"},{"inputs":[],"name":"PoolOngoing","type":"error"},{"inputs":[],"name":"PoolStarted","type":"error"},{"inputs":[],"name":"RewardFailed","type":"error"},{"inputs":[],"name":"StakeFailed","type":"error"},{"inputs":[],"name":"WithdrawFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bonus","type":"uint256"}],"name":"Harvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bonusToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"duration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getParticipants","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getStakeOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getStakes","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"account","type":"address"},{"components":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"uint256","name":"bonusAmount","type":"uint256"}],"internalType":"struct GemPool.Reward[]","name":"rewards","type":"tuple[]"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"uint256","name":"expire","type":"uint256"}],"internalType":"struct GemPool.Claim","name":"_claim","type":"tuple"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_start","type":"uint256"}],"name":"launch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pullToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"start","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_claimSigner","type":"address"}],"name":"updateSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101c06040526302c7ea006101a0523480156200001b57600080fd5b5060405162002844380380620028448339810160408190526200003e91620001a2565b6040805180820182526009815268105b18da195b5a5cdd60ba1b6020808301918252835180850190945260058452640312e302e360dc1b908401526000805460ff191690558151902060e08190527f06c015bd22b4c69690933c1058878ebdfef31f9aaae40bbe86d8a09fe1b2972c6101008190524660a0529192917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6200012b8184846040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b6080523060c05261012052505060008054610100600160a81b03191633610100021790555050600180546001600160a01b0319166001600160a01b03958616179055918316610140528216610160521661018052620001ff565b80516001600160a01b03811681146200019d57600080fd5b919050565b60008060008060808587031215620001b957600080fd5b620001c48562000185565b9350620001d46020860162000185565b9250620001e46040860162000185565b9150620001f46060860162000185565b905092959194509250565b60805160a05160c05160e05161010051610120516101405161016051610180516101a05161257c620002c860003960008181610141015281816109080152610df10152600081816101b401528181610a1101528181610c0801526115d30152600081816103ac0152818161096c01528181610ab401526114e001526000818161023e0152818161078a01528181610ea4015261123501526000611a6d01526000611abc01526000611a97015260006119f001526000611a1a01526000611a44015261257c6000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806375ce5202116100b8578063a7ecd37e1161007c578063a7ecd37e146102c6578063be9a6555146102d9578063d359ff92146102e2578063d8ee36cb1461038c578063e9fad8ee1461039f578063f7c618c1146103a757600080fd5b806375ce5202146102605780637ba6f4581461026857806385b12c7c146102885780638da5cb5b1461029b578063a694fc3a146102b357600080fd5b806341d4a1ab116100ff57806341d4a1ab146101af5780635aa68ac0146101ee5780635c975abb1461020357806370a082311461021957806372f702f31461023957600080fd5b80630fb5a6b41461013c57806318160ddd14610176578063288502931461017f5780632e1a7d4d14610194578063385df649146101a7575b600080fd5b6101637f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61016360045481565b61019261018d36600461207b565b6103ce565b005b6101926101a236600461211a565b6105a0565b610192610878565b6101d67f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161016d565b6101f66108c5565b60405161016d9190612133565b60005460ff16604051901515815260200161016d565b61016361022736600461219c565b60056020526000908152604090205481565b6101d67f000000000000000000000000000000000000000000000000000000000000000081565b6101926108d6565b61027b61027636600461219c565b610d39565b60405161016d91906121b7565b61019261029636600461211a565b610d63565b6000546101d69061010090046001600160a01b031681565b6101926102c136600461211a565b610db9565b6101926102d436600461219c565b61105b565b61016360035481565b6103646102f03660046121ef565b6001600160a01b0391909116600081815260076020908152604080832094835293815283822084516080810186528154815260018201548184019081526002830154828801908152600390930154606083019081529585526005909352949092205493519051915192519394909391929190565b604080519586526020860194909452928401919091526060830152608082015260a00161016d565b6001546101d6906001600160a01b031681565b6101926110ad565b6101d67f000000000000000000000000000000000000000000000000000000000000000081565b6103d6611320565b6103e3602084018461219c565b6001600160a01b0316336001600160a01b031614610414576040516357b9b1c760e11b815260040160405180910390fd5b6000610427610422856122ac565b61136b565b9050836060013542111561044e576040516341524ecf60e11b815260040160405180910390fd5b60008181526002602052604090205460ff161561047e57604051633b4f091f60e21b815260040160405180910390fd5b6000818152600260205260409020805460ff19166001908117909155546001600160a01b03166104ec6104b0836113f9565b85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061144792505050565b6001600160a01b03161461051357604051638baa579f60e01b815260040160405180910390fd5b600061052260208601866123a9565b9050905060005b8181101561059857610590610541602088018861219c565b61054e60208901896123a9565b8481811061055e5761055e6123f2565b6060029190910135905061057560208a018a6123a9565b85818110610585576105856123f2565b90506060020161146b565b600101610529565b505050505050565b806105be576040516301a2868b60e31b815260040160405180910390fd5b336000818152600560205260409020546105eb5760405163e65ff00d60e01b815260040160405180910390fd5b6001600160a01b038116600090815260066020526040812061060c906116c8565b905060008167ffffffffffffffff81111561062957610629612219565b604051908082528060200260200182016040528015610652578160200160208202803683370190505b50905060005b8281101561071a576001600160a01b038416600090815260066020526040812061068290836116d2565b6001600160a01b038616600081815260076020908152604080832085845282528083209383526005909152902054600182015492935090916106c590899061241e565b6106cf919061243d565b8160010160008282546106e2919061245f565b909155505060018101546107105781848481518110610703576107036123f2565b6020026020010181815250505b5050600101610658565b5061072581846116e5565b6001600160a01b0383166000908152600560205260408120805486929061074d90849061245f565b925050819055508360046000828254610766919061245f565b909155505060405163a9059cbb60e01b8152336004820152602481018590526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90604401602060405180830381600087803b1580156107d657600080fd5b505af11580156107ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080e9190612476565b90508061082e57604051631d42c86760e21b815260040160405180910390fd5b836001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243648660405161086991815260200190565b60405180910390a25050505050565b60005461010090046001600160a01b031633146108a85760405163ea8e4eb560e01b815260040160405180910390fd5b60005460ff16156108bd576108bb611795565b565b6108bb6117e7565b60606108d16008611824565b905090565b60005461010090046001600160a01b031633146109065760405163ea8e4eb560e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006003546109349190612498565b4210156109545760405163e2723eb560e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b1580156109b657600080fd5b505afa1580156109ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ee91906124b0565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b158015610a5357600080fd5b505afa158015610a67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8b91906124b0565b90508115610be157600080546040516370a0823160e01b81523060048201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263a9059cbb926101009091049091169083906370a082319060240160206040518083038186803b158015610b0957600080fd5b505afa158015610b1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4191906124b0565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015610b8757600080fd5b505af1158015610b9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbf9190612476565b905080610bdf5760405163d48c254760e01b815260040160405180910390fd5b505b8015610d3557600080546040516370a0823160e01b81523060048201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263a9059cbb926101009091049091169083906370a082319060240160206040518083038186803b158015610c5d57600080fd5b505afa158015610c71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9591906124b0565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015610cdb57600080fd5b505af1158015610cef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d139190612476565b905080610d335760405163673745a960e11b815260040160405180910390fd5b505b5050565b6001600160a01b0381166000908152600660205260409020606090610d5d90611824565b92915050565b60005461010090046001600160a01b03163314610d935760405163ea8e4eb560e01b815260040160405180910390fd5b60035415610db457604051639606826760e01b815260040160405180910390fd5b600355565b610dc1611320565b6003541580610dd1575060035442105b15610def576040516309fb928560e21b815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000600354610e1d9190612498565b421115610e3d57604051632e95ae4160e21b815260040160405180910390fd5b80610e5b576040516301a2868b60e31b815260040160405180910390fd5b33600081815260076020908152604080832042808552925280832090516323b872dd60e01b81526004810185905230602482015260448101869052919290916001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90606401602060405180830381600087803b158015610ee857600080fd5b505af1158015610efc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f209190612476565b905080610f4057604051630e5ee9cb60e01b815260040160405180910390fd5b6001600160a01b03841660009081526005602052604081208054879290610f68908490612498565b90915550506001600160a01b0384166000908152600660205260409020610f8f9084611831565b15610fce5784826000016000828254610fa89190612498565b9250508190555084826001016000828254610fc39190612498565b90915550610ffc9050565b6001600160a01b0384166000908152600660205260409020610ff09084611849565b50848255600182018590555b846004600082825461100e9190612498565b9091555061101f9050600885611855565b50836001600160a01b03167febedb8b3c678666e7f36970bc8f57abf6d8fa2e828c0da91ea5b75bf68ed101a8460405161086991815260200190565b60005461010090046001600160a01b0316331461108b5760405163ea8e4eb560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b336000818152600560205260409020546110da5760405163e65ff00d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602090815260408083205460069092528220909190611109906116c8565b905060008167ffffffffffffffff81111561112657611126612219565b60405190808252806020026020018201604052801561114f578160200160208202803683370190505b50905060005b828110156111d9576001600160a01b038516600090815260066020526040812061117f90836116d2565b6001600160a01b03871660009081526007602090815260408083208484529091528120600181019190915584519192509082908590859081106111c4576111c46123f2565b60209081029190910101525050600101611155565b506111e481856116e5565b6001600160a01b03841660009081526005602052604081208190556004805485929061121190849061245f565b909155505060405163a9059cbb60e01b8152336004820152602481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561128157600080fd5b505af1158015611295573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b99190612476565b9050806112d957604051631d42c86760e21b815260040160405180910390fd5b6112e460088661186a565b50846001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243648560405161086991815260200190565b60005460ff16156108bb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064015b60405180910390fd5b60007f8b16c4c34ac81a8e1def2c13e0b64dcd9da40639eb7af000e952c3aa4da143cc82600001516113a0846020015161187f565b604080860151606080880151835160208101979097526001600160a01b039095169286019290925290840191909152608083015260a082015260c001604051602081830303815290604052805190602001209050919050565b6000610d5d6114066119e3565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006114568585611b0a565b9150915061146381611b7a565b509392505050565b6001600160a01b0383166000908152600760209081526040808320858452825290912090820135156115805781602001358160020160008282546114af9190612498565b909155505060405163a9059cbb60e01b81526001600160a01b038581166004830152602084013560248301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb90604401602060405180830381600087803b15801561152657600080fd5b505af115801561153a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155e9190612476565b90508061157e5760405163d48c254760e01b815260040160405180910390fd5b505b6040820135156116715781604001358160030160008282546115a29190612498565b90915550506040805163a9059cbb60e01b81526001600160a01b0386811660048301529184013560248201526000917f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b15801561161757600080fd5b505af115801561162b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164f9190612476565b90508061166f5760405163673745a960e11b815260040160405180910390fd5b505b6040805184815260208481013590820152838201358183015290516001600160a01b038616917f4534f107610758c3931de9ad1e176476fcfb8c74adf920167e1d54ee84fcfe76919081900360600190a250505050565b6000610d5d825490565b60006116de8383611d38565b9392505050565b6000805b835181101561177a57838181518110611704576117046123f2565b6020026020010151600014611772578161171d816124c9565b925050611770848281518110611735576117356123f2565b602002602001015160066000866001600160a01b03166001600160a01b03168152602001908152602001600020611d6290919063ffffffff16565b505b6001016116e9565b508083511415610d335761178f60088361186a565b50505050565b61179d611d6e565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6117ef611320565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586117ca3390565b606060006116de83611db7565b600081815260018301602052604081205415156116de565b60006116de8383611e13565b60006116de836001600160a01b038416611e13565b60006116de836001600160a01b038416611e62565b600080825167ffffffffffffffff81111561189c5761189c612219565b6040519080825280602002602001820160405280156118c5578160200160208202803683370190505b50905060005b83518110156119b3577f247ed61a441b4e531a3b79e9e84c51c0767cebeef54ba4077173eb646af2297f848281518110611907576119076123f2565b602002602001015160000151858381518110611925576119256123f2565b602002602001015160200151868481518110611943576119436123f2565b602002602001015160400151604051602001611978949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001208282815181106119a0576119a06123f2565b60209081029190910101526001016118cb565b50806040516020016119c591906124e4565b60405160208183030381529060405280519060200120915050919050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148015611a3c57507f000000000000000000000000000000000000000000000000000000000000000046145b15611a6657507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b600080825160411415611b415760208301516040840151606085015160001a611b3587828585611f55565b94509450505050611b73565b825160401415611b6b5760208301516040840151611b60868383612042565b935093505050611b73565b506000905060025b9250929050565b6000816004811115611b8e57611b8e61251a565b1415611b975750565b6001816004811115611bab57611bab61251a565b1415611bf95760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401611362565b6002816004811115611c0d57611c0d61251a565b1415611c5b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401611362565b6003816004811115611c6f57611c6f61251a565b1415611cc85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401611362565b6004816004811115611cdc57611cdc61251a565b1415611d355760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401611362565b50565b6000826000018281548110611d4f57611d4f6123f2565b9060005260206000200154905092915050565b60006116de8383611e62565b60005460ff166108bb5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401611362565b606081600001805480602002602001604051908101604052809291908181526020018280548015611e0757602002820191906000526020600020905b815481526020019060010190808311611df3575b50505050509050919050565b6000818152600183016020526040812054611e5a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d5d565b506000610d5d565b60008181526001830160205260408120548015611f4b576000611e8660018361245f565b8554909150600090611e9a9060019061245f565b9050818114611eff576000866000018281548110611eba57611eba6123f2565b9060005260206000200154905080876000018481548110611edd57611edd6123f2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611f1057611f10612530565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d5d565b6000915050610d5d565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611f8c5750600090506003612039565b8460ff16601b14158015611fa457508460ff16601c14155b15611fb55750600090506004612039565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612009573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661203257600060019250925050612039565b9150600090505b94509492505050565b6000806001600160ff1b0383168161205f60ff86901c601b612498565b905061206d87828885611f55565b935093505050935093915050565b60008060006040848603121561209057600080fd5b833567ffffffffffffffff808211156120a857600080fd5b90850190608082880312156120bc57600080fd5b909350602085013590808211156120d257600080fd5b818601915086601f8301126120e657600080fd5b8135818111156120f557600080fd5b87602082850101111561210757600080fd5b6020830194508093505050509250925092565b60006020828403121561212c57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156121745783516001600160a01b03168352928401929184019160010161214f565b50909695505050505050565b80356001600160a01b038116811461219757600080fd5b919050565b6000602082840312156121ae57600080fd5b6116de82612180565b6020808252825182820181905260009190848201906040850190845b81811015612174578351835292840192918401916001016121d3565b6000806040838503121561220257600080fd5b61220b83612180565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561225257612252612219565b60405290565b6040516060810167ffffffffffffffff8111828210171561225257612252612219565b604051601f8201601f1916810167ffffffffffffffff811182821017156122a4576122a4612219565b604052919050565b6000608082360312156122be57600080fd5b6122c661222f565b6122cf83612180565b815260208084013567ffffffffffffffff808211156122ed57600080fd5b9085019036601f83011261230057600080fd5b81358181111561231257612312612219565b612320848260051b0161227b565b8181528481019250606091820284018501913683111561233f57600080fd5b938501935b828510156123895780853603121561235c5760008081fd5b612364612258565b8535815286860135878201526040808701359082015284529384019392850192612344565b948601525050506040848101359083015292830135928101929092525090565b6000808335601e198436030181126123c057600080fd5b83018035915067ffffffffffffffff8211156123db57600080fd5b6020019150606081023603821315611b7357600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561243857612438612408565b500290565b60008261245a57634e487b7160e01b600052601260045260246000fd5b500490565b60008282101561247157612471612408565b500390565b60006020828403121561248857600080fd5b815180151581146116de57600080fd5b600082198211156124ab576124ab612408565b500190565b6000602082840312156124c257600080fd5b5051919050565b60006000198214156124dd576124dd612408565b5060010190565b815160009082906020808601845b8381101561250e578151855293820193908201906001016124f2565b50929695505050505050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122071842cb8c5c916bebf1796de4d9211aad58af8f64b1c86c18c7cfd47234265e264736f6c63430008090033000000000000000000000000865515f201a511da9dea4ffe9250657e54dbd915000000000000000000000000cfc38d15cc4642ae6ad2df238649406d21420a530000000000000000000000005a57d7c2a83db9027209877555d9ec6933c2477c000000000000000000000000b763f1177e9b2fb66fbe0d50372e3e2575c043e5
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101375760003560e01c806375ce5202116100b8578063a7ecd37e1161007c578063a7ecd37e146102c6578063be9a6555146102d9578063d359ff92146102e2578063d8ee36cb1461038c578063e9fad8ee1461039f578063f7c618c1146103a757600080fd5b806375ce5202146102605780637ba6f4581461026857806385b12c7c146102885780638da5cb5b1461029b578063a694fc3a146102b357600080fd5b806341d4a1ab116100ff57806341d4a1ab146101af5780635aa68ac0146101ee5780635c975abb1461020357806370a082311461021957806372f702f31461023957600080fd5b80630fb5a6b41461013c57806318160ddd14610176578063288502931461017f5780632e1a7d4d14610194578063385df649146101a7575b600080fd5b6101637f0000000000000000000000000000000000000000000000000000000002c7ea0081565b6040519081526020015b60405180910390f35b61016360045481565b61019261018d36600461207b565b6103ce565b005b6101926101a236600461211a565b6105a0565b610192610878565b6101d67f000000000000000000000000b763f1177e9b2fb66fbe0d50372e3e2575c043e581565b6040516001600160a01b03909116815260200161016d565b6101f66108c5565b60405161016d9190612133565b60005460ff16604051901515815260200161016d565b61016361022736600461219c565b60056020526000908152604090205481565b6101d67f000000000000000000000000cfc38d15cc4642ae6ad2df238649406d21420a5381565b6101926108d6565b61027b61027636600461219c565b610d39565b60405161016d91906121b7565b61019261029636600461211a565b610d63565b6000546101d69061010090046001600160a01b031681565b6101926102c136600461211a565b610db9565b6101926102d436600461219c565b61105b565b61016360035481565b6103646102f03660046121ef565b6001600160a01b0391909116600081815260076020908152604080832094835293815283822084516080810186528154815260018201548184019081526002830154828801908152600390930154606083019081529585526005909352949092205493519051915192519394909391929190565b604080519586526020860194909452928401919091526060830152608082015260a00161016d565b6001546101d6906001600160a01b031681565b6101926110ad565b6101d67f0000000000000000000000005a57d7c2a83db9027209877555d9ec6933c2477c81565b6103d6611320565b6103e3602084018461219c565b6001600160a01b0316336001600160a01b031614610414576040516357b9b1c760e11b815260040160405180910390fd5b6000610427610422856122ac565b61136b565b9050836060013542111561044e576040516341524ecf60e11b815260040160405180910390fd5b60008181526002602052604090205460ff161561047e57604051633b4f091f60e21b815260040160405180910390fd5b6000818152600260205260409020805460ff19166001908117909155546001600160a01b03166104ec6104b0836113f9565b85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061144792505050565b6001600160a01b03161461051357604051638baa579f60e01b815260040160405180910390fd5b600061052260208601866123a9565b9050905060005b8181101561059857610590610541602088018861219c565b61054e60208901896123a9565b8481811061055e5761055e6123f2565b6060029190910135905061057560208a018a6123a9565b85818110610585576105856123f2565b90506060020161146b565b600101610529565b505050505050565b806105be576040516301a2868b60e31b815260040160405180910390fd5b336000818152600560205260409020546105eb5760405163e65ff00d60e01b815260040160405180910390fd5b6001600160a01b038116600090815260066020526040812061060c906116c8565b905060008167ffffffffffffffff81111561062957610629612219565b604051908082528060200260200182016040528015610652578160200160208202803683370190505b50905060005b8281101561071a576001600160a01b038416600090815260066020526040812061068290836116d2565b6001600160a01b038616600081815260076020908152604080832085845282528083209383526005909152902054600182015492935090916106c590899061241e565b6106cf919061243d565b8160010160008282546106e2919061245f565b909155505060018101546107105781848481518110610703576107036123f2565b6020026020010181815250505b5050600101610658565b5061072581846116e5565b6001600160a01b0383166000908152600560205260408120805486929061074d90849061245f565b925050819055508360046000828254610766919061245f565b909155505060405163a9059cbb60e01b8152336004820152602481018590526000907f000000000000000000000000cfc38d15cc4642ae6ad2df238649406d21420a536001600160a01b03169063a9059cbb90604401602060405180830381600087803b1580156107d657600080fd5b505af11580156107ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080e9190612476565b90508061082e57604051631d42c86760e21b815260040160405180910390fd5b836001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243648660405161086991815260200190565b60405180910390a25050505050565b60005461010090046001600160a01b031633146108a85760405163ea8e4eb560e01b815260040160405180910390fd5b60005460ff16156108bd576108bb611795565b565b6108bb6117e7565b60606108d16008611824565b905090565b60005461010090046001600160a01b031633146109065760405163ea8e4eb560e01b815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000002c7ea006003546109349190612498565b4210156109545760405163e2723eb560e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000907f0000000000000000000000005a57d7c2a83db9027209877555d9ec6933c2477c6001600160a01b0316906370a082319060240160206040518083038186803b1580156109b657600080fd5b505afa1580156109ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ee91906124b0565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000b763f1177e9b2fb66fbe0d50372e3e2575c043e516906370a082319060240160206040518083038186803b158015610a5357600080fd5b505afa158015610a67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8b91906124b0565b90508115610be157600080546040516370a0823160e01b81523060048201526001600160a01b037f0000000000000000000000005a57d7c2a83db9027209877555d9ec6933c2477c81169263a9059cbb926101009091049091169083906370a082319060240160206040518083038186803b158015610b0957600080fd5b505afa158015610b1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4191906124b0565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015610b8757600080fd5b505af1158015610b9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbf9190612476565b905080610bdf5760405163d48c254760e01b815260040160405180910390fd5b505b8015610d3557600080546040516370a0823160e01b81523060048201526001600160a01b037f000000000000000000000000b763f1177e9b2fb66fbe0d50372e3e2575c043e581169263a9059cbb926101009091049091169083906370a082319060240160206040518083038186803b158015610c5d57600080fd5b505afa158015610c71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9591906124b0565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015610cdb57600080fd5b505af1158015610cef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d139190612476565b905080610d335760405163673745a960e11b815260040160405180910390fd5b505b5050565b6001600160a01b0381166000908152600660205260409020606090610d5d90611824565b92915050565b60005461010090046001600160a01b03163314610d935760405163ea8e4eb560e01b815260040160405180910390fd5b60035415610db457604051639606826760e01b815260040160405180910390fd5b600355565b610dc1611320565b6003541580610dd1575060035442105b15610def576040516309fb928560e21b815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000002c7ea00600354610e1d9190612498565b421115610e3d57604051632e95ae4160e21b815260040160405180910390fd5b80610e5b576040516301a2868b60e31b815260040160405180910390fd5b33600081815260076020908152604080832042808552925280832090516323b872dd60e01b81526004810185905230602482015260448101869052919290916001600160a01b037f000000000000000000000000cfc38d15cc4642ae6ad2df238649406d21420a5316906323b872dd90606401602060405180830381600087803b158015610ee857600080fd5b505af1158015610efc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f209190612476565b905080610f4057604051630e5ee9cb60e01b815260040160405180910390fd5b6001600160a01b03841660009081526005602052604081208054879290610f68908490612498565b90915550506001600160a01b0384166000908152600660205260409020610f8f9084611831565b15610fce5784826000016000828254610fa89190612498565b9250508190555084826001016000828254610fc39190612498565b90915550610ffc9050565b6001600160a01b0384166000908152600660205260409020610ff09084611849565b50848255600182018590555b846004600082825461100e9190612498565b9091555061101f9050600885611855565b50836001600160a01b03167febedb8b3c678666e7f36970bc8f57abf6d8fa2e828c0da91ea5b75bf68ed101a8460405161086991815260200190565b60005461010090046001600160a01b0316331461108b5760405163ea8e4eb560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b336000818152600560205260409020546110da5760405163e65ff00d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602090815260408083205460069092528220909190611109906116c8565b905060008167ffffffffffffffff81111561112657611126612219565b60405190808252806020026020018201604052801561114f578160200160208202803683370190505b50905060005b828110156111d9576001600160a01b038516600090815260066020526040812061117f90836116d2565b6001600160a01b03871660009081526007602090815260408083208484529091528120600181019190915584519192509082908590859081106111c4576111c46123f2565b60209081029190910101525050600101611155565b506111e481856116e5565b6001600160a01b03841660009081526005602052604081208190556004805485929061121190849061245f565b909155505060405163a9059cbb60e01b8152336004820152602481018490526000907f000000000000000000000000cfc38d15cc4642ae6ad2df238649406d21420a536001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561128157600080fd5b505af1158015611295573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b99190612476565b9050806112d957604051631d42c86760e21b815260040160405180910390fd5b6112e460088661186a565b50846001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243648560405161086991815260200190565b60005460ff16156108bb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064015b60405180910390fd5b60007f8b16c4c34ac81a8e1def2c13e0b64dcd9da40639eb7af000e952c3aa4da143cc82600001516113a0846020015161187f565b604080860151606080880151835160208101979097526001600160a01b039095169286019290925290840191909152608083015260a082015260c001604051602081830303815290604052805190602001209050919050565b6000610d5d6114066119e3565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006114568585611b0a565b9150915061146381611b7a565b509392505050565b6001600160a01b0383166000908152600760209081526040808320858452825290912090820135156115805781602001358160020160008282546114af9190612498565b909155505060405163a9059cbb60e01b81526001600160a01b038581166004830152602084013560248301526000917f0000000000000000000000005a57d7c2a83db9027209877555d9ec6933c2477c9091169063a9059cbb90604401602060405180830381600087803b15801561152657600080fd5b505af115801561153a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155e9190612476565b90508061157e5760405163d48c254760e01b815260040160405180910390fd5b505b6040820135156116715781604001358160030160008282546115a29190612498565b90915550506040805163a9059cbb60e01b81526001600160a01b0386811660048301529184013560248201526000917f000000000000000000000000b763f1177e9b2fb66fbe0d50372e3e2575c043e5169063a9059cbb90604401602060405180830381600087803b15801561161757600080fd5b505af115801561162b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164f9190612476565b90508061166f5760405163673745a960e11b815260040160405180910390fd5b505b6040805184815260208481013590820152838201358183015290516001600160a01b038616917f4534f107610758c3931de9ad1e176476fcfb8c74adf920167e1d54ee84fcfe76919081900360600190a250505050565b6000610d5d825490565b60006116de8383611d38565b9392505050565b6000805b835181101561177a57838181518110611704576117046123f2565b6020026020010151600014611772578161171d816124c9565b925050611770848281518110611735576117356123f2565b602002602001015160066000866001600160a01b03166001600160a01b03168152602001908152602001600020611d6290919063ffffffff16565b505b6001016116e9565b508083511415610d335761178f60088361186a565b50505050565b61179d611d6e565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6117ef611320565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586117ca3390565b606060006116de83611db7565b600081815260018301602052604081205415156116de565b60006116de8383611e13565b60006116de836001600160a01b038416611e13565b60006116de836001600160a01b038416611e62565b600080825167ffffffffffffffff81111561189c5761189c612219565b6040519080825280602002602001820160405280156118c5578160200160208202803683370190505b50905060005b83518110156119b3577f247ed61a441b4e531a3b79e9e84c51c0767cebeef54ba4077173eb646af2297f848281518110611907576119076123f2565b602002602001015160000151858381518110611925576119256123f2565b602002602001015160200151868481518110611943576119436123f2565b602002602001015160400151604051602001611978949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001208282815181106119a0576119a06123f2565b60209081029190910101526001016118cb565b50806040516020016119c591906124e4565b60405160208183030381529060405280519060200120915050919050565b6000306001600160a01b037f0000000000000000000000001aa3aa59de12f4d07a2e3a9c31a27b763c99df6616148015611a3c57507f000000000000000000000000000000000000000000000000000000000000008946145b15611a6657507f07c0fc73334fb2b59cdca854192c3e26d6fe8441cc76fae99b63207f836250fc90565b50604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527f9fa3d2645b1ff41433ec4b5f960209c281de228aa0055a14990a6eba0fedc0f2828401527f06c015bd22b4c69690933c1058878ebdfef31f9aaae40bbe86d8a09fe1b2972c60608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b600080825160411415611b415760208301516040840151606085015160001a611b3587828585611f55565b94509450505050611b73565b825160401415611b6b5760208301516040840151611b60868383612042565b935093505050611b73565b506000905060025b9250929050565b6000816004811115611b8e57611b8e61251a565b1415611b975750565b6001816004811115611bab57611bab61251a565b1415611bf95760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401611362565b6002816004811115611c0d57611c0d61251a565b1415611c5b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401611362565b6003816004811115611c6f57611c6f61251a565b1415611cc85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401611362565b6004816004811115611cdc57611cdc61251a565b1415611d355760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401611362565b50565b6000826000018281548110611d4f57611d4f6123f2565b9060005260206000200154905092915050565b60006116de8383611e62565b60005460ff166108bb5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401611362565b606081600001805480602002602001604051908101604052809291908181526020018280548015611e0757602002820191906000526020600020905b815481526020019060010190808311611df3575b50505050509050919050565b6000818152600183016020526040812054611e5a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d5d565b506000610d5d565b60008181526001830160205260408120548015611f4b576000611e8660018361245f565b8554909150600090611e9a9060019061245f565b9050818114611eff576000866000018281548110611eba57611eba6123f2565b9060005260206000200154905080876000018481548110611edd57611edd6123f2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611f1057611f10612530565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d5d565b6000915050610d5d565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611f8c5750600090506003612039565b8460ff16601b14158015611fa457508460ff16601c14155b15611fb55750600090506004612039565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612009573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661203257600060019250925050612039565b9150600090505b94509492505050565b6000806001600160ff1b0383168161205f60ff86901c601b612498565b905061206d87828885611f55565b935093505050935093915050565b60008060006040848603121561209057600080fd5b833567ffffffffffffffff808211156120a857600080fd5b90850190608082880312156120bc57600080fd5b909350602085013590808211156120d257600080fd5b818601915086601f8301126120e657600080fd5b8135818111156120f557600080fd5b87602082850101111561210757600080fd5b6020830194508093505050509250925092565b60006020828403121561212c57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156121745783516001600160a01b03168352928401929184019160010161214f565b50909695505050505050565b80356001600160a01b038116811461219757600080fd5b919050565b6000602082840312156121ae57600080fd5b6116de82612180565b6020808252825182820181905260009190848201906040850190845b81811015612174578351835292840192918401916001016121d3565b6000806040838503121561220257600080fd5b61220b83612180565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561225257612252612219565b60405290565b6040516060810167ffffffffffffffff8111828210171561225257612252612219565b604051601f8201601f1916810167ffffffffffffffff811182821017156122a4576122a4612219565b604052919050565b6000608082360312156122be57600080fd5b6122c661222f565b6122cf83612180565b815260208084013567ffffffffffffffff808211156122ed57600080fd5b9085019036601f83011261230057600080fd5b81358181111561231257612312612219565b612320848260051b0161227b565b8181528481019250606091820284018501913683111561233f57600080fd5b938501935b828510156123895780853603121561235c5760008081fd5b612364612258565b8535815286860135878201526040808701359082015284529384019392850192612344565b948601525050506040848101359083015292830135928101929092525090565b6000808335601e198436030181126123c057600080fd5b83018035915067ffffffffffffffff8211156123db57600080fd5b6020019150606081023603821315611b7357600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561243857612438612408565b500290565b60008261245a57634e487b7160e01b600052601260045260246000fd5b500490565b60008282101561247157612471612408565b500390565b60006020828403121561248857600080fd5b815180151581146116de57600080fd5b600082198211156124ab576124ab612408565b500190565b6000602082840312156124c257600080fd5b5051919050565b60006000198214156124dd576124dd612408565b5060010190565b815160009082906020808601845b8381101561250e578151855293820193908201906001016124f2565b50929695505050505050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122071842cb8c5c916bebf1796de4d9211aad58af8f64b1c86c18c7cfd47234265e264736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000865515f201a511da9dea4ffe9250657e54dbd915000000000000000000000000cfc38d15cc4642ae6ad2df238649406d21420a530000000000000000000000005a57d7c2a83db9027209877555d9ec6933c2477c000000000000000000000000b763f1177e9b2fb66fbe0d50372e3e2575c043e5
-----Decoded View---------------
Arg [0] : _claimSigner (address): 0x865515F201a511Da9deA4FFE9250657e54dBd915
Arg [1] : _stakingToken (address): 0xCFC38d15cc4642ae6AD2dF238649406d21420a53
Arg [2] : _rewardToken (address): 0x5a57D7c2a83DB9027209877555d9Ec6933c2477c
Arg [3] : _bonusToken (address): 0xb763F1177E9B2Fb66FBe0d50372E3e2575c043e5
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000865515f201a511da9dea4ffe9250657e54dbd915
Arg [1] : 000000000000000000000000cfc38d15cc4642ae6ad2df238649406d21420a53
Arg [2] : 0000000000000000000000005a57d7c2a83db9027209877555d9ec6933c2477c
Arg [3] : 000000000000000000000000b763f1177e9b2fb66fbe0d50372e3e2575c043e5
Deployed Bytecode Sourcemap
552:9401:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1565:44;;;;;;;;160:25:12;;;148:2;133:18;1565:44:4;;;;;;;;1791:26;;;;;;4558:696;;;;;;:::i;:::-;;:::i;:::-;;6278:929;;;;;;:::i;:::-;;:::i;9077:124::-;;;:::i;1526:34::-;;;;;;;;-1:-1:-1;;;;;1419:32:12;;;1401:51;;1389:2;1374:18;1526:34:4;1240:218:12;7213:109:4;;;:::i;:::-;;;;;;;:::i;1608:84:7:-;1655:4;1678:7;;;1608:84;;2291:14:12;;2284:22;2266:41;;2254:2;2239:18;1608:84:7;2126:187:12;1864:44:4;;;;;;:::i;:::-;;;;;;;;;;;;;;1445:36;;;;;9207:635;;;:::i;5260:141::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;8950:121::-;;;;;;:::i;:::-;;:::i;1616:20::-;;;;;;;;-1:-1:-1;;;;;1616:20:4;;;3050:769;;;;;;:::i;:::-;;:::i;9848:102::-;;;;;;:::i;:::-;;:::i;1747:20::-;;;;;;5407:410;;;;;;:::i;:::-;-1:-1:-1;;;;;5629:20:4;;;;5511:7;5629:20;;;:10;:20;;;;;;;;:32;;;;;;;;;5600:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5684:19;;;:9;:19;;;;;;;;5712:17;;5738;;5764:16;;5789:15;;5684:19;;5712:17;;5738;;5764:16;5789:15;5407:410;;;;;4050:25:12;;;4106:2;4091:18;;4084:34;;;;4134:18;;;4127:34;;;;4192:2;4177:18;;4170:34;4235:3;4220:19;;4213:35;4037:3;4022:19;5407:410:4;3791:463:12;1641:26:4;;;;;-1:-1:-1;;;;;1641:26:4;;;7328:834;;;:::i;1486:35::-;;;;;4558:696;1232:19:7;:17;:19::i;:::-;4686:14:4::1;;::::0;::::1;:6:::0;:14:::1;:::i;:::-;-1:-1:-1::0;;;;;4672:28:4::1;:10;-1:-1:-1::0;;;;;4672:28:4::1;;4668:60;;4709:19;;-1:-1:-1::0;;;4709:19:4::1;;;;;;;;;;;4668:60;4735:17;4755:12;;4760:6:::0;4755:12:::1;:::i;:::-;:4;:12::i;:::-;4735:32;;4796:6;:13;;;4778:15;:31;4774:58;;;4818:14;;-1:-1:-1::0;;;4818:14:4::1;;;;;;;;;;;4774:58;4843:24;::::0;;;:13:::1;:24;::::0;;;;;::::1;;4839:51;;;4876:14;;-1:-1:-1::0;;;4876:14:4::1;;;;;;;;;;;4839:51;4897:24;::::0;;;:13:::1;:24;::::0;;;;:31;;-1:-1:-1;;4897:31:4::1;4924:4;4897:31:::0;;::::1;::::0;;;4997:11;-1:-1:-1;;;;;4997:11:4::1;4939:54;4953:27;4911:9:::0;4953:16:::1;:27::i;:::-;4982:10;;4939:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;4939:13:4::1;::::0;-1:-1:-1;;;4939:54:4:i:1;:::-;-1:-1:-1::0;;;;;4939:69:4::1;;4935:107;;5024:18;;-1:-1:-1::0;;;5024:18:4::1;;;;;;;;;;;4935:107;5049:11;5063:14;;::::0;::::1;:6:::0;:14:::1;:::i;:::-;:21;;5049:35;;5096:9;5091:158;5111:3;5107:1;:7;5091:158;;;5127:72;5136:14;;::::0;::::1;:6:::0;:14:::1;:::i;:::-;5152;;::::0;::::1;:6:::0;:14:::1;:::i;:::-;5167:1;5152:17;;;;;;;:::i;:::-;;;::::0;;;::::1;:27;::::0;-1:-1:-1;5181:14:4::1;;::::0;::::1;:6:::0;:14:::1;:::i;:::-;5196:1;5181:17;;;;;;;:::i;:::-;;;;;;5127:8;:72::i;:::-;5229:3;;5091:158;;;;4661:593;;4558:696:::0;;;:::o;6278:929::-;6333:12;6329:38;;6354:13;;-1:-1:-1;;;6354:13:4;;;;;;;;;;;6329:38;6392:10;6374:15;6413:18;;;:9;:18;;;;;;6409:49;;6445:13;;-1:-1:-1;;;6445:13:4;;;;;;;;;;;6409:49;-1:-1:-1;;;;;6479:15:4;;6465:11;6479:15;;;:6;:15;;;;;:24;;:22;:24::i;:::-;6465:38;;6510:34;6561:3;6547:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6547:18:4;;6510:55;;6577:9;6572:365;6592:3;6588:1;:7;6572:365;;;-1:-1:-1;;;;;6628:15:4;;6608:17;6628:15;;;:6;:15;;;;;:21;;6647:1;6628:18;:21::i;:::-;-1:-1:-1;;;;;6688:19:4;;6658:27;6688:19;;;:10;:19;;;;;;;;:30;;;;;;;;6780:18;;;:9;:18;;;;;;6749:17;;;;6608:41;;-1:-1:-1;6688:30:4;;6749:27;;6769:7;;6749:27;:::i;:::-;6748:50;;;;:::i;:::-;6727:9;:17;;;:71;;;;;;;:::i;:::-;;;;-1:-1:-1;;6811:17:4;;;;6807:81;;6869:9;6846:17;6864:1;6846:20;;;;;;;;:::i;:::-;;;;;;:32;;;;;6807:81;-1:-1:-1;;6917:3:4;;6572:365;;;;6943:45;6961:17;6980:7;6943:17;:45::i;:::-;-1:-1:-1;;;;;6995:18:4;;;;;;:9;:18;;;;;:29;;7017:7;;6995:18;:29;;7017:7;;6995:29;:::i;:::-;;;;;;;;7046:7;7031:11;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;7075:42:4;;-1:-1:-1;;;7075:42:4;;7097:10;7075:42;;;8374:51:12;8441:18;;;8434:34;;;7060:12:4;;7075;-1:-1:-1;;;;;7075:21:4;;;;8347:18:12;;7075:42:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7060:57;;7129:7;7124:37;;7145:16;;-1:-1:-1;;;7145:16:4;;;;;;;;;;;7124:37;7184:7;-1:-1:-1;;;;;7175:26:4;;7193:7;7175:26;;;;160:25:12;;148:2;133:18;;14:177;7175:26:4;;;;;;;;6322:885;;;;6278:929;:::o;9077:124::-;2826:5;;;;;-1:-1:-1;;;;;2826:5:4;2812:10;:19;2808:47;;2840:15;;-1:-1:-1;;;2840:15:4;;;;;;;;;;;2808:47;1655:4:7;1678:7;;;9124:72:4::1;;;9147:10;:8;:10::i;:::-;9077:124::o:0;9124:72::-:1;9180:8;:6;:8::i;7213:109::-:0;7263:16;7295:21;:12;:19;:21::i;:::-;7288:28;;7213:109;:::o;9207:635::-;2826:5;;;;;-1:-1:-1;;;;;2826:5:4;2812:10;:19;2808:47;;2840:15;;-1:-1:-1;;;2840:15:4;;;;;;;;;;;2808:47;9284:8:::1;9276:5;;:16;;;;:::i;:::-;9258:15;:34;9254:60;;;9301:13;;-1:-1:-1::0;;;9301:13:4::1;;;;;;;;;;;9254:60;9345:36;::::0;-1:-1:-1;;;9345:36:4;;9375:4:::1;9345:36;::::0;::::1;1401:51:12::0;9321:21:4::1;::::0;9345:11:::1;-1:-1:-1::0;;;;;9345:21:4::1;::::0;::::1;::::0;1374:18:12;;9345:36:4::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9411:35;::::0;-1:-1:-1;;;9411:35:4;;9440:4:::1;9411:35;::::0;::::1;1401:51:12::0;9321:60:4;;-1:-1:-1;9388:20:4::1;::::0;-1:-1:-1;;;;;9411:10:4::1;:20;::::0;::::1;::::0;1374:18:12;;9411:35:4::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9388:58:::0;-1:-1:-1;9457:17:4;;9453:191:::1;;9485:12;9531:5:::0;;9547:36:::1;::::0;-1:-1:-1;;;9547:36:4;;9577:4:::1;9547:36;::::0;::::1;1401:51:12::0;-1:-1:-1;;;;;9500:11:4::1;:20:::0;::::1;::::0;::::1;::::0;9531:5:::1;::::0;;::::1;::::0;;::::1;::::0;9500:20;;9547:21:::1;::::0;1374:18:12;;9547:36:4::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9500:92;::::0;-1:-1:-1;;;;;;9500:92:4::1;::::0;;;;;;-1:-1:-1;;;;;8392:32:12;;;9500:92:4::1;::::0;::::1;8374:51:12::0;8441:18;;;8434:34;8347:18;;9500:92:4::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9485:107;;9606:7;9601:35;;9622:14;;-1:-1:-1::0;;;9622:14:4::1;;;;;;;;;;;9601:35;9476:168;9453:191;9654:16:::0;;9650:187:::1;;9681:12;9726:5:::0;;9742:35:::1;::::0;-1:-1:-1;;;9742:35:4;;9771:4:::1;9742:35;::::0;::::1;1401:51:12::0;-1:-1:-1;;;;;9696:10:4::1;:19:::0;::::1;::::0;::::1;::::0;9726:5:::1;::::0;;::::1;::::0;;::::1;::::0;9696:19;;9742:20:::1;::::0;1374:18:12;;9742:35:4::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9696:90;::::0;-1:-1:-1;;;;;;9696:90:4::1;::::0;;;;;;-1:-1:-1;;;;;8392:32:12;;;9696:90:4::1;::::0;::::1;8374:51:12::0;8441:18;;;8434:34;8347:18;;9696:90:4::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9681:105;;9800:7;9795:34;;9816:13;;-1:-1:-1::0;;;9816:13:4::1;;;;;;;;;;;9795:34;9672:165;9650:187;9247:595;;9207:635::o:0;5260:141::-;-1:-1:-1;;;;;5370:16:4;;;;;;:6;:16;;;;;5335;;5370:25;;:23;:25::i;:::-;5363:32;5260:141;-1:-1:-1;;5260:141:4:o;8950:121::-;2826:5;;;;;-1:-1:-1;;;;;2826:5:4;2812:10;:19;2808:47;;2840:15;;-1:-1:-1;;;2840:15:4;;;;;;;;;;;2808:47;9012:5:::1;::::0;:10;9008:36:::1;;9031:13;;-1:-1:-1::0;;;9031:13:4::1;;;;;;;;;;;9008:36;9051:5;:14:::0;8950:121::o;3050:769::-;1232:19:7;:17;:19::i;:::-;2905:5:4::1;::::0;:10;;:37:::1;;;2937:5;;2919:15;:23;2905:37;2901:64;;;2951:14;;-1:-1:-1::0;;;2951:14:4::1;;;;;;;;;;;2901:64;3002:8;2994:5;;:16;;;;:::i;:::-;2976:15;:34;2972:58;;;3019:11;;-1:-1:-1::0;;;3019:11:4::1;;;;;;;;;;;2972:58;3124:12:::0;3120:38:::2;;3145:13;;-1:-1:-1::0;;;3145:13:4::2;;;;;;;;;;;3120:38;3183:10;3165:15;3272:19:::0;;;:10:::2;:19;::::0;;;;;;;3220:15:::2;3272:30:::0;;;;;;;;3324:58;;-1:-1:-1;;;3324:58:4;;::::2;::::0;::::2;9323:34:12::0;;;3367:4:4::2;9373:18:12::0;;;9366:43;9425:18;;;9418:34;;;3220:15:4;;3272:30;;-1:-1:-1;;;;;3324:12:4::2;:25;::::0;::::2;::::0;9258:18:12;;3324:58:4::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3309:73;;3394:7;3389:34;;3410:13;;-1:-1:-1::0;;;3410:13:4::2;;;;;;;;;;;3389:34;-1:-1:-1::0;;;;;3430:18:4;::::2;;::::0;;;:9:::2;:18;::::0;;;;:29;;3452:7;;3430:18;:29:::2;::::0;3452:7;;3430:29:::2;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;3470:15:4;::::2;;::::0;;;:6:::2;:15;::::0;;;;:35:::2;::::0;3495:9;3470:24:::2;:35::i;:::-;3466:248;;;3537:7;3516:9;:17;;;:28;;;;;;;:::i;:::-;;;;;;;;3574:7;3553:9;:17;;;:28;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;3466:248:4::2;::::0;-1:-1:-1;3466:248:4::2;;-1:-1:-1::0;;;;;3604:15:4;::::2;;::::0;;;:6:::2;:15;::::0;;;;:30:::2;::::0;3624:9;3604:19:::2;:30::i;:::-;-1:-1:-1::0;3643:27:4;;;3679:17:::2;::::0;::::2;:27:::0;;;3466:248:::2;3735:7;3720:11;;:22;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;3749:25:4::2;::::0;-1:-1:-1;3749:12:4::2;3766:7:::0;3749:16:::2;:25::i;:::-;;3794:7;-1:-1:-1::0;;;;;3788:25:4::2;;3803:9;3788:25;;;;160::12::0;;148:2;133:18;;14:177;9848:102:4;2826:5;;;;;-1:-1:-1;;;;;2826:5:4;2812:10;:19;2808:47;;2840:15;;-1:-1:-1;;;2840:15:4;;;;;;;;;;;2808:47;9918:11:::1;:26:::0;;-1:-1:-1;;;;;;9918:26:4::1;-1:-1:-1::0;;;;;9918:26:4;;;::::1;::::0;;;::::1;::::0;;9848:102::o;7328:834::-;7378:10;7360:15;7399:18;;;:9;:18;;;;;;7395:49;;7431:13;;-1:-1:-1;;;7431:13:4;;;;;;;;;;;7395:49;-1:-1:-1;;;;;7468:18:4;;7451:14;7468:18;;;:9;:18;;;;;;;;;7507:6;:15;;;;;7468:18;;7451:14;7507:24;;:22;:24::i;:::-;7493:38;;7538:34;7589:3;7575:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7575:18:4;;7538:55;;7605:9;7600:267;7620:3;7616:1;:7;7600:267;;;-1:-1:-1;;;;;7656:15:4;;7636:17;7656:15;;;:6;:15;;;;;:21;;7675:1;7656:18;:21::i;:::-;-1:-1:-1;;;;;7716:19:4;;7686:27;7716:19;;;:10;:19;;;;;;;;:30;;;;;;;;7755:17;;;:21;;;;7785:20;;7636:41;;-1:-1:-1;7716:30:4;7636:41;;7785:17;;7803:1;;7785:20;;;;;;:::i;:::-;;;;;;;;;;:32;-1:-1:-1;;7847:3:4;;7600:267;;;;7873:45;7891:17;7910:7;7873:17;:45::i;:::-;-1:-1:-1;;;;;7925:18:4;;7946:1;7925:18;;;:9;:18;;;;;:22;;;7954:11;:21;;7969:6;;7946:1;7954:21;;7969:6;;7954:21;:::i;:::-;;;;-1:-1:-1;;7997:41:4;;-1:-1:-1;;;7997:41:4;;8019:10;7997:41;;;8374:51:12;8441:18;;;8434:34;;;7982:12:4;;7997;-1:-1:-1;;;;;7997:21:4;;;;8347:18:12;;7997:41:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7982:56;;8050:7;8045:37;;8066:16;;-1:-1:-1;;;8066:16:4;;;;;;;;;;;8045:37;8089:28;:12;8109:7;8089:19;:28::i;:::-;;8140:7;-1:-1:-1;;;;;8131:25:4;;8149:6;8131:25;;;;160::12;;148:2;133:18;;14:177;1760:106:7;1655:4;1678:7;;;1829:9;1821:38;;;;-1:-1:-1;;;1821:38:7;;9665:2:12;1821:38:7;;;9647:21:12;9704:2;9684:18;;;9677:30;-1:-1:-1;;;9723:18:12;;;9716:46;9779:18;;1821:38:7;;;;;;;;8673:271:4;8729:7;915:160;8825:5;:13;;;8851:19;8856:5;:13;;;8851:4;:19::i;:::-;8883:10;;;;;8906:12;;;;;8779:150;;;;;10067:25:12;;;;-1:-1:-1;;;;;10128:32:12;;;10108:18;;;10101:60;;;;10177:18;;;10170:34;;;;10220:18;;;10213:34;10263:19;;;10256:35;10039:19;;8779:150:4;;;;;;;;;;;;8759:179;;;;;;8745:193;;8673:271;;;:::o;4339:165:10:-;4416:7;4442:55;4464:20;:18;:20::i;:::-;4486:10;9319:57:2;;-1:-1:-1;;;9319:57:2;;;11968:27:12;12011:11;;;12004:27;;;12047:12;;;12040:28;;;9283:7:2;;12084:12:12;;9319:57:2;;;;;;;;;;;;9309:68;;;;;;9302:75;;9190:194;;;;;4401:227;4479:7;4499:17;4518:18;4540:27;4551:4;4557:9;4540:10;:27::i;:::-;4498:69;;;;4577:18;4589:5;4577:11;:18::i;:::-;-1:-1:-1;4612:9:2;4401:227;-1:-1:-1;;;4401:227:2:o;3825:727:4:-;-1:-1:-1;;;;;3971:20:4;;3941:27;3971:20;;;:10;:20;;;;;;;;:32;;;;;;;;;4014:20;;;:24;4010:207;;4069:7;:20;;;4049:9;:16;;;:40;;;;;;;:::i;:::-;;;;-1:-1:-1;;4113:52:4;;-1:-1:-1;;;4113:52:4;;-1:-1:-1;;;;;8392:32:12;;;4113:52:4;;;8374:51:12;4144:20:4;;;;8441:18:12;;;8434:34;4098:12:4;;4113:11;:20;;;;;;8347:18:12;;4113:52:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4098:67;;4179:7;4174:35;;4195:14;;-1:-1:-1;;;4195:14:4;;;;;;;;;;;4174:35;4040:177;4010:207;4229:19;;;;:23;4225:201;;4282:7;:19;;;4263:9;:15;;;:38;;;;;;;:::i;:::-;;;;-1:-1:-1;;4355:19:4;4325:50;;-1:-1:-1;;;4325:50:4;;-1:-1:-1;;;;;8392:32:12;;;4325:50:4;;;8374:51:12;4355:19:4;;;;8441:18:12;;;8434:34;4310:12:4;;4325:10;:19;;;;8347:18:12;;4325:50:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4310:65;;4389:7;4384:34;;4405:13;;-1:-1:-1;;;4405:13:4;;;;;;;;;;;4384:34;4254:172;4225:201;4520:19;4439:107;;10504:25:12;;;4491:20:4;;;;;10545:18:12;;;10538:34;4520:19:4;;;;10588:18:12;;;10581:34;4439:107:4;;-1:-1:-1;;;;;4439:107:4;;;;;;;;;10492:2:12;4439:107:4;;;3934:618;3825:727;;;:::o;11254:112:3:-;11314:7;11340:19;11348:3;4444:18;;4362:107;11708:135;11779:7;11813:22;11817:3;11829:5;11813:3;:22::i;:::-;11805:31;11708:135;-1:-1:-1;;;11708:135:3:o;5823:449:4:-;5933:13;5962:9;5957:220;5977:17;:24;5973:1;:28;5957:220;;;6018:17;6036:1;6018:20;;;;;;;;:::i;:::-;;;;;;;6042:1;6018:25;6014:114;;6056:7;;;;:::i;:::-;;;;6074:44;6097:17;6115:1;6097:20;;;;;;;;:::i;:::-;;;;;;;6074:6;:15;6081:7;-1:-1:-1;;;;;6074:15:4;-1:-1:-1;;;;;6074:15:4;;;;;;;;;;;;:22;;:44;;;;:::i;:::-;;6014:114;6157:3;;5957:220;;;;6215:5;6187:17;:24;:33;6183:84;;;6231:28;:12;6251:7;6231:19;:28::i;:::-;;5926:346;5823:449;;:::o;2426:117:7:-;1479:16;:14;:16::i;:::-;2494:5:::1;2484:15:::0;;-1:-1:-1;;2484:15:7::1;::::0;;2514:22:::1;719:10:1::0;2523:12:7::1;2514:22;::::0;-1:-1:-1;;;;;1419:32:12;;;1401:51;;1389:2;1374:18;2514:22:7::1;;;;;;;2426:117::o:0;2179:115::-;1232:19;:17;:19::i;:::-;2238:7:::1;:14:::0;;-1:-1:-1;;2238:14:7::1;2248:4;2238:14;::::0;;2267:20:::1;2274:12;719:10:1::0;;640:96;9982:300:3;10045:16;10073:22;10098:19;10106:3;10098:7;:19::i;11029:144::-;11106:4;4250:19;;;:12;;;:19;;;;;;:24;;11129:37;4154:127;10516:129;10583:4;10606:32;10611:3;10631:5;10606:4;:32::i;8028:150::-;8098:4;8121:50;8126:3;-1:-1:-1;;;;;8146:23:3;;8121:4;:50::i;8346:156::-;8419:4;8442:53;8450:3;-1:-1:-1;;;;;8470:23:3;;8442:7;:53::i;8168:499:4:-;8229:7;8245:28;8290:7;:14;8276:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8276:29:4;;8245:60;;8317:9;8312:296;8336:7;:14;8332:1;:18;8312:296;;;774:93;8447:7;8455:1;8447:10;;;;;;;;:::i;:::-;;;;;;;:20;;;8480:7;8488:1;8480:10;;;;;;;;:::i;:::-;;;;;;;:23;;;8516:7;8524:1;8516:10;;;;;;;;:::i;:::-;;;;;;;:22;;;8400:149;;;;;;;;;;10997:25:12;;;11053:2;11038:18;;11031:34;;;;11096:2;11081:18;;11074:34;11139:2;11124:18;;11117:34;10984:3;10969:19;;10766:391;8400:149:4;;;;;;;;;;;;;8380:178;;;;;;8363:11;8375:1;8363:14;;;;;;;;:::i;:::-;;;;;;;;;;:195;8588:3;;8312:296;;;;8648:11;8631:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;8621:40;;;;;;8614:47;;;8168:499;;;:::o;3143:308:10:-;3196:7;3227:4;-1:-1:-1;;;;;3236:12:10;3219:29;;:66;;;;;3269:16;3252:13;:33;3219:66;3215:230;;;-1:-1:-1;3308:24:10;;3143:308::o;3215:230::-;-1:-1:-1;3633:73:10;;;3392:10;3633:73;;;;14498:25:12;;;;3404:12:10;14539:18:12;;;14532:34;3418:15:10;14582:18:12;;;14575:34;3677:13:10;14625:18:12;;;14618:34;3700:4:10;14668:19:12;;;;14661:61;;;;3633:73:10;;;;;;;;;;14470:19:12;;;;3633:73:10;;;3623:84;;;;;;7213:109:4:o;2242:1373:2:-;2323:7;2332:12;2553:9;:16;2573:2;2553:22;2549:1060;;;2889:4;2874:20;;2868:27;2938:4;2923:20;;2917:27;2995:4;2980:20;;2974:27;2591:9;2966:36;3036:25;3047:4;2966:36;2868:27;2917;3036:10;:25::i;:::-;3029:32;;;;;;;;;2549:1060;3082:9;:16;3102:2;3082:22;3078:531;;;3398:4;3383:20;;3377:27;3448:4;3433:20;;3427:27;3488:23;3499:4;3377:27;3427;3488:10;:23::i;:::-;3481:30;;;;;;;;3078:531;-1:-1:-1;3558:1:2;;-1:-1:-1;3562:35:2;3078:531;2242:1373;;;;;:::o;547:631::-;624:20;615:5;:29;;;;;;;;:::i;:::-;;611:561;;;547:631;:::o;611:561::-;720:29;711:5;:38;;;;;;;;:::i;:::-;;707:465;;;765:34;;-1:-1:-1;;;765:34:2;;12441:2:12;765:34:2;;;12423:21:12;12480:2;12460:18;;;12453:30;12519:26;12499:18;;;12492:54;12563:18;;765:34:2;12239:348:12;707:465:2;829:35;820:5;:44;;;;;;;;:::i;:::-;;816:356;;;880:41;;-1:-1:-1;;;880:41:2;;12794:2:12;880:41:2;;;12776:21:12;12833:2;12813:18;;;12806:30;12872:33;12852:18;;;12845:61;12923:18;;880:41:2;12592:355:12;816:356:2;951:30;942:5;:39;;;;;;;;:::i;:::-;;938:234;;;997:44;;-1:-1:-1;;;997:44:2;;13154:2:12;997:44:2;;;13136:21:12;13193:2;13173:18;;;13166:30;13232:34;13212:18;;;13205:62;-1:-1:-1;;;13283:18:12;;;13276:32;13325:19;;997:44:2;12952:398:12;938:234:2;1071:30;1062:5;:39;;;;;;;;:::i;:::-;;1058:114;;;1117:44;;-1:-1:-1;;;1117:44:2;;13557:2:12;1117:44:2;;;13539:21:12;13596:2;13576:18;;;13569:30;13635:34;13615:18;;;13608:62;-1:-1:-1;;;13686:18:12;;;13679:32;13728:19;;1117:44:2;13355:398:12;1058:114:2;547:631;:::o;4811:118:3:-;4878:7;4904:3;:11;;4916:5;4904:18;;;;;;;;:::i;:::-;;;;;;;;;4897:25;;4811:118;;;;:::o;10813:135::-;10883:4;10906:35;10914:3;10934:5;10906:7;:35::i;1938:106:7:-;1655:4;1678:7;;;1996:41;;;;-1:-1:-1;;;1996:41:7;;13960:2:12;1996:41:7;;;13942:21:12;13999:2;13979:18;;;13972:30;-1:-1:-1;;;14018:18:12;;;14011:50;14078:18;;1996:41:7;13758:344:12;5469:109:3;5525:16;5560:3;:11;;5553:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5469:109;;;:::o;2113:404::-;2176:4;4250:19;;;:12;;;:19;;;;;;2192:319;;-1:-1:-1;2234:23:3;;;;;;;;:11;:23;;;;;;;;;;;;;2414:18;;2392:19;;;:12;;;:19;;;;;;:40;;;;2446:11;;2192:319;-1:-1:-1;2495:5:3;2488:12;;2685:1388;2751:4;2888:19;;;:12;;;:19;;;;;;2922:15;;2918:1149;;3291:21;3315:14;3328:1;3315:10;:14;:::i;:::-;3363:18;;3291:38;;-1:-1:-1;3343:17:3;;3363:22;;3384:1;;3363:22;:::i;:::-;3343:42;;3417:13;3404:9;:26;3400:398;;3450:17;3470:3;:11;;3482:9;3470:22;;;;;;;;:::i;:::-;;;;;;;;;3450:42;;3621:9;3592:3;:11;;3604:13;3592:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3704:23;;;:12;;;:23;;;;;:36;;;3400:398;3876:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;3968:3;:12;;:19;3981:5;3968:19;;;;;;;;;;;3961:26;;;4009:4;4002:11;;;;;;;2918:1149;4051:5;4044:12;;;;;5809:1603:2;5935:7;;6859:66;6846:79;;6842:161;;;-1:-1:-1;6957:1:2;;-1:-1:-1;6961:30:2;6941:51;;6842:161;7016:1;:7;;7021:2;7016:7;;:18;;;;;7027:1;:7;;7032:2;7027:7;;7016:18;7012:100;;;-1:-1:-1;7066:1:2;;-1:-1:-1;7070:30:2;7050:51;;7012:100;7223:24;;;7206:14;7223:24;;;;;;;;;14960:25:12;;;15033:4;15021:17;;15001:18;;;14994:45;;;;15055:18;;;15048:34;;;15098:18;;;15091:34;;;7223:24:2;;14932:19:12;;7223:24:2;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7223:24:2;;-1:-1:-1;;7223:24:2;;;-1:-1:-1;;;;;;;7261:20:2;;7257:101;;7313:1;7317:29;7297:50;;;;;;;7257:101;7376:6;-1:-1:-1;7384:20:2;;-1:-1:-1;5809:1603:2;;;;;;;;:::o;4882:336::-;4992:7;;-1:-1:-1;;;;;5037:80:2;;4992:7;5143:25;5159:3;5144:18;;;5166:2;5143:25;:::i;:::-;5127:42;;5186:25;5197:4;5203:1;5206;5209;5186:10;:25::i;:::-;5179:32;;;;;;4882:336;;;;;;:::o;196:854:12:-;300:6;308;316;369:2;357:9;348:7;344:23;340:32;337:52;;;385:1;382;375:12;337:52;425:9;412:23;454:18;495:2;487:6;484:14;481:34;;;511:1;508;501:12;481:34;534:22;;;;590:3;572:16;;;568:26;565:46;;;607:1;604;597:12;565:46;630:2;;-1:-1:-1;685:2:12;670:18;;657:32;;701:16;;;698:36;;;730:1;727;720:12;698:36;768:8;757:9;753:24;743:34;;815:7;808:4;804:2;800:13;796:27;786:55;;837:1;834;827:12;786:55;877:2;864:16;903:2;895:6;892:14;889:34;;;919:1;916;909:12;889:34;964:7;959:2;950:6;946:2;942:15;938:24;935:37;932:57;;;985:1;982;975:12;932:57;1016:2;1012;1008:11;998:21;;1038:6;1028:16;;;;;196:854;;;;;:::o;1055:180::-;1114:6;1167:2;1155:9;1146:7;1142:23;1138:32;1135:52;;;1183:1;1180;1173:12;1135:52;-1:-1:-1;1206:23:12;;1055:180;-1:-1:-1;1055:180:12:o;1463:658::-;1634:2;1686:21;;;1756:13;;1659:18;;;1778:22;;;1605:4;;1634:2;1857:15;;;;1831:2;1816:18;;;1605:4;1900:195;1914:6;1911:1;1908:13;1900:195;;;1979:13;;-1:-1:-1;;;;;1975:39:12;1963:52;;2070:15;;;;2035:12;;;;2011:1;1929:9;1900:195;;;-1:-1:-1;2112:3:12;;1463:658;-1:-1:-1;;;;;;1463:658:12:o;2318:173::-;2386:20;;-1:-1:-1;;;;;2435:31:12;;2425:42;;2415:70;;2481:1;2478;2471:12;2415:70;2318:173;;;:::o;2496:186::-;2555:6;2608:2;2596:9;2587:7;2583:23;2579:32;2576:52;;;2624:1;2621;2614:12;2576:52;2647:29;2666:9;2647:29;:::i;2687:632::-;2858:2;2910:21;;;2980:13;;2883:18;;;3002:22;;;2829:4;;2858:2;3081:15;;;;3055:2;3040:18;;;2829:4;3124:169;3138:6;3135:1;3132:13;3124:169;;;3199:13;;3187:26;;3268:15;;;;3233:12;;;;3160:1;3153:9;3124:169;;3532:254;3600:6;3608;3661:2;3649:9;3640:7;3636:23;3632:32;3629:52;;;3677:1;3674;3667:12;3629:52;3700:29;3719:9;3700:29;:::i;:::-;3690:39;3776:2;3761:18;;;;3748:32;;-1:-1:-1;;;3532:254:12:o;4259:127::-;4320:10;4315:3;4311:20;4308:1;4301:31;4351:4;4348:1;4341:15;4375:4;4372:1;4365:15;4391:253;4463:2;4457:9;4505:4;4493:17;;4540:18;4525:34;;4561:22;;;4522:62;4519:88;;;4587:18;;:::i;:::-;4623:2;4616:22;4391:253;:::o;4649:::-;4721:2;4715:9;4763:4;4751:17;;4798:18;4783:34;;4819:22;;;4780:62;4777:88;;;4845:18;;:::i;4907:275::-;4978:2;4972:9;5043:2;5024:13;;-1:-1:-1;;5020:27:12;5008:40;;5078:18;5063:34;;5099:22;;;5060:62;5057:88;;;5125:18;;:::i;:::-;5161:2;5154:22;4907:275;;-1:-1:-1;4907:275:12:o;5187:1640::-;5285:9;5344:4;5336:5;5320:14;5316:26;5312:37;5309:57;;;5362:1;5359;5352:12;5309:57;5390:22;;:::i;:::-;5437:25;5456:5;5437:25;:::i;:::-;5428:7;5421:42;5482:2;5531;5524:5;5520:14;5507:28;5554:18;5595:2;5587:6;5584:14;5581:34;;;5611:1;5608;5601:12;5581:34;5634:18;;;;5690:14;5683:4;5675:13;;5671:34;5661:62;;5719:1;5716;5709:12;5661:62;5755:2;5742:16;5777:2;5773;5770:10;5767:36;;;5783:18;;:::i;:::-;5823:36;5855:2;5850;5847:1;5843:10;5839:19;5823:36;:::i;:::-;5893:15;;;5924:12;;;;-1:-1:-1;5955:4:12;5994:11;;;5986:20;;5982:29;;;6034:14;6023:26;;6020:46;;;6062:1;6059;6052:12;6020:46;6086:11;;;;6106:520;6122:6;6117:3;6114:15;6106:520;;;6209:2;6203:3;6187:14;6183:24;6179:33;6176:123;;;6253:1;6282:2;6278;6271:14;6176:123;6327:22;;:::i;:::-;6378:17;;6362:34;;6447:12;;;6434:26;6416:16;;;6409:52;6484:2;6537:12;;;6524:26;6506:16;;;6499:52;6564:20;;6139:12;;;;6604;;;;6106:520;;;6642:16;;;6635:31;-1:-1:-1;;;6724:2:12;6713:14;;;6700:28;6682:16;;;6675:54;6776:14;;;6763:28;6745:16;;;6738:54;;;;-1:-1:-1;6646:7:12;5187:1640::o;6832:574::-;6951:4;6957:6;7017:11;7004:25;7111:2;7107:7;7096:8;7080:14;7076:29;7072:43;7052:18;7048:68;7038:96;;7130:1;7127;7120:12;7038:96;7157:33;;7209:20;;;-1:-1:-1;7252:18:12;7241:30;;7238:50;;;7284:1;7281;7274:12;7238:50;7317:4;7305:17;;-1:-1:-1;7376:4:12;7364:17;;7348:14;7344:38;7334:49;;7331:69;;;7396:1;7393;7386:12;7411:127;7472:10;7467:3;7463:20;7460:1;7453:31;7503:4;7500:1;7493:15;7527:4;7524:1;7517:15;7543:127;7604:10;7599:3;7595:20;7592:1;7585:31;7635:4;7632:1;7625:15;7659:4;7656:1;7649:15;7675:168;7715:7;7781:1;7777;7773:6;7769:14;7766:1;7763:21;7758:1;7751:9;7744:17;7740:45;7737:71;;;7788:18;;:::i;:::-;-1:-1:-1;7828:9:12;;7675:168::o;7848:217::-;7888:1;7914;7904:132;;7958:10;7953:3;7949:20;7946:1;7939:31;7993:4;7990:1;7983:15;8021:4;8018:1;8011:15;7904:132;-1:-1:-1;8050:9:12;;7848:217::o;8070:125::-;8110:4;8138:1;8135;8132:8;8129:34;;;8143:18;;:::i;:::-;-1:-1:-1;8180:9:12;;8070:125::o;8479:277::-;8546:6;8599:2;8587:9;8578:7;8574:23;8570:32;8567:52;;;8615:1;8612;8605:12;8567:52;8647:9;8641:16;8700:5;8693:13;8686:21;8679:5;8676:32;8666:60;;8722:1;8719;8712:12;8761:128;8801:3;8832:1;8828:6;8825:1;8822:13;8819:39;;;8838:18;;:::i;:::-;-1:-1:-1;8874:9:12;;8761:128::o;8894:184::-;8964:6;9017:2;9005:9;8996:7;8992:23;8988:32;8985:52;;;9033:1;9030;9023:12;8985:52;-1:-1:-1;9056:16:12;;8894:184;-1:-1:-1;8894:184:12:o;10626:135::-;10665:3;-1:-1:-1;;10686:17:12;;10683:43;;;10706:18;;:::i;:::-;-1:-1:-1;10753:1:12;10742:13;;10626:135::o;11162:543::-;11380:13;;11323:3;;11354;;11433:4;11460:15;;;11323:3;11503:175;11517:6;11514:1;11511:13;11503:175;;;11580:13;;11566:28;;11616:14;;;;11653:15;;;;11539:1;11532:9;11503:175;;;-1:-1:-1;11694:5:12;;11162:543;-1:-1:-1;;;;;;11162:543:12:o;12107:127::-;12168:10;12163:3;12159:20;12156:1;12149:31;12199:4;12196:1;12189:15;12223:4;12220:1;12213:15;14107:127;14168:10;14163:3;14159:20;14156:1;14149:31;14199:4;14196:1;14189:15;14223:4;14220:1;14213:15
Swarm Source
ipfs://71842cb8c5c916bebf1796de4d9211aad58af8f64b1c86c18c7cfd47234265e2
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 29 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
POL | 100.00% | $0.002465 | 86,622.2636 | $213.5 |
[ 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.