Overview
ETH Balance
0 ETH
ETH Value
$0.00Token Holdings
Latest 25 from a total of 34,802 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Increase Amount | 128913243 | 22 secs ago | IN | 0 ETH | 0.000000732632 | ||||
Increase Amount | 128913226 | 56 secs ago | IN | 0 ETH | 0.000001057862 | ||||
Increase Unlock ... | 128910964 | 1 hr ago | IN | 0 ETH | 0.000000763023 | ||||
Increase Amount | 128910945 | 1 hr ago | IN | 0 ETH | 0.000000843892 | ||||
Increase Amount | 128910095 | 1 hr ago | IN | 0 ETH | 0.000001558523 | ||||
Increase Amount | 128909994 | 1 hr ago | IN | 0 ETH | 0.00000215468 | ||||
Increase Amount | 128909988 | 1 hr ago | IN | 0 ETH | 0.00000210247 | ||||
Increase Unlock ... | 128909959 | 1 hr ago | IN | 0 ETH | 0.000001900035 | ||||
Increase Amount | 128909248 | 2 hrs ago | IN | 0 ETH | 0.000002685506 | ||||
Increase Amount | 128908753 | 2 hrs ago | IN | 0 ETH | 0.000002786778 | ||||
Increase Amount | 128908542 | 2 hrs ago | IN | 0 ETH | 0.000005409408 | ||||
Increase Unlock ... | 128908356 | 2 hrs ago | IN | 0 ETH | 0.000005707636 | ||||
Increase Amount | 128908346 | 2 hrs ago | IN | 0 ETH | 0.000005320955 | ||||
Increase Amount | 128908285 | 2 hrs ago | IN | 0 ETH | 0.000005602307 | ||||
Increase Unlock ... | 128908276 | 2 hrs ago | IN | 0 ETH | 0.000005018171 | ||||
Increase Amount | 128908245 | 2 hrs ago | IN | 0 ETH | 0.00000542029 | ||||
Increase Amount | 128908236 | 2 hrs ago | IN | 0 ETH | 0.000006247549 | ||||
Increase Amount | 128908183 | 2 hrs ago | IN | 0 ETH | 0.000005421629 | ||||
Increase Unlock ... | 128907984 | 2 hrs ago | IN | 0 ETH | 0.000002363183 | ||||
Increase Unlock ... | 128907922 | 2 hrs ago | IN | 0 ETH | 0.000002858597 | ||||
Increase Amount | 128907906 | 2 hrs ago | IN | 0 ETH | 0.00000319 | ||||
Increase Amount | 128907807 | 3 hrs ago | IN | 0 ETH | 0.000002089568 | ||||
Increase Amount | 128907712 | 3 hrs ago | IN | 0 ETH | 0.000001852965 | ||||
Increase Unlock ... | 128907426 | 3 hrs ago | IN | 0 ETH | 0.000002017348 | ||||
Increase Unlock ... | 128907289 | 3 hrs ago | IN | 0 ETH | 0.000001643392 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
107558271 | 494 days ago | 0 ETH | ||||
107557985 | 494 days ago | 0 ETH | ||||
107557796 | 494 days ago | 0 ETH | ||||
107557773 | 494 days ago | 0 ETH | ||||
107557494 | 494 days ago | 0 ETH | ||||
107557441 | 494 days ago | 0 ETH | ||||
107557441 | 494 days ago | 0 ETH | ||||
107557441 | 494 days ago | 0 ETH | ||||
107557441 | 494 days ago | 0 ETH | ||||
107557420 | 494 days ago | 0 ETH | ||||
107557394 | 494 days ago | 0 ETH | ||||
107557225 | 494 days ago | 0 ETH | ||||
107557057 | 494 days ago | 0 ETH | ||||
107556845 | 494 days ago | 0 ETH | ||||
107556615 | 494 days ago | 0 ETH | ||||
107556568 | 494 days ago | 0 ETH | ||||
107556393 | 494 days ago | 0 ETH | ||||
107556231 | 494 days ago | 0 ETH | ||||
107555838 | 494 days ago | 0 ETH | ||||
107555612 | 494 days ago | 0 ETH | ||||
107555574 | 494 days ago | 0 ETH | ||||
107555528 | 494 days ago | 0 ETH | ||||
107555267 | 494 days ago | 0 ETH | ||||
107555144 | 494 days ago | 0 ETH | ||||
107555090 | 494 days ago | 0 ETH |
Loading...
Loading
Contract Name:
VeToken
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at optimistic.etherscan.io on 2023-05-24 */ // SPDX-License-Identifier: gpl-3.0 // Sources flattened with hardhat v2.13.0 https://hardhat.org // File contracts/external/openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File contracts/external/openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) // pragma solidity ^0.8.0; /** * @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 Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { 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 contracts/external/openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File contracts/external/openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval( address indexed owner, address indexed spender, uint256 value ); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance( address owner, address spender ) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); } // File contracts/external/openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) // pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require( address(this).balance >= amount, "Address: insufficient balance" ); (bool success, ) = recipient.call{value: amount}(""); require( success, "Address: unable to send value, recipient may have reverted" ); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data ) internal returns (bytes memory) { return functionCallWithValue( target, data, 0, "Address: low-level call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, "Address: low-level call with value failed" ); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require( address(this).balance >= value, "Address: insufficient balance for call" ); (bool success, bytes memory returndata) = target.call{value: value}( data ); return verifyCallResultFromTarget( target, success, returndata, errorMessage ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data ) internal view returns (bytes memory) { return functionStaticCall( target, data, "Address: low-level static call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget( target, success, returndata, errorMessage ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data ) internal returns (bytes memory) { return functionDelegateCall( target, data, "Address: low-level delegate call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget( target, success, returndata, errorMessage ); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert( bytes memory returndata, string memory errorMessage ) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File contracts/external/openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) // pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transfer.selector, to, value) ); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, value) ); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require( oldAllowance >= value, "SafeERC20: decreased allowance below zero" ); uint256 newAllowance = oldAllowance - value; _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require( nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed" ); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall( data, "SafeERC20: low-level call failed" ); if (returndata.length > 0) { // Return data is optional require( abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed" ); } } } // File contracts/external/openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File contracts/interfaces/IveToken.sol // pragma solidity ^0.8.0; interface IveToken { function checkpoint() external; function depositFor(address addr, uint128 value) external; function createLock(uint128 value, uint256 unlockTime) external; function increaseAmount(uint128 value) external; function increaseUnlockTime(uint256 unlockTime) external; function withdraw() external; function userPointEpoch(address addr) external view returns (uint256); function lockedEnd(address addr) external view returns (uint256); function getLastUserSlope(address addr) external view returns (int128); function getUserPointHistoryTS( address addr, uint256 idx ) external view returns (uint256); function balanceOf( address addr, uint256 ts ) external view returns (uint256); function balanceOf(address addr) external view returns (uint256); function balanceOfAt( address, uint256 blockNumber ) external view returns (uint256); function totalSupply(uint256 ts) external view returns (uint256); function totalSupply() external view returns (uint256); function totalSupplyAt(uint256 blockNumber) external view returns (uint256); } // File contracts/VeToken.sol // pragma solidity ^0.8.0; contract VeToken is IveToken, Ownable, ReentrancyGuard { using SafeERC20 for IERC20; enum ActionType { DEPOSIT_FOR, CREATE_LOCK, INCREASE_AMOUNT, INCREASE_LOCK_TIME } struct Point { int128 bias; // veToken value at this point int128 slope; // slope at this point uint256 ts; // timestamp of this point uint256 blk; // block number of this point } /* We cannot really do block numbers per se b/c slope is per time, not per block * and per block could be fairly bad b/c Ethereum changes blocktimes. * What we can do is to extrapolate ***At functions */ struct LockedBalance { uint128 amount; // amount of Token locked for a user. uint256 end; // the expiry time of the deposit. } // veToken token related string public version; string public constant name = "Vote-escrow EXTRA"; string public constant symbol = "veEXTRA"; uint8 public constant decimals = 18; uint256 public totalTokenLocked; uint256 public constant WEEK = 1 weeks; uint256 public constant MAX_TIME = 1 * 365 days; uint256 public constant MIN_TIME = 1 * WEEK; uint256 public constant MULTIPLIER = 10 ** 18; int128 public constant I_SLOPE_DENOMINATOR = int128(uint128(MAX_TIME)); int128 public constant I_MIN_TIME = int128(uint128(WEEK)); /// Base Token related information address public immutable Token; /// @dev Mappings to store global point information uint256 public epoch; mapping(uint256 => Point) public pointHistory; // epoch -> unsigned point mapping(uint256 => int128) public slopeChanges; // time -> signed slope change /// @dev Mappings to store user deposit information mapping(address => LockedBalance) public lockedBalances; // user Deposits mapping(address => mapping(uint256 => Point)) public userPointHistory; // user -> point[userEpoch] mapping(address => uint256) public userPointEpoch; event UserCheckpoint( ActionType indexed actionType, address indexed provider, uint256 value, uint256 indexed locktime ); event GlobalCheckpoint(address caller, uint256 epoch); event Withdraw(address indexed provider, uint256 value, uint256 ts); event Supply(uint256 prevSupply, uint256 supply); /// @dev Constructor constructor(address _token, string memory _version) { require(_token != address(0), "_token is zero address"); Token = _token; version = _version; pointHistory[0].blk = block.number; pointHistory[0].ts = block.timestamp; } /// @notice Record global data to checkpoint function checkpoint() external { _updateGlobalPoint(); emit GlobalCheckpoint(_msgSender(), epoch); } /// @notice Deposit and lock tokens for a user /// @dev Anyone (even a smart contract) can deposit tokens for someone else, but /// cannot extend their locktime and deposit for a user that is not locked /// @param addr Address of the user /// @param value Amount of tokens to deposit function depositFor(address addr, uint128 value) external nonReentrant { LockedBalance memory existingDeposit = lockedBalances[addr]; require(value > 0, "Cannot deposit 0 tokens"); require(existingDeposit.amount > 0, "No existing lock"); require( existingDeposit.end > block.timestamp, "Lock expired. Withdraw" ); _depositFor(addr, value, 0, existingDeposit, ActionType.DEPOSIT_FOR); } /// @notice Deposit `value` for `msg.sender` and lock untill `unlockTime` /// @param value Amount of tokens to deposit /// @param unlockTime Time when the tokens will be unlocked /// @dev the user's veToken balance will decay to 0 after `unlockTime` /// @dev unlockTime is rownded down to whole weeks function createLock( uint128 value, uint256 unlockTime ) external nonReentrant { address account = _msgSender(); uint256 roundedUnlockTime = (unlockTime / WEEK) * WEEK; LockedBalance memory existingDeposit = lockedBalances[account]; require(value > 0, "Cannot lock 0 tokens"); require(existingDeposit.amount == 0, "Withdraw old tokens first"); require(roundedUnlockTime > block.timestamp, "Cannot lock in the past"); require( roundedUnlockTime <= block.timestamp + MAX_TIME, "Voting lock can not longer than MAX_TIME" ); _depositFor( account, value, roundedUnlockTime, existingDeposit, ActionType.CREATE_LOCK ); } /// @notice Deposit `value` additional tokens for `msg.sender` without /// modifying the locktime /// @param value Amount of tokens to deposit function increaseAmount(uint128 value) external nonReentrant { address account = _msgSender(); LockedBalance memory existingDeposit = lockedBalances[account]; require(value > 0, "Cannot deposit 0 tokens"); require(existingDeposit.amount > 0, "No existing lock found"); require( existingDeposit.end > block.timestamp, "Lock expired. Withdraw" ); _depositFor( account, value, 0, existingDeposit, ActionType.INCREASE_AMOUNT ); } /// @notice Extend the locktime of `msg.sender`'s tokens to `unlockTime` /// @param unlockTime New locktime function increaseUnlockTime(uint256 unlockTime) external { address account = _msgSender(); LockedBalance memory existingDeposit = lockedBalances[account]; uint256 roundedUnlockTime = (unlockTime / WEEK) * WEEK; // Locktime is rounded down to weeks require(existingDeposit.amount > 0, "No existing lock found"); require( existingDeposit.end > block.timestamp, "Lock expired. Withdraw" ); require( roundedUnlockTime > existingDeposit.end, "Can only increase lock duration" ); require( roundedUnlockTime <= block.timestamp + MAX_TIME, "Voting lock can not longer than MAX_TIME" ); _depositFor( account, 0, roundedUnlockTime, existingDeposit, ActionType.INCREASE_LOCK_TIME ); } /// @notice Withdraw tokens for `msg.sender` /// @dev Only possible if the locktime has expired function withdraw() external nonReentrant { address account = _msgSender(); LockedBalance memory existingDeposit = lockedBalances[account]; require(existingDeposit.amount > 0, "No existing lock found"); require(block.timestamp >= existingDeposit.end, "Lock not expired."); uint128 value = existingDeposit.amount; LockedBalance memory oldDeposit = lockedBalances[account]; lockedBalances[account] = LockedBalance(0, 0); uint256 prevSupply = totalTokenLocked; totalTokenLocked -= value; // oldDeposit can have either expired <= timestamp or 0 end // existingDeposit has 0 end // Both can have >= 0 amount _checkpoint(account, oldDeposit, LockedBalance(0, 0)); IERC20(Token).safeTransfer(account, value); emit Withdraw(account, value, block.timestamp); emit Supply(prevSupply, totalTokenLocked); } /// @notice Calculate total voting power at a given block number in past /// @param blockNumber Block number to calculate total voting power at /// @return Total voting power at block number function totalSupplyAt( uint256 blockNumber ) external view returns (uint256) { require(blockNumber <= block.number); uint256 _epoch = epoch; uint256 targetEpoch = _findBlockEpoch(blockNumber, _epoch); Point memory point0 = pointHistory[targetEpoch]; uint256 dt = 0; if (targetEpoch < _epoch) { Point memory point1 = pointHistory[targetEpoch + 1]; dt = ((blockNumber - point0.blk) * (point1.ts - point0.ts)) / (point1.blk - point0.blk); } else { if (point0.blk != block.number) { dt = ((blockNumber - point0.blk) * (block.timestamp - point0.ts)) / (block.number - point0.blk); } } // Now dt contains info on how far we are beyond point0 return supplyAt(point0, point0.ts + dt); } /// @notice Get the most recently recorded rate of voting power decrease for `addr` /// @param addr The address to get the rate for /// @return value of the slope function getLastUserSlope(address addr) external view returns (int128) { uint256 uEpoch = userPointEpoch[addr]; if (uEpoch == 0) { return 0; } return userPointHistory[addr][uEpoch].slope; } /// @notice Get the timestamp for checkpoint `idx` for `addr` /// @param addr User wallet address /// @param idx User epoch number /// @return Epoch time of the checkpoint function getUserPointHistoryTS( address addr, uint256 idx ) external view returns (uint256) { return userPointHistory[addr][idx].ts; } /// @notice Get timestamp when `addr`'s lock finishes /// @param addr User wallet address /// @return Timestamp when lock finishes function lockedEnd(address addr) external view returns (uint256) { return lockedBalances[addr].end; } /// @notice Function to estimate the user deposit /// @param value Amount of Token to deposit /// @param expectedUnlockTime The expected unlock time /// @dev if autoCooldown is true, the user's veToken balance will /// decay to 0 after `unlockTime` else the user's veToken balance /// will remain = residual balance till user initiates cooldown function estimateDeposit( uint128 value, uint256 expectedUnlockTime ) public view returns ( int128 initialVeTokenBalance, // initial veToken balance int128 slope, // slope of the user's graph int128 bias, // bias of the user's graph uint256 actualUnlockTime, // actual rounded unlock time uint256 providedUnlockTime // expected unlock time ) { actualUnlockTime = (expectedUnlockTime / WEEK) * WEEK; require(actualUnlockTime > block.timestamp, "Cannot lock in the past"); require( actualUnlockTime <= block.timestamp + MAX_TIME, "Voting lock can not longer than MAX_TIME" ); int128 amt = int128(value); slope = amt / I_SLOPE_DENOMINATOR; bias = slope * int128(int256(actualUnlockTime) - int256(block.timestamp)); if (bias <= 0) { bias = 0; } initialVeTokenBalance = bias; return ( initialVeTokenBalance, slope, bias, actualUnlockTime, expectedUnlockTime ); } /// @notice Get the voting power for a user at the specified timestamp /// @dev Adheres to ERC20 `balanceOf` interface for Aragon compatibility /// @param addr User wallet address /// @param ts Timestamp to get voting power at /// @return Voting power of user at timestamp function balanceOf(address addr, uint256 ts) public view returns (uint256) { uint256 _epoch = _findUserTimestampEpoch(addr, ts); if (_epoch == 0) { return 0; } else { Point memory lastPoint = userPointHistory[addr][_epoch]; lastPoint.bias -= lastPoint.slope * int128(int256(ts) - int256(lastPoint.ts)); if (lastPoint.bias < 0) { lastPoint.bias = 0; } return uint256(int256(lastPoint.bias)); } } /// @notice Get the current voting power for a user /// @param addr User wallet address /// @return Voting power of user at current timestamp function balanceOf(address addr) public view returns (uint256) { return balanceOf(addr, block.timestamp); } /// @notice Get the voting power of `addr` at block `blockNumber` /// @param addr User wallet address /// @param blockNumber Block number to get voting power at /// @return Voting power of user at block number function balanceOfAt( address addr, uint256 blockNumber ) public view returns (uint256) { uint256 min = 0; uint256 max = userPointEpoch[addr]; // Find the approximate timestamp for the block number for (uint256 i = 0; i < 128; i++) { if (min >= max) { break; } uint256 mid = (min + max + 1) / 2; if (userPointHistory[addr][mid].blk <= blockNumber) { min = mid; } else { max = mid - 1; } } // min is the userEpoch nearest to the block number Point memory uPoint = userPointHistory[addr][min]; uint256 maxEpoch = epoch; // blocktime using the global point history uint256 _epoch = _findBlockEpoch(blockNumber, maxEpoch); Point memory point0 = pointHistory[_epoch]; uint256 dBlock = 0; uint256 dt = 0; if (_epoch < maxEpoch) { Point memory point1 = pointHistory[_epoch + 1]; dBlock = point1.blk - point0.blk; dt = point1.ts - point0.ts; } else { dBlock = block.number - point0.blk; dt = block.timestamp - point0.ts; } uint256 blockTime = point0.ts; if (dBlock != 0) { blockTime += (dt * (blockNumber - point0.blk)) / dBlock; } uPoint.bias -= uPoint.slope * int128(int256(blockTime) - int256(uPoint.ts)); if (uPoint.bias < 0) { uPoint.bias = 0; } return uint256(int256(uPoint.bias)); } /// @notice Calculate total voting power at current timestamp /// @return Total voting power at current timestamp function totalSupply() public view returns (uint256) { return totalSupply(block.timestamp); } /// @notice Calculate total voting power at a given timestamp /// @return Total voting power at timestamp function totalSupply(uint256 ts) public view returns (uint256) { uint256 _epoch = _findGlobalTimestampEpoch(ts); Point memory lastPoint = pointHistory[_epoch]; return supplyAt(lastPoint, ts); } /// @notice Record global and per-user data to checkpoint /// @param addr User wallet address. No user checkpoint if 0x0 /// @param oldDeposit Previous locked balance / end lock time for the user /// @param newDeposit New locked balance / end lock time for the user function _checkpoint( address addr, LockedBalance memory oldDeposit, LockedBalance memory newDeposit ) internal { Point memory uOld = Point(0, 0, 0, 0); Point memory uNew = Point(0, 0, 0, 0); int128 dSlopeOld = 0; int128 dSlopeNew = 0; // Calculate slopes and biases for oldDeposit // Skipped in case of createLock if (oldDeposit.amount > 0) { int128 amt = int128(oldDeposit.amount); if (oldDeposit.end > block.timestamp) { uOld.slope = amt / I_SLOPE_DENOMINATOR; uOld.bias = uOld.slope * int128(int256(oldDeposit.end) - int256(block.timestamp)); } } // Calculate slopes and biases for newDeposit // Skipped in case of withdraw if ((newDeposit.end > block.timestamp) && (newDeposit.amount > 0)) { int128 amt = int128(newDeposit.amount); if (newDeposit.end > block.timestamp) { uNew.slope = amt / I_SLOPE_DENOMINATOR; uNew.bias = uNew.slope * int128(int256(newDeposit.end) - int256(block.timestamp)); } } // Read values of scheduled changes in the slope // oldDeposit.end can be in the past and in the future // newDeposit.end can ONLY be in the future, unless everything expired: than zeros dSlopeOld = slopeChanges[oldDeposit.end]; if (newDeposit.end != 0) { // if not "withdraw" dSlopeNew = slopeChanges[newDeposit.end]; } // add all global checkpoints from last added global check point until now Point memory lastPoint = _updateGlobalPoint(); // If last point was in this block, the slope change has been applied already // But in such case we have 0 slope(s) // update the last global checkpoint (now) with user action's consequences lastPoint.slope += (uNew.slope - uOld.slope); lastPoint.bias += (uNew.bias - uOld.bias); if (lastPoint.slope < 0) { lastPoint.slope = 0; } if (lastPoint.bias < 0) { lastPoint.bias = 0; } pointHistory[epoch] = lastPoint; // Record the changed point into the global history by replacement // Schedule the slope changes (slope is going down) // We subtract new_user_slope from [new_locked.end] // and add old_user_slope to [old_locked.end] if (oldDeposit.end > block.timestamp) { // old_dslope was <something> - u_old.slope, so we cancel that dSlopeOld += uOld.slope; if (newDeposit.end == oldDeposit.end) { // It was a new deposit, not extension dSlopeOld -= uNew.slope; } slopeChanges[oldDeposit.end] = dSlopeOld; } if (newDeposit.end > block.timestamp) { if (newDeposit.end > oldDeposit.end) { dSlopeNew -= uNew.slope; // old slope disappeared at this point slopeChanges[newDeposit.end] = dSlopeNew; } // else: we recorded it already in old_dslopes̄ } // Now handle user history uint256 userEpc = userPointEpoch[addr] + 1; userPointEpoch[addr] = userEpc; uNew.ts = block.timestamp; uNew.blk = block.number; userPointHistory[addr][userEpc] = uNew; } /// @notice Deposit and lock tokens for a user /// @param addr Address of the user /// @param value Amount of tokens to deposit /// @param unlockTime Time when the tokens will be unlocked /// @param oldDeposit Previous locked balance of the user / timestamp function _depositFor( address addr, // bool autoCooldown, // bool enableCooldown, uint128 value, uint256 unlockTime, LockedBalance memory oldDeposit, ActionType _type ) internal { LockedBalance memory newDeposit = lockedBalances[addr]; uint256 prevSupply = totalTokenLocked; totalTokenLocked += value; // Adding to existing lock, or if a lock is expired - creating a new one newDeposit.amount += value; // newDeposit.autoCooldown = autoCooldown; // newDeposit.cooldownInitiated = enableCooldown; if (unlockTime != 0) { newDeposit.end = unlockTime; } lockedBalances[addr] = newDeposit; /// Possibilities: // Both oldDeposit.end could be current or expired (>/<block.timestamp) // value == 0 (extend lock) or value > 0 (add to lock or extend lock) // newDeposit.end > block.timestamp (always) _checkpoint(addr, oldDeposit, newDeposit); if (value != 0) { IERC20(Token).safeTransferFrom(_msgSender(), address(this), value); } emit UserCheckpoint(_type, addr, value, newDeposit.end); emit Supply(prevSupply, totalTokenLocked); } /// @notice Calculate total voting power at some point in the past /// @param point The point (bias/slope) to start search from /// @param ts Timestamp to calculate total voting power at /// @return Total voting power at timestamp function supplyAt( Point memory point, uint256 ts ) internal view returns (uint256) { Point memory lastPoint = point; uint256 ti = (lastPoint.ts / WEEK) * WEEK; // Calculate the missing checkpoints for (uint256 i = 0; i < 255; i++) { ti += WEEK; int128 dSlope = 0; if (ti > ts) { ti = ts; } else { dSlope = slopeChanges[ti]; } lastPoint.bias -= lastPoint.slope * int128(int256(ti) - int256(lastPoint.ts)); if (ti == ts) { break; } lastPoint.slope += dSlope; lastPoint.ts = ti; } if (lastPoint.bias < 0) { lastPoint.bias = 0; } return uint256(int256(lastPoint.bias)); } // ----------------------VIEW functions---------------------- /// NOTE:The following ERC20/minime-compatible methods are not real balanceOf and supply!! /// They measure the weights for the purpose of voting, so they don't represent real coins. /// @notice Binary search to find the latest epoch before specifc blockNumber /// Therefore, we can use the checkpoint of the epoch /// to estimate the timestamp at the blockNumber /// @param blockNumber Block number to estimate timestamp for /// @param maxEpoch Don't go beyond this epoch /// @return LatestEpcoh before the blockNumber function _findBlockEpoch( uint256 blockNumber, uint256 maxEpoch ) internal view returns (uint256) { uint256 min = 0; uint256 max = maxEpoch; for (uint256 i = 0; i < 128; i++) { if (min >= max) { break; } uint256 mid = (min + max + 1) / 2; if (pointHistory[mid].blk <= blockNumber) { min = mid; } else { max = mid - 1; } } return min; } function _findUserTimestampEpoch( address addr, uint256 ts ) internal view returns (uint256) { uint256 min = 0; uint256 max = userPointEpoch[addr]; for (uint256 i = 0; i < 128; i++) { if (min >= max) { break; } uint256 mid = (min + max + 1) / 2; if (userPointHistory[addr][mid].ts <= ts) { min = mid; } else { max = mid - 1; } } return min; } function _findGlobalTimestampEpoch( uint256 ts ) internal view returns (uint256) { uint256 min = 0; uint256 max = epoch; for (uint256 i = 0; i < 128; i++) { if (min >= max) { break; } uint256 mid = (min + max + 1) / 2; if (pointHistory[mid].ts <= ts) { min = mid; } else { max = mid - 1; } } return min; } /// @notice add checkpoints to pointHistory for every week from last added checkpoint until now /// @dev block number for each added checkpoint is estimated by their respective timestamp and the blockslope /// where the blockslope is estimated by the last added time/block point and the current time/block point /// @dev pointHistory include all weekly global checkpoints and some additional in-week global checkpoints /// @return lastPoint by calling this function function _updateGlobalPoint() private returns (Point memory lastPoint) { uint256 _epoch = epoch; lastPoint = Point({ bias: 0, slope: 0, ts: block.timestamp, blk: block.number }); Point memory initialLastPoint = Point({ bias: 0, slope: 0, ts: block.timestamp, blk: block.number }); if (_epoch > 0) { lastPoint = pointHistory[_epoch]; initialLastPoint = pointHistory[_epoch]; } uint256 lastCheckpoint = lastPoint.ts; // initialLastPoint is used for extrapolation to calculate block number // (approximately, for *At functions) and save them // as we cannot figure that out exactly from inside the contract uint256 blockSlope = 0; // dblock/dt, how much blocks mined per seconds if (block.timestamp > lastPoint.ts) { blockSlope = (MULTIPLIER * (block.number - lastPoint.blk)) / (block.timestamp - lastPoint.ts); } // If last point is already recorded in this block, blockSlope is zero // But that's ok b/c we know the block in such case. // Go over weeks to fill history from lastCheckpoint by creating checkpoints for each epoch(week) // and calculate what the current point is { uint256 ti = (lastCheckpoint / WEEK) * WEEK; for (uint256 i = 0; i < 255; i++) { // Hopefully it won't happen that this won't get used in 4 years! // If it does, users will be able to withdraw but vote weight will be broken ti += WEEK; int128 dslope = 0; if (ti > block.timestamp) { ti = block.timestamp; } else { dslope = slopeChanges[ti]; // If dslope is 0, it means that the slope does not change at time ti. // Each time a user locks new tokens, there will be a slope change at the unlock time recorded in slopeChanges[]. } // calculate the slope and bia of the new last point lastPoint.bias -= lastPoint.slope * int128(int256(ti) - int256(lastCheckpoint)); lastPoint.slope += dslope; // check sanity if (lastPoint.bias < 0) { lastPoint.bias = 0; } if (lastPoint.slope < 0) { lastPoint.slope = 0; } lastCheckpoint = ti; lastPoint.ts = ti; lastPoint.blk = initialLastPoint.blk + (blockSlope * (ti - initialLastPoint.ts)) / MULTIPLIER; _epoch += 1; if (ti == block.timestamp) { lastPoint.blk = block.number; pointHistory[_epoch] = lastPoint; break; } pointHistory[_epoch] = lastPoint; } } epoch = _epoch; return lastPoint; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"string","name":"_version","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"GlobalCheckpoint","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":"uint256","name":"prevSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"supply","type":"uint256"}],"name":"Supply","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum VeToken.ActionType","name":"actionType","type":"uint8"},{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"locktime","type":"uint256"}],"name":"UserCheckpoint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ts","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"I_MIN_TIME","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"I_SLOPE_DENOMINATOR","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WEEK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"ts","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"balanceOfAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkpoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"value","type":"uint128"},{"internalType":"uint256","name":"unlockTime","type":"uint256"}],"name":"createLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint128","name":"value","type":"uint128"}],"name":"depositFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"value","type":"uint128"},{"internalType":"uint256","name":"expectedUnlockTime","type":"uint256"}],"name":"estimateDeposit","outputs":[{"internalType":"int128","name":"initialVeTokenBalance","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"uint256","name":"actualUnlockTime","type":"uint256"},{"internalType":"uint256","name":"providedUnlockTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getLastUserSlope","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"idx","type":"uint256"}],"name":"getUserPointHistoryTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"value","type":"uint128"}],"name":"increaseAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"unlockTime","type":"uint256"}],"name":"increaseUnlockTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lockedBalances","outputs":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint256","name":"end","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"lockedEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pointHistory","outputs":[{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"uint256","name":"ts","type":"uint256"},{"internalType":"uint256","name":"blk","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"slopeChanges","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"ts","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"totalSupplyAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTokenLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userPointEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userPointHistory","outputs":[{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"uint256","name":"ts","type":"uint256"},{"internalType":"uint256","name":"blk","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162002c8438038062002c84833981016040819052620000349162000177565b6200003f3362000111565b600180556001600160a01b0382166200009e5760405162461bcd60e51b815260206004820152601660248201527f5f746f6b656e206973207a65726f206164647265737300000000000000000000604482015260640160405180910390fd5b6001600160a01b0382166080526002620000b98282620002fc565b505060008052506005602052437f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746be55427f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bd55620003c8565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200018b57600080fd5b82516001600160a01b0381168114620001a357600080fd5b602084810151919350906001600160401b0380821115620001c357600080fd5b818601915086601f830112620001d857600080fd5b815181811115620001ed57620001ed62000161565b604051601f8201601f19908116603f0116810190838211818310171562000218576200021862000161565b8160405282815289868487010111156200023157600080fd5b600093505b8284101562000255578484018601518185018701529285019262000236565b60008684830101528096505050505050509250929050565b600181811c908216806200028257607f821691505b602082108103620002a357634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002f757600081815260208120601f850160051c81016020861015620002d25750805b601f850160051c820191505b81811015620002f357828155600101620002de565b5050505b505050565b81516001600160401b0381111562000318576200031862000161565b62000330816200032984546200026d565b84620002a9565b602080601f8311600181146200036857600084156200034f5750858301515b600019600386901b1c1916600185901b178555620002f3565b600085815260208120601f198616915b82811015620003995788860151825594840194600190910190840162000378565b5085821015620003b85787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051612892620003f26000396000818161055b01528181610a30015261177e01526128926000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c806381fc83bb11610130578063bd85b039116100b8578063e54357bc1161007c578063e54357bc146105be578063f2fde38b14610604578063f3a6d60814610617578063f4359ce51461062a578063f52a36f71461063457600080fd5b8063bd85b0391461053a578063c00c4da11461054d578063c241267614610556578063c2c4c5c11461057d578063e2c5b4d21461058557600080fd5b8063900cf0cf116100ff578063900cf0cf146104db578063911dcf5c146104e457806395d89b41146104ee578063981b24d0146105145780639a3f14f71461052757600080fd5b806381fc83bb146104505780638ad4c447146104705780638da5cb5b146104ae5780638ff07b5b146104d357600080fd5b80633c3b3189116101b35780634ee2cd7e116101825780634ee2cd7e1461040757806354fd4d501461041a57806370a0823114610422578063715018a6146104355780637c616fe61461043d57600080fd5b80633c3b3189146103a25780633ccfd60b146103c05780634deafcae146103c85780634e3430ca146103f457600080fd5b806318160ddd116101fa57806318160ddd146102ef57806326949984146102f7578063313ce5671461030257806334d901a41461031c5780633527d1c01461038d57600080fd5b8062fdd58e1461022b5780630483a7f614610251578063059f8b16146102a357806306fdde03146102b2575b600080fd5b61023e61023936600461245b565b610657565b6040519081526020015b60405180910390f35b61028461025f366004612485565b600760205260009081526040902080546001909101546001600160801b039091169082565b604080516001600160801b039093168352602083019190915201610248565b61023e670de0b6b3a764000081565b6102e260405180604001604052806011815260200170566f74652d657363726f7720455854524160781b81525081565b60405161024891906124cb565b61023e61072b565b61023e6301e1338081565b61030a601281565b60405160ff9091168152602001610248565b61036561032a36600461245b565b6008602090815260009283526040808420909152908252902080546001820154600290920154600f82810b93600160801b909304900b919084565b60408051600f95860b81529390940b6020840152928201526060810191909152608001610248565b6103a061039b366004612515565b61073b565b005b6103ad6301e1338081565b604051600f9190910b8152602001610248565b6103a06108d8565b61023e6103d6366004612485565b6001600160a01b031660009081526007602052604090206001015490565b6103a0610402366004612531565b610af9565b61023e61041536600461245b565b610be7565b6102e2610e97565b61023e610430366004612485565b610f25565b6103a0610f31565b6103a061044b36600461254c565b610f43565b61023e61045e366004612485565b60096020526000908152604090205481565b61036561047e36600461254c565b600560205260009081526040902080546001820154600290920154600f82810b93600160801b909304900b919084565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610248565b61023e611070565b61023e60045481565b6103ad62093a8081565b6102e2604051806040016040528060078152602001667665455854524160c81b81525081565b61023e61052236600461254c565b611081565b6103a0610535366004612565565b611210565b61023e61054836600461254c565b611326565b61023e60035481565b6104bb7f000000000000000000000000000000000000000000000000000000000000000081565b6103a0611392565b61023e61059336600461245b565b6001600160a01b03919091166000908152600860209081526040808320938352929052206001015490565b6105d16105cc366004612515565b6113db565b60408051600f96870b815294860b60208601529290940b918301919091526060820152608081019190915260a001610248565b6103a0610612366004612485565b6114b8565b6103ad610625366004612485565b61152e565b61023e62093a8081565b6103ad61064236600461254c565b600660205260009081526040902054600f0b81565b600080610664848461158d565b905080600003610678576000915050610725565b6001600160a01b038416600090815260086020908152604080832084845282529182902082516080810184528154600f81810b8352600160801b909104900b928101929092526001810154928201839052600201546060820152906106dd90856125ae565b81602001516106ec91906125ce565b815182906106fb9083906125ee565b600f90810b90915282516000910b1215905061071657600081525b51600f0b91506107259050565b505b92915050565b600061073642611326565b905090565b610743611641565b33600062093a806107548185612631565b61075e9190612645565b6001600160a01b038316600090815260076020908152604091829020825180840190935280546001600160801b039081168452600190910154918301919091529192509085166107ec5760405162461bcd60e51b815260206004820152601460248201527343616e6e6f74206c6f636b203020746f6b656e7360601b60448201526064015b60405180910390fd5b80516001600160801b0316156108445760405162461bcd60e51b815260206004820152601960248201527f5769746864726177206f6c6420746f6b656e732066697273740000000000000060448201526064016107e3565b42821161088d5760405162461bcd60e51b815260206004820152601760248201527610d85b9b9bdd081b1bd8dac81a5b881d1a19481c185cdd604a1b60448201526064016107e3565b61089b6301e133804261265c565b8211156108ba5760405162461bcd60e51b81526004016107e39061266f565b6108c883868484600161169a565b5050506108d460018055565b5050565b6108e0611641565b33600081815260076020908152604091829020825180840190935280546001600160801b0316808452600190910154918301919091526109325760405162461bcd60e51b81526004016107e3906126b7565b806020015142101561097a5760405162461bcd60e51b81526020600482015260116024820152702637b1b5903737ba1032bc3834b932b21760791b60448201526064016107e3565b80516001600160a01b03831660008181526007602081815260408084208151808301835281546001600160801b03808216835260018401805484880152855180870190965288865285870189815299895296909552925184166001600160801b031990931692909217905593519091556003805492918516916109fd83856126e7565b90915550506040805180820190915260008082526020820152610a23908690849061185a565b610a606001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016866001600160801b038616611be3565b604080516001600160801b03851681524260208201526001600160a01b038716917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a26003546040805183815260208101929092527f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c910160405180910390a15050505050610af760018055565b565b610b01611641565b33600081815260076020908152604091829020825180840190935280546001600160801b039081168452600190910154918301919091528316610b805760405162461bcd60e51b815260206004820152601760248201527643616e6e6f74206465706f736974203020746f6b656e7360481b60448201526064016107e3565b80516001600160801b0316610ba75760405162461bcd60e51b81526004016107e3906126b7565b42816020015111610bca5760405162461bcd60e51b81526004016107e3906126fa565b610bd98284600084600261169a565b5050610be460018055565b50565b6001600160a01b0382166000908152600960205260408120548190815b6080811015610c915781831015610c915760006002610c23848661265c565b610c2e90600161265c565b610c389190612631565b6001600160a01b03881660009081526008602090815260408083208484529091529020600201549091508610610c7057809350610c7e565b610c7b6001826126e7565b92505b5080610c898161272a565b915050610c04565b506001600160a01b0385166000908152600860209081526040808320858452825280832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201526004549091610cfb8783611c4b565b600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201529192508084841015610dda576000600581610d5f87600161265c565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060808301829052860151919250610dbc91906126e7565b925083604001518160400151610dd291906126e7565b915050610dfe565b6060830151610de990436126e7565b9150826040015142610dfb91906126e7565b90505b60408301518215610e3b578284606001518c610e1a91906126e7565b610e249084612645565b610e2e9190612631565b610e38908261265c565b90505b6040870151610e4a90826125ae565b8760200151610e5991906125ce565b87518890610e689083906125ee565b600f90810b90915288516000910b12159050610e8357600087525b50509351600f0b9998505050505050505050565b60028054610ea490612743565b80601f0160208091040260200160405190810160405280929190818152602001828054610ed090612743565b8015610f1d5780601f10610ef257610100808354040283529160200191610f1d565b820191906000526020600020905b815481529060010190602001808311610f0057829003601f168201915b505050505081565b60006107258242610657565b610f39611cc9565b610af76000611d23565b336000818152600760209081526040808320815180830190925280546001600160801b0316825260010154918101919091529062093a80610f848186612631565b610f8e9190612645565b82519091506001600160801b0316610fb85760405162461bcd60e51b81526004016107e3906126b7565b42826020015111610fdb5760405162461bcd60e51b81526004016107e3906126fa565b8160200151811161102e5760405162461bcd60e51b815260206004820152601f60248201527f43616e206f6e6c7920696e637265617365206c6f636b206475726174696f6e0060448201526064016107e3565b61103c6301e133804261265c565b81111561105b5760405162461bcd60e51b81526004016107e39061266f565b61106a8360008385600361169a565b50505050565b61107e62093a806001612645565b81565b60004382111561109057600080fd5b600454600061109f8483611c4b565b600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201529192508383101561119e57600060058161110286600161265c565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606080830182905285015191925061115f91906126e7565b8360400151826040015161117391906126e7565b6060850151611182908a6126e7565b61118c9190612645565b6111969190612631565b9150506111ed565b438260600151146111ed5760608201516111b890436126e7565b60408301516111c790426126e7565b60608401516111d690896126e7565b6111e09190612645565b6111ea9190612631565b90505b61120682828460400151611201919061265c565b611d73565b9695505050505050565b611218611641565b6001600160a01b038216600090815260076020908152604091829020825180840190935280546001600160801b0390811684526001909101549183019190915282166112a05760405162461bcd60e51b815260206004820152601760248201527643616e6e6f74206465706f736974203020746f6b656e7360481b60448201526064016107e3565b80516001600160801b03166112ea5760405162461bcd60e51b815260206004820152601060248201526f4e6f206578697374696e67206c6f636b60801b60448201526064016107e3565b4281602001511161130d5760405162461bcd60e51b81526004016107e3906126fa565b61131c8383600084600061169a565b506108d460018055565b60008061133283611e70565b60008181526005602090815260409182902082516080810184528154600f81810b8352600160801b909104900b92810192909252600181015492820192909252600290910154606082015290915061138a8185611d73565b949350505050565b61139a611efb565b5060045460408051338152602081019290925280517fb2f2e419d90cdd327434f0dcf95856b4393cdeca3bb6506d39d9619e2572a55d9281900390910190a1565b60008080808062093a806113ef8188612631565b6113f99190612645565b91504282116114445760405162461bcd60e51b815260206004820152601760248201527610d85b9b9bdd081b1bd8dac81a5b881d1a19481c185cdd604a1b60448201526064016107e3565b6114526301e133804261265c565b8211156114715760405162461bcd60e51b81526004016107e39061266f565b866114806301e133808261277d565b945061148c42846125ae565b61149690866125ce565b9350600084600f0b136114a857600093505b5091969295508694909350919050565b6114c0611cc9565b6001600160a01b0381166115255760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107e3565b610be481611d23565b6001600160a01b0381166000908152600960205260408120548082036115575750600092915050565b6001600160a01b0390921660009081526008602090815260408083209483529390529190912054600160801b9004600f0b919050565b6001600160a01b0382166000908152600960205260408120548190815b6080811015611637578183101561163757600060026115c9848661265c565b6115d490600161265c565b6115de9190612631565b6001600160a01b0388166000908152600860209081526040808320848452909152902060010154909150861061161657809350611624565b6116216001826126e7565b92505b508061162f8161272a565b9150506115aa565b5090949350505050565b6002600154036116935760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107e3565b6002600155565b6001600160a01b0385166000908152600760209081526040808320815180830190925280546001600160801b0390811683526001909101549282019290925260038054919391928816916116ee838561265c565b90915550508151869083906117049083906127bb565b6001600160801b0316905250841561171e57602082018590525b6001600160a01b0387166000908152600760209081526040909120835181546001600160801b0319166001600160801b039091161781559083015160019091015561176a87858461185a565b6001600160801b038616156117b7576117b77f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633306001600160801b038a16612212565b8160200151876001600160a01b03168460038111156117d8576117d86127db565b6040516001600160801b038a1681527f145d66d91f92d1a062bf7236ac6068ac75f08301bdbe776e3a8775136e486aa89060200160405180910390a46003546040805183815260208101929092527f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c910160405180910390a150505050505050565b60408051608080820183526000808352602080840182905283850182905260608085018390528551938401865282845290830182905293820181905292810183905284519192909181906001600160801b0316156118ff57855160208701514210156118fd576118ce6301e133808261277d565b600f0b6020808701919091528701516118e89042906125ae565b85602001516118f791906125ce565b600f0b85525b505b42856020015111801561191b575084516001600160801b031615155b1561196d578451602086015142101561196b5761193c6301e133808261277d565b600f0b6020808601919091528601516119569042906125ae565b846020015161196591906125ce565b600f0b84525b505b602080870151600090815260068252604090205490860151600f9190910b9250156119ac5750602080850151600090815260069091526040902054600f0b5b60006119b6611efb565b9050846020015184602001516119cc91906125ee565b816020018181516119dd91906127f1565b600f0b905250845184516119f191906125ee565b81518290611a009083906127f1565b600f90810b90915260208301516000910b12159050611a2157600060208201525b60008160000151600f0b1215611a3657600081525b6004546000908152600560209081526040918290208351828501516001600160801b03908116600160801b0291161781559183015160018301556060830151600290920191909155870151421015611ae8576020850151611a9790846127f1565b92508660200151866020015103611aba576020840151611ab790846125ee565b92505b602087810151600090815260069091526040902080546001600160801b0319166001600160801b0385161790555b4286602001511115611b4357866020015186602001511115611b43576020840151611b1390836125ee565b602087810151600090815260069091526040902080546001600160801b0319166001600160801b03831617905591505b6001600160a01b038816600090815260096020526040812054611b6790600161265c565b6001600160a01b0390991660008181526009602090815260408083208d9055428982019081524360608b01908152948452600883528184209d84529c8252909120875197909101516001600160801b03908116600160801b02971696909617865598516001860155505095516002909201919091555050505050565b6040516001600160a01b038316602482015260448101829052611c4690849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261224a565b505050565b60008082815b608081101561163757818310156116375760006002611c70848661265c565b611c7b90600161265c565b611c859190612631565b6000818152600560205260409020600201549091508710611ca857809350611cb6565b611cb36001826126e7565b92505b5080611cc18161272a565b915050611c51565b6000546001600160a01b03163314610af75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107e3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080839050600062093a80808360400151611d8f9190612631565b611d999190612645565b905060005b60ff811015611e4e57611db462093a808361265c565b9150600085831115611dc857859250611ddc565b50600082815260066020526040902054600f0b5b6040840151611deb90846125ae565b8460200151611dfa91906125ce565b84518590611e099083906125ee565b600f0b905250858303611e1c5750611e4e565b8084602001818151611e2e91906127f1565b600f0b905250506040830182905280611e468161272a565b915050611d9e565b5060008260000151600f0b1215611e6457600082525b5051600f0b9392505050565b6004546000908190815b6080811015611ef25781831015611ef25760006002611e99848661265c565b611ea490600161265c565b611eae9190612631565b6000818152600560205260409020600101549091508610611ed157809350611edf565b611edc6001826126e7565b92505b5080611eea8161272a565b915050611e7a565b50909392505050565b6040805160808082018352600080835260208084018290528385018290526060938401829052600454855180850187528381528083018490524281880181905243828801819052885196870189528587529386019490945295840192909252928201929092528115611fdc575060008181526005602081815260408084208151608080820184528254600f81810b808552600160801b909204900b83870181905260018501548487018190526002909501546060808601829052998b9052978752855192830186529082529481019490945291830152928101919091529092505b6040830151600042821015612028576040850151611ffa90426126e7565b606086015161200990436126e7565b61201b90670de0b6b3a7640000612645565b6120259190612631565b90505b600062093a806120388185612631565b6120429190612645565b905060005b60ff8110156122025761205d62093a808361265c565b915060004283111561207157429250612085565b50600082815260066020526040902054600f0b5b61208f85846125ae565b886020015161209e91906125ce565b885189906120ad9083906125ee565b600f0b9052506020880180518291906120c79083906127f1565b600f90810b90915289516000910b121590506120e257600088525b60008860200151600f0b12156120fa57600060208901525b60408089018490528601519294508492670de0b6b3a76400009061211e90856126e7565b6121289086612645565b6121329190612631565b8660600151612141919061265c565b606089015261215160018861265c565b96504283036121aa575043606088019081526000878152600560209081526040918290208a51918b01516001600160801b03908116600160801b0292169190911781559089015160018201559051600290910155612202565b506000868152600560209081526040918290208951918a01516001600160801b03908116600160801b0292169190911781559088015160018201556060880151600290910155806121fa8161272a565b915050612047565b5050836004819055505050505090565b6040516001600160a01b038085166024830152831660448201526064810182905261106a9085906323b872dd60e01b90608401611c0f565b600061229f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661231c9092919063ffffffff16565b805190915015611c4657808060200190518101906122bd919061281e565b611c465760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107e3565b606061138a848460008585600080866001600160a01b031685876040516123439190612840565b60006040518083038185875af1925050503d8060008114612380576040519150601f19603f3d011682016040523d82523d6000602084013e612385565b606091505b5091509150612396878383876123a1565b979650505050505050565b60608315612410578251600003612409576001600160a01b0385163b6124095760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107e3565b508161138a565b61138a83838151156124255781518083602001fd5b8060405162461bcd60e51b81526004016107e391906124cb565b80356001600160a01b038116811461245657600080fd5b919050565b6000806040838503121561246e57600080fd5b6124778361243f565b946020939093013593505050565b60006020828403121561249757600080fd5b6124a08261243f565b9392505050565b60005b838110156124c25781810151838201526020016124aa565b50506000910152565b60208152600082518060208401526124ea8160408501602087016124a7565b601f01601f19169190910160400192915050565b80356001600160801b038116811461245657600080fd5b6000806040838503121561252857600080fd5b612477836124fe565b60006020828403121561254357600080fd5b6124a0826124fe565b60006020828403121561255e57600080fd5b5035919050565b6000806040838503121561257857600080fd5b6125818361243f565b915061258f602084016124fe565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b818103600083128015838313168383128216171561072357610723612598565b600082600f0b82600f0b0280600f0b915080821461072357610723612598565b600f82810b9082900b0360016001607f1b0319811260016001607f1b038213171561072557610725612598565b634e487b7160e01b600052601260045260246000fd5b6000826126405761264061261b565b500490565b808202811582820484141761072557610725612598565b8082018082111561072557610725612598565b60208082526028908201527f566f74696e67206c6f636b2063616e206e6f74206c6f6e676572207468616e206040820152674d41585f54494d4560c01b606082015260800190565b602080825260169082015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b604082015260600190565b8181038181111561072557610725612598565b6020808252601690820152754c6f636b20657870697265642e20576974686472617760501b604082015260600190565b60006001820161273c5761273c612598565b5060010190565b600181811c9082168061275757607f821691505b60208210810361277757634e487b7160e01b600052602260045260246000fd5b50919050565b600081600f0b83600f0b806127945761279461261b565b60016001607f1b03198214600019821416156127b2576127b2612598565b90059392505050565b6001600160801b0381811683821601908082111561072357610723612598565b634e487b7160e01b600052602160045260246000fd5b600f81810b9083900b0160016001607f1b03811360016001607f1b03198212171561072557610725612598565b60006020828403121561283057600080fd5b815180151581146124a057600080fd5b600082516128528184602087016124a7565b919091019291505056fea26469706673582212203d91a50ab44e42857b36dafbef2a673d51d911acb6eaafb3cb73533ff7aa745464736f6c634300081200330000000000000000000000002dad3a13ef0c6366220f989157009e501e7938f800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102265760003560e01c806381fc83bb11610130578063bd85b039116100b8578063e54357bc1161007c578063e54357bc146105be578063f2fde38b14610604578063f3a6d60814610617578063f4359ce51461062a578063f52a36f71461063457600080fd5b8063bd85b0391461053a578063c00c4da11461054d578063c241267614610556578063c2c4c5c11461057d578063e2c5b4d21461058557600080fd5b8063900cf0cf116100ff578063900cf0cf146104db578063911dcf5c146104e457806395d89b41146104ee578063981b24d0146105145780639a3f14f71461052757600080fd5b806381fc83bb146104505780638ad4c447146104705780638da5cb5b146104ae5780638ff07b5b146104d357600080fd5b80633c3b3189116101b35780634ee2cd7e116101825780634ee2cd7e1461040757806354fd4d501461041a57806370a0823114610422578063715018a6146104355780637c616fe61461043d57600080fd5b80633c3b3189146103a25780633ccfd60b146103c05780634deafcae146103c85780634e3430ca146103f457600080fd5b806318160ddd116101fa57806318160ddd146102ef57806326949984146102f7578063313ce5671461030257806334d901a41461031c5780633527d1c01461038d57600080fd5b8062fdd58e1461022b5780630483a7f614610251578063059f8b16146102a357806306fdde03146102b2575b600080fd5b61023e61023936600461245b565b610657565b6040519081526020015b60405180910390f35b61028461025f366004612485565b600760205260009081526040902080546001909101546001600160801b039091169082565b604080516001600160801b039093168352602083019190915201610248565b61023e670de0b6b3a764000081565b6102e260405180604001604052806011815260200170566f74652d657363726f7720455854524160781b81525081565b60405161024891906124cb565b61023e61072b565b61023e6301e1338081565b61030a601281565b60405160ff9091168152602001610248565b61036561032a36600461245b565b6008602090815260009283526040808420909152908252902080546001820154600290920154600f82810b93600160801b909304900b919084565b60408051600f95860b81529390940b6020840152928201526060810191909152608001610248565b6103a061039b366004612515565b61073b565b005b6103ad6301e1338081565b604051600f9190910b8152602001610248565b6103a06108d8565b61023e6103d6366004612485565b6001600160a01b031660009081526007602052604090206001015490565b6103a0610402366004612531565b610af9565b61023e61041536600461245b565b610be7565b6102e2610e97565b61023e610430366004612485565b610f25565b6103a0610f31565b6103a061044b36600461254c565b610f43565b61023e61045e366004612485565b60096020526000908152604090205481565b61036561047e36600461254c565b600560205260009081526040902080546001820154600290920154600f82810b93600160801b909304900b919084565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610248565b61023e611070565b61023e60045481565b6103ad62093a8081565b6102e2604051806040016040528060078152602001667665455854524160c81b81525081565b61023e61052236600461254c565b611081565b6103a0610535366004612565565b611210565b61023e61054836600461254c565b611326565b61023e60035481565b6104bb7f0000000000000000000000002dad3a13ef0c6366220f989157009e501e7938f881565b6103a0611392565b61023e61059336600461245b565b6001600160a01b03919091166000908152600860209081526040808320938352929052206001015490565b6105d16105cc366004612515565b6113db565b60408051600f96870b815294860b60208601529290940b918301919091526060820152608081019190915260a001610248565b6103a0610612366004612485565b6114b8565b6103ad610625366004612485565b61152e565b61023e62093a8081565b6103ad61064236600461254c565b600660205260009081526040902054600f0b81565b600080610664848461158d565b905080600003610678576000915050610725565b6001600160a01b038416600090815260086020908152604080832084845282529182902082516080810184528154600f81810b8352600160801b909104900b928101929092526001810154928201839052600201546060820152906106dd90856125ae565b81602001516106ec91906125ce565b815182906106fb9083906125ee565b600f90810b90915282516000910b1215905061071657600081525b51600f0b91506107259050565b505b92915050565b600061073642611326565b905090565b610743611641565b33600062093a806107548185612631565b61075e9190612645565b6001600160a01b038316600090815260076020908152604091829020825180840190935280546001600160801b039081168452600190910154918301919091529192509085166107ec5760405162461bcd60e51b815260206004820152601460248201527343616e6e6f74206c6f636b203020746f6b656e7360601b60448201526064015b60405180910390fd5b80516001600160801b0316156108445760405162461bcd60e51b815260206004820152601960248201527f5769746864726177206f6c6420746f6b656e732066697273740000000000000060448201526064016107e3565b42821161088d5760405162461bcd60e51b815260206004820152601760248201527610d85b9b9bdd081b1bd8dac81a5b881d1a19481c185cdd604a1b60448201526064016107e3565b61089b6301e133804261265c565b8211156108ba5760405162461bcd60e51b81526004016107e39061266f565b6108c883868484600161169a565b5050506108d460018055565b5050565b6108e0611641565b33600081815260076020908152604091829020825180840190935280546001600160801b0316808452600190910154918301919091526109325760405162461bcd60e51b81526004016107e3906126b7565b806020015142101561097a5760405162461bcd60e51b81526020600482015260116024820152702637b1b5903737ba1032bc3834b932b21760791b60448201526064016107e3565b80516001600160a01b03831660008181526007602081815260408084208151808301835281546001600160801b03808216835260018401805484880152855180870190965288865285870189815299895296909552925184166001600160801b031990931692909217905593519091556003805492918516916109fd83856126e7565b90915550506040805180820190915260008082526020820152610a23908690849061185a565b610a606001600160a01b037f0000000000000000000000002dad3a13ef0c6366220f989157009e501e7938f816866001600160801b038616611be3565b604080516001600160801b03851681524260208201526001600160a01b038716917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a26003546040805183815260208101929092527f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c910160405180910390a15050505050610af760018055565b565b610b01611641565b33600081815260076020908152604091829020825180840190935280546001600160801b039081168452600190910154918301919091528316610b805760405162461bcd60e51b815260206004820152601760248201527643616e6e6f74206465706f736974203020746f6b656e7360481b60448201526064016107e3565b80516001600160801b0316610ba75760405162461bcd60e51b81526004016107e3906126b7565b42816020015111610bca5760405162461bcd60e51b81526004016107e3906126fa565b610bd98284600084600261169a565b5050610be460018055565b50565b6001600160a01b0382166000908152600960205260408120548190815b6080811015610c915781831015610c915760006002610c23848661265c565b610c2e90600161265c565b610c389190612631565b6001600160a01b03881660009081526008602090815260408083208484529091529020600201549091508610610c7057809350610c7e565b610c7b6001826126e7565b92505b5080610c898161272a565b915050610c04565b506001600160a01b0385166000908152600860209081526040808320858452825280832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201526004549091610cfb8783611c4b565b600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201529192508084841015610dda576000600581610d5f87600161265c565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060808301829052860151919250610dbc91906126e7565b925083604001518160400151610dd291906126e7565b915050610dfe565b6060830151610de990436126e7565b9150826040015142610dfb91906126e7565b90505b60408301518215610e3b578284606001518c610e1a91906126e7565b610e249084612645565b610e2e9190612631565b610e38908261265c565b90505b6040870151610e4a90826125ae565b8760200151610e5991906125ce565b87518890610e689083906125ee565b600f90810b90915288516000910b12159050610e8357600087525b50509351600f0b9998505050505050505050565b60028054610ea490612743565b80601f0160208091040260200160405190810160405280929190818152602001828054610ed090612743565b8015610f1d5780601f10610ef257610100808354040283529160200191610f1d565b820191906000526020600020905b815481529060010190602001808311610f0057829003601f168201915b505050505081565b60006107258242610657565b610f39611cc9565b610af76000611d23565b336000818152600760209081526040808320815180830190925280546001600160801b0316825260010154918101919091529062093a80610f848186612631565b610f8e9190612645565b82519091506001600160801b0316610fb85760405162461bcd60e51b81526004016107e3906126b7565b42826020015111610fdb5760405162461bcd60e51b81526004016107e3906126fa565b8160200151811161102e5760405162461bcd60e51b815260206004820152601f60248201527f43616e206f6e6c7920696e637265617365206c6f636b206475726174696f6e0060448201526064016107e3565b61103c6301e133804261265c565b81111561105b5760405162461bcd60e51b81526004016107e39061266f565b61106a8360008385600361169a565b50505050565b61107e62093a806001612645565b81565b60004382111561109057600080fd5b600454600061109f8483611c4b565b600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201529192508383101561119e57600060058161110286600161265c565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606080830182905285015191925061115f91906126e7565b8360400151826040015161117391906126e7565b6060850151611182908a6126e7565b61118c9190612645565b6111969190612631565b9150506111ed565b438260600151146111ed5760608201516111b890436126e7565b60408301516111c790426126e7565b60608401516111d690896126e7565b6111e09190612645565b6111ea9190612631565b90505b61120682828460400151611201919061265c565b611d73565b9695505050505050565b611218611641565b6001600160a01b038216600090815260076020908152604091829020825180840190935280546001600160801b0390811684526001909101549183019190915282166112a05760405162461bcd60e51b815260206004820152601760248201527643616e6e6f74206465706f736974203020746f6b656e7360481b60448201526064016107e3565b80516001600160801b03166112ea5760405162461bcd60e51b815260206004820152601060248201526f4e6f206578697374696e67206c6f636b60801b60448201526064016107e3565b4281602001511161130d5760405162461bcd60e51b81526004016107e3906126fa565b61131c8383600084600061169a565b506108d460018055565b60008061133283611e70565b60008181526005602090815260409182902082516080810184528154600f81810b8352600160801b909104900b92810192909252600181015492820192909252600290910154606082015290915061138a8185611d73565b949350505050565b61139a611efb565b5060045460408051338152602081019290925280517fb2f2e419d90cdd327434f0dcf95856b4393cdeca3bb6506d39d9619e2572a55d9281900390910190a1565b60008080808062093a806113ef8188612631565b6113f99190612645565b91504282116114445760405162461bcd60e51b815260206004820152601760248201527610d85b9b9bdd081b1bd8dac81a5b881d1a19481c185cdd604a1b60448201526064016107e3565b6114526301e133804261265c565b8211156114715760405162461bcd60e51b81526004016107e39061266f565b866114806301e133808261277d565b945061148c42846125ae565b61149690866125ce565b9350600084600f0b136114a857600093505b5091969295508694909350919050565b6114c0611cc9565b6001600160a01b0381166115255760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107e3565b610be481611d23565b6001600160a01b0381166000908152600960205260408120548082036115575750600092915050565b6001600160a01b0390921660009081526008602090815260408083209483529390529190912054600160801b9004600f0b919050565b6001600160a01b0382166000908152600960205260408120548190815b6080811015611637578183101561163757600060026115c9848661265c565b6115d490600161265c565b6115de9190612631565b6001600160a01b0388166000908152600860209081526040808320848452909152902060010154909150861061161657809350611624565b6116216001826126e7565b92505b508061162f8161272a565b9150506115aa565b5090949350505050565b6002600154036116935760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107e3565b6002600155565b6001600160a01b0385166000908152600760209081526040808320815180830190925280546001600160801b0390811683526001909101549282019290925260038054919391928816916116ee838561265c565b90915550508151869083906117049083906127bb565b6001600160801b0316905250841561171e57602082018590525b6001600160a01b0387166000908152600760209081526040909120835181546001600160801b0319166001600160801b039091161781559083015160019091015561176a87858461185a565b6001600160801b038616156117b7576117b77f0000000000000000000000002dad3a13ef0c6366220f989157009e501e7938f86001600160a01b031633306001600160801b038a16612212565b8160200151876001600160a01b03168460038111156117d8576117d86127db565b6040516001600160801b038a1681527f145d66d91f92d1a062bf7236ac6068ac75f08301bdbe776e3a8775136e486aa89060200160405180910390a46003546040805183815260208101929092527f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c910160405180910390a150505050505050565b60408051608080820183526000808352602080840182905283850182905260608085018390528551938401865282845290830182905293820181905292810183905284519192909181906001600160801b0316156118ff57855160208701514210156118fd576118ce6301e133808261277d565b600f0b6020808701919091528701516118e89042906125ae565b85602001516118f791906125ce565b600f0b85525b505b42856020015111801561191b575084516001600160801b031615155b1561196d578451602086015142101561196b5761193c6301e133808261277d565b600f0b6020808601919091528601516119569042906125ae565b846020015161196591906125ce565b600f0b84525b505b602080870151600090815260068252604090205490860151600f9190910b9250156119ac5750602080850151600090815260069091526040902054600f0b5b60006119b6611efb565b9050846020015184602001516119cc91906125ee565b816020018181516119dd91906127f1565b600f0b905250845184516119f191906125ee565b81518290611a009083906127f1565b600f90810b90915260208301516000910b12159050611a2157600060208201525b60008160000151600f0b1215611a3657600081525b6004546000908152600560209081526040918290208351828501516001600160801b03908116600160801b0291161781559183015160018301556060830151600290920191909155870151421015611ae8576020850151611a9790846127f1565b92508660200151866020015103611aba576020840151611ab790846125ee565b92505b602087810151600090815260069091526040902080546001600160801b0319166001600160801b0385161790555b4286602001511115611b4357866020015186602001511115611b43576020840151611b1390836125ee565b602087810151600090815260069091526040902080546001600160801b0319166001600160801b03831617905591505b6001600160a01b038816600090815260096020526040812054611b6790600161265c565b6001600160a01b0390991660008181526009602090815260408083208d9055428982019081524360608b01908152948452600883528184209d84529c8252909120875197909101516001600160801b03908116600160801b02971696909617865598516001860155505095516002909201919091555050505050565b6040516001600160a01b038316602482015260448101829052611c4690849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261224a565b505050565b60008082815b608081101561163757818310156116375760006002611c70848661265c565b611c7b90600161265c565b611c859190612631565b6000818152600560205260409020600201549091508710611ca857809350611cb6565b611cb36001826126e7565b92505b5080611cc18161272a565b915050611c51565b6000546001600160a01b03163314610af75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107e3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080839050600062093a80808360400151611d8f9190612631565b611d999190612645565b905060005b60ff811015611e4e57611db462093a808361265c565b9150600085831115611dc857859250611ddc565b50600082815260066020526040902054600f0b5b6040840151611deb90846125ae565b8460200151611dfa91906125ce565b84518590611e099083906125ee565b600f0b905250858303611e1c5750611e4e565b8084602001818151611e2e91906127f1565b600f0b905250506040830182905280611e468161272a565b915050611d9e565b5060008260000151600f0b1215611e6457600082525b5051600f0b9392505050565b6004546000908190815b6080811015611ef25781831015611ef25760006002611e99848661265c565b611ea490600161265c565b611eae9190612631565b6000818152600560205260409020600101549091508610611ed157809350611edf565b611edc6001826126e7565b92505b5080611eea8161272a565b915050611e7a565b50909392505050565b6040805160808082018352600080835260208084018290528385018290526060938401829052600454855180850187528381528083018490524281880181905243828801819052885196870189528587529386019490945295840192909252928201929092528115611fdc575060008181526005602081815260408084208151608080820184528254600f81810b808552600160801b909204900b83870181905260018501548487018190526002909501546060808601829052998b9052978752855192830186529082529481019490945291830152928101919091529092505b6040830151600042821015612028576040850151611ffa90426126e7565b606086015161200990436126e7565b61201b90670de0b6b3a7640000612645565b6120259190612631565b90505b600062093a806120388185612631565b6120429190612645565b905060005b60ff8110156122025761205d62093a808361265c565b915060004283111561207157429250612085565b50600082815260066020526040902054600f0b5b61208f85846125ae565b886020015161209e91906125ce565b885189906120ad9083906125ee565b600f0b9052506020880180518291906120c79083906127f1565b600f90810b90915289516000910b121590506120e257600088525b60008860200151600f0b12156120fa57600060208901525b60408089018490528601519294508492670de0b6b3a76400009061211e90856126e7565b6121289086612645565b6121329190612631565b8660600151612141919061265c565b606089015261215160018861265c565b96504283036121aa575043606088019081526000878152600560209081526040918290208a51918b01516001600160801b03908116600160801b0292169190911781559089015160018201559051600290910155612202565b506000868152600560209081526040918290208951918a01516001600160801b03908116600160801b0292169190911781559088015160018201556060880151600290910155806121fa8161272a565b915050612047565b5050836004819055505050505090565b6040516001600160a01b038085166024830152831660448201526064810182905261106a9085906323b872dd60e01b90608401611c0f565b600061229f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661231c9092919063ffffffff16565b805190915015611c4657808060200190518101906122bd919061281e565b611c465760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107e3565b606061138a848460008585600080866001600160a01b031685876040516123439190612840565b60006040518083038185875af1925050503d8060008114612380576040519150601f19603f3d011682016040523d82523d6000602084013e612385565b606091505b5091509150612396878383876123a1565b979650505050505050565b60608315612410578251600003612409576001600160a01b0385163b6124095760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107e3565b508161138a565b61138a83838151156124255781518083602001fd5b8060405162461bcd60e51b81526004016107e391906124cb565b80356001600160a01b038116811461245657600080fd5b919050565b6000806040838503121561246e57600080fd5b6124778361243f565b946020939093013593505050565b60006020828403121561249757600080fd5b6124a08261243f565b9392505050565b60005b838110156124c25781810151838201526020016124aa565b50506000910152565b60208152600082518060208401526124ea8160408501602087016124a7565b601f01601f19169190910160400192915050565b80356001600160801b038116811461245657600080fd5b6000806040838503121561252857600080fd5b612477836124fe565b60006020828403121561254357600080fd5b6124a0826124fe565b60006020828403121561255e57600080fd5b5035919050565b6000806040838503121561257857600080fd5b6125818361243f565b915061258f602084016124fe565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b818103600083128015838313168383128216171561072357610723612598565b600082600f0b82600f0b0280600f0b915080821461072357610723612598565b600f82810b9082900b0360016001607f1b0319811260016001607f1b038213171561072557610725612598565b634e487b7160e01b600052601260045260246000fd5b6000826126405761264061261b565b500490565b808202811582820484141761072557610725612598565b8082018082111561072557610725612598565b60208082526028908201527f566f74696e67206c6f636b2063616e206e6f74206c6f6e676572207468616e206040820152674d41585f54494d4560c01b606082015260800190565b602080825260169082015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b604082015260600190565b8181038181111561072557610725612598565b6020808252601690820152754c6f636b20657870697265642e20576974686472617760501b604082015260600190565b60006001820161273c5761273c612598565b5060010190565b600181811c9082168061275757607f821691505b60208210810361277757634e487b7160e01b600052602260045260246000fd5b50919050565b600081600f0b83600f0b806127945761279461261b565b60016001607f1b03198214600019821416156127b2576127b2612598565b90059392505050565b6001600160801b0381811683821601908082111561072357610723612598565b634e487b7160e01b600052602160045260246000fd5b600f81810b9083900b0160016001607f1b03811360016001607f1b03198212171561072557610725612598565b60006020828403121561283057600080fd5b815180151581146124a057600080fd5b600082516128528184602087016124a7565b919091019291505056fea26469706673582212203d91a50ab44e42857b36dafbef2a673d51d911acb6eaafb3cb73533ff7aa745464736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000002dad3a13ef0c6366220f989157009e501e7938f800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _token (address): 0x2dAD3a13ef0C6366220f989157009e501e7938F8
Arg [1] : _version (string):
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000002dad3a13ef0c6366220f989157009e501e7938f8
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
28796:27960:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40709:564;;;;;;:::i;:::-;;:::i;:::-;;;597:25:1;;;585:2;570:18;40709:564:0;;;;;;;;30602:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;30602:55:0;;;;;;;;;;-1:-1:-1;;;;;1016:47:1;;;998:66;;1095:2;1080:18;;1073:34;;;;971:18;30602:55:0;824:289:1;30022:45:0;;30059:8;30022:45;;29687:49;;;;;;;;;;;;;;;-1:-1:-1;;;29687:49:0;;;;;;;;;;;;:::i;43603:107::-;;;:::i;29918:47::-;;29953:12;29918:47;;29791:35;;29824:2;29791:35;;;;;1946:4:1;1934:17;;;1916:36;;1904:2;1889:18;29791:35:0;1774:184:1;30681:69:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;30681:69:0;;;;;;;;;;;;;2219:2:1;2208:22;;;2190:41;;2267:22;;;;2262:2;2247:18;;2240:50;2306:18;;;2299:34;2364:2;2349:18;;2342:34;;;;2177:3;2162:19;30681:69:0;1963:419:1;32809:824:0;;;;;;:::i;:::-;;:::i;:::-;;30074:70;;29953:12;30074:70;;;;;3012:2:1;3001:22;;;;2983:41;;2971:2;2956:18;30074:70:0;2839:191:1;35577:949:0;;;:::i;38656:115::-;;;;;;:::i;:::-;-1:-1:-1;;;;;38739:20:0;38712:7;38739:20;;;:14;:20;;;;;:24;;;;38656:115;33807:597;;;;;;:::i;:::-;;:::i;41797:1674::-;;;;;;:::i;:::-;;:::i;29659:21::-;;;:::i;41438:121::-;;;;;;:::i;:::-;;:::i;2938:103::-;;;:::i;34530:933::-;;;;;;:::i;:::-;;:::i;30785:49::-;;;;;;:::i;:::-;;;;;;;;;;;;;;30380:45;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;30380:45:0;;;;;;;;;2290:87;2336:7;2363:6;-1:-1:-1;;;;;2363:6:0;2290:87;;;-1:-1:-1;;;;;3575:32:1;;;3557:51;;3545:2;3530:18;2290:87:0;3411:203:1;29972:43:0;;;:::i;30353:20::-;;;;;;30151:57;;29904:7;30151:57;;29743:41;;;;;;;;;;;;;;;-1:-1:-1;;;29743:41:0;;;;;36740:962;;;;;;:::i;:::-;;:::i;32003:472::-;;;;;;:::i;:::-;;:::i;43834:225::-;;;;;;:::i;:::-;;:::i;29835:31::-;;;;;;30257:30;;;;;31558:123;;;:::i;38331:171::-;;;;;;:::i;:::-;-1:-1:-1;;;;;38464:22:0;;;;38437:7;38464:22;;;:16;:22;;;;;;;;:27;;;;;;;:30;;;;38331:171;39164:1239;;;;;;:::i;:::-;;:::i;:::-;;;;4166:2:1;4155:22;;;4137:41;;4214:22;;;4209:2;4194:18;;4187:50;4273:22;;;;4253:18;;;4246:50;;;;4327:2;4312:18;;4305:34;4370:3;4355:19;;4348:35;;;;4124:3;4109:19;39164:1239:0;3884:505:1;3196:238:0;;;;;;:::i;:::-;;:::i;37888:243::-;;;;;;:::i;:::-;;:::i;29873:38::-;;29904:7;29873:38;;30459:46;;;;;;:::i;:::-;;;;;;;;;;;;;;;;40709:564;40775:7;40795:14;40812:33;40836:4;40842:2;40812:23;:33::i;:::-;40795:50;;40860:6;40870:1;40860:11;40856:410;;40895:1;40888:8;;;;;40856:410;-1:-1:-1;;;;;40954:22:0;;40929;40954;;;:16;:22;;;;;;;;:30;;;;;;;;;40929:55;;;;;;;;;;;;;;;-1:-1:-1;;;40929:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41076:33;;41083:2;41076:33;:::i;:::-;41034:9;:15;;;:76;;;;:::i;:::-;40999:111;;:9;;:111;;;;;:::i;:::-;;;;;;;;41129:14;;41146:1;41129:18;;;41125:77;;-1:-1:-1;41125:77:0;;41185:1;41168:18;;41125:77;41238:14;41231:22;;;-1:-1:-1;41216:38:0;;-1:-1:-1;41216:38:0;40856:410;40784:489;40709:564;;;;;:::o;43603:107::-;43647:7;43674:28;43686:15;43674:11;:28::i;:::-;43667:35;;43603:107;:::o;32809:824::-;26817:21;:19;:21::i;:::-;878:10;32922:15:::1;29904:7;32992:17;29904:7:::0;32992:10;:17:::1;:::i;:::-;32991:26;;;;:::i;:::-;-1:-1:-1::0;;;;;33067:23:0;::::1;33028:36;33067:23:::0;;;:14:::1;:23;::::0;;;;;;;;33028:62;;;;::::1;::::0;;;;;-1:-1:-1;;;;;33028:62:0;;::::1;::::0;;;;;::::1;::::0;;;::::1;::::0;;;;32963:54;;-1:-1:-1;33028:62:0;33111:9;::::1;33103:42;;;::::0;-1:-1:-1;;;33103:42:0;;5863:2:1;33103:42:0::1;::::0;::::1;5845:21:1::0;5902:2;5882:18;;;5875:30;-1:-1:-1;;;5921:18:1;;;5914:50;5981:18;;33103:42:0::1;;;;;;;;;33164:22:::0;;-1:-1:-1;;;;;33164:27:0::1;::::0;33156:65:::1;;;::::0;-1:-1:-1;;;33156:65:0;;6212:2:1;33156:65:0::1;::::0;::::1;6194:21:1::0;6251:2;6231:18;;;6224:30;6290:27;6270:18;;;6263:55;6335:18;;33156:65:0::1;6010:349:1::0;33156:65:0::1;33260:15;33240:17;:35;33232:71;;;::::0;-1:-1:-1;;;33232:71:0;;6566:2:1;33232:71:0::1;::::0;::::1;6548:21:1::0;6605:2;6585:18;;;6578:30;-1:-1:-1;;;6624:18:1;;;6617:53;6687:18;;33232:71:0::1;6364:347:1::0;33232:71:0::1;33357:26;29953:12;33357:15;:26;:::i;:::-;33336:17;:47;;33314:137;;;;-1:-1:-1::0;;;33314:137:0::1;;;;;;;:::i;:::-;33462:163;33488:7;33510:5;33530:17;33562:15;33592:22;33462:11;:163::i;:::-;32911:722;;;26861:20:::0;26255:1;27381:22;;27198:213;26861:20;32809:824;;:::o;35577:949::-;26817:21;:19;:21::i;:::-;878:10;35630:15:::1;35710:23:::0;;;:14:::1;:23;::::0;;;;;;;;35671:62;;;;::::1;::::0;;;;;-1:-1:-1;;;;;35671:62:0::1;::::0;;;;;;::::1;::::0;;;::::1;::::0;;;;35744:61:::1;;;;-1:-1:-1::0;;;35744:61:0::1;;;;;;;:::i;:::-;35843:15;:19;;;35824:15;:38;;35816:68;;;::::0;-1:-1:-1;;;35816:68:0;;7808:2:1;35816:68:0::1;::::0;::::1;7790:21:1::0;7847:2;7827:18;;;7820:30;-1:-1:-1;;;7866:18:1;;;7859:47;7923:18;;35816:68:0::1;7606:341:1::0;35816:68:0::1;35911:22:::0;;-1:-1:-1;;;;;35980:23:0;::::1;35895:13;35980:23:::0;;;:14:::1;:23;::::0;;;;;;;35946:57;;;;::::1;::::0;;;;-1:-1:-1;;;;;35946:57:0;;::::1;::::0;;;;::::1;::::0;;;;::::1;::::0;36040:19;;;;::::1;::::0;;;;;;;;::::1;::::0;;;36014:23;;;;;;;:45;;;::::1;-1:-1:-1::0;;;;;;36014:45:0;;::::1;::::0;;;::::1;::::0;;;;;;;36091:16:::1;::::0;;;36118:25;;::::1;::::0;::::1;::::0;36091:16;36118:25:::1;:::i;:::-;::::0;;;-1:-1:-1;;36334:19:0::1;::::0;;;;::::1;::::0;;;-1:-1:-1;36334:19:0;;;::::1;::::0;::::1;::::0;36301:53:::1;::::0;36313:7;;36322:10;;36301:11:::1;:53::i;:::-;36367:42;-1:-1:-1::0;;;;;36374:5:0::1;36367:26;36394:7:::0;-1:-1:-1;;;;;36367:42:0;::::1;:26;:42::i;:::-;36425:41;::::0;;-1:-1:-1;;;;;1016:47:1;;998:66;;36450:15:0::1;1095:2:1::0;1080:18;;1073:34;-1:-1:-1;;;;;36425:41:0;::::1;::::0;::::1;::::0;971:18:1;36425:41:0::1;;;;;;;36501:16;::::0;36482:36:::1;::::0;;8553:25:1;;;8609:2;8594:18;;8587:34;;;;36482:36:0::1;::::0;8526:18:1;36482:36:0::1;;;;;;;35619:907;;;;;26861:20:::0;26255:1;27381:22;;27198:213;26861:20;35577:949::o;33807:597::-;26817:21;:19;:21::i;:::-;878:10;33879:15:::1;33959:23:::0;;;:14:::1;:23;::::0;;;;;;;;33920:62;;;;::::1;::::0;;;;;-1:-1:-1;;;;;33920:62:0;;::::1;::::0;;;;;::::1;::::0;;;::::1;::::0;;;;34003:9;::::1;33995:45;;;::::0;-1:-1:-1;;;33995:45:0;;8834:2:1;33995:45:0::1;::::0;::::1;8816:21:1::0;8873:2;8853:18;;;8846:30;-1:-1:-1;;;8892:18:1;;;8885:53;8955:18;;33995:45:0::1;8632:347:1::0;33995:45:0::1;34059:22:::0;;-1:-1:-1;;;;;34059:26:0::1;34051:61;;;;-1:-1:-1::0;;;34051:61:0::1;;;;;;;:::i;:::-;34169:15;34147;:19;;;:37;34125:109;;;;-1:-1:-1::0;;;34125:109:0::1;;;;;;;:::i;:::-;34245:151;34271:7;34293:5;34313:1;34329:15;34359:26;34245:11;:151::i;:::-;33868:536;;26861:20:::0;26255:1;27381:22;;27198:213;26861:20;33807:597;:::o;41797:1674::-;-1:-1:-1;;;;;41959:20:0;;41899:7;41959:20;;;:14;:20;;;;;;41899:7;;;42056:328;42080:3;42076:1;:7;42056:328;;;42116:3;42109;:10;42105:56;42140:5;42105:56;42175:11;42207:1;42190:9;42196:3;42190;:9;:::i;:::-;:13;;42202:1;42190:13;:::i;:::-;42189:19;;;;:::i;:::-;-1:-1:-1;;;;;42227:22:0;;;;;;:16;:22;;;;;;;;:27;;;;;;;;:31;;;42175:33;;-1:-1:-1;42227:46:0;-1:-1:-1;42223:150:0;;42300:3;42294:9;;42223:150;;;42350:7;42356:1;42350:3;:7;:::i;:::-;42344:13;;42223:150;-1:-1:-1;42085:3:0;;;;:::i;:::-;;;;42056:328;;;-1:-1:-1;;;;;;42479:22:0;;42457:19;42479:22;;;:16;:22;;;;;;;;:27;;;;;;;;42457:49;;;;;;;;;;;;;;;-1:-1:-1;;;42457:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42536:5;;42457:49;;42624:38;42640:11;42536:5;42624:15;:38::i;:::-;42673:19;42695:20;;;:12;:20;;;;;;;;42673:42;;;;;;;;;;;;;;;-1:-1:-1;;;42673:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42607:55;;-1:-1:-1;42673:19:0;42786:17;;;42782:298;;;42820:19;42842:12;42820:19;42855:10;:6;42864:1;42855:10;:::i;:::-;42842:24;;;;;;;;;;;;;;-1:-1:-1;42842:24:0;42820:46;;;;;;;;;;;;;;;-1:-1:-1;;;42820:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42903:10;;;42820:46;;-1:-1:-1;42890:23:0;;42903:10;42890:23;:::i;:::-;42881:32;;42945:6;:9;;;42933:6;:9;;;:21;;;;:::i;:::-;42928:26;;42805:161;42782:298;;;43011:10;;;;42996:25;;:12;:25;:::i;:::-;42987:34;;43059:6;:9;;;43041:15;:27;;;;:::i;:::-;43036:32;;42782:298;43112:9;;;;43136:11;;43132:99;;43213:6;43198;:10;;;43184:11;:24;;;;:::i;:::-;43178:31;;:2;:31;:::i;:::-;43177:42;;;;:::i;:::-;43164:55;;;;:::i;:::-;;;43132:99;43333:9;;;;43306:37;;43313:9;43306:37;:::i;:::-;43271:6;:12;;;:73;;;;:::i;:::-;43243:101;;:6;;:101;;;;;:::i;:::-;;;;;;;;43359:11;;43373:1;43359:15;;;43355:63;;-1:-1:-1;43355:63:0;;43405:1;43391:15;;43355:63;-1:-1:-1;;43450:11:0;;43443:19;;;41797:1674;-1:-1:-1;;;;;;;;;41797:1674:0:o;29659:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;41438:121::-;41492:7;41519:32;41529:4;41535:15;41519:9;:32::i;2938:103::-;2176:13;:11;:13::i;:::-;3003:30:::1;3030:1;3003:18;:30::i;34530:933::-:0;878:10;34598:15;34678:23;;;:14;:23;;;;;;;;34639:62;;;;;;;;;;-1:-1:-1;;;;;34639:62:0;;;;;;;;;;;;;;29904:7;34741:17;29904:7;34741:10;:17;:::i;:::-;34740:26;;;;:::i;:::-;34824:22;;34712:54;;-1:-1:-1;;;;;;34824:26:0;34816:61;;;;-1:-1:-1;;;34816:61:0;;;;;;;:::i;:::-;34932:15;34910;:19;;;:37;34888:109;;;;-1:-1:-1;;;34888:109:0;;;;;;;:::i;:::-;35050:15;:19;;;35030:17;:39;35008:120;;;;-1:-1:-1;;;35008:120:0;;10062:2:1;35008:120:0;;;10044:21:1;10101:2;10081:18;;;10074:30;10140:33;10120:18;;;10113:61;10191:18;;35008:120:0;9860:355:1;35008:120:0;35182:26;29953:12;35182:15;:26;:::i;:::-;35161:17;:47;;35139:137;;;;-1:-1:-1;;;35139:137:0;;;;;;;:::i;:::-;35289:166;35315:7;35337:1;35353:17;35385:15;35415:29;35289:11;:166::i;:::-;34587:876;;;34530:933;:::o;29972:43::-;30007:8;29904:7;30007:1;:8;:::i;:::-;29972:43;:::o;36740:962::-;36823:7;36866:12;36851:11;:27;;36843:36;;;;;;36907:5;;36890:14;36945:36;36961:11;36907:5;36945:15;:36::i;:::-;36994:19;37016:25;;;:12;:25;;;;;;;;36994:47;;;;;;;;;;;;;;;-1:-1:-1;;;36994:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36923:58;;-1:-1:-1;37083:20:0;;;37079:501;;;37120:19;37142:12;37120:19;37155:15;:11;37169:1;37155:15;:::i;:::-;37142:29;;;;;;;;;;;;;;-1:-1:-1;37142:29:0;37120:51;;;;;;;;;;;;;;;-1:-1:-1;;;37120:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37296:10;;;37120:51;;-1:-1:-1;37283:23:0;;37296:10;37283:23;:::i;:::-;37251:6;:9;;;37239:6;:9;;;:21;;;;:::i;:::-;37224:10;;;;37210:24;;:11;:24;:::i;:::-;37209:52;;;;:::i;:::-;37208:99;;;;:::i;:::-;37186:121;;37105:214;37079:501;;;37358:12;37344:6;:10;;;:26;37340:229;;37542:10;;;;37527:25;;:12;:25;:::i;:::-;37491:9;;;;37473:27;;:15;:27;:::i;:::-;37433:10;;;;37419:24;;:11;:24;:::i;:::-;37418:83;;;;:::i;:::-;37417:136;;;;:::i;:::-;37391:162;;37340:229;37662:32;37671:6;37691:2;37679:6;:9;;;:14;;;;:::i;:::-;37662:8;:32::i;:::-;37655:39;36740:962;-1:-1:-1;;;;;;36740:962:0:o;32003:472::-;26817:21;:19;:21::i;:::-;-1:-1:-1;;;;;32124:20:0;::::1;32085:36;32124:20:::0;;;:14:::1;:20;::::0;;;;;;;;32085:59;;;;::::1;::::0;;;;;-1:-1:-1;;;;;32085:59:0;;::::1;::::0;;;;;::::1;::::0;;;::::1;::::0;;;;32163:9;::::1;32155:45;;;::::0;-1:-1:-1;;;32155:45:0;;8834:2:1;32155:45:0::1;::::0;::::1;8816:21:1::0;8873:2;8853:18;;;8846:30;-1:-1:-1;;;8892:18:1;;;8885:53;8955:18;;32155:45:0::1;8632:347:1::0;32155:45:0::1;32219:22:::0;;-1:-1:-1;;;;;32219:26:0::1;32211:55;;;::::0;-1:-1:-1;;;32211:55:0;;10422:2:1;32211:55:0::1;::::0;::::1;10404:21:1::0;10461:2;10441:18;;;10434:30;-1:-1:-1;;;10480:18:1;;;10473:46;10536:18;;32211:55:0::1;10220:340:1::0;32211:55:0::1;32323:15;32301;:19;;;:37;32279:109;;;;-1:-1:-1::0;;;32279:109:0::1;;;;;;;:::i;:::-;32399:68;32411:4;32417:5;32424:1;32427:15;32444:22;32399:11;:68::i;:::-;32074:401;26861:20:::0;26255:1;27381:22;;27198:213;43834:225;43888:7;43908:14;43925:29;43951:2;43925:25;:29::i;:::-;43965:22;43990:20;;;:12;:20;;;;;;;;;43965:45;;;;;;;;;;;;;;;-1:-1:-1;;;43965:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43908:46;;-1:-1:-1;44028:23:0;43965:45;44048:2;44028:8;:23::i;:::-;44021:30;43834:225;-1:-1:-1;;;;43834:225:0:o;31558:123::-;31600:20;:18;:20::i;:::-;-1:-1:-1;31667:5:0;;31636:37;;;878:10;10739:51:1;;10821:2;10806:18;;10799:34;;;;31636:37:0;;;;;;;;;;;;31558:123::o;39164:1239::-;39319:28;;;;;29904:7;39666:25;29904:7;39666:18;:25;:::i;:::-;39665:34;;;;:::i;:::-;39646:53;;39739:15;39720:16;:34;39712:70;;;;-1:-1:-1;;;39712:70:0;;6566:2:1;39712:70:0;;;6548:21:1;6605:2;6585:18;;;6578:30;-1:-1:-1;;;6624:18:1;;;6617:53;6687:18;;39712:70:0;6364:347:1;39712:70:0;39835:26;29953:12;39835:15;:26;:::i;:::-;39815:16;:46;;39793:136;;;;-1:-1:-1;;;39793:136:0;;;;;;;:::i;:::-;39962:5;39987:25;29953:12;39962:5;39987:25;:::i;:::-;39979:33;-1:-1:-1;40073:50:0;40107:15;40080:16;40073:50;:::i;:::-;40045:79;;:5;:79;:::i;:::-;40025:99;;40149:1;40141:4;:9;;;40137:50;;40174:1;40167:8;;40137:50;-1:-1:-1;40221:4:0;;39164:1239;;-1:-1:-1;40221:4:0;;39164:1239;;-1:-1:-1;40366:18:0;39164:1239;-1:-1:-1;39164:1239:0:o;3196:238::-;2176:13;:11;:13::i;:::-;-1:-1:-1;;;;;3299:22:0;::::1;3277:110;;;::::0;-1:-1:-1;;;3277:110:0;;11356:2:1;3277:110:0::1;::::0;::::1;11338:21:1::0;11395:2;11375:18;;;11368:30;11434:34;11414:18;;;11407:62;-1:-1:-1;;;11485:18:1;;;11478:36;11531:19;;3277:110:0::1;11154:402:1::0;3277:110:0::1;3398:28;3417:8;3398:18;:28::i;37888:243::-:0;-1:-1:-1;;;;;37987:20:0;;37951:6;37987:20;;;:14;:20;;;;;;38022:11;;;38018:52;;-1:-1:-1;38057:1:0;;37888:243;-1:-1:-1;;37888:243:0:o;38018:52::-;-1:-1:-1;;;;;38087:22:0;;;;;;;:16;:22;;;;;;;;:30;;;;;;;;;;:36;-1:-1:-1;;;38087:36:0;;;;;37888:243;-1:-1:-1;37888:243:0:o;51889:546::-;-1:-1:-1;;;;;52056:20:0;;51996:7;52056:20;;;:14;:20;;;;;;51996:7;;;52089:318;52113:3;52109:1;:7;52089:318;;;52149:3;52142;:10;52138:56;52173:5;52138:56;52208:11;52240:1;52223:9;52229:3;52223;:9;:::i;:::-;:13;;52235:1;52223:13;:::i;:::-;52222:19;;;;:::i;:::-;-1:-1:-1;;;;;52260:22:0;;;;;;:16;:22;;;;;;;;:27;;;;;;;;:30;;;52208:33;;-1:-1:-1;52260:36:0;-1:-1:-1;52256:140:0;;52323:3;52317:9;;52256:140;;;52373:7;52379:1;52373:3;:7;:::i;:::-;52367:13;;52256:140;-1:-1:-1;52118:3:0;;;;:::i;:::-;;;;52089:318;;;-1:-1:-1;52424:3:0;;51889:546;-1:-1:-1;;;;51889:546:0:o;26897:293::-;26299:1;27031:7;;:19;27023:63;;;;-1:-1:-1;;;27023:63:0;;11763:2:1;27023:63:0;;;11745:21:1;11802:2;11782:18;;;11775:30;11841:33;11821:18;;;11814:61;11892:18;;27023:63:0;11561:355:1;27023:63:0;26299:1;27164:7;:18;26897:293::o;48245:1301::-;-1:-1:-1;;;;;48536:20:0;;48502:31;48536:20;;;:14;:20;;;;;;;;48502:54;;;;;;;;;;-1:-1:-1;;;;;48502:54:0;;;;;;;;;;;;;;;;;48588:16;;;48502:54;;48588:16;;48617:25;;;;;48588:16;48617:25;:::i;:::-;;;;-1:-1:-1;;48735:26:0;;48756:5;;48735:10;;:26;;48756:5;;48735:26;:::i;:::-;-1:-1:-1;;;;;48735:26:0;;;-1:-1:-1;48887:15:0;;48883:75;;48919:14;;;:27;;;48883:75;-1:-1:-1;;;;;48968:20:0;;;;;;:14;:20;;;;;;;;:33;;;;-1:-1:-1;;;;;;48968:33:0;-1:-1:-1;;;;;48968:33:0;;;;;;;;;;-1:-1:-1;48968:33:0;;;;49256:41;48968:20;49274:10;48968:33;49256:11;:41::i;:::-;-1:-1:-1;;;;;49314:10:0;;;49310:109;;49341:66;49348:5;-1:-1:-1;;;;;49341:30:0;878:10;49394:4;-1:-1:-1;;;;;49341:66:0;;:30;:66::i;:::-;49471:10;:14;;;49458:4;-1:-1:-1;;;;;49436:50:0;49451:5;49436:50;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;12419:47:1;;12401:66;;49436:50:0;;12389:2:1;12374:18;49436:50:0;;;;;;;49521:16;;49502:36;;;8553:25:1;;;8609:2;8594:18;;8587:34;;;;49502:36:0;;8526:18:1;49502:36:0;;;;;;;48491:1055;;48245:1301;;;;;:::o;44353:3601::-;44528:17;;;;;;;;;44508;44528;;;;;;;;;;;;;;;;;;;;;;;44576;;;;;;;;;;;;;;;;;;;;;;;;;;;;44769;;44528;;44576;;44508;;-1:-1:-1;;;;;44769:21:0;;44765:363;;44827:17;;44866:14;;;;44883:15;-1:-1:-1;44862:255:0;;;44932:25;29953:12;44932:3;:25;:::i;:::-;44919:38;;:10;;;;:38;;;;45059:14;;;45052:48;;45084:15;;45052:48;:::i;:::-;45011:4;:10;;;:90;;;;:::i;:::-;44978:123;;;;44862:255;44792:336;44765:363;45255:15;45238:10;:14;;;:32;45237:61;;;;-1:-1:-1;45276:17:0;;-1:-1:-1;;;;;45276:21:0;;;45237:61;45233:401;;;45335:17;;45374:14;;;;45391:15;-1:-1:-1;45370:253:0;;;45440:25;29953:12;45440:3;:25;:::i;:::-;45427:38;;:10;;;;:38;;;;45565:14;;;45558:48;;45590:15;;45558:48;:::i;:::-;45517:4;:10;;;:90;;;;:::i;:::-;45484:123;;;;45370:253;45300:334;45233:401;45885:14;;;;;45872:28;;;;:12;:28;;;;;;45915:14;;;;45872:28;;;;;;-1:-1:-1;45915:19:0;45911:126;;-1:-1:-1;46010:14:0;;;;;45997:28;;;;:12;:28;;;;;;;;;45911:126;46133:22;46158:20;:18;:20::i;:::-;46133:45;;46443:4;:10;;;46430:4;:10;;;:23;;;;:::i;:::-;46410:9;:15;;:44;;;;;;;:::i;:::-;;;;;-1:-1:-1;46496:9:0;;46484;;:21;;46496:9;46484:21;:::i;:::-;46465:41;;:9;;:41;;;;;:::i;:::-;;;;;;;;46521:15;;;;46539:1;46521:19;;;46517:71;;-1:-1:-1;46517:71:0;;46575:1;46557:15;;;:19;46517:71;46619:1;46602:9;:14;;;:18;;;46598:69;;;46654:1;46637:18;;46598:69;46690:5;;46677:19;;;;:12;:19;;;;;;;;;:31;;;;;;-1:-1:-1;;;;;46677:31:0;;;-1:-1:-1;;;46677:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;46969:14;;;46986:15;-1:-1:-1;46965:385:0;;;47107:10;;;;47094:23;;;;:::i;:::-;;;47154:10;:14;;;47136:10;:14;;;:32;47132:152;;47258:10;;;;47245:23;;;;:::i;:::-;;;47132:152;47311:14;;;;;47298:28;;;;:12;:28;;;;;;:40;;-1:-1:-1;;;;;;47298:40:0;-1:-1:-1;;;;;47298:40:0;;;;;46965:385;47383:15;47366:10;:14;;;:32;47362:336;;;47436:10;:14;;;47419:10;:14;;;:31;47415:210;;;47484:10;;;;47471:23;;;;:::i;:::-;47582:14;;;;;47569:28;;;;:12;:28;;;;;;:40;;-1:-1:-1;;;;;;47569:40:0;-1:-1:-1;;;;;47569:40:0;;;;;;-1:-1:-1;47415:210:0;-1:-1:-1;;;;;47762:20:0;;47744:15;47762:20;;;:14;:20;;;;;;:24;;47785:1;47762:24;:::i;:::-;-1:-1:-1;;;;;47797:20:0;;;;;;;:14;:20;;;;;;;;:30;;;47848:15;47838:7;;;:25;;;47885:12;47874:8;;;:23;;;47908:22;;;:16;:22;;;;;:31;;;;;;;;;:38;;;;;;;-1:-1:-1;;;;;47908:38:0;;;-1:-1:-1;;;47908:38:0;;;;;;;;;;;;;;;-1:-1:-1;;47908:38:0;;;;;;;;;;-1:-1:-1;;;;;44353:3601:0:o;20182:214::-;20319:58;;-1:-1:-1;;;;;10757:32:1;;20319:58:0;;;10739:51:1;10806:18;;;10799:34;;;20265:123:0;;20299:5;;-1:-1:-1;;;20342:23:0;10712:18:1;;20319:58:0;;;;-1:-1:-1;;20319:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;20319:58:0;-1:-1:-1;;;;;;20319:58:0;;;;;;;;;;20265:19;:123::i;:::-;20182:214;;;:::o;51342:539::-;51454:7;;51514:8;51454:7;51535:318;51559:3;51555:1;:7;51535:318;;;51595:3;51588;:10;51584:56;51619:5;51584:56;51654:11;51686:1;51669:9;51675:3;51669;:9;:::i;:::-;:13;;51681:1;51669:13;:::i;:::-;51668:19;;;;:::i;:::-;51706:17;;;;:12;:17;;;;;:21;;;51654:33;;-1:-1:-1;51706:36:0;-1:-1:-1;51702:140:0;;51769:3;51763:9;;51702:140;;;51819:7;51825:1;51819:3;:7;:::i;:::-;51813:13;;51702:140;-1:-1:-1;51564:3:0;;;;:::i;:::-;;;;51535:318;;2455:132;2336:7;2363:6;-1:-1:-1;;;;;2363:6:0;878:10;2519:23;2511:68;;;;-1:-1:-1;;;2511:68:0;;12930:2:1;2511:68:0;;;12912:21:1;;;12949:18;;;12942:30;13008:34;12988:18;;;12981:62;13060:18;;2511:68:0;12728:356:1;3594:191:0;3668:16;3687:6;;-1:-1:-1;;;;;3704:17:0;;;-1:-1:-1;;;;;;3704:17:0;;;;;;3737:40;;3687:6;;;;;;;3737:40;;3668:16;3737:40;3657:128;3594:191;:::o;49805:900::-;49903:7;49923:22;49948:5;49923:30;;49964:10;29904:7;;49978:9;:12;;;:19;;;;:::i;:::-;49977:28;;;;:::i;:::-;49964:41;;50069:9;50064:504;50088:3;50084:1;:7;50064:504;;;50113:10;29904:7;50113:10;;:::i;:::-;;;50138:13;50179:2;50174;:7;50170:121;;;50207:2;50202:7;;50170:121;;;-1:-1:-1;50259:16:0;;;;:12;:16;;;;;;;;50170:121;50402:12;;;;50382:33;;50389:2;50382:33;:::i;:::-;50340:9;:15;;;:76;;;;:::i;:::-;50305:111;;:9;;:111;;;;;:::i;:::-;;;;;-1:-1:-1;50435:8:0;;;50431:54;;50464:5;;;50431:54;50518:6;50499:9;:15;;:25;;;;;;;:::i;:::-;;;;;-1:-1:-1;;50539:12:0;;;:17;;;50093:3;;;;:::i;:::-;;;;50064:504;;;;50601:1;50584:9;:14;;;:18;;;50580:69;;;50636:1;50619:18;;50580:69;-1:-1:-1;50681:14:0;50674:22;;;49805:900;-1:-1:-1;;;49805:900:0:o;52443:500::-;52589:5;;52529:7;;;;;52607:308;52631:3;52627:1;:7;52607:308;;;52667:3;52660;:10;52656:56;52691:5;52656:56;52726:11;52758:1;52741:9;52747:3;52741;:9;:::i;:::-;:13;;52753:1;52741:13;:::i;:::-;52740:19;;;;:::i;:::-;52778:17;;;;:12;:17;;;;;:20;;;52726:33;;-1:-1:-1;52778:26:0;-1:-1:-1;52774:130:0;;52831:3;52825:9;;52774:130;;;52881:7;52887:1;52881:3;:7;:::i;:::-;52875:13;;52774:130;-1:-1:-1;52636:3:0;;;;:::i;:::-;;;;52607:308;;;-1:-1:-1;52932:3:0;;52443:500;-1:-1:-1;;;52443:500:0:o;53450:3303::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53549:5:0;;53577:129;;;;;;;;;;;;;;;;53647:15;53577:129;;;;;;53682:12;53577:129;;;;;;53749;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53893:10;;53889:129;;-1:-1:-1;53932:20:0;;;;:12;:20;;;;;;;;53920:32;;;;;;;;;;;;;;;;;-1:-1:-1;;;53920:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53986:20;;;;;;;53967:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;53920:32;;-1:-1:-1;53889:129:0;54053:12;;;;54028:22;54379:15;:30;-1:-1:-1;54375:190:0;;;54540:12;;;;54522:30;;:15;:30;:::i;:::-;54486:13;;;;54471:28;;:12;:28;:::i;:::-;54457:43;;30059:8;54457:43;:::i;:::-;54456:97;;;;:::i;:::-;54426:127;;54375:190;54893:10;29904:7;54907:21;29904:7;54907:14;:21;:::i;:::-;54906:30;;;;:::i;:::-;54893:43;;54956:9;54951:1730;54975:3;54971:1;:7;54951:1730;;;55183:10;29904:7;55183:10;;:::i;:::-;;;55212:13;55257:15;55252:2;:20;55248:390;;;55302:15;55297:20;;55248:390;;;-1:-1:-1;55375:16:0;;;;:12;:16;;;;;;;;55248:390;55813:35;55833:14;55820:2;55813:35;:::i;:::-;55767:9;:15;;;:82;;;;:::i;:::-;55728:121;;:9;;:121;;;;;:::i;:::-;;;;;-1:-1:-1;55868:15:0;;;:25;;55887:6;;55868:15;:25;;55887:6;;55868:25;:::i;:::-;;;;;;;;55949:14;;55966:1;55949:18;;;55945:85;;-1:-1:-1;55945:85:0;;56009:1;55992:18;;55945:85;56070:1;56052:9;:15;;;:19;;;56048:87;;;56114:1;56096:15;;;:19;56048:87;56193:12;;;;:17;;;56330:19;;;56172:2;;-1:-1:-1;56172:2:0;;30059:8;;56325:24;;56172:2;56325:24;:::i;:::-;56311:39;;:10;:39;:::i;:::-;56310:75;;;;:::i;:::-;56266:16;:20;;;:119;;;;:::i;:::-;56229:13;;;:156;56404:11;56414:1;56404:11;;:::i;:::-;;;56444:15;56438:2;:21;56434:181;;-1:-1:-1;56500:12:0;56484:13;;;:28;;;56535:20;;;;:12;:20;;;;;;;;;:32;;;;;;-1:-1:-1;;;;;56535:32:0;;;-1:-1:-1;;;56535:32:0;;;;;;;;;;;;;;;;;;;;;;;;56590:5;;56434:181;-1:-1:-1;56633:20:0;;;;:12;:20;;;;;;;;;:32;;;;;;-1:-1:-1;;;;;56633:32:0;;;-1:-1:-1;;;56633:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;54980:3;;;;:::i;:::-;;;;54951:1730;;;;54878:1814;56712:6;56704:5;:14;;;;56729:16;;;;53450:3303;:::o;20404:285::-;20602:68;;-1:-1:-1;;;;;13347:15:1;;;20602:68:0;;;13329:34:1;13399:15;;13379:18;;;13372:43;13431:18;;;13424:34;;;20548:133:0;;20582:5;;-1:-1:-1;;;20625:27:0;13264:18:1;;20602:68:0;13089:375:1;23646:802:0;24070:23;24096:106;24138:4;24096:106;;;;;;;;;;;;;;;;;24104:5;-1:-1:-1;;;;;24096:27:0;;;:106;;;;;:::i;:::-;24217:17;;24070:132;;-1:-1:-1;24217:21:0;24213:228;;24332:10;24321:30;;;;;;;;;;;;:::i;:::-;24295:134;;;;-1:-1:-1;;;24295:134:0;;13953:2:1;24295:134:0;;;13935:21:1;13992:2;13972:18;;;13965:30;14031:34;14011:18;;;14004:62;-1:-1:-1;;;14082:18:1;;;14075:40;14132:19;;24295:134:0;13751:406:1;13334:229:0;13471:12;13503:52;13525:6;13533:4;13539:1;13542:12;13471;14875;14889:23;14916:6;-1:-1:-1;;;;;14916:11:0;14935:5;14956:4;14916:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14874:97;;;;15002:152;15047:6;15072:7;15098:10;15127:12;15002:26;:152::i;:::-;14982:172;14550:612;-1:-1:-1;;;;;;;14550:612:0:o;17680:644::-;17865:12;17894:7;17890:427;;;17922:10;:17;17943:1;17922:22;17918:290;;-1:-1:-1;;;;;10677:19:0;;;18132:60;;;;-1:-1:-1;;;18132:60:0;;15063:2:1;18132:60:0;;;15045:21:1;15102:2;15082:18;;;15075:30;15141:31;15121:18;;;15114:59;15190:18;;18132:60:0;14861:353:1;18132:60:0;-1:-1:-1;18229:10:0;18222:17;;17890:427;18272:33;18280:10;18292:12;19052:17;;:21;19048:388;;19284:10;19278:17;19341:15;19328:10;19324:2;19320:19;19313:44;19048:388;19411:12;19404:20;;-1:-1:-1;;;19404:20:0;;;;;;;;:::i;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:254::-;260:6;268;321:2;309:9;300:7;296:23;292:32;289:52;;;337:1;334;327:12;289:52;360:29;379:9;360:29;:::i;:::-;350:39;436:2;421:18;;;;408:32;;-1:-1:-1;;;192:254:1:o;633:186::-;692:6;745:2;733:9;724:7;720:23;716:32;713:52;;;761:1;758;751:12;713:52;784:29;803:9;784:29;:::i;:::-;774:39;633:186;-1:-1:-1;;;633:186:1:o;1118:250::-;1203:1;1213:113;1227:6;1224:1;1221:13;1213:113;;;1303:11;;;1297:18;1284:11;;;1277:39;1249:2;1242:10;1213:113;;;-1:-1:-1;;1360:1:1;1342:16;;1335:27;1118:250::o;1373:396::-;1522:2;1511:9;1504:21;1485:4;1554:6;1548:13;1597:6;1592:2;1581:9;1577:18;1570:34;1613:79;1685:6;1680:2;1669:9;1665:18;1660:2;1652:6;1648:15;1613:79;:::i;:::-;1753:2;1732:15;-1:-1:-1;;1728:29:1;1713:45;;;;1760:2;1709:54;;1373:396;-1:-1:-1;;1373:396:1:o;2387:188::-;2455:20;;-1:-1:-1;;;;;2504:46:1;;2494:57;;2484:85;;2565:1;2562;2555:12;2580:254;2648:6;2656;2709:2;2697:9;2688:7;2684:23;2680:32;2677:52;;;2725:1;2722;2715:12;2677:52;2748:29;2767:9;2748:29;:::i;3035:186::-;3094:6;3147:2;3135:9;3126:7;3122:23;3118:32;3115:52;;;3163:1;3160;3153:12;3115:52;3186:29;3205:9;3186:29;:::i;3226:180::-;3285:6;3338:2;3326:9;3317:7;3313:23;3309:32;3306:52;;;3354:1;3351;3344:12;3306:52;-1:-1:-1;3377:23:1;;3226:180;-1:-1:-1;3226:180:1:o;3619:260::-;3687:6;3695;3748:2;3736:9;3727:7;3723:23;3719:32;3716:52;;;3764:1;3761;3754:12;3716:52;3787:29;3806:9;3787:29;:::i;:::-;3777:39;;3835:38;3869:2;3858:9;3854:18;3835:38;:::i;:::-;3825:48;;3619:260;;;;;:::o;4394:127::-;4455:10;4450:3;4446:20;4443:1;4436:31;4486:4;4483:1;4476:15;4510:4;4507:1;4500:15;4526:200;4592:9;;;4565:4;4620:9;;4648:10;;4660:12;;;4644:29;4683:12;;;4675:21;;4641:56;4638:82;;;4700:18;;:::i;4731:241::-;4770:7;4849:1;4845:2;4834:17;4830:1;4826:2;4815:17;4811:41;4887:11;4883:2;4872:27;4861:38;;4930:11;4921:7;4918:24;4908:58;;4946:18;;:::i;4977:249::-;5077:2;5066:17;;;5047;;;;5043:41;-1:-1:-1;;;;;;5099:50:1;;-1:-1:-1;;;;;5151:45:1;;5096:101;5093:127;;;5200:18;;:::i;5231:127::-;5292:10;5287:3;5283:20;5280:1;5273:31;5323:4;5320:1;5313:15;5347:4;5344:1;5337:15;5363:120;5403:1;5429;5419:35;;5434:18;;:::i;:::-;-1:-1:-1;5468:9:1;;5363:120::o;5488:168::-;5561:9;;;5592;;5609:15;;;5603:22;;5589:37;5579:71;;5630:18;;:::i;6716:125::-;6781:9;;;6802:10;;;6799:36;;;6815:18;;:::i;6846:404::-;7048:2;7030:21;;;7087:2;7067:18;;;7060:30;7126:34;7121:2;7106:18;;7099:62;-1:-1:-1;;;7192:2:1;7177:18;;7170:38;7240:3;7225:19;;6846:404::o;7255:346::-;7457:2;7439:21;;;7496:2;7476:18;;;7469:30;-1:-1:-1;;;7530:2:1;7515:18;;7508:52;7592:2;7577:18;;7255:346::o;7952:128::-;8019:9;;;8040:11;;;8037:37;;;8054:18;;:::i;8984:346::-;9186:2;9168:21;;;9225:2;9205:18;;;9198:30;-1:-1:-1;;;9259:2:1;9244:18;;9237:52;9321:2;9306:18;;8984:346::o;9335:135::-;9374:3;9395:17;;;9392:43;;9415:18;;:::i;:::-;-1:-1:-1;9462:1:1;9451:13;;9335:135::o;9475:380::-;9554:1;9550:12;;;;9597;;;9618:61;;9672:4;9664:6;9660:17;9650:27;;9618:61;9725:2;9717:6;9714:14;9694:18;9691:38;9688:161;;9771:10;9766:3;9762:20;9759:1;9752:31;9806:4;9803:1;9796:15;9834:4;9831:1;9824:15;9688:161;;9475:380;;;:::o;10844:305::-;10883:1;10925;10921:2;10910:17;10962:1;10958:2;10947:17;10983:3;10973:37;;10990:18;;:::i;:::-;-1:-1:-1;;;;;;11026:48:1;;-1:-1:-1;;11076:15:1;;11022:70;11019:96;;;11095:18;;:::i;:::-;11129:14;;;10844:305;-1:-1:-1;;;10844:305:1:o;11921:197::-;-1:-1:-1;;;;;12043:10:1;;;12055;;;12039:27;;12078:11;;;12075:37;;;12092:18;;:::i;12123:127::-;12184:10;12179:3;12175:20;12172:1;12165:31;12215:4;12212:1;12205:15;12239:4;12236:1;12229:15;12478:245;12576:2;12546:17;;;12565;;;;12542:41;-1:-1:-1;;;;;12598:44:1;;-1:-1:-1;;;;;;12644:49:1;;12595:99;12592:125;;;12697:18;;:::i;13469:277::-;13536:6;13589:2;13577:9;13568:7;13564:23;13560:32;13557:52;;;13605:1;13602;13595:12;13557:52;13637:9;13631:16;13690:5;13683:13;13676:21;13669:5;13666:32;13656:60;;13712:1;13709;13702:12;14569:287;14698:3;14736:6;14730:13;14752:66;14811:6;14806:3;14799:4;14791:6;14787:17;14752:66;:::i;:::-;14834:16;;;;;14569:287;-1:-1:-1;;14569:287:1:o
Swarm Source
ipfs://3d91a50ab44e42857b36dafbef2a673d51d911acb6eaafb3cb73533ff7aa7454
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.