ERC-20
Overview
Max Total Supply
3,152,980.062260522300215722 pxCVX
Holders
294
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
0.000000000000079416 pxCVXValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
PxCvx
Compiler Version
v0.8.12+commit.f00d7308
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-05-31 */ // Sources flattened with hardhat v2.8.3 https://hardhat.org // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @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; } } // File @openzeppelin/contracts/access/[email protected] // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File @openzeppelin/contracts/security/[email protected] // OpenZeppelin Contracts v4.4.1 (security/Pausable.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 Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { 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()); } } // File @openzeppelin/contracts/utils/math/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol) /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a / b + (a % b == 0 ? 0 : 1); } } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol) /** * @dev Collection of functions related to array types. */ library Arrays { /** * @dev Searches a sorted `array` and returns the first index that contains * a value greater or equal to `element`. If no such index exists (i.e. all * values in the array are strictly less than `element`), the array length is * returned. Time complexity O(log n). * * `array` is expected to be sorted in ascending order, and to contain no * repeated elements. */ function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { if (array.length == 0) { return 0; } uint256 low = 0; uint256 high = array.length; while (low < high) { uint256 mid = Math.average(low, high); // Note that mid will always be strictly less than high (i.e. it will be a valid array index) // because Math.average rounds down (it does integer division with truncation). if (array[mid] > element) { high = mid; } else { low = mid + 1; } } // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound. if (low > 0 && array[low - 1] == element) { return low - 1; } else { return low; } } } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @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); } } // File @openzeppelin/contracts/utils/cryptography/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.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. 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. 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)); } } // File contracts/tokens/ERC20SnapshotSolmate.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Snapshot.sol) /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval( address indexed owner, address indexed spender, uint256 amount ); /*/////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*/////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*/////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*/////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function _approve( address owner, address spender, uint256 amount ) internal { allowance[owner][spender] = amount; emit Approval(owner, spender, amount); } function transfer(address to, uint256 amount) public virtual returns (bool) { _beforeTokenTransfer(msg.sender, to, amount); balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { _beforeTokenTransfer(from, to, amount); uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*/////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ECDSA.recover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require( recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER" ); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*/////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { _beforeTokenTransfer(address(0), to, amount); totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { _beforeTokenTransfer(from, address(0), amount); balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } /** * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and * total supply at the time are recorded for later access. * * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting. * In naive implementations it's possible to perform a "double spend" attack by reusing the same balance from different * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be * used to create an efficient ERC20 forking mechanism. * * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id * and the account address. * * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it * return `block.number` will trigger the creation of snapshot at the begining of each new block. When overridding this * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract. * * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient * alternative consider {ERC20Votes}. * * ==== Gas Costs * * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much * smaller since identical balances in subsequent snapshots are stored as a single entry. * * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent * transfers will have normal cost until the next snapshot, and so on. */ contract ERC20SnapshotSolmate is ERC20 { // Inspired by Jordi Baylina's MiniMeToken to record historical balances: // https://github.com/Giveth/minimd/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol using Arrays for uint256[]; using Counters for Counters.Counter; // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a // Snapshot struct, but that would impede usage of functions that work on an array. struct Snapshots { uint256[] ids; uint256[] values; } mapping(address => Snapshots) private _accountBalanceSnapshots; Snapshots private _totalSupplySnapshots; // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid. Counters.Counter private _currentSnapshotId; /** * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created. */ event Snapshot(uint256 id); constructor( string memory _name, string memory _symbol, uint8 _decimals ) ERC20(_name, _symbol, _decimals) {} /** * @dev Creates a new snapshot and returns its snapshot id. * * Emits a {Snapshot} event that contains the same id. * * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a * set of accounts, for example using {AccessControl}, or it may be open to the public. * * [WARNING] * ==== * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking, * you must consider that it can potentially be used by attackers in two ways. * * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs * section above. * * We haven't measured the actual numbers; if this is something you're interested in please reach out to us. * ==== */ function _snapshot() internal virtual returns (uint256) { _currentSnapshotId.increment(); uint256 currentId = _getCurrentSnapshotId(); emit Snapshot(currentId); return currentId; } /** * @dev Get the current snapshotId */ function _getCurrentSnapshotId() internal view virtual returns (uint256) { return _currentSnapshotId.current(); } /** * @dev Retrieves the balance of `account` at the time `snapshotId` was created. */ function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) { (bool snapshotted, uint256 value) = _valueAt( snapshotId, _accountBalanceSnapshots[account] ); return snapshotted ? value : balanceOf[account]; } /** * @dev Retrieves the total supply at the time `snapshotId` was created. */ function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) { (bool snapshotted, uint256 value) = _valueAt( snapshotId, _totalSupplySnapshots ); return snapshotted ? value : totalSupply; } // Update balance and/or total supply snapshots before the values are modified. This is implemented // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations. function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._beforeTokenTransfer(from, to, amount); if (from == address(0)) { // mint _updateAccountSnapshot(to); _updateTotalSupplySnapshot(); } else if (to == address(0)) { // burn _updateAccountSnapshot(from); _updateTotalSupplySnapshot(); } else { // transfer _updateAccountSnapshot(from); _updateAccountSnapshot(to); } } function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) { require(snapshotId > 0, "ERC20Snapshot: id is 0"); require( snapshotId <= _getCurrentSnapshotId(), "ERC20Snapshot: nonexistent id" ); // When a valid snapshot is queried, there are three possibilities: // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds // to this id is the current one. // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the // requested id, and its value is the one to return. // c) More snapshots were created after the requested one, and the queried value was later modified. There will be // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is // larger than the requested one. // // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does // exactly this. uint256 index = snapshots.ids.findUpperBound(snapshotId); if (index == snapshots.ids.length) { return (false, 0); } else { return (true, snapshots.values[index]); } } function _updateAccountSnapshot(address account) private { _updateSnapshot(_accountBalanceSnapshots[account], balanceOf[account]); } function _updateTotalSupplySnapshot() private { _updateSnapshot(_totalSupplySnapshots, totalSupply); } function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private { uint256 currentId = _getCurrentSnapshotId(); if (_lastSnapshotId(snapshots.ids) < currentId) { snapshots.ids.push(currentId); snapshots.values.push(currentValue); } } function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) { uint256 idsLen = ids.length; if (idsLen == 0) { return 0; } else { return ids[idsLen - 1]; } } } // File contracts/PxCvx.sol // SPDX-License-Identifier: MIT pragma solidity 0.8.12; contract PxCvx is ERC20SnapshotSolmate("Pirex CVX", "pxCVX", 18), Ownable { /** @notice Epoch details Reward/snapshotRewards/futuresRewards indexes are associated with 1 reward @param snapshotId uint256 Snapshot id @param rewards bytes32[] Rewards @param snapshotRewards uint256[] Snapshot reward amounts @param futuresRewards uint256[] Futures reward amounts @param redeemedSnapshotRewards mapping Redeemed snapshot rewards */ struct Epoch { uint256 snapshotId; bytes32[] rewards; uint256[] snapshotRewards; uint256[] futuresRewards; mapping(address => uint256) redeemedSnapshotRewards; } // Address of currently assigned operator address public operator; // Epochs mapped to epoch details mapping(uint256 => Epoch) private epochs; event SetOperator(address operator); event UpdateEpochFuturesRewards( uint256 indexed epoch, uint256[] futuresRewards ); error NotAuthorized(); error NoOperator(); error Paused(); error ZeroAddress(); error ZeroAmount(); error InvalidEpoch(); error InvalidFuturesRewards(); error MismatchedFuturesRewards(); modifier onlyOperator() { if (msg.sender != operator) revert NotAuthorized(); _; } modifier onlyOperatorOrNotPaused() { address _operator = operator; // Ensure an operator is set if (_operator == address(0)) revert NoOperator(); // This contract shares the same pause state as the operator if (msg.sender != _operator && Pausable(_operator).paused()) revert Paused(); _; } /** @notice Set a new operator address @param _operator address New operator address */ function setOperator(address _operator) external onlyOwner { if (_operator == address(0)) revert ZeroAddress(); emit SetOperator(_operator); // If it's the first operator, also set up 1st epoch with snapshot id 1 // and prevent reward claims until subsequent epochs if (operator == address(0)) { uint256 currentEpoch = getCurrentEpoch(); epochs[currentEpoch].snapshotId = _snapshot(); } operator = _operator; } /** @notice Return the current snapshotId @return uint256 Current snapshot id */ function getCurrentSnapshotId() external view returns (uint256) { return _getCurrentSnapshotId(); } /** @notice Get current epoch @return uint256 Current epoch */ function getCurrentEpoch() public view returns (uint256) { return (block.timestamp / 1209600) * 1209600; } /** @notice Get epoch @param epoch uint256 Epoch @return snapshotId uint256 Snapshot id @return rewards address[] Reward tokens @return snapshotRewards uint256[] Snapshot reward amounts @return futuresRewards uint256[] Futures reward amounts */ function getEpoch(uint256 epoch) external view returns ( uint256 snapshotId, bytes32[] memory rewards, uint256[] memory snapshotRewards, uint256[] memory futuresRewards ) { Epoch storage e = epochs[epoch]; return (e.snapshotId, e.rewards, e.snapshotRewards, e.futuresRewards); } /** @notice Get redeemed snapshot rewards bitmap @param account address Account @param epoch uint256 Epoch @return uint256 Redeemed snapshot bitmap */ function getEpochRedeemedSnapshotRewards(address account, uint256 epoch) external view returns (uint256) { return epochs[epoch].redeemedSnapshotRewards[account]; } /** @notice Add new epoch reward metadata @param epoch uint256 Epoch @param token address Token address @param snapshotReward uint256 Snapshot reward amount @param futuresReward uint256 Futures reward amount */ function addEpochRewardMetadata( uint256 epoch, bytes32 token, uint256 snapshotReward, uint256 futuresReward ) external onlyOperator { Epoch storage e = epochs[epoch]; e.rewards.push(token); e.snapshotRewards.push(snapshotReward); e.futuresRewards.push(futuresReward); } /** @notice Set redeemed snapshot rewards bitmap @param account address Account @param epoch uint256 Epoch @param redeemed uint256 Redeemed bitmap */ function setEpochRedeemedSnapshotRewards( address account, uint256 epoch, uint256 redeemed ) external onlyOperator { epochs[epoch].redeemedSnapshotRewards[account] = redeemed; } /** @notice Update epoch futures rewards to reflect amounts remaining after redemptions @param epoch uint256 Epoch @param futuresRewards uint256[] Futures rewards */ function updateEpochFuturesRewards( uint256 epoch, uint256[] memory futuresRewards ) external onlyOperator { if (epoch == 0) revert InvalidEpoch(); uint256 fLen = epochs[epoch].futuresRewards.length; if (fLen == 0) revert InvalidEpoch(); if (futuresRewards.length == 0) revert InvalidFuturesRewards(); if (futuresRewards.length != fLen) revert MismatchedFuturesRewards(); epochs[epoch].futuresRewards = futuresRewards; emit UpdateEpochFuturesRewards(epoch, futuresRewards); } /** @notice Mint the specified amount of tokens to the specified account @param account address Receiver of the tokens @param amount uint256 Amount to be minted */ function mint(address account, uint256 amount) external onlyOperator { if (account == address(0)) revert ZeroAddress(); if (amount == 0) revert ZeroAmount(); _mint(account, amount); } /** @notice Burn the specified amount of tokens from the specified account @param account address Owner of the tokens @param amount uint256 Amount to be burned */ function burn(address account, uint256 amount) external onlyOperator { if (account == address(0)) revert ZeroAddress(); if (amount == 0) revert ZeroAmount(); _burn(account, amount); } /** @notice Approve allowances by operator with specified accounts and amount @param from address Owner of the tokens @param to address Account to be approved @param amount uint256 Amount to be approved */ function operatorApprove( address from, address to, uint256 amount ) external onlyOperator { if (from == address(0)) revert ZeroAddress(); if (to == address(0)) revert ZeroAddress(); if (amount == 0) revert ZeroAmount(); _approve(from, to, amount); } /** @notice Snapshot token balances for the current epoch */ function takeEpochSnapshot() external onlyOperatorOrNotPaused { uint256 currentEpoch = getCurrentEpoch(); // If snapshot has not been set for current epoch, take snapshot if (epochs[currentEpoch].snapshotId == 0) { epochs[currentEpoch].snapshotId = _snapshot(); } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"InvalidEpoch","type":"error"},{"inputs":[],"name":"InvalidFuturesRewards","type":"error"},{"inputs":[],"name":"MismatchedFuturesRewards","type":"error"},{"inputs":[],"name":"NoOperator","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"Paused","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"SetOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Snapshot","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"futuresRewards","type":"uint256[]"}],"name":"UpdateEpochFuturesRewards","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"snapshotReward","type":"uint256"},{"internalType":"uint256","name":"futuresReward","type":"uint256"}],"name":"addEpochRewardMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"snapshotId","type":"uint256"}],"name":"balanceOfAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentSnapshotId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"getEpoch","outputs":[{"internalType":"uint256","name":"snapshotId","type":"uint256"},{"internalType":"bytes32[]","name":"rewards","type":"bytes32[]"},{"internalType":"uint256[]","name":"snapshotRewards","type":"uint256[]"},{"internalType":"uint256[]","name":"futuresRewards","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"getEpochRedeemedSnapshotRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"operatorApprove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"redeemed","type":"uint256"}],"name":"setEpochRedeemedSnapshotRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"takeEpochSnapshot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"snapshotId","type":"uint256"}],"name":"totalSupplyAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256[]","name":"futuresRewards","type":"uint256[]"}],"name":"updateEpochFuturesRewards","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e06040523480156200001157600080fd5b50604051806040016040528060098152602001680a0d2e4caf04086acb60bb1b815250604051806040016040528060058152602001640e0f086acb60db1b815250601282828282600090805190602001906200006f929190620001b3565b50815162000085906001906020850190620001b3565b5060ff81166080524660a0526200009b620000c1565b60c05250620000bb9450620000b59350506200015d915050565b62000161565b6200033a565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051620000f5919062000296565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620001c19062000259565b90600052602060002090601f016020900481019282620001e5576000855562000230565b82601f106200020057805160ff191683800117855562000230565b8280016001018555821562000230579182015b828111156200023057825182559160200191906001019062000213565b506200023e92915062000242565b5090565b5b808211156200023e576000815560010162000243565b600181811c908216806200026e57607f821691505b602082108114156200029057634e487b7160e01b600052602260045260246000fd5b50919050565b600080835481600182811c915080831680620002b357607f831692505b6020808410821415620002d457634e487b7160e01b86526022600452602486fd5b818015620002eb5760018114620002fd576200032c565b60ff198616895284890196506200032c565b60008a81526020902060005b86811015620003245781548b82015290850190830162000309565b505084890196505b509498975050505050505050565b60805160a05160c051611fd46200036a600039600061079a01526000610765015260006102900152611fd46000f3fe608060405234801561001057600080fd5b50600436106101ba5760003560e01c8063715018a6116100f45780639dc29fac116100a2578063bc0bc6ba11610071578063bc0bc6ba14610408578063d505accf1461042b578063dd62ed3e1461043e578063f2fde38b1461046957600080fd5b80639dc29fac146103c7578063a9059cbb146103da578063b3ab15fb146103ed578063b97dd9e21461040057600080fd5b8063715018a61461034d578063734b1d87146103555780637ecebe00146103685780638da5cb5b146103885780638dcc05831461039957806395d89b41146103ac578063981b24d0146103b457600080fd5b8063313ce5671161016c5780634ee2cd7e1161013b5780634ee2cd7e146102e75780635439ad86146102fa578063570ca7351461030257806370a082311461032d57600080fd5b8063313ce5671461028b5780633644e515146102c457806340c10f19146102cc5780634108d57c146102df57600080fd5b806306fdde03146101bf578063095ea7b3146101dd5780630c2970291461020057806318160ddd146102155780631e38bf311461022c578063206e4f071461023f57806323b872dd14610278575b600080fd5b6101c761047c565b6040516101d491906119ea565b60405180910390f35b6101f06101eb366004611a5b565b61050a565b60405190151581526020016101d4565b61021361020e366004611a85565b610577565b005b61021e60025481565b6040519081526020016101d4565b61021361023a366004611ac1565b61061e565b61021e61024d366004611a5b565b6000908152600c602090815260408083206001600160a01b0394909416835260049093019052205490565b6101f0610286366004611a85565b610674565b6102b27f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016101d4565b61021e610761565b6102136102da366004611a5b565b6107bc565b61021361083a565b61021e6102f5366004611a5b565b610933565b61021e61098c565b600b54610315906001600160a01b031681565b6040516001600160a01b0390911681526020016101d4565b61021e61033b366004611af4565b60036020526000908152604090205481565b610213610996565b610213610363366004611b25565b6109d5565b61021e610376366004611af4565b60056020526000908152604090205481565b600a546001600160a01b0316610315565b6102136103a7366004611bef565b610af1565b6101c7610b6d565b61021e6103c2366004611c21565b610b7a565b6102136103d5366004611a5b565b610ba5565b6101f06103e8366004611a5b565b610c1f565b6102136103fb366004611af4565b610c90565b61021e610d74565b61041b610416366004611c21565b610d90565b6040516101d49493929190611c75565b610213610439366004611ceb565b610eb9565b61021e61044c366004611d5e565b600460209081526000928352604080842090915290825290205481565b610213610477366004611af4565b6110a8565b6000805461048990611d91565b80601f01602080910402602001604051908101604052809291908181526020018280546104b590611d91565b80156105025780601f106104d757610100808354040283529160200191610502565b820191906000526020600020905b8154815290600101906020018083116104e557829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906105659086815260200190565b60405180910390a35060015b92915050565b600b546001600160a01b031633146105a25760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b0383166105c95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0382166105f05760405163d92e233d60e01b815260040160405180910390fd5b8061060e57604051631f2a200560e01b815260040160405180910390fd5b610619838383611143565b505050565b600b546001600160a01b031633146106495760405163ea8e4eb560e01b815260040160405180910390fd5b6000918252600c602090815260408084206001600160a01b0390951684526004909401905291902055565b60006106818484846111a4565b6001600160a01b038416600090815260046020908152604080832033845290915290205460001981146106dd576106b88382611ddc565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610705908490611ddc565b90915550506001600160a01b0380851660008181526003602052604090819020805487019055519091871690600080516020611f7f8339815191529061074e9087815260200190565b60405180910390a3506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610797576107926111ec565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b600b546001600160a01b031633146107e75760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03821661080e5760405163d92e233d60e01b815260040160405180910390fd5b8061082c57604051631f2a200560e01b815260040160405180910390fd5b6108368282611286565b5050565b600b546001600160a01b031680610864576040516337ff16a960e01b815260040160405180910390fd5b336001600160a01b038216148015906108da5750806001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108da9190611df3565b156108f8576040516313d0ff5960e31b815260040160405180910390fd5b6000610902610d74565b6000818152600c6020526040902054909150610836576109206112ec565b6000828152600c60205260409020555050565b6001600160a01b03821660009081526006602052604081208190819061095a908590611346565b9150915081610981576001600160a01b038516600090815260036020526040902054610983565b805b95945050505050565b600061079261143d565b600a546001600160a01b031633146109c95760405162461bcd60e51b81526004016109c090611e15565b60405180910390fd5b6109d36000611448565b565b600b546001600160a01b03163314610a005760405163ea8e4eb560e01b815260040160405180910390fd5b81610a1e5760405163d5b25b6360e01b815260040160405180910390fd5b6000828152600c602052604090206003015480610a4e5760405163d5b25b6360e01b815260040160405180910390fd5b8151610a6d57604051631b7d775760e01b815260040160405180910390fd5b80825114610a8e576040516324d96f8960e11b815260040160405180910390fd5b6000838152600c602090815260409091208351610ab39260039092019185019061198a565b50827fd14f4d687c7695013d50cc578614c3f9cc3402759ab997d52ffeacc02515026383604051610ae49190611e4a565b60405180910390a2505050565b600b546001600160a01b03163314610b1c5760405163ea8e4eb560e01b815260040160405180910390fd5b6000938452600c602090815260408520600180820180548083018255908852838820019590955560028101805480870182559087528287200193909355600390920180549384018155845292200155565b6001805461048990611d91565b6000806000610b8a846007611346565b9150915081610b9b57600254610b9d565b805b949350505050565b600b546001600160a01b03163314610bd05760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b038216610bf75760405163d92e233d60e01b815260040160405180910390fd5b80610c1557604051631f2a200560e01b815260040160405180910390fd5b610836828261149a565b6000610c2c3384846111a4565b3360009081526003602052604081208054849290610c4b908490611ddc565b90915550506001600160a01b03831660008181526003602052604090819020805485019055513390600080516020611f7f833981519152906105659086815260200190565b600a546001600160a01b03163314610cba5760405162461bcd60e51b81526004016109c090611e15565b6001600160a01b038116610ce15760405163d92e233d60e01b815260040160405180910390fd5b6040516001600160a01b03821681527fdbebfba65bd6398fb722063efc10c99f624f9cd8ba657201056af918a676d5ee9060200160405180910390a1600b546001600160a01b0316610d52576000610d37610d74565b9050610d416112ec565b6000918252600c6020526040909120555b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610d836212750042611e5d565b6107929062127500611e7f565b6000818152600c6020908152604080832080546001820180548451818702810187019095528085526060958695869594939260028601926003870192918591830182828015610dfe57602002820191906000526020600020905b815481526020019060010190808311610dea575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015610e5057602002820191906000526020600020905b815481526020019060010190808311610e3c575b5050505050915080805480602002602001604051908101604052809291908181526020018280548015610ea257602002820191906000526020600020905b815481526020019060010190808311610e8e575b505050505090509450945094509450509193509193565b42841015610f035760405162461bcd60e51b815260206004820152601760248201527614115493525517d11150511312539157d1561412549151604a1b60448201526064016109c0565b6000610fd7610f10610761565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301825280519084012061190160f01b610100840152610102830194909452610122808301949094528051808303909401845261014290910190528151910120858585611508565b90506001600160a01b038116158015906110025750876001600160a01b0316816001600160a01b0316145b61103f5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b60448201526064016109c0565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b600a546001600160a01b031633146110d25760405162461bcd60e51b81526004016109c090611e15565b6001600160a01b0381166111375760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109c0565b61114081611448565b50565b6001600160a01b0383811660008181526004602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166111c3576111bb82611530565b61061961155e565b6001600160a01b0382166111da576111bb83611530565b6111e383611530565b61061982611530565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405161121e9190611e9e565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b611292600083836111a4565b80600260008282546112a49190611f3a565b90915550506001600160a01b038216600081815260036020908152604080832080548601905551848152600080516020611f7f83398151915291015b60405180910390a35050565b60006112fc600980546001019055565b600061130661143d565b90507f8030e83b04d87bef53480e26263266d6ca66863aa8506aca6f2559d18aa1cb678160405161133991815260200190565b60405180910390a1919050565b600080600084116113925760405162461bcd60e51b815260206004820152601660248201527504552433230536e617073686f743a20696420697320360541b60448201526064016109c0565b61139a61143d565b8411156113e95760405162461bcd60e51b815260206004820152601d60248201527f4552433230536e617073686f743a206e6f6e6578697374656e7420696400000060448201526064016109c0565b60006113f5848661156b565b845490915081141561140e576000809250925050611436565b600184600101828154811061142557611425611f52565b906000526020600020015492509250505b9250929050565b600061079260095490565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6114a6826000836111a4565b6001600160a01b038216600090815260036020526040812080548392906114ce908490611ddc565b90915550506002805482900390556040518181526000906001600160a01b03841690600080516020611f7f833981519152906020016112e0565b60008060006115198787878761162e565b915091506115268161171b565b5095945050505050565b6001600160a01b038116600090815260066020908152604080832060039092529091205461114091906118d6565b6109d360076002546118d6565b815460009061157c57506000610571565b82546000905b808210156115d85760006115968383611920565b9050848682815481106115ab576115ab611f52565b906000526020600020015411156115c4578091506115d2565b6115cf816001611f3a565b92505b50611582565b60008211801561160d575083856115f0600185611ddc565b8154811061160057611600611f52565b9060005260206000200154145b156116265761161d600183611ddc565b92505050610571565b509050610571565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156116655750600090506003611712565b8460ff16601b1415801561167d57508460ff16601c14155b1561168e5750600090506004611712565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156116e2573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661170b57600060019250925050611712565b9150600090505b94509492505050565b600081600481111561172f5761172f611f68565b14156117385750565b600181600481111561174c5761174c611f68565b141561179a5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016109c0565b60028160048111156117ae576117ae611f68565b14156117fc5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016109c0565b600381600481111561181057611810611f68565b14156118695760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016109c0565b600481600481111561187d5761187d611f68565b14156111405760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016109c0565b60006118e061143d565b9050806118ec84611942565b1015610619578254600180820185556000858152602080822090930193909355938401805494850181558252902090910155565b600061192f6002848418611e5d565b61193b90848416611f3a565b9392505050565b8054600090806119555750600092915050565b82611961600183611ddc565b8154811061197157611971611f52565b9060005260206000200154915050919050565b50919050565b8280548282559060005260206000209081019282156119c5579160200282015b828111156119c55782518255916020019190600101906119aa565b506119d19291506119d5565b5090565b5b808211156119d157600081556001016119d6565b600060208083528351808285015260005b81811015611a17578581018301518582016040015282016119fb565b81811115611a29576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b0381168114611a5657600080fd5b919050565b60008060408385031215611a6e57600080fd5b611a7783611a3f565b946020939093013593505050565b600080600060608486031215611a9a57600080fd5b611aa384611a3f565b9250611ab160208501611a3f565b9150604084013590509250925092565b600080600060608486031215611ad657600080fd5b611adf84611a3f565b95602085013595506040909401359392505050565b600060208284031215611b0657600080fd5b61193b82611a3f565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215611b3857600080fd5b8235915060208084013567ffffffffffffffff80821115611b5857600080fd5b818601915086601f830112611b6c57600080fd5b813581811115611b7e57611b7e611b0f565b8060051b604051601f19603f83011681018181108582111715611ba357611ba3611b0f565b604052918252848201925083810185019189831115611bc157600080fd5b938501935b82851015611bdf57843584529385019392850192611bc6565b8096505050505050509250929050565b60008060008060808587031215611c0557600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215611c3357600080fd5b5035919050565b600081518084526020808501945080840160005b83811015611c6a57815187529582019590820190600101611c4e565b509495945050505050565b600060808201868352602060808185015281875180845260a086019150828901935060005b81811015611cb657845183529383019391830191600101611c9a565b50508481036040860152611cca8188611c3a565b925050508281036060840152611ce08185611c3a565b979650505050505050565b600080600080600080600060e0888a031215611d0657600080fd5b611d0f88611a3f565b9650611d1d60208901611a3f565b95506040880135945060608801359350608088013560ff81168114611d4157600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611d7157600080fd5b611d7a83611a3f565b9150611d8860208401611a3f565b90509250929050565b600181811c90821680611da557607f821691505b6020821081141561198457634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082821015611dee57611dee611dc6565b500390565b600060208284031215611e0557600080fd5b8151801515811461193b57600080fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208152600061193b6020830184611c3a565b600082611e7a57634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615611e9957611e99611dc6565b500290565b600080835481600182811c915080831680611eba57607f831692505b6020808410821415611eda57634e487b7160e01b86526022600452602486fd5b818015611eee5760018114611eff57611f2c565b60ff19861689528489019650611f2c565b60008a81526020902060005b86811015611f245781548b820152908501908301611f0b565b505084890196505b509498975050505050505050565b60008219821115611f4d57611f4d611dc6565b500190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122024cc35816c85aa467ce8ffe72418d55cfc07066960aa28c0702f9a599901b27e64736f6c634300080c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101ba5760003560e01c8063715018a6116100f45780639dc29fac116100a2578063bc0bc6ba11610071578063bc0bc6ba14610408578063d505accf1461042b578063dd62ed3e1461043e578063f2fde38b1461046957600080fd5b80639dc29fac146103c7578063a9059cbb146103da578063b3ab15fb146103ed578063b97dd9e21461040057600080fd5b8063715018a61461034d578063734b1d87146103555780637ecebe00146103685780638da5cb5b146103885780638dcc05831461039957806395d89b41146103ac578063981b24d0146103b457600080fd5b8063313ce5671161016c5780634ee2cd7e1161013b5780634ee2cd7e146102e75780635439ad86146102fa578063570ca7351461030257806370a082311461032d57600080fd5b8063313ce5671461028b5780633644e515146102c457806340c10f19146102cc5780634108d57c146102df57600080fd5b806306fdde03146101bf578063095ea7b3146101dd5780630c2970291461020057806318160ddd146102155780631e38bf311461022c578063206e4f071461023f57806323b872dd14610278575b600080fd5b6101c761047c565b6040516101d491906119ea565b60405180910390f35b6101f06101eb366004611a5b565b61050a565b60405190151581526020016101d4565b61021361020e366004611a85565b610577565b005b61021e60025481565b6040519081526020016101d4565b61021361023a366004611ac1565b61061e565b61021e61024d366004611a5b565b6000908152600c602090815260408083206001600160a01b0394909416835260049093019052205490565b6101f0610286366004611a85565b610674565b6102b27f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff90911681526020016101d4565b61021e610761565b6102136102da366004611a5b565b6107bc565b61021361083a565b61021e6102f5366004611a5b565b610933565b61021e61098c565b600b54610315906001600160a01b031681565b6040516001600160a01b0390911681526020016101d4565b61021e61033b366004611af4565b60036020526000908152604090205481565b610213610996565b610213610363366004611b25565b6109d5565b61021e610376366004611af4565b60056020526000908152604090205481565b600a546001600160a01b0316610315565b6102136103a7366004611bef565b610af1565b6101c7610b6d565b61021e6103c2366004611c21565b610b7a565b6102136103d5366004611a5b565b610ba5565b6101f06103e8366004611a5b565b610c1f565b6102136103fb366004611af4565b610c90565b61021e610d74565b61041b610416366004611c21565b610d90565b6040516101d49493929190611c75565b610213610439366004611ceb565b610eb9565b61021e61044c366004611d5e565b600460209081526000928352604080842090915290825290205481565b610213610477366004611af4565b6110a8565b6000805461048990611d91565b80601f01602080910402602001604051908101604052809291908181526020018280546104b590611d91565b80156105025780601f106104d757610100808354040283529160200191610502565b820191906000526020600020905b8154815290600101906020018083116104e557829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906105659086815260200190565b60405180910390a35060015b92915050565b600b546001600160a01b031633146105a25760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b0383166105c95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0382166105f05760405163d92e233d60e01b815260040160405180910390fd5b8061060e57604051631f2a200560e01b815260040160405180910390fd5b610619838383611143565b505050565b600b546001600160a01b031633146106495760405163ea8e4eb560e01b815260040160405180910390fd5b6000918252600c602090815260408084206001600160a01b0390951684526004909401905291902055565b60006106818484846111a4565b6001600160a01b038416600090815260046020908152604080832033845290915290205460001981146106dd576106b88382611ddc565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610705908490611ddc565b90915550506001600160a01b0380851660008181526003602052604090819020805487019055519091871690600080516020611f7f8339815191529061074e9087815260200190565b60405180910390a3506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000014614610797576107926111ec565b905090565b507f5b6b604899a414047e9a6f188da3de9ab9bca6b829ea96817580debe885a425190565b600b546001600160a01b031633146107e75760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03821661080e5760405163d92e233d60e01b815260040160405180910390fd5b8061082c57604051631f2a200560e01b815260040160405180910390fd5b6108368282611286565b5050565b600b546001600160a01b031680610864576040516337ff16a960e01b815260040160405180910390fd5b336001600160a01b038216148015906108da5750806001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108da9190611df3565b156108f8576040516313d0ff5960e31b815260040160405180910390fd5b6000610902610d74565b6000818152600c6020526040902054909150610836576109206112ec565b6000828152600c60205260409020555050565b6001600160a01b03821660009081526006602052604081208190819061095a908590611346565b9150915081610981576001600160a01b038516600090815260036020526040902054610983565b805b95945050505050565b600061079261143d565b600a546001600160a01b031633146109c95760405162461bcd60e51b81526004016109c090611e15565b60405180910390fd5b6109d36000611448565b565b600b546001600160a01b03163314610a005760405163ea8e4eb560e01b815260040160405180910390fd5b81610a1e5760405163d5b25b6360e01b815260040160405180910390fd5b6000828152600c602052604090206003015480610a4e5760405163d5b25b6360e01b815260040160405180910390fd5b8151610a6d57604051631b7d775760e01b815260040160405180910390fd5b80825114610a8e576040516324d96f8960e11b815260040160405180910390fd5b6000838152600c602090815260409091208351610ab39260039092019185019061198a565b50827fd14f4d687c7695013d50cc578614c3f9cc3402759ab997d52ffeacc02515026383604051610ae49190611e4a565b60405180910390a2505050565b600b546001600160a01b03163314610b1c5760405163ea8e4eb560e01b815260040160405180910390fd5b6000938452600c602090815260408520600180820180548083018255908852838820019590955560028101805480870182559087528287200193909355600390920180549384018155845292200155565b6001805461048990611d91565b6000806000610b8a846007611346565b9150915081610b9b57600254610b9d565b805b949350505050565b600b546001600160a01b03163314610bd05760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b038216610bf75760405163d92e233d60e01b815260040160405180910390fd5b80610c1557604051631f2a200560e01b815260040160405180910390fd5b610836828261149a565b6000610c2c3384846111a4565b3360009081526003602052604081208054849290610c4b908490611ddc565b90915550506001600160a01b03831660008181526003602052604090819020805485019055513390600080516020611f7f833981519152906105659086815260200190565b600a546001600160a01b03163314610cba5760405162461bcd60e51b81526004016109c090611e15565b6001600160a01b038116610ce15760405163d92e233d60e01b815260040160405180910390fd5b6040516001600160a01b03821681527fdbebfba65bd6398fb722063efc10c99f624f9cd8ba657201056af918a676d5ee9060200160405180910390a1600b546001600160a01b0316610d52576000610d37610d74565b9050610d416112ec565b6000918252600c6020526040909120555b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610d836212750042611e5d565b6107929062127500611e7f565b6000818152600c6020908152604080832080546001820180548451818702810187019095528085526060958695869594939260028601926003870192918591830182828015610dfe57602002820191906000526020600020905b815481526020019060010190808311610dea575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015610e5057602002820191906000526020600020905b815481526020019060010190808311610e3c575b5050505050915080805480602002602001604051908101604052809291908181526020018280548015610ea257602002820191906000526020600020905b815481526020019060010190808311610e8e575b505050505090509450945094509450509193509193565b42841015610f035760405162461bcd60e51b815260206004820152601760248201527614115493525517d11150511312539157d1561412549151604a1b60448201526064016109c0565b6000610fd7610f10610761565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301825280519084012061190160f01b610100840152610102830194909452610122808301949094528051808303909401845261014290910190528151910120858585611508565b90506001600160a01b038116158015906110025750876001600160a01b0316816001600160a01b0316145b61103f5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b60448201526064016109c0565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b600a546001600160a01b031633146110d25760405162461bcd60e51b81526004016109c090611e15565b6001600160a01b0381166111375760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109c0565b61114081611448565b50565b6001600160a01b0383811660008181526004602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166111c3576111bb82611530565b61061961155e565b6001600160a01b0382166111da576111bb83611530565b6111e383611530565b61061982611530565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405161121e9190611e9e565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b611292600083836111a4565b80600260008282546112a49190611f3a565b90915550506001600160a01b038216600081815260036020908152604080832080548601905551848152600080516020611f7f83398151915291015b60405180910390a35050565b60006112fc600980546001019055565b600061130661143d565b90507f8030e83b04d87bef53480e26263266d6ca66863aa8506aca6f2559d18aa1cb678160405161133991815260200190565b60405180910390a1919050565b600080600084116113925760405162461bcd60e51b815260206004820152601660248201527504552433230536e617073686f743a20696420697320360541b60448201526064016109c0565b61139a61143d565b8411156113e95760405162461bcd60e51b815260206004820152601d60248201527f4552433230536e617073686f743a206e6f6e6578697374656e7420696400000060448201526064016109c0565b60006113f5848661156b565b845490915081141561140e576000809250925050611436565b600184600101828154811061142557611425611f52565b906000526020600020015492509250505b9250929050565b600061079260095490565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6114a6826000836111a4565b6001600160a01b038216600090815260036020526040812080548392906114ce908490611ddc565b90915550506002805482900390556040518181526000906001600160a01b03841690600080516020611f7f833981519152906020016112e0565b60008060006115198787878761162e565b915091506115268161171b565b5095945050505050565b6001600160a01b038116600090815260066020908152604080832060039092529091205461114091906118d6565b6109d360076002546118d6565b815460009061157c57506000610571565b82546000905b808210156115d85760006115968383611920565b9050848682815481106115ab576115ab611f52565b906000526020600020015411156115c4578091506115d2565b6115cf816001611f3a565b92505b50611582565b60008211801561160d575083856115f0600185611ddc565b8154811061160057611600611f52565b9060005260206000200154145b156116265761161d600183611ddc565b92505050610571565b509050610571565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156116655750600090506003611712565b8460ff16601b1415801561167d57508460ff16601c14155b1561168e5750600090506004611712565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156116e2573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661170b57600060019250925050611712565b9150600090505b94509492505050565b600081600481111561172f5761172f611f68565b14156117385750565b600181600481111561174c5761174c611f68565b141561179a5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016109c0565b60028160048111156117ae576117ae611f68565b14156117fc5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016109c0565b600381600481111561181057611810611f68565b14156118695760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016109c0565b600481600481111561187d5761187d611f68565b14156111405760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016109c0565b60006118e061143d565b9050806118ec84611942565b1015610619578254600180820185556000858152602080822090930193909355938401805494850181558252902090910155565b600061192f6002848418611e5d565b61193b90848416611f3a565b9392505050565b8054600090806119555750600092915050565b82611961600183611ddc565b8154811061197157611971611f52565b9060005260206000200154915050919050565b50919050565b8280548282559060005260206000209081019282156119c5579160200282015b828111156119c55782518255916020019190600101906119aa565b506119d19291506119d5565b5090565b5b808211156119d157600081556001016119d6565b600060208083528351808285015260005b81811015611a17578581018301518582016040015282016119fb565b81811115611a29576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b0381168114611a5657600080fd5b919050565b60008060408385031215611a6e57600080fd5b611a7783611a3f565b946020939093013593505050565b600080600060608486031215611a9a57600080fd5b611aa384611a3f565b9250611ab160208501611a3f565b9150604084013590509250925092565b600080600060608486031215611ad657600080fd5b611adf84611a3f565b95602085013595506040909401359392505050565b600060208284031215611b0657600080fd5b61193b82611a3f565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215611b3857600080fd5b8235915060208084013567ffffffffffffffff80821115611b5857600080fd5b818601915086601f830112611b6c57600080fd5b813581811115611b7e57611b7e611b0f565b8060051b604051601f19603f83011681018181108582111715611ba357611ba3611b0f565b604052918252848201925083810185019189831115611bc157600080fd5b938501935b82851015611bdf57843584529385019392850192611bc6565b8096505050505050509250929050565b60008060008060808587031215611c0557600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215611c3357600080fd5b5035919050565b600081518084526020808501945080840160005b83811015611c6a57815187529582019590820190600101611c4e565b509495945050505050565b600060808201868352602060808185015281875180845260a086019150828901935060005b81811015611cb657845183529383019391830191600101611c9a565b50508481036040860152611cca8188611c3a565b925050508281036060840152611ce08185611c3a565b979650505050505050565b600080600080600080600060e0888a031215611d0657600080fd5b611d0f88611a3f565b9650611d1d60208901611a3f565b95506040880135945060608801359350608088013560ff81168114611d4157600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611d7157600080fd5b611d7a83611a3f565b9150611d8860208401611a3f565b90509250929050565b600181811c90821680611da557607f821691505b6020821081141561198457634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082821015611dee57611dee611dc6565b500390565b600060208284031215611e0557600080fd5b8151801515811461193b57600080fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208152600061193b6020830184611c3a565b600082611e7a57634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615611e9957611e99611dc6565b500290565b600080835481600182811c915080831680611eba57607f831692505b6020808410821415611eda57634e487b7160e01b86526022600452602486fd5b818015611eee5760018114611eff57611f2c565b60ff19861689528489019650611f2c565b60008a81526020902060005b86811015611f245781548b820152908501908301611f0b565b505084890196505b509498975050505050505050565b60008219821115611f4d57611f4d611dc6565b500190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122024cc35816c85aa467ce8ffe72418d55cfc07066960aa28c0702f9a599901b27e64736f6c634300080c0033
Deployed Bytecode Sourcemap
39427:7893:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22774:18;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24255:249;;;;;;:::i;:::-;;:::i;:::-;;;1218:14:1;;1211:22;1193:41;;1181:2;1166:18;24255:249:0;1053:187:1;46582:325:0;;;;;;:::i;:::-;;:::i;:::-;;23058:26;;;;;;;;;1724:25:1;;;1712:2;1697:18;23058:26:0;1578:177:1;44410:223:0;;;;;;:::i;:::-;;:::i;43323:209::-;;;;;;:::i;:::-;43446:7;43478:13;;;:6;:13;;;;;;;;-1:-1:-1;;;;;43478:46:0;;;;;;:37;;;;:46;;;;;43323:209;25214:676;;;;;;:::i;:::-;;:::i;22830:31::-;;;;;;;;2259:4:1;2247:17;;;2229:36;;2217:2;2202:18;22830:31:0;2087:184:1;27675:226:0;;;:::i;45654:217::-;;;;;;:::i;:::-;;:::i;46996:321::-;;;:::i;35138:344::-;;;;;;:::i;:::-;;:::i;42019:113::-;;;:::i;40273:23::-;;;;;-1:-1:-1;;;;;40273:23:0;;;;;;-1:-1:-1;;;;;2622:32:1;;;2604:51;;2592:2;2577:18;40273:23:0;2458:203:1;23093:44:0;;;;;;:::i;:::-;;;;;;;;;;;;;;2624:103;;;:::i;44862:574::-;;;;;;:::i;:::-;;:::i;23521:41::-;;;;;;:::i;:::-;;;;;;;;;;;;;;1973:87;2046:6;;-1:-1:-1;;;;;2046:6:0;1973:87;;43838:354;;;;;;:::i;:::-;;:::i;22801:20::-;;;:::i;35586:310::-;;;;;;:::i;:::-;;:::i;46088:217::-;;;;;;:::i;:::-;;:::i;24732:474::-;;;;;;:::i;:::-;;:::i;41389:510::-;;;;;;:::i;:::-;;:::i;42233:120::-;;;:::i;42710:396::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;26087:1580::-;;;;;;:::i;:::-;;:::i;23146:64::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;2882:201;;;;;;:::i;:::-;;:::i;22774:18::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;24255:249::-;24388:10;24356:4;24378:21;;;:9;:21;;;;;;;;-1:-1:-1;;;;;24378:30:0;;;;;;;;;;:39;;;24435:37;24356:4;;24378:30;;24435:37;;;;24411:6;1724:25:1;;1712:2;1697:18;;1578:177;24435:37:0;;;;;;;;-1:-1:-1;24492:4:0;24255:249;;;;;:::o;46582:325::-;40831:8;;-1:-1:-1;;;;;40831:8:0;40817:10;:22;40813:50;;40848:15;;-1:-1:-1;;;40848:15:0;;;;;;;;;;;40813:50;-1:-1:-1;;;;;46720:18:0;::::1;46716:44;;46747:13;;-1:-1:-1::0;;;46747:13:0::1;;;;;;;;;;;46716:44;-1:-1:-1::0;;;;;46775:16:0;::::1;46771:42;;46800:13;;-1:-1:-1::0;;;46800:13:0::1;;;;;;;;;;;46771:42;46828:11:::0;46824:36:::1;;46848:12;;-1:-1:-1::0;;;46848:12:0::1;;;;;;;;;;;46824:36;46873:26;46882:4;46888:2;46892:6;46873:8;:26::i;:::-;46582:325:::0;;;:::o;44410:223::-;40831:8;;-1:-1:-1;;;;;40831:8:0;40817:10;:22;40813:50;;40848:15;;-1:-1:-1;;;40848:15:0;;;;;;;;;;;40813:50;44568:13:::1;::::0;;;:6:::1;:13;::::0;;;;;;;-1:-1:-1;;;;;44568:46:0;;::::1;::::0;;:37:::1;::::0;;::::1;:46:::0;;;;;:57;44410:223::o;25214:676::-;25336:4;25353:38;25374:4;25380:2;25384:6;25353:20;:38::i;:::-;-1:-1:-1;;;;;25422:15:0;;25404;25422;;;:9;:15;;;;;;;;25438:10;25422:27;;;;;;;;-1:-1:-1;;25502:28:0;;25498:93;;25575:16;25585:6;25575:7;:16;:::i;:::-;-1:-1:-1;;;;;25545:15:0;;;;;;:9;:15;;;;;;;;25561:10;25545:27;;;;;;;:46;25498:93;-1:-1:-1;;;;;25604:15:0;;;;;;:9;:15;;;;;:25;;25623:6;;25604:15;:25;;25623:6;;25604:25;:::i;:::-;;;;-1:-1:-1;;;;;;;25780:13:0;;;;;;;:9;:13;;;;;;;:23;;;;;;25832:26;25780:13;;25832:26;;;-1:-1:-1;;;;;;;;;;;25832:26:0;;;25797:6;1724:25:1;;1712:2;1697:18;;1578:177;25832:26:0;;;;;;;;-1:-1:-1;25878:4:0;;25214:676;-1:-1:-1;;;;25214:676:0:o;27675:226::-;27732:7;27789:16;27772:13;:33;:121;;27869:24;:22;:24::i;:::-;27752:141;;27675:226;:::o;27772:121::-;-1:-1:-1;27825:24:0;;27675:226::o;45654:217::-;40831:8;;-1:-1:-1;;;;;40831:8:0;40817:10;:22;40813:50;;40848:15;;-1:-1:-1;;;40848:15:0;;;;;;;;;;;40813:50;-1:-1:-1;;;;;45738:21:0;::::1;45734:47;;45768:13;;-1:-1:-1::0;;;45768:13:0::1;;;;;;;;;;;45734:47;45796:11:::0;45792:36:::1;;45816:12;;-1:-1:-1::0;;;45816:12:0::1;;;;;;;;;;;45792:36;45841:22;45847:7;45856:6;45841:5;:22::i;:::-;45654:217:::0;;:::o;46996:321::-;40957:8;;-1:-1:-1;;;;;40957:8:0;41020:23;41016:48;;41052:12;;-1:-1:-1;;;41052:12:0;;;;;;;;;;;41016:48;41151:10;-1:-1:-1;;;;;41151:23:0;;;;;;:55;;;41187:9;-1:-1:-1;;;;;41178:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41147:89;;;41228:8;;-1:-1:-1;;;41228:8:0;;;;;;;;;;;41147:89;47069:20:::1;47092:17;:15;:17::i;:::-;47200:20;::::0;;;:6:::1;:20;::::0;;;;:31;47069:40;;-1:-1:-1;47196:114:0::1;;47287:11;:9;:11::i;:::-;47253:20;::::0;;;:6:::1;:20;::::0;;;;:45;47058:259:::1;40926:330:::0;46996:321::o;35138:344::-;-1:-1:-1;;;;;35370:33:0;;35261:7;35370:33;;;:24;:33;;;;;35261:7;;;;35322:92;;35345:10;;35322:8;:92::i;:::-;35286:128;;;;35434:11;:40;;-1:-1:-1;;;;;35456:18:0;;;;;;:9;:18;;;;;;35434:40;;;35448:5;35434:40;35427:47;35138:344;-1:-1:-1;;;;;35138:344:0:o;42019:113::-;42074:7;42101:23;:21;:23::i;2624:103::-;2046:6;;-1:-1:-1;;;;;2046:6:0;800:10;2193:23;2185:68;;;;-1:-1:-1;;;2185:68:0;;;;;;;:::i;:::-;;;;;;;;;2689:30:::1;2716:1;2689:18;:30::i;:::-;2624:103::o:0;44862:574::-;40831:8;;-1:-1:-1;;;;;40831:8:0;40817:10;:22;40813:50;;40848:15;;-1:-1:-1;;;40848:15:0;;;;;;;;;;;40813:50;45007:10;45003:37:::1;;45026:14;;-1:-1:-1::0;;;45026:14:0::1;;;;;;;;;;;45003:37;45053:12;45068:13:::0;;;:6:::1;:13;::::0;;;;:28:::1;;:35:::0;45120:9;45116:36:::1;;45138:14;;-1:-1:-1::0;;;45138:14:0::1;;;;;;;;;;;45116:36;45167:21:::0;;45163:62:::1;;45202:23;;-1:-1:-1::0;;;45202:23:0::1;;;;;;;;;;;45163:62;45265:4;45240:14;:21;:29;45236:68;;45278:26;;-1:-1:-1::0;;;45278:26:0::1;;;;;;;;;;;45236:68;45317:13;::::0;;;:6:::1;:13;::::0;;;;;;;:45;;::::1;::::0;:28:::1;::::0;;::::1;::::0;:45;::::1;::::0;::::1;:::i;:::-;;45406:5;45380:48;45413:14;45380:48;;;;;;:::i;:::-;;;;;;;;44992:444;44862:574:::0;;:::o;43838:354::-;40831:8;;-1:-1:-1;;;;;40831:8:0;40817:10;:22;40813:50;;40848:15;;-1:-1:-1;;;40848:15:0;;;;;;;;;;;40813:50;44023:15:::1;44041:13:::0;;;:6:::1;:13;::::0;;;;;;44067:9:::1;::::0;;::::1;:21:::0;;;;::::1;::::0;;;;;;;;::::1;::::0;;;;44099:17:::1;::::0;::::1;:38:::0;;;;::::1;::::0;;;;;;;;::::1;::::0;;;;44148:16:::1;::::0;;::::1;:36:::0;;;;::::1;::::0;;;;;;::::1;::::0;43838:354::o;22801:20::-;;;;;;;:::i;35586:310::-;35694:7;35720:16;35738:13;35755:80;35778:10;35803:21;35755:8;:80::i;:::-;35719:116;;;;35855:11;:33;;35877:11;;35855:33;;;35869:5;35855:33;35848:40;35586:310;-1:-1:-1;;;;35586:310:0:o;46088:217::-;40831:8;;-1:-1:-1;;;;;40831:8:0;40817:10;:22;40813:50;;40848:15;;-1:-1:-1;;;40848:15:0;;;;;;;;;;;40813:50;-1:-1:-1;;;;;46172:21:0;::::1;46168:47;;46202:13;;-1:-1:-1::0;;;46202:13:0::1;;;;;;;;;;;46168:47;46230:11:::0;46226:36:::1;;46250:12;;-1:-1:-1::0;;;46250:12:0::1;;;;;;;;;;;46226:36;46275:22;46281:7;46290:6;46275:5;:22::i;24732:474::-:0;24829:4;24851:44;24872:10;24884:2;24888:6;24851:20;:44::i;:::-;24918:10;24908:21;;;;:9;:21;;;;;:31;;24933:6;;24908:21;:31;;24933:6;;24908:31;:::i;:::-;;;;-1:-1:-1;;;;;;;25090:13:0;;;;;;:9;:13;;;;;;;:23;;;;;;25142:32;25151:10;;-1:-1:-1;;;;;;;;;;;25142:32:0;;;25107:6;1724:25:1;;1712:2;1697:18;;1578:177;41389:510:0;2046:6;;-1:-1:-1;;;;;2046:6:0;800:10;2193:23;2185:68;;;;-1:-1:-1;;;2185:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;41463:23:0;::::1;41459:49;;41495:13;;-1:-1:-1::0;;;41495:13:0::1;;;;;;;;;;;41459:49;41526:22;::::0;-1:-1:-1;;;;;2622:32:1;;2604:51;;41526:22:0::1;::::0;2592:2:1;2577:18;41526:22:0::1;;;;;;;41708:8;::::0;-1:-1:-1;;;;;41708:8:0::1;41704:155;;41747:20;41770:17;:15;:17::i;:::-;41747:40;;41836:11;:9;:11::i;:::-;41802:20;::::0;;;:6:::1;:20;::::0;;;;;:45;41704:155:::1;41871:8;:20:::0;;-1:-1:-1;;;;;;41871:20:0::1;-1:-1:-1::0;;;;;41871:20:0;;;::::1;::::0;;;::::1;::::0;;41389:510::o;42233:120::-;42281:7;42309:25;42327:7;42309:15;:25;:::i;:::-;42308:37;;42338:7;42308:37;:::i;42710:396::-;42807:18;43003:13;;;:6;:13;;;;;;;;43037:12;;43051:9;;;43029:69;;;;;;;;;;;;;;;;;42840:24;;;;;;43003:13;43037:12;43051:9;43062:17;;;;43081:16;;;;43029:69;43051:9;;43029:69;;43051:9;43029:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42710:396;;;;;:::o;26087:1580::-;26315:15;26303:8;:27;;26295:63;;;;-1:-1:-1;;;26295:63:0;;9395:2:1;26295:63:0;;;9377:21:1;9434:2;9414:18;;;9407:30;-1:-1:-1;;;9453:18:1;;;9446:53;9516:18;;26295:63:0;9193:347:1;26295:63:0;26528:24;26555:831;26699:18;:16;:18::i;:::-;-1:-1:-1;;;;;27153:13:0;;;;;;;:6;:13;;;;;;;;;:15;;;;;;;;26784:458;;26829:167;26784:458;;;9832:25:1;9911:18;;;9904:43;;;;9983:15;;;9963:18;;;9956:43;10015:18;;;10008:34;;;10058:19;;;10051:35;;;;10102:19;;;;10095:35;;;26784:458:0;;;;;;;;;;9804:19:1;;;26784:458:0;;26744:525;;;;;;-1:-1:-1;;;26619:673:0;;;10399:27:1;10442:11;;;10435:27;;;;10478:12;;;;10471:28;;;;26619:673:0;;;;;;;;;;10515:12:1;;;;26619:673:0;;26587:724;;;;;27330:1;27350;27370;26555:13;:831::i;:::-;26528:858;-1:-1:-1;;;;;;27429:30:0;;;;;;:59;;;27483:5;-1:-1:-1;;;;;27463:25:0;:16;-1:-1:-1;;;;;27463:25:0;;27429:59;27403:135;;;;-1:-1:-1;;;27403:135:0;;10740:2:1;27403:135:0;;;10722:21:1;10779:2;10759:18;;;10752:30;-1:-1:-1;;;10798:18:1;;;10791:44;10852:18;;27403:135:0;10538:338:1;27403:135:0;-1:-1:-1;;;;;27555:27:0;;;;;;;:9;:27;;;;;;;;:36;;;;;;;;;;;;;:44;;;27628:31;1724:25:1;;;27555:36:0;;27628:31;;;;;1697:18:1;27628:31:0;;;;;;;26087:1580;;;;;;;:::o;2882:201::-;2046:6;;-1:-1:-1;;;;;2046:6:0;800:10;2193:23;2185:68;;;;-1:-1:-1;;;2185:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;2971:22:0;::::1;2963:73;;;::::0;-1:-1:-1;;;2963:73:0;;11083:2:1;2963:73:0::1;::::0;::::1;11065:21:1::0;11122:2;11102:18;;;11095:30;11161:34;11141:18;;;11134:62;-1:-1:-1;;;11212:18:1;;;11205:36;11258:19;;2963:73:0::1;10881:402:1::0;2963:73:0::1;3047:28;3066:8;3047:18;:28::i;:::-;2882:201:::0;:::o;24512:212::-;-1:-1:-1;;;;;24632:16:0;;;;;;;:9;:16;;;;;;;;:25;;;;;;;;;;;;;:34;;;24684:32;;1724:25:1;;;24684:32:0;;1697:18:1;24684:32:0;;;;;;;24512:212;;;:::o;36113:622::-;-1:-1:-1;;;;;36317:18:0;;36313:415;;36373:26;36396:2;36373:22;:26::i;:::-;36414:28;:26;:28::i;36313:415::-;-1:-1:-1;;;;;36464:16:0;;36460:268;;36518:28;36541:4;36518:22;:28::i;36460:268::-;36647:28;36670:4;36647:22;:28::i;:::-;36690:26;36713:2;36690:22;:26::i;27909:505::-;27974:7;28075:143;28257:4;28241:22;;;;;;:::i;:::-;;;;;;;;;;28042:349;;;12785:25:1;;;;12826:18;;12819:34;;;;28286:14:0;12869:18:1;;;12862:34;28323:13:0;12912:18:1;;;12905:34;28367:4:0;12955:19:1;;;12948:61;12757:19;;28042:349:0;;;;;;;;;;;;28014:392;;;;;;27994:412;;27909:505;:::o;28614:392::-;28685:44;28714:1;28718:2;28722:6;28685:20;:44::i;:::-;28757:6;28742:11;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;28914:13:0;;;;;;:9;:13;;;;;;;;:23;;;;;;28966:32;1724:25:1;;;-1:-1:-1;;;;;;;;;;;28966:32:0;1697:18:1;28966:32:0;;;;;;;;28614:392;;:::o;34610:223::-;34657:7;34677:30;:18;9625:19;;9643:1;9625:19;;;9536:127;34677:30;34720:17;34740:23;:21;:23::i;:::-;34720:43;;34779:19;34788:9;34779:19;;;;1724:25:1;;1712:2;1697:18;;1578:177;34779:19:0;;;;;;;;34816:9;34610:223;-1:-1:-1;34610:223:0:o;36743:1688::-;36859:4;36865:7;36911:1;36898:10;:14;36890:49;;;;-1:-1:-1;;;36890:49:0;;13355:2:1;36890:49:0;;;13337:21:1;13394:2;13374:18;;;13367:30;-1:-1:-1;;;13413:18:1;;;13406:52;13475:18;;36890:49:0;13153:346:1;36890:49:0;36986:23;:21;:23::i;:::-;36972:10;:37;;36950:116;;;;-1:-1:-1;;;36950:116:0;;13706:2:1;36950:116:0;;;13688:21:1;13745:2;13725:18;;;13718:30;13784:31;13764:18;;;13757:59;13833:18;;36950:116:0;13504:353:1;36950:116:0;38205:13;38221:40;:9;38250:10;38221:28;:40::i;:::-;38287:20;;38205:56;;-1:-1:-1;38278:29:0;;38274:150;;;38332:5;38339:1;38324:17;;;;;;;38274:150;38382:4;38388:9;:16;;38405:5;38388:23;;;;;;;;:::i;:::-;;;;;;;;;38374:38;;;;;36743:1688;;;;;;:::o;34899:127::-;34963:7;34990:28;:18;9506:14;;9414:114;3243:191;3336:6;;;-1:-1:-1;;;;;3353:17:0;;;-1:-1:-1;;;;;;3353:17:0;;;;;;;3386:40;;3336:6;;;3353:17;3336:6;;3386:40;;3317:16;;3386:40;3306:128;3243:191;:::o;29014:397::-;29087:46;29108:4;29122:1;29126:6;29087:20;:46::i;:::-;-1:-1:-1;;;;;29146:15:0;;;;;;:9;:15;;;;;:25;;29165:6;;29146:15;:25;;29165:6;;29146:25;:::i;:::-;;;;-1:-1:-1;;29319:11:0;:21;;;;;;;29369:34;;1724:25:1;;;-1:-1:-1;;;;;;;29369:34:0;;;-1:-1:-1;;;;;;;;;;;29369:34:0;1712:2:1;1697:18;29369:34:0;1578:177:1;19727:279:0;19855:7;19876:17;19895:18;19917:25;19928:4;19934:1;19937;19940;19917:10;:25::i;:::-;19875:67;;;;19953:18;19965:5;19953:11;:18::i;:::-;-1:-1:-1;19989:9:0;19727:279;-1:-1:-1;;;;;19727:279:0:o;38439:146::-;-1:-1:-1;;;;;38523:33:0;;;;;;:24;:33;;;;;;;;38558:9;:18;;;;;;;38507:70;;38523:33;38507:15;:70::i;38593:116::-;38650:51;38666:21;38689:11;;38650:15;:51::i;7638:918::-;7751:12;;7727:7;;7747:58;;-1:-1:-1;7792:1:0;7785:8;;7747:58;7858:12;;7817:11;;7883:424;7896:4;7890:3;:10;7883:424;;;7917:11;7931:23;7944:3;7949:4;7931:12;:23::i;:::-;7917:37;;8188:7;8175:5;8181:3;8175:10;;;;;;;;:::i;:::-;;;;;;;;;:20;8171:125;;;8223:3;8216:10;;8171:125;;;8273:7;:3;8279:1;8273:7;:::i;:::-;8267:13;;8171:125;7902:405;7883:424;;;8433:1;8427:3;:7;:36;;;;-1:-1:-1;8456:7:0;8438:5;8444:7;8450:1;8444:3;:7;:::i;:::-;8438:14;;;;;;;;:::i;:::-;;;;;;;;;:25;8427:36;8423:126;;;8487:7;8493:1;8487:3;:7;:::i;:::-;8480:14;;;;;;8423:126;-1:-1:-1;8534:3:0;-1:-1:-1;8527:10:0;;17956:1632;18087:7;;19021:66;19008:79;;19004:163;;;-1:-1:-1;19120:1:0;;-1:-1:-1;19124:30:0;19104:51;;19004:163;19181:1;:7;;19186:2;19181:7;;:18;;;;;19192:1;:7;;19197:2;19192:7;;19181:18;19177:102;;;-1:-1:-1;19232:1:0;;-1:-1:-1;19236:30:0;19216:51;;19177:102;19393:24;;;19376:14;19393:24;;;;;;;;;14221:25:1;;;14294:4;14282:17;;14262:18;;;14255:45;;;;14316:18;;;14309:34;;;14359:18;;;14352:34;;;19393:24:0;;14193:19:1;;19393:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;19393:24:0;;-1:-1:-1;;19393:24:0;;;-1:-1:-1;;;;;;;19432:20:0;;19428:103;;19485:1;19489:29;19469:50;;;;;;;19428:103;19551:6;-1:-1:-1;19559:20:0;;-1:-1:-1;17956:1632:0;;;;;;;;:::o;12665:643::-;12743:20;12734:5;:29;;;;;;;;:::i;:::-;;12730:571;;;12665:643;:::o;12730:571::-;12841:29;12832:5;:38;;;;;;;;:::i;:::-;;12828:473;;;12887:34;;-1:-1:-1;;;12887:34:0;;14731:2:1;12887:34:0;;;14713:21:1;14770:2;14750:18;;;14743:30;14809:26;14789:18;;;14782:54;14853:18;;12887:34:0;14529:348:1;12828:473:0;12952:35;12943:5;:44;;;;;;;;:::i;:::-;;12939:362;;;13004:41;;-1:-1:-1;;;13004:41:0;;15084:2:1;13004:41:0;;;15066:21:1;15123:2;15103:18;;;15096:30;15162:33;15142:18;;;15135:61;15213:18;;13004:41:0;14882:355:1;12939:362:0;13076:30;13067:5;:39;;;;;;;;:::i;:::-;;13063:238;;;13123:44;;-1:-1:-1;;;13123:44:0;;15444:2:1;13123:44:0;;;15426:21:1;15483:2;15463:18;;;15456:30;15522:34;15502:18;;;15495:62;-1:-1:-1;;;15573:18:1;;;15566:32;15615:19;;13123:44:0;15242:398:1;13063:238:0;13198:30;13189:5;:39;;;;;;;;:::i;:::-;;13185:116;;;13245:44;;-1:-1:-1;;;13245:44:0;;15847:2:1;13245:44:0;;;15829:21:1;15886:2;15866:18;;;15859:30;15925:34;15905:18;;;15898:62;-1:-1:-1;;;15976:18:1;;;15969:32;16018:19;;13245:44:0;15645:398:1;38717:324:0;38826:17;38846:23;:21;:23::i;:::-;38826:43;-1:-1:-1;38826:43:0;38884:30;38900:9;38884:15;:30::i;:::-;:42;38880:154;;;38943:29;;;;;;;;-1:-1:-1;38943:29:0;;;;;;;;;;;;;;38987:16;;;:35;;;;;;;;;;;;;;;38717:324::o;6445:156::-;6507:7;6582:11;6592:1;6583:5;;;6582:11;:::i;:::-;6572:21;;6573:5;;;6572:21;:::i;:::-;6565:28;6445:156;-1:-1:-1;;;6445:156:0:o;39049:276::-;39188:10;;39146:7;;39215:11;39211:107;;-1:-1:-1;39250:1:0;;39049:276;-1:-1:-1;;39049:276:0:o;39211:107::-;39291:3;39295:10;39304:1;39295:6;:10;:::i;:::-;39291:15;;;;;;;;:::i;:::-;;;;;;;;;39284:22;;;39049:276;;;:::o;39211:107::-;39160:165;39049:276;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:597:1;126:4;155:2;184;173:9;166:21;216:6;210:13;259:6;254:2;243:9;239:18;232:34;284:1;294:140;308:6;305:1;302:13;294:140;;;403:14;;;399:23;;393:30;369:17;;;388:2;365:26;358:66;323:10;;294:140;;;452:6;449:1;446:13;443:91;;;522:1;517:2;508:6;497:9;493:22;489:31;482:42;443:91;-1:-1:-1;595:2:1;574:15;-1:-1:-1;;570:29:1;555:45;;;;602:2;551:54;;14:597;-1:-1:-1;;;14:597:1:o;616:173::-;684:20;;-1:-1:-1;;;;;733:31:1;;723:42;;713:70;;779:1;776;769:12;713:70;616:173;;;:::o;794:254::-;862:6;870;923:2;911:9;902:7;898:23;894:32;891:52;;;939:1;936;929:12;891:52;962:29;981:9;962:29;:::i;:::-;952:39;1038:2;1023:18;;;;1010:32;;-1:-1:-1;;;794:254:1:o;1245:328::-;1322:6;1330;1338;1391:2;1379:9;1370:7;1366:23;1362:32;1359:52;;;1407:1;1404;1397:12;1359:52;1430:29;1449:9;1430:29;:::i;:::-;1420:39;;1478:38;1512:2;1501:9;1497:18;1478:38;:::i;:::-;1468:48;;1563:2;1552:9;1548:18;1535:32;1525:42;;1245:328;;;;;:::o;1760:322::-;1837:6;1845;1853;1906:2;1894:9;1885:7;1881:23;1877:32;1874:52;;;1922:1;1919;1912:12;1874:52;1945:29;1964:9;1945:29;:::i;:::-;1935:39;2021:2;2006:18;;1993:32;;-1:-1:-1;2072:2:1;2057:18;;;2044:32;;1760:322;-1:-1:-1;;;1760:322:1:o;2666:186::-;2725:6;2778:2;2766:9;2757:7;2753:23;2749:32;2746:52;;;2794:1;2791;2784:12;2746:52;2817:29;2836:9;2817:29;:::i;2857:127::-;2918:10;2913:3;2909:20;2906:1;2899:31;2949:4;2946:1;2939:15;2973:4;2970:1;2963:15;2989:1183;3082:6;3090;3143:2;3131:9;3122:7;3118:23;3114:32;3111:52;;;3159:1;3156;3149:12;3111:52;3195:9;3182:23;3172:33;;3224:2;3277;3266:9;3262:18;3249:32;3300:18;3341:2;3333:6;3330:14;3327:34;;;3357:1;3354;3347:12;3327:34;3395:6;3384:9;3380:22;3370:32;;3440:7;3433:4;3429:2;3425:13;3421:27;3411:55;;3462:1;3459;3452:12;3411:55;3498:2;3485:16;3520:2;3516;3513:10;3510:36;;;3526:18;;:::i;:::-;3572:2;3569:1;3565:10;3604:2;3598:9;3667:2;3663:7;3658:2;3654;3650:11;3646:25;3638:6;3634:38;3722:6;3710:10;3707:22;3702:2;3690:10;3687:18;3684:46;3681:72;;;3733:18;;:::i;:::-;3769:2;3762:22;3819:18;;;3853:15;;;;-1:-1:-1;3895:11:1;;;3891:20;;;3923:19;;;3920:39;;;3955:1;3952;3945:12;3920:39;3979:11;;;;3999:142;4015:6;4010:3;4007:15;3999:142;;;4081:17;;4069:30;;4032:12;;;;4119;;;;3999:142;;;4160:6;4150:16;;;;;;;;2989:1183;;;;;:::o;4177:385::-;4263:6;4271;4279;4287;4340:3;4328:9;4319:7;4315:23;4311:33;4308:53;;;4357:1;4354;4347:12;4308:53;-1:-1:-1;;4380:23:1;;;4450:2;4435:18;;4422:32;;-1:-1:-1;4501:2:1;4486:18;;4473:32;;4552:2;4537:18;4524:32;;-1:-1:-1;4177:385:1;-1:-1:-1;4177:385:1:o;4567:180::-;4626:6;4679:2;4667:9;4658:7;4654:23;4650:32;4647:52;;;4695:1;4692;4685:12;4647:52;-1:-1:-1;4718:23:1;;4567:180;-1:-1:-1;4567:180:1:o;4752:435::-;4805:3;4843:5;4837:12;4870:6;4865:3;4858:19;4896:4;4925:2;4920:3;4916:12;4909:19;;4962:2;4955:5;4951:14;4983:1;4993:169;5007:6;5004:1;5001:13;4993:169;;;5068:13;;5056:26;;5102:12;;;;5137:15;;;;5029:1;5022:9;4993:169;;;-1:-1:-1;5178:3:1;;4752:435;-1:-1:-1;;;;;4752:435:1:o;5192:1082::-;5518:4;5566:3;5555:9;5551:19;5597:6;5586:9;5579:25;5623:2;5661:3;5656:2;5645:9;5641:18;5634:31;5685:6;5720;5714:13;5751:6;5743;5736:22;5789:3;5778:9;5774:19;5767:26;;5828:2;5820:6;5816:15;5802:29;;5849:1;5859:169;5873:6;5870:1;5867:13;5859:169;;;5934:13;;5922:26;;6003:15;;;;5968:12;;;;5895:1;5888:9;5859:169;;;5863:3;;6073:9;6068:3;6064:19;6059:2;6048:9;6044:18;6037:47;6107:41;6144:3;6136:6;6107:41;:::i;:::-;6093:55;;;;6196:9;6188:6;6184:22;6179:2;6168:9;6164:18;6157:50;6224:44;6261:6;6253;6224:44;:::i;:::-;6216:52;5192:1082;-1:-1:-1;;;;;;;5192:1082:1:o;6279:693::-;6390:6;6398;6406;6414;6422;6430;6438;6491:3;6479:9;6470:7;6466:23;6462:33;6459:53;;;6508:1;6505;6498:12;6459:53;6531:29;6550:9;6531:29;:::i;:::-;6521:39;;6579:38;6613:2;6602:9;6598:18;6579:38;:::i;:::-;6569:48;;6664:2;6653:9;6649:18;6636:32;6626:42;;6715:2;6704:9;6700:18;6687:32;6677:42;;6769:3;6758:9;6754:19;6741:33;6814:4;6807:5;6803:16;6796:5;6793:27;6783:55;;6834:1;6831;6824:12;6783:55;6279:693;;;;-1:-1:-1;6279:693:1;;;;6857:5;6909:3;6894:19;;6881:33;;-1:-1:-1;6961:3:1;6946:19;;;6933:33;;6279:693;-1:-1:-1;;6279:693:1:o;6977:260::-;7045:6;7053;7106:2;7094:9;7085:7;7081:23;7077:32;7074:52;;;7122:1;7119;7112:12;7074:52;7145:29;7164:9;7145:29;:::i;:::-;7135:39;;7193:38;7227:2;7216:9;7212:18;7193:38;:::i;:::-;7183:48;;6977:260;;;;;:::o;7242:380::-;7321:1;7317:12;;;;7364;;;7385:61;;7439:4;7431:6;7427:17;7417:27;;7385:61;7492:2;7484:6;7481:14;7461:18;7458:38;7455:161;;;7538:10;7533:3;7529:20;7526:1;7519:31;7573:4;7570:1;7563:15;7601:4;7598:1;7591:15;7627:127;7688:10;7683:3;7679:20;7676:1;7669:31;7719:4;7716:1;7709:15;7743:4;7740:1;7733:15;7759:125;7799:4;7827:1;7824;7821:8;7818:34;;;7832:18;;:::i;:::-;-1:-1:-1;7869:9:1;;7759:125::o;7889:277::-;7956:6;8009:2;7997:9;7988:7;7984:23;7980:32;7977:52;;;8025:1;8022;8015:12;7977:52;8057:9;8051:16;8110:5;8103:13;8096:21;8089:5;8086:32;8076:60;;8132:1;8129;8122:12;8171:356;8373:2;8355:21;;;8392:18;;;8385:30;8451:34;8446:2;8431:18;;8424:62;8518:2;8503:18;;8171:356::o;8532:261::-;8711:2;8700:9;8693:21;8674:4;8731:56;8783:2;8772:9;8768:18;8760:6;8731:56;:::i;8798:217::-;8838:1;8864;8854:132;;8908:10;8903:3;8899:20;8896:1;8889:31;8943:4;8940:1;8933:15;8971:4;8968:1;8961:15;8854:132;-1:-1:-1;9000:9:1;;8798:217::o;9020:168::-;9060:7;9126:1;9122;9118:6;9114:14;9111:1;9108:21;9103:1;9096:9;9089:17;9085:45;9082:71;;;9133:18;;:::i;:::-;-1:-1:-1;9173:9:1;;9020:168::o;11417:1104::-;11547:3;11576:1;11609:6;11603:13;11639:3;11661:1;11689:9;11685:2;11681:18;11671:28;;11749:2;11738:9;11734:18;11771;11761:61;;11815:4;11807:6;11803:17;11793:27;;11761:61;11841:2;11889;11881:6;11878:14;11858:18;11855:38;11852:165;;;-1:-1:-1;;;11916:33:1;;11972:4;11969:1;11962:15;12002:4;11923:3;11990:17;11852:165;12033:18;12060:104;;;;12178:1;12173:323;;;;12026:470;;12060:104;-1:-1:-1;;12093:24:1;;12081:37;;12138:16;;;;-1:-1:-1;12060:104:1;;12173:323;11364:1;11357:14;;;11401:4;11388:18;;12271:1;12285:165;12299:6;12296:1;12293:13;12285:165;;;12377:14;;12364:11;;;12357:35;12420:16;;;;12314:10;;12285:165;;;12289:3;;12479:6;12474:3;12470:16;12463:23;;12026:470;-1:-1:-1;12512:3:1;;11417:1104;-1:-1:-1;;;;;;;;11417:1104:1:o;13020:128::-;13060:3;13091:1;13087:6;13084:1;13081:13;13078:39;;;13097:18;;:::i;:::-;-1:-1:-1;13133:9:1;;13020:128::o;13862:127::-;13923:10;13918:3;13914:20;13911:1;13904:31;13954:4;13951:1;13944:15;13978:4;13975:1;13968:15;14397:127;14458:10;14453:3;14449:20;14446:1;14439:31;14489:4;14486:1;14479:15;14513:4;14510:1;14503:15
Swarm Source
ipfs://24cc35816c85aa467ce8ffe72418d55cfc07066960aa28c0702f9a599901b27e
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.