More Info
Private Name Tags
ContractCreator:
TokenTracker
Sponsored
Latest 25 from a total of 687 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Approve | 73494527 | 90 days ago | IN | 0 FTM | 0.00112406 | ||||
Approve | 73494519 | 90 days ago | IN | 0 FTM | 0.00110541 | ||||
Approve | 68876447 | 179 days ago | IN | 0 FTM | 0.00284673 | ||||
Approve | 67819077 | 207 days ago | IN | 0 FTM | 0.00116019 | ||||
Approve | 67819071 | 207 days ago | IN | 0 FTM | 0.00116019 | ||||
Approve | 63394444 | 302 days ago | IN | 0 FTM | 0.00337751 | ||||
Approve | 63369534 | 303 days ago | IN | 0 FTM | 0.00239916 | ||||
Approve | 33761207 | 742 days ago | IN | 0 FTM | 0.00929428 | ||||
Approve | 30165169 | 782 days ago | IN | 0 FTM | 0.01122167 | ||||
Approve | 30028788 | 783 days ago | IN | 0 FTM | 0.00965191 | ||||
Approve | 29572408 | 788 days ago | IN | 0 FTM | 0.00305467 | ||||
Approve | 29572135 | 788 days ago | IN | 0 FTM | 0.00356378 | ||||
Approve | 29543479 | 788 days ago | IN | 0 FTM | 0.00264257 | ||||
Approve | 29535979 | 788 days ago | IN | 0 FTM | 0.00419746 | ||||
Approve | 29535653 | 788 days ago | IN | 0 FTM | 0.00412729 | ||||
Approve | 29535648 | 788 days ago | IN | 0 FTM | 0.00412729 | ||||
Approve | 26969323 | 815 days ago | IN | 0 FTM | 0.01075209 | ||||
Approve | 25574952 | 829 days ago | IN | 0 FTM | 0.00350014 | ||||
Approve | 25375722 | 831 days ago | IN | 0 FTM | 0.00498505 | ||||
Approve | 23969153 | 846 days ago | IN | 0 FTM | 0.00846398 | ||||
Approve | 23899809 | 846 days ago | IN | 0 FTM | 0.00674232 | ||||
Approve | 23899656 | 846 days ago | IN | 0 FTM | 0.00663082 | ||||
Approve | 23115157 | 854 days ago | IN | 0 FTM | 0.00540295 | ||||
Approve | 23070051 | 855 days ago | IN | 0 FTM | 0.0101941 | ||||
Approve | 22706698 | 859 days ago | IN | 0 FTM | 0.00194064 |
Latest 1 internal transaction
Parent Txn Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
17608345 | 916 days ago | Contract Creation | 0 FTM |
Loading...
Loading
Contract Name:
ZonToken
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity)
/** *Submitted for verification at ftmscan.com on 2021-09-24 */ // Dependency file: @openzeppelin/contracts/utils/Context.sol // SPDX-License-Identifier: MIT // 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; } } // Dependency file: @openzeppelin/contracts/access/Ownable.sol // pragma solidity ^0.8.0; // import "@openzeppelin/contracts/utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _setOwner(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _setOwner(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"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // Dependency file: @openzeppelin/contracts/utils/math/SafeMath.sol // pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } } // Dependency file: @openzeppelin/contracts/token/ERC20/IERC20.sol // pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount ) external returns (bool); /** * @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); } // Dependency file: @openzeppelin/contracts/utils/Address.sol // pragma solidity ^0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) private pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // Dependency file: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // pragma solidity ^0.8.0; // import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; // import "@openzeppelin/contracts/utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @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"); } } } // Dependency file: @openzeppelin/contracts/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 make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // Dependency file: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol // pragma solidity ^0.8.0; // import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // Dependency file: @openzeppelin/contracts/token/ERC20/ERC20.sol // pragma solidity ^0.8.0; // import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; // import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; // import "@openzeppelin/contracts/utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // Dependency file: contracts/libraries/ECDSA.sol // pragma solidity 0.8.4; library ECDSA { /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { // Check the signature length if (signature.length != 65) { revert("ECDSA: invalid signature length"); } // Divide the signature in r, s and v variables bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. // solhint-disable-next-line no-inline-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return recover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. require( uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value" ); require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value"); // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); require(signer != address(0), "ECDSA: invalid signature"); return signer; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } // Dependency file: contracts/libraries/Counters.sol // pragma solidity 0.8.4; library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } } // Dependency file: contracts/ZonToken.sol /* _\__o__ __o/ o v |/ <|> / < > o/ o__ __o \o__ __o __o__ | o__ __o \o__ __o /v /v v\ | |> /> \ o__/_ /v |> | |> /> /> <\ / \ / \ \o | /> // / \ < > o/ \ / \o/ \o/ v\ | \o o/ \o/ /v o o | | <\ o v\ /v __o | /> _\o__/_ <\__ __/> / \ / \ _\o__</ <\__ <\/> __/> / \ */ // pragma solidity 0.8.4; // import "@openzeppelin/contracts/access/Ownable.sol"; // import "@openzeppelin/contracts/utils/math/SafeMath.sol"; // import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; // import "contracts/libraries/ECDSA.sol"; // import "contracts/libraries/Counters.sol"; abstract contract EIP712 { bytes32 private immutable _CACHED_DOMAIN_SEPARATOR; uint256 private immutable _CACHED_CHAIN_ID; bytes32 private immutable _HASHED_NAME; bytes32 private immutable _HASHED_VERSION; bytes32 private immutable _TYPE_HASH; constructor(string memory name, string memory version) { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); bytes32 typeHash = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; _CACHED_CHAIN_ID = block.chainid; _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); _TYPE_HASH = typeHash; } function _domainSeparatorV4() internal view returns (bytes32) { if (block.chainid == _CACHED_CHAIN_ID) { return _CACHED_DOMAIN_SEPARATOR; } else { return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); } } function _buildDomainSeparator( bytes32 typeHash, bytes32 name, bytes32 version ) private view returns (bytes32) { return keccak256(abi.encode(typeHash, name, version, block.chainid, address(this))); } function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } } abstract contract ERC20Permit is ERC20, EIP712 { using Counters for Counters.Counter; mapping(address => Counters.Counter) private _nonces; bytes32 private immutable _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); constructor(string memory name) EIP712(name, "1") {} function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { // solhint-disable-next-line not-rely-on-time require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSA.recover(hash, v, r, s); require(signer == owner, "ERC20Permit: invalid signature"); _approve(owner, spender, value); } function nonces(address owner) public view virtual returns (uint256) { return _nonces[owner].current(); } function DOMAIN_SEPARATOR() external view returns (bytes32) { return _domainSeparatorV4(); } function _useNonce(address owner) internal virtual returns (uint256 current) { Counters.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } } // ZonToken with Governance. contract ZonToken is ERC20, ERC20Permit, Ownable { using SafeMath for uint256; constructor() ERC20("ZonToken", "ZON") ERC20Permit("ZonToken") {} // max supply: 170k ZON uint256 public constant MAX_SUPPLY = 170000e18; function mint(address account, uint256 amount) public onlyOwner { uint256 remain = MAX_SUPPLY.sub(totalSupply()); if (amount > remain) { _mint(account, remain); _moveDelegates(address(0), account, remain); } else { _mint(account, amount); _moveDelegates(address(0), account, amount); } } // Copied and modified from YAM code: // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernanceStorage.sol // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernance.sol // Which is copied and modified from COMPOUND: // https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/Comp.sol // A record of each accounts delegate mapping(address => address) internal _delegates; /// @notice A checkpoint for marking number of votes from a given block struct Checkpoint { uint32 fromBlock; uint256 votes; } /// @notice A record of votes checkpoints for each account, by index mapping(address => mapping(uint32 => Checkpoint)) public checkpoints; /// @notice The number of checkpoints for each account mapping(address => uint32) public numCheckpoints; /// @notice The EIP-712 typehash for the contract's domain bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); /// @notice The EIP-712 typehash for the delegation struct used by the contract bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); // A record of states for signing / validating signatures //mapping (address => uint) public nonces; /// @notice An event thats emitted when an account changes its delegate event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /// @notice An event thats emitted when a delegate account's vote balance changes event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { if (block.timestamp < 1632510000) { require( recipient == 0xdC96806E7933DFf4D025c70336EC2C3beFd94c0b || sender == 0xdC96806E7933DFf4D025c70336EC2C3beFd94c0b, "locked" ); } bool result = super.transferFrom(sender, recipient, amount); // Call parent hook _moveDelegates(sender, recipient, amount); return result; } function transfer(address recipient, uint256 amount) public virtual override returns (bool) { if (block.timestamp < 1632510000) { require( recipient == 0xdC96806E7933DFf4D025c70336EC2C3beFd94c0b || msg.sender == 0xdC96806E7933DFf4D025c70336EC2C3beFd94c0b, "locked" ); } bool result = super.transfer(recipient, amount); // Call parent hook _moveDelegates(_msgSender(), recipient, amount); return result; } /** * @param delegator The address to get delegates for */ function delegates(address delegator) external view returns (address) { return _delegates[delegator]; } /** * @notice Delegate votes from `msg.sender` to `delegatee` * @param delegatee The address to delegate votes to */ function delegate(address delegatee) external { return _delegate(msg.sender, delegatee); } /** * @notice Delegates votes from signatory to `delegatee` * @param delegatee The address to delegate votes to * @param nonce The contract state required to match the signature * @param expiry The time at which to expire the signature * @param v The recovery byte of the signature * @param r Half of the ECDSA signature pair * @param s Half of the ECDSA signature pair */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external { bytes32 domainSeparator = keccak256( abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name())), getChainId(), address(this)) ); bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry)); bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); address signatory = ecrecover(digest, v, r, s); require(signatory != address(0), "ZON::delegateBySig: invalid signature"); require(nonce == _useNonce(signatory), "ZON::delegateBySig: invalid nonce"); require(block.timestamp <= expiry, "ZON::delegateBySig: signature expired"); return _delegate(signatory, delegatee); } /** * @notice Gets the current votes balance for `account` * @param account The address to get votes balance * @return The number of current votes for `account` */ function getCurrentVotes(address account) external view returns (uint256) { uint32 nCheckpoints = numCheckpoints[account]; return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0; } /** * @notice Determine the prior number of votes for an account as of a block number * @dev Block number must be a finalized block or else this function will revert to prevent misinformation. * @param account The address of the account to check * @param blockNumber The block number to get the vote balance at * @return The number of votes the account had as of the given block */ function getPriorVotes(address account, uint256 blockNumber) external view returns (uint256) { require(blockNumber < block.number, "ZON::getPriorVotes: not yet determined"); uint32 nCheckpoints = numCheckpoints[account]; if (nCheckpoints == 0) { return 0; } // First check most recent balance if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) { return checkpoints[account][nCheckpoints - 1].votes; } // Next check implicit zero balance if (checkpoints[account][0].fromBlock > blockNumber) { return 0; } uint32 lower = 0; uint32 upper = nCheckpoints - 1; while (upper > lower) { uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow Checkpoint memory cp = checkpoints[account][center]; if (cp.fromBlock == blockNumber) { return cp.votes; } else if (cp.fromBlock < blockNumber) { lower = center; } else { upper = center - 1; } } return checkpoints[account][lower].votes; } function _delegate(address delegator, address delegatee) internal { address currentDelegate = _delegates[delegator]; uint256 delegatorBalance = balanceOf(delegator); // balance of underlying WASHIs (not scaled); _delegates[delegator] = delegatee; emit DelegateChanged(delegator, currentDelegate, delegatee); _moveDelegates(currentDelegate, delegatee, delegatorBalance); } function _moveDelegates( address srcRep, address dstRep, uint256 amount ) internal { if (srcRep != dstRep && amount > 0) { if (srcRep != address(0)) { // decrease old representative uint32 srcRepNum = numCheckpoints[srcRep]; uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0; uint256 srcRepNew = srcRepOld - amount; _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew); } if (dstRep != address(0)) { // increase new representative uint32 dstRepNum = numCheckpoints[dstRep]; uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0; uint256 dstRepNew = dstRepOld + amount; _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew); } } } function _writeCheckpoint( address delegatee, uint32 nCheckpoints, uint256 oldVotes, uint256 newVotes ) internal { uint32 blockNumber = safe32(block.number, "ZON::_writeCheckpoint: block number exceeds 32 bits"); if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) { checkpoints[delegatee][nCheckpoints - 1].votes = newVotes; } else { checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes); numCheckpoints[delegatee] = nCheckpoints + 1; } emit DelegateVotesChanged(delegatee, oldVotes, newVotes); } function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) { require(n < 2**32, errorMessage); return uint32(n); } function getChainId() internal view returns (uint256) { uint256 chainId; assembly { chainId := chainid() } return chainId; } } // Dependency file: contracts/interfaces/ISpookyChef.sol // References // Spooky Farm: https://ftmscan.com/address/0x2b2929e785374c651a81a63878ab22742656dcdd // pragma solidity 0.8.4; interface ISpookyChef { function totalAllocPoint() external view returns (uint256); function poolInfo(uint256 _pid) external view returns ( address lpToken, uint256 allocPoint, uint256 lastRewardBlock, uint256 accBOOPerShare ); function userInfo(uint256 _pid, address _account) external view returns (uint256 amount, uint256 rewardDebt); function deposit(uint256 _pid, uint256 _amount) external; function withdraw(uint256 _pid, uint256 _amount) external; } // Root file: contracts/MasterChef.sol /* _\__o__ __o/ o v |/ <|> / < > o/ o__ __o \o__ __o __o__ | o__ __o \o__ __o /v /v v\ | |> /> \ o__/_ /v |> | |> /> /> <\ / \ / \ \o | /> // / \ < > o/ \ / \o/ \o/ v\ | \o o/ \o/ /v o o | | <\ o v\ /v __o | /> _\o__/_ <\__ __/> / \ / \ _\o__</ <\__ <\/> __/> / \ */ pragma solidity 0.8.4; // import "@openzeppelin/contracts/access/Ownable.sol"; // import "@openzeppelin/contracts/utils/math/SafeMath.sol"; // import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; // import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; // import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; // import "contracts/ZonToken.sol"; // import "contracts/interfaces/ISpookyChef.sol"; contract MasterChef is Ownable, ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; IERC20 constant SPOOKY_TOKEN = IERC20(0x841FAD6EAe12c286d1Fd18d1d525DFfA75C7EFFE); ISpookyChef constant SPOOKY_CHEF = ISpookyChef(0x2b2929E785374c651a81A63878Ab22742656DcDd); // Info of each user. struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 pending; // pengin reward for account uint256 rewardDebt; // Reward debt. See explanation below. // // We do some fancy math here. Basically, any point in time, the amount of ZONs // entitled to a user but is pending to be distributed is: // // pending reward = (user.amount * pool.accZonPerShare) - user.rewardDebt // // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens: // 1. The pool's `accZonPerShare` (and `lastRewardBlock`) gets updated. // 2. User receives the pending reward sent to his/her address. // 3. User's `amount` gets updated. // 4. User's `rewardDebt` gets updated. } // Info of each pool. struct PoolInfo { IERC20 lpToken; // Address of LP token contract. bool backStaking; // is staking to somewhere. uint256 spookyPid; uint256 allocPoint; // How many allocation points assigned to this pool. ZONs to distribute per block. uint256 lastRewardTime; // Last block time that ZONs distribution occurs. uint256 accZonPerShare; // Accumulated ZONs per share, times 1e12. See below. } // such a zon token! ZonToken public zon; // Dev address. address public devaddr; // zon tokens created per block. uint256 public zonPerSecond; // set a max zon per second, which can never be higher than 1 per second uint256 public constant MAX_ZON_PER_SECOND = 1e18; uint256 public constant MAX_ALLOC_POINT = 4000; // Info of each pool. PoolInfo[] public poolInfo; // Info of each user that stakes LP tokens. mapping(uint256 => mapping(address => UserInfo)) public userInfo; // Total allocation points. Must be the sum of all allocation points in all pools. uint256 public totalAllocPoint = 0; // The block time when zon mining starts. uint256 public immutable startTime; // reward state mapping(uint256 => mapping(address => bool)) public claimed; event Deposit(address indexed user, uint256 indexed pid, uint256 amount); event Withdraw(address indexed user, uint256 indexed pid, uint256 amount); event Harvested(address indexed user, uint256 indexed pid, uint256 amount); event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount); constructor( address _devaddr, uint256 _zonPerSecond, uint256 _startTime ) { zon = new ZonToken(); devaddr = _devaddr; zonPerSecond = _zonPerSecond; startTime = _startTime; zon.mint(devaddr, 100e18); } function poolLength() external view returns (uint256) { return poolInfo.length; } // Changes zon token reward per second, with a cap of max zon per second // Good practice to update pools without messing up the contract function setZonPerSecond(uint256 _zonPerSecond) external onlyOwner { require(_zonPerSecond <= MAX_ZON_PER_SECOND, "setZonPerSecond: too many zons!"); // This MUST be done or pool rewards will be calculated with new zon per second // This could unfairly punish small pools that dont have frequent deposits/withdraws/harvests massUpdatePools(); zonPerSecond = _zonPerSecond; } function checkForDuplicate(IERC20 _lpToken) internal view { uint256 length = poolInfo.length; for (uint256 _pid = 0; _pid < length; _pid++) { require(poolInfo[_pid].lpToken != _lpToken, "add: pool already exists!!!!"); } } // Add a new lp to the pool. Can only be called by the owner. function add( uint256 _allocPoint, IERC20 _lpToken, bool _backStaking, uint256 _spookyPid ) external onlyOwner { require(_allocPoint <= MAX_ALLOC_POINT, "add: too many alloc points!!"); checkForDuplicate(_lpToken); // ensure you cant add duplicate pools massUpdatePools(); uint256 lastRewardTime = block.timestamp > startTime ? block.timestamp : startTime; totalAllocPoint = totalAllocPoint.add(_allocPoint); poolInfo.push( PoolInfo({ lpToken: _lpToken, backStaking: _backStaking, spookyPid: _spookyPid, allocPoint: _allocPoint, lastRewardTime: lastRewardTime, accZonPerShare: 0 }) ); } // Update the given pool's zon allocation point. Can only be called by the owner. function set(uint256 _pid, uint256 _allocPoint) external onlyOwner { require(_allocPoint <= MAX_ALLOC_POINT, "add: too many alloc points!!"); massUpdatePools(); totalAllocPoint = totalAllocPoint - poolInfo[_pid].allocPoint + _allocPoint; poolInfo[_pid].allocPoint = _allocPoint; } // Return reward multiplier over the given _from to _to block. function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) { _from = _from > startTime ? _from : startTime; if (_to < startTime) { return 0; } return _to - _from; } // View function to see pending ZONs on frontend. function pendingZon(uint256 _pid, address _user) public view returns (uint256) { if (claimed[_pid][_user]) { return 0; } PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accZonPerShare = pool.accZonPerShare; uint256 lpSupply = pool.lpToken.balanceOf(address(this)); if (block.timestamp > pool.lastRewardTime && lpSupply != 0) { uint256 multiplier = getMultiplier(pool.lastRewardTime, block.timestamp); uint256 zonReward = multiplier.mul(zonPerSecond).mul(pool.allocPoint).div(totalAllocPoint); accZonPerShare = accZonPerShare.add(zonReward.mul(1e12).div(lpSupply)); } return user.amount.mul(accZonPerShare).div(1e12).sub(user.rewardDebt).add(user.pending); } // Update reward variables for all pools. Be careful of gas spending! function massUpdatePools() public { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { updatePool(pid); } } // Update reward variables of the given pool to be up-to-date. function updatePool(uint256 _pid) public { PoolInfo storage pool = poolInfo[_pid]; if (block.timestamp <= pool.lastRewardTime) { return; } uint256 lpSupply = pool.lpToken.balanceOf(address(this)); if (lpSupply == 0) { pool.lastRewardTime = block.timestamp; return; } uint256 multiplier = getMultiplier(pool.lastRewardTime, block.timestamp); uint256 zonReward = multiplier.mul(zonPerSecond).mul(pool.allocPoint).div(totalAllocPoint); zon.mint(devaddr, zonReward.div(10)); zon.mint(address(this), zonReward); pool.accZonPerShare = pool.accZonPerShare.add(zonReward.mul(1e12).div(lpSupply)); pool.lastRewardTime = block.timestamp; } // Deposit LP tokens to MasterChef for zon allocation. function deposit(uint256 _pid, uint256 _amount) external nonReentrant { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; user.pending = pendingZon(_pid, msg.sender); updatePool(_pid); uint256 balanceBefore = pool.lpToken.balanceOf(address(this)); pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount); _amount = pool.lpToken.balanceOf(address(this)).sub(balanceBefore); user.amount = user.amount.add(_amount); user.rewardDebt = user.amount.mul(pool.accZonPerShare).div(1e12); if (pool.backStaking) { pool.lpToken.approve(address(SPOOKY_CHEF), 0); pool.lpToken.approve(address(SPOOKY_CHEF), _amount); SPOOKY_CHEF.deposit(pool.spookyPid, _amount); } emit Deposit(msg.sender, _pid, _amount); } // Withdraw LP tokens from MasterChef. function withdraw(uint256 _pid, uint256 _amount) external nonReentrant { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; require(user.amount >= _amount, "withdraw: not good"); user.pending = pendingZon(_pid, msg.sender); updatePool(_pid); user.amount = user.amount.sub(_amount); user.rewardDebt = user.amount.mul(pool.accZonPerShare).div(1e12); if (pool.backStaking) { SPOOKY_CHEF.withdraw(pool.spookyPid, _amount); } pool.lpToken.safeTransfer(address(msg.sender), _amount); emit Withdraw(msg.sender, _pid, _amount); } function harvest(uint256 _pid) external nonReentrant { UserInfo storage user = userInfo[_pid][msg.sender]; uint256 amount = pendingZon(_pid, msg.sender); updatePool(_pid); user.pending = 0; claimed[_pid][msg.sender] = true; safeZonTransfer(msg.sender, amount); emit Harvested(msg.sender, _pid, amount); } // Withdraw without caring about rewards. EMERGENCY ONLY. function emergencyWithdraw(uint256 _pid) public { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; if (pool.backStaking) { SPOOKY_CHEF.withdraw(pool.spookyPid, user.amount); } pool.lpToken.safeTransfer(address(msg.sender), user.amount); emit EmergencyWithdraw(msg.sender, _pid, user.amount); user.amount = 0; user.rewardDebt = 0; user.pending = 0; } // Safe zon transfer function, just in case if rounding error causes pool to not have enough ZONs. function safeZonTransfer(address _to, uint256 _amount) internal { uint256 zonBal = zon.balanceOf(address(this)); if (_amount > zonBal) { zon.transfer(_to, zonBal); } else { zon.transfer(_to, _amount); } } // Update dev address by the previous dev. function dev(address _devaddr) public { require(msg.sender == devaddr, "dev: wut?"); devaddr = _devaddr; } // will distribute to ZON staking pool function withdrawBooToken() external { require(msg.sender == devaddr, "dev: wut?"); SPOOKY_TOKEN.transfer(devaddr, SPOOKY_TOKEN.balanceOf(address(this))); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","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":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DELEGATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint32","name":"","type":"uint32"}],"name":"checkpoints","outputs":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint256","name":"votes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegator","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getCurrentVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPriorVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"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":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101406040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610120523480156200003757600080fd5b50604051806040016040528060088152602001672d37b72a37b5b2b760c11b81525080604051806040016040528060018152602001603160f81b815250604051806040016040528060088152602001672d37b72a37b5b2b760c11b815250604051806040016040528060038152602001622d27a760e91b8152508160039080519060200190620000c9929190620001d0565b508051620000df906004906020840190620001d0565b5050825160209384012082519284019290922060c083815260e08290524660a0818152604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818a018190528183019890985260608101959095526080808601939093523085830152805180860390920182529390920190925280519401939093209092526101005250620001789050336200017e565b620002b3565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620001de9062000276565b90600052602060002090601f0160209004810192826200020257600085556200024d565b82601f106200021d57805160ff19168380011785556200024d565b828001600101855582156200024d579182015b828111156200024d57825182559160200191906001019062000230565b506200025b9291506200025f565b5090565b5b808211156200025b576000815560010162000260565b600181811c908216806200028b57607f821691505b60208210811415620002ad57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e0516101005161012051611f82620003036000396000610e7c0152600061139b015260006113ea015260006113c501526000611349015260006113720152611f826000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c8063715018a6116100f9578063b4b5ea5711610097578063dd62ed3e11610071578063dd62ed3e14610407578063e7a324dc14610440578063f1127ed814610467578063f2fde38b146104be57600080fd5b8063b4b5ea57146103ce578063c3cda520146103e1578063d505accf146103f457600080fd5b80638da5cb5b116100d35780638da5cb5b1461038f57806395d89b41146103a0578063a457c2d7146103a8578063a9059cbb146103bb57600080fd5b8063715018a614610361578063782d6fe1146103695780637ecebe001461037c57600080fd5b80633644e51511610166578063587cde1e11610140578063587cde1e146102a65780635c19a95c146102ea5780636fcfff45146102fd57806370a082311461033857600080fd5b80633644e51514610276578063395093511461027e57806340c10f191461029157600080fd5b806320606b70116101a257806320606b701461021c57806323b872dd14610243578063313ce5671461025657806332cb6b0c1461026557600080fd5b806306fdde03146101c9578063095ea7b3146101e757806318160ddd1461020a575b600080fd5b6101d16104d1565b6040516101de9190611d9b565b60405180910390f35b6101fa6101f5366004611cdd565b610563565b60405190151581526020016101de565b6002545b6040519081526020016101de565b61020e7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6101fa610251366004611c39565b61057a565b604051601281526020016101de565b61020e6923ffb7ed6565d640000081565b61020e61062b565b6101fa61028c366004611cdd565b61063a565b6102a461029f366004611cdd565b610676565b005b6102d26102b4366004611bed565b6001600160a01b039081166000908152600760205260409020541690565b6040516001600160a01b0390911681526020016101de565b6102a46102f8366004611bed565b6106fa565b61032361030b366004611bed565b60096020526000908152604090205463ffffffff1681565b60405163ffffffff90911681526020016101de565b61020e610346366004611bed565b6001600160a01b031660009081526020819052604090205490565b6102a4610707565b61020e610377366004611cdd565b61073d565b61020e61038a366004611bed565b6109a1565b6006546001600160a01b03166102d2565b6101d16109bf565b6101fa6103b6366004611cdd565b6109ce565b6101fa6103c9366004611cdd565b610a67565b61020e6103dc366004611bed565b610b08565b6102a46103ef366004611d06565b610b7c565b6102a4610402366004611c74565b610e28565b61020e610415366004611c07565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b61020e7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b6104a2610475366004611d5d565b60086020908152600092835260408084209091529082529020805460019091015463ffffffff9091169082565b6040805163ffffffff90931683526020830191909152016101de565b6102a46104cc366004611bed565b610f80565b6060600380546104e090611ece565b80601f016020809104026020016040519081016040528092919081815260200182805461050c90611ece565b80156105595780601f1061052e57610100808354040283529160200191610559565b820191906000526020600020905b81548152906001019060200180831161053c57829003601f168201915b5050505050905090565b6000610570338484611018565b5060015b92915050565b600063614e20304210156106095773dc96806e7933dff4d025c70336ec2c3befd94c0b6001600160a01b03841614806105cf575073dc96806e7933dff4d025c70336ec2c3befd94c0b6001600160a01b038516145b6106095760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b60448201526064015b60405180910390fd5b600061061685858561113c565b90506106238585856111e6565b949350505050565b6000610635611345565b905090565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610570918590610671908690611e23565b611018565b6006546001600160a01b031633146106a05760405162461bcd60e51b815260040161060090611dee565b60006106bf6106ae60025490565b6923ffb7ed6565d640000090611438565b9050808211156106e4576106d38382611444565b6106df600084836111e6565b505050565b6106ee8383611444565b6106df600084846111e6565b6107043382611523565b50565b6006546001600160a01b031633146107315760405162461bcd60e51b815260040161060090611dee565b61073b60006115a2565b565b600043821061079d5760405162461bcd60e51b815260206004820152602660248201527f5a4f4e3a3a6765745072696f72566f7465733a206e6f742079657420646574656044820152651c9b5a5b995960d21b6064820152608401610600565b6001600160a01b03831660009081526009602052604090205463ffffffff16806107cb576000915050610574565b6001600160a01b038416600090815260086020526040812084916107f0600185611ea9565b63ffffffff90811682526020820192909252604001600020541611610859576001600160a01b038416600090815260086020526040812090610833600184611ea9565b63ffffffff1663ffffffff16815260200190815260200160002060010154915050610574565b6001600160a01b038416600090815260086020908152604080832083805290915290205463ffffffff16831015610894576000915050610574565b6000806108a2600184611ea9565b90505b8163ffffffff168163ffffffff16111561096a57600060026108c78484611ea9565b6108d19190611e63565b6108db9083611ea9565b6001600160a01b038816600090815260086020908152604080832063ffffffff808616855290835292819020815180830190925280549093168082526001909301549181019190915291925087141561093e576020015194506105749350505050565b805163ffffffff1687111561095557819350610963565b610960600183611ea9565b92505b50506108a5565b506001600160a01b038516600090815260086020908152604080832063ffffffff9094168352929052206001015491505092915050565b6001600160a01b038116600090815260056020526040812054610574565b6060600480546104e090611ece565b3360009081526001602090815260408083206001600160a01b038616845290915281205482811015610a505760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610600565b610a5d3385858403611018565b5060019392505050565b600063614e2030421015610ae85773dc96806e7933dff4d025c70336ec2c3befd94c0b6001600160a01b0384161480610ab3575073dc96806e7933dff4d025c70336ec2c3befd94c0b33145b610ae85760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b6044820152606401610600565b6000610af484846115f4565b9050610b013385856111e6565b9392505050565b6001600160a01b03811660009081526009602052604081205463ffffffff1680610b33576000610b01565b6001600160a01b038316600090815260086020526040812090610b57600184611ea9565b63ffffffff1663ffffffff168152602001908152602001600020600101549392505050565b60007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866610ba76104d1565b80519060200120610bb54690565b60408051602080820195909552808201939093526060830191909152306080808401919091528151808403909101815260a0830182528051908401207fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60c08401526001600160a01b038b1660e084015261010083018a90526101208084018a90528251808503909101815261014084019092528151919093012061190160f01b610160830152610162820183905261018282018190529192506000906101a20160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa158015610ce1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610d525760405162461bcd60e51b815260206004820152602560248201527f5a4f4e3a3a64656c656761746542795369673a20696e76616c6964207369676e604482015264617475726560d81b6064820152608401610600565b610d5b81611601565b8914610db35760405162461bcd60e51b815260206004820152602160248201527f5a4f4e3a3a64656c656761746542795369673a20696e76616c6964206e6f6e636044820152606560f81b6064820152608401610600565b87421115610e115760405162461bcd60e51b815260206004820152602560248201527f5a4f4e3a3a64656c656761746542795369673a207369676e61747572652065786044820152641c1a5c995960da1b6064820152608401610600565b610e1b818b611523565b505050505b505050505050565b83421115610e785760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610600565b60007f0000000000000000000000000000000000000000000000000000000000000000888888610ea78c611601565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610f0282611629565b90506000610f1282878787611677565b9050896001600160a01b0316816001600160a01b031614610f755760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610600565b610e1b8a8a8a611018565b6006546001600160a01b03163314610faa5760405162461bcd60e51b815260040161060090611dee565b6001600160a01b03811661100f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610600565b610704816115a2565b6001600160a01b03831661107a5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610600565b6001600160a01b0382166110db5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610600565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000611149848484611820565b6001600160a01b0384166000908152600160209081526040808320338452909152902054828110156111ce5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b6064820152608401610600565b6111db8533858403611018565b506001949350505050565b816001600160a01b0316836001600160a01b0316141580156112085750600081115b156106df576001600160a01b038316156112ab576001600160a01b03831660009081526009602052604081205463ffffffff16908161124857600061128b565b6001600160a01b03851660009081526008602052604081209061126c600185611ea9565b63ffffffff1663ffffffff168152602001908152602001600020600101545b905060006112998483611e92565b90506112a7868484846119ee565b5050505b6001600160a01b038216156106df576001600160a01b03821660009081526009602052604081205463ffffffff1690816112e6576000611329565b6001600160a01b03841660009081526008602052604081209061130a600185611ea9565b63ffffffff1663ffffffff168152602001908152602001600020600101545b905060006113378483611e23565b9050610e20858484846119ee565b60007f000000000000000000000000000000000000000000000000000000000000000046141561139457507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b6000610b018284611e92565b6001600160a01b03821661149a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610600565b80600260008282546114ac9190611e23565b90915550506001600160a01b038216600090815260208190526040812080548392906114d9908490611e23565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038281166000818152600760208181526040808420805485845282862054949093528787166001600160a01b03198416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a461159c8284836111e6565b50505050565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610570338484611820565b6001600160a01b03811660009081526005602052604090208054600181018255905b50919050565b6000610574611636611345565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08211156116f45760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610600565b8360ff16601b148061170957508360ff16601c145b6117605760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610600565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa1580156117b4573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166118175760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610600565b95945050505050565b6001600160a01b0383166118845760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610600565b6001600160a01b0382166118e65760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610600565b6001600160a01b0383166000908152602081905260409020548181101561195e5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610600565b6001600160a01b03808516600090815260208190526040808220858503905591851681529081208054849290611995908490611e23565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516119e191815260200190565b60405180910390a361159c565b6000611a1243604051806060016040528060338152602001611f1a60339139611b90565b905060008463ffffffff16118015611a6c57506001600160a01b038516600090815260086020526040812063ffffffff831691611a50600188611ea9565b63ffffffff908116825260208201929092526040016000205416145b15611ab5576001600160a01b03851660009081526008602052604081208391611a96600188611ea9565b63ffffffff168152602081019190915260400160002060010155611b45565b60408051808201825263ffffffff838116825260208083018681526001600160a01b038a166000908152600883528581208a851682529092529390209151825463ffffffff191691161781559051600191820155611b14908590611e3b565b6001600160a01b0386166000908152600960205260409020805463ffffffff191663ffffffff929092169190911790555b60408051848152602081018490526001600160a01b038716917fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724910160405180910390a25050505050565b6000816401000000008410611bb85760405162461bcd60e51b81526004016106009190611d9b565b509192915050565b80356001600160a01b0381168114611bd757600080fd5b919050565b803560ff81168114611bd757600080fd5b600060208284031215611bfe578081fd5b610b0182611bc0565b60008060408385031215611c19578081fd5b611c2283611bc0565b9150611c3060208401611bc0565b90509250929050565b600080600060608486031215611c4d578081fd5b611c5684611bc0565b9250611c6460208501611bc0565b9150604084013590509250925092565b600080600080600080600060e0888a031215611c8e578283fd5b611c9788611bc0565b9650611ca560208901611bc0565b95506040880135945060608801359350611cc160808901611bdc565b925060a0880135915060c0880135905092959891949750929550565b60008060408385031215611cef578182fd5b611cf883611bc0565b946020939093013593505050565b60008060008060008060c08789031215611d1e578182fd5b611d2787611bc0565b95506020870135945060408701359350611d4360608801611bdc565b92506080870135915060a087013590509295509295509295565b60008060408385031215611d6f578182fd5b611d7883611bc0565b9150602083013563ffffffff81168114611d90578182fd5b809150509250929050565b6000602080835283518082850152825b81811015611dc757858101830151858201604001528201611dab565b81811115611dd85783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60008219821115611e3657611e36611f03565b500190565b600063ffffffff808316818516808303821115611e5a57611e5a611f03565b01949350505050565b600063ffffffff80841680611e8657634e487b7160e01b83526012600452602483fd5b92169190910492915050565b600082821015611ea457611ea4611f03565b500390565b600063ffffffff83811690831681811015611ec657611ec6611f03565b039392505050565b600181811c90821680611ee257607f821691505b6020821081141561162357634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fdfe5a4f4e3a3a5f7772697465436865636b706f696e743a20626c6f636b206e756d62657220657863656564732033322062697473a26469706673582212207df15a1377325f17720fafc220605045deef4ff0e0777b13bc84ed60cac1b03e64736f6c63430008040033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101c45760003560e01c8063715018a6116100f9578063b4b5ea5711610097578063dd62ed3e11610071578063dd62ed3e14610407578063e7a324dc14610440578063f1127ed814610467578063f2fde38b146104be57600080fd5b8063b4b5ea57146103ce578063c3cda520146103e1578063d505accf146103f457600080fd5b80638da5cb5b116100d35780638da5cb5b1461038f57806395d89b41146103a0578063a457c2d7146103a8578063a9059cbb146103bb57600080fd5b8063715018a614610361578063782d6fe1146103695780637ecebe001461037c57600080fd5b80633644e51511610166578063587cde1e11610140578063587cde1e146102a65780635c19a95c146102ea5780636fcfff45146102fd57806370a082311461033857600080fd5b80633644e51514610276578063395093511461027e57806340c10f191461029157600080fd5b806320606b70116101a257806320606b701461021c57806323b872dd14610243578063313ce5671461025657806332cb6b0c1461026557600080fd5b806306fdde03146101c9578063095ea7b3146101e757806318160ddd1461020a575b600080fd5b6101d16104d1565b6040516101de9190611d9b565b60405180910390f35b6101fa6101f5366004611cdd565b610563565b60405190151581526020016101de565b6002545b6040519081526020016101de565b61020e7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6101fa610251366004611c39565b61057a565b604051601281526020016101de565b61020e6923ffb7ed6565d640000081565b61020e61062b565b6101fa61028c366004611cdd565b61063a565b6102a461029f366004611cdd565b610676565b005b6102d26102b4366004611bed565b6001600160a01b039081166000908152600760205260409020541690565b6040516001600160a01b0390911681526020016101de565b6102a46102f8366004611bed565b6106fa565b61032361030b366004611bed565b60096020526000908152604090205463ffffffff1681565b60405163ffffffff90911681526020016101de565b61020e610346366004611bed565b6001600160a01b031660009081526020819052604090205490565b6102a4610707565b61020e610377366004611cdd565b61073d565b61020e61038a366004611bed565b6109a1565b6006546001600160a01b03166102d2565b6101d16109bf565b6101fa6103b6366004611cdd565b6109ce565b6101fa6103c9366004611cdd565b610a67565b61020e6103dc366004611bed565b610b08565b6102a46103ef366004611d06565b610b7c565b6102a4610402366004611c74565b610e28565b61020e610415366004611c07565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b61020e7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b6104a2610475366004611d5d565b60086020908152600092835260408084209091529082529020805460019091015463ffffffff9091169082565b6040805163ffffffff90931683526020830191909152016101de565b6102a46104cc366004611bed565b610f80565b6060600380546104e090611ece565b80601f016020809104026020016040519081016040528092919081815260200182805461050c90611ece565b80156105595780601f1061052e57610100808354040283529160200191610559565b820191906000526020600020905b81548152906001019060200180831161053c57829003601f168201915b5050505050905090565b6000610570338484611018565b5060015b92915050565b600063614e20304210156106095773dc96806e7933dff4d025c70336ec2c3befd94c0b6001600160a01b03841614806105cf575073dc96806e7933dff4d025c70336ec2c3befd94c0b6001600160a01b038516145b6106095760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b60448201526064015b60405180910390fd5b600061061685858561113c565b90506106238585856111e6565b949350505050565b6000610635611345565b905090565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610570918590610671908690611e23565b611018565b6006546001600160a01b031633146106a05760405162461bcd60e51b815260040161060090611dee565b60006106bf6106ae60025490565b6923ffb7ed6565d640000090611438565b9050808211156106e4576106d38382611444565b6106df600084836111e6565b505050565b6106ee8383611444565b6106df600084846111e6565b6107043382611523565b50565b6006546001600160a01b031633146107315760405162461bcd60e51b815260040161060090611dee565b61073b60006115a2565b565b600043821061079d5760405162461bcd60e51b815260206004820152602660248201527f5a4f4e3a3a6765745072696f72566f7465733a206e6f742079657420646574656044820152651c9b5a5b995960d21b6064820152608401610600565b6001600160a01b03831660009081526009602052604090205463ffffffff16806107cb576000915050610574565b6001600160a01b038416600090815260086020526040812084916107f0600185611ea9565b63ffffffff90811682526020820192909252604001600020541611610859576001600160a01b038416600090815260086020526040812090610833600184611ea9565b63ffffffff1663ffffffff16815260200190815260200160002060010154915050610574565b6001600160a01b038416600090815260086020908152604080832083805290915290205463ffffffff16831015610894576000915050610574565b6000806108a2600184611ea9565b90505b8163ffffffff168163ffffffff16111561096a57600060026108c78484611ea9565b6108d19190611e63565b6108db9083611ea9565b6001600160a01b038816600090815260086020908152604080832063ffffffff808616855290835292819020815180830190925280549093168082526001909301549181019190915291925087141561093e576020015194506105749350505050565b805163ffffffff1687111561095557819350610963565b610960600183611ea9565b92505b50506108a5565b506001600160a01b038516600090815260086020908152604080832063ffffffff9094168352929052206001015491505092915050565b6001600160a01b038116600090815260056020526040812054610574565b6060600480546104e090611ece565b3360009081526001602090815260408083206001600160a01b038616845290915281205482811015610a505760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610600565b610a5d3385858403611018565b5060019392505050565b600063614e2030421015610ae85773dc96806e7933dff4d025c70336ec2c3befd94c0b6001600160a01b0384161480610ab3575073dc96806e7933dff4d025c70336ec2c3befd94c0b33145b610ae85760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b6044820152606401610600565b6000610af484846115f4565b9050610b013385856111e6565b9392505050565b6001600160a01b03811660009081526009602052604081205463ffffffff1680610b33576000610b01565b6001600160a01b038316600090815260086020526040812090610b57600184611ea9565b63ffffffff1663ffffffff168152602001908152602001600020600101549392505050565b60007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866610ba76104d1565b80519060200120610bb54690565b60408051602080820195909552808201939093526060830191909152306080808401919091528151808403909101815260a0830182528051908401207fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60c08401526001600160a01b038b1660e084015261010083018a90526101208084018a90528251808503909101815261014084019092528151919093012061190160f01b610160830152610162820183905261018282018190529192506000906101a20160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa158015610ce1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610d525760405162461bcd60e51b815260206004820152602560248201527f5a4f4e3a3a64656c656761746542795369673a20696e76616c6964207369676e604482015264617475726560d81b6064820152608401610600565b610d5b81611601565b8914610db35760405162461bcd60e51b815260206004820152602160248201527f5a4f4e3a3a64656c656761746542795369673a20696e76616c6964206e6f6e636044820152606560f81b6064820152608401610600565b87421115610e115760405162461bcd60e51b815260206004820152602560248201527f5a4f4e3a3a64656c656761746542795369673a207369676e61747572652065786044820152641c1a5c995960da1b6064820152608401610600565b610e1b818b611523565b505050505b505050505050565b83421115610e785760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610600565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610ea78c611601565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610f0282611629565b90506000610f1282878787611677565b9050896001600160a01b0316816001600160a01b031614610f755760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610600565b610e1b8a8a8a611018565b6006546001600160a01b03163314610faa5760405162461bcd60e51b815260040161060090611dee565b6001600160a01b03811661100f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610600565b610704816115a2565b6001600160a01b03831661107a5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610600565b6001600160a01b0382166110db5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610600565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000611149848484611820565b6001600160a01b0384166000908152600160209081526040808320338452909152902054828110156111ce5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b6064820152608401610600565b6111db8533858403611018565b506001949350505050565b816001600160a01b0316836001600160a01b0316141580156112085750600081115b156106df576001600160a01b038316156112ab576001600160a01b03831660009081526009602052604081205463ffffffff16908161124857600061128b565b6001600160a01b03851660009081526008602052604081209061126c600185611ea9565b63ffffffff1663ffffffff168152602001908152602001600020600101545b905060006112998483611e92565b90506112a7868484846119ee565b5050505b6001600160a01b038216156106df576001600160a01b03821660009081526009602052604081205463ffffffff1690816112e6576000611329565b6001600160a01b03841660009081526008602052604081209061130a600185611ea9565b63ffffffff1663ffffffff168152602001908152602001600020600101545b905060006113378483611e23565b9050610e20858484846119ee565b60007f00000000000000000000000000000000000000000000000000000000000000fa46141561139457507fdfb0a146a2fc2c3032248997932041a4baf52548727422be9d3eab353d175a3b90565b50604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527f3f1abb26940545c2809302cfaebb1d77b05f1ffda9afee1eedce900715a7ac5b828401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b6000610b018284611e92565b6001600160a01b03821661149a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610600565b80600260008282546114ac9190611e23565b90915550506001600160a01b038216600090815260208190526040812080548392906114d9908490611e23565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038281166000818152600760208181526040808420805485845282862054949093528787166001600160a01b03198416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a461159c8284836111e6565b50505050565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610570338484611820565b6001600160a01b03811660009081526005602052604090208054600181018255905b50919050565b6000610574611636611345565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08211156116f45760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610600565b8360ff16601b148061170957508360ff16601c145b6117605760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610600565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa1580156117b4573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166118175760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610600565b95945050505050565b6001600160a01b0383166118845760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610600565b6001600160a01b0382166118e65760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610600565b6001600160a01b0383166000908152602081905260409020548181101561195e5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610600565b6001600160a01b03808516600090815260208190526040808220858503905591851681529081208054849290611995908490611e23565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516119e191815260200190565b60405180910390a361159c565b6000611a1243604051806060016040528060338152602001611f1a60339139611b90565b905060008463ffffffff16118015611a6c57506001600160a01b038516600090815260086020526040812063ffffffff831691611a50600188611ea9565b63ffffffff908116825260208201929092526040016000205416145b15611ab5576001600160a01b03851660009081526008602052604081208391611a96600188611ea9565b63ffffffff168152602081019190915260400160002060010155611b45565b60408051808201825263ffffffff838116825260208083018681526001600160a01b038a166000908152600883528581208a851682529092529390209151825463ffffffff191691161781559051600191820155611b14908590611e3b565b6001600160a01b0386166000908152600960205260409020805463ffffffff191663ffffffff929092169190911790555b60408051848152602081018490526001600160a01b038716917fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724910160405180910390a25050505050565b6000816401000000008410611bb85760405162461bcd60e51b81526004016106009190611d9b565b509192915050565b80356001600160a01b0381168114611bd757600080fd5b919050565b803560ff81168114611bd757600080fd5b600060208284031215611bfe578081fd5b610b0182611bc0565b60008060408385031215611c19578081fd5b611c2283611bc0565b9150611c3060208401611bc0565b90509250929050565b600080600060608486031215611c4d578081fd5b611c5684611bc0565b9250611c6460208501611bc0565b9150604084013590509250925092565b600080600080600080600060e0888a031215611c8e578283fd5b611c9788611bc0565b9650611ca560208901611bc0565b95506040880135945060608801359350611cc160808901611bdc565b925060a0880135915060c0880135905092959891949750929550565b60008060408385031215611cef578182fd5b611cf883611bc0565b946020939093013593505050565b60008060008060008060c08789031215611d1e578182fd5b611d2787611bc0565b95506020870135945060408701359350611d4360608801611bdc565b92506080870135915060a087013590509295509295509295565b60008060408385031215611d6f578182fd5b611d7883611bc0565b9150602083013563ffffffff81168114611d90578182fd5b809150509250929050565b6000602080835283518082850152825b81811015611dc757858101830151858201604001528201611dab565b81811115611dd85783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60008219821115611e3657611e36611f03565b500190565b600063ffffffff808316818516808303821115611e5a57611e5a611f03565b01949350505050565b600063ffffffff80841680611e8657634e487b7160e01b83526012600452602483fd5b92169190910492915050565b600082821015611ea457611ea4611f03565b500390565b600063ffffffff83811690831681811015611ec657611ec6611f03565b039392505050565b600181811c90821680611ee257607f821691505b6020821081141561162357634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fdfe5a4f4e3a3a5f7772697465436865636b706f696e743a20626c6f636b206e756d62657220657863656564732033322062697473a26469706673582212207df15a1377325f17720fafc220605045deef4ff0e0777b13bc84ed60cac1b03e64736f6c63430008040033
Deployed Bytecode Sourcemap
50240:9972:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30708:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32875:169;;;;;;:::i;:::-;;:::i;:::-;;;3753:14:1;;3746:22;3728:41;;3716:2;3701:18;32875:169:0;3683:92:1;31828:108:0;31916:12;;31828:108;;;3926:25:1;;;3914:2;3899:18;31828:108:0;3881:76:1;51873:131:0;;51924:80;51873:131;;52731:595;;;;;;:::i;:::-;;:::i;31670:93::-;;;31753:2;15748:36:1;;15736:2;15721:18;31670:93:0;15703:87:1;50433:46:0;;50470:9;50433:46;;49882:106;;;:::i;34427:215::-;;;;;;:::i;:::-;;:::i;50488:380::-;;;;;;:::i;:::-;;:::i;:::-;;53957:117;;;;;;:::i;:::-;-1:-1:-1;;;;;54045:21:0;;;54018:7;54045:21;;;:10;:21;;;;;;;;53957:117;;;;-1:-1:-1;;;;;3544:32:1;;;;3526:51;;3514:2;3499:18;53957:117:0;3481:102:1;54222:104:0;;;;;;:::i;:::-;;:::i;51752:48::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;15315:10:1;15303:23;;;15285:42;;15273:2;15258:18;51752:48:0;15240:93:1;31999:127:0;;;;;;:::i;:::-;-1:-1:-1;;;;;32100:18:0;32073:7;32100:18;;;;;;;;;;;;31999:127;2602:94;;;:::i;56515:1223::-;;;;;;:::i;:::-;;:::i;49755:119::-;;;;;;:::i;:::-;;:::i;1951:87::-;2024:6;;-1:-1:-1;;;;;2024:6:0;1951:87;;30927:104;;;:::i;35145:413::-;;;;;;:::i;:::-;;:::i;53334:539::-;;;;;;:::i;:::-;;:::i;55861:223::-;;;;;;:::i;:::-;;:::i;54760:900::-;;;;;;:::i;:::-;;:::i;49056:691::-;;;;;;:::i;:::-;;:::i;32577:151::-;;;;;;:::i;:::-;-1:-1:-1;;;;;32693:18:0;;;32666:7;32693:18;;;-1:-1:-1;32693:18:0;;;;;;;;:27;;;;;;;;;;;;;32577:151;52098:126;;52153:71;52098:126;;51615:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15540:10:1;15528:23;;;15510:42;;15583:2;15568:18;;15561:34;;;;15483:18;51615:68:0;15465:136:1;2851:192:0;;;;;;:::i;:::-;;:::i;30708:100::-;30762:13;30795:5;30788:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30708:100;:::o;32875:169::-;32958:4;32975:39;749:10;32998:7;33007:6;32975:8;:39::i;:::-;-1:-1:-1;33032:4:0;32875:169;;;;;:::o;52731:595::-;52871:4;52910:10;52892:15;:28;52888:261;;;-1:-1:-1;;;;;52963:55:0;;52976:42;52963:55;;:132;;-1:-1:-1;;;;;;53043:52:0;;53053:42;53043:52;52963:132;52937:200;;;;-1:-1:-1;;;52937:200:0;;12595:2:1;52937:200:0;;;12577:21:1;12634:1;12614:18;;;12607:29;-1:-1:-1;;;12652:18:1;;;12645:36;12698:18;;52937:200:0;;;;;;;;;53161:11;53175:45;53194:6;53202:9;53213:6;53175:18;:45::i;:::-;53161:59;;53251:41;53266:6;53274:9;53285:6;53251:14;:41::i;:::-;53312:6;52731:595;-1:-1:-1;;;;52731:595:0:o;49882:106::-;49933:7;49960:20;:18;:20::i;:::-;49953:27;;49882:106;:::o;34427:215::-;749:10;34515:4;34564:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;34564:34:0;;;;;;;;;;34515:4;;34532:80;;34564:34;;:47;;34601:10;;34564:47;:::i;:::-;34532:8;:80::i;50488:380::-;2024:6;;-1:-1:-1;;;;;2024:6:0;749:10;2171:23;2163:68;;;;-1:-1:-1;;;2163:68:0;;;;;;;:::i;:::-;50563:14:::1;50580:29;50595:13;31916:12:::0;;;31828:108;50595:13:::1;50470:9;::::0;50580:14:::1;:29::i;:::-;50563:46;;50633:6;50624;:15;50620:241;;;50656:22;50662:7;50671:6;50656:5;:22::i;:::-;50693:43;50716:1;50720:7;50729:6;50693:14;:43::i;:::-;2242:1;50488:380:::0;;:::o;50620:241::-:1;50769:22;50775:7;50784:6;50769:5;:22::i;:::-;50806:43;50829:1;50833:7;50842:6;50806:14;:43::i;54222:104::-:0;54286:32;54296:10;54308:9;54286;:32::i;:::-;54222:104;:::o;2602:94::-;2024:6;;-1:-1:-1;;;;;2024:6:0;749:10;2171:23;2163:68;;;;-1:-1:-1;;;2163:68:0;;;;;;;:::i;:::-;2667:21:::1;2685:1;2667:9;:21::i;:::-;2602:94::o:0;56515:1223::-;56599:7;56641:12;56627:11;:26;56619:77;;;;-1:-1:-1;;;56619:77:0;;12188:2:1;56619:77:0;;;12170:21:1;12227:2;12207:18;;;12200:30;12266:34;12246:18;;;12239:62;-1:-1:-1;;;12317:18:1;;;12310:36;12363:19;;56619:77:0;12160:228:1;56619:77:0;-1:-1:-1;;;;;56731:23:0;;56709:19;56731:23;;;:14;:23;;;;;;;;;56765:58;;56810:1;56803:8;;;;;56765:58;-1:-1:-1;;;;;56883:20:0;;;;;;:11;:20;;;;;56935:11;;56904:16;-1:-1:-1;56904:12:0;:16;:::i;:::-;56883:38;;;;;;;;;;;;;;;-1:-1:-1;56883:38:0;:48;;:63;56879:147;;-1:-1:-1;;;;;56970:20:0;;;;;;:11;:20;;;;;;56991:16;-1:-1:-1;56991:12:0;:16;:::i;:::-;56970:38;;;;;;;;;;;;;;;:44;;;56963:51;;;;;56879:147;-1:-1:-1;;;;;57087:20:0;;;;;;:11;:20;;;;;;;;:23;;;;;;;;:33;:23;:33;-1:-1:-1;;57083:88:0;;;57158:1;57151:8;;;;;57083:88;57183:12;;57225:16;57240:1;57225:12;:16;:::i;:::-;57210:31;;57252:428;57267:5;57259:13;;:5;:13;;;57252:428;;;57289:13;57331:1;57314:13;57322:5;57314;:13;:::i;:::-;57313:19;;;;:::i;:::-;57305:27;;:5;:27;:::i;:::-;-1:-1:-1;;;;;57397:20:0;;57374;57397;;;:11;:20;;;;;;;;:28;;;;;;;;;;;;;57374:51;;;;;;;;;;;;;;;;-1:-1:-1;57374:51:0;;;;;;;;;;;57397:28;;-1:-1:-1;57444:27:0;;57440:229;;;57499:8;;;;-1:-1:-1;57492:15:0;;-1:-1:-1;;;;57492:15:0;57440:229;57533:12;;:26;;;-1:-1:-1;57529:140:0;;;57588:6;57580:14;;57529:140;;;57643:10;57652:1;57643:6;:10;:::i;:::-;57635:18;;57529:140;57252:428;;;;;-1:-1:-1;;;;;;57697:20:0;;;;;;:11;:20;;;;;;;;:27;;;;;;;;;;:33;;;;-1:-1:-1;;56515:1223:0;;;;:::o;49755:119::-;-1:-1:-1;;;;;49842:14:0;;49815:7;49842:14;;;:7;:14;;;;;45692;49842:24;45600:114;30927:104;30983:13;31016:7;31009:14;;;;;:::i;35145:413::-;749:10;35238:4;35282:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;35282:34:0;;;;;;;;;;35335:35;;;;35327:85;;;;-1:-1:-1;;;35327:85:0;;14142:2:1;35327:85:0;;;14124:21:1;14181:2;14161:18;;;14154:30;14220:34;14200:18;;;14193:62;-1:-1:-1;;;14271:18:1;;;14264:35;14316:19;;35327:85:0;14114:227:1;35327:85:0;35448:67;749:10;35471:7;35499:15;35480:16;:34;35448:8;:67::i;:::-;-1:-1:-1;35546:4:0;;35145:413;-1:-1:-1;;;35145:413:0:o;53334:539::-;53420:4;53459:10;53441:15;:28;53437:265;;;-1:-1:-1;;;;;53512:55:0;;53525:42;53512:55;;:136;;-1:-1:-1;53606:42:0;53592:10;:56;53512:136;53486:204;;;;-1:-1:-1;;;53486:204:0;;12595:2:1;53486:204:0;;;12577:21:1;12634:1;12614:18;;;12607:29;-1:-1:-1;;;12652:18:1;;;12645:36;12698:18;;53486:204:0;12567:155:1;53486:204:0;53714:11;53728:33;53743:9;53754:6;53728:14;:33::i;:::-;53714:47;-1:-1:-1;53792:47:0;749:10;53821:9;53832:6;53792:14;:47::i;:::-;53859:6;53334:539;-1:-1:-1;;;53334:539:0:o;55861:223::-;-1:-1:-1;;;;;55968:23:0;;55926:7;55968:23;;;:14;:23;;;;;;;;;56009:67;;56075:1;56009:67;;;-1:-1:-1;;;;;56028:20:0;;;;;;:11;:20;;;;;;56049:16;-1:-1:-1;56049:12:0;:16;:::i;:::-;56028:38;;;;;;;;;;;;;;;:44;;;56002:74;55861:223;-1:-1:-1;;;55861:223:0:o;54760:900::-;54945:23;51924:80;55039:6;:4;:6::i;:::-;55023:24;;;;;;55049:12;60157:9;;60031:178;55049:12;54995:82;;;;;;;5705:25:1;;;;5746:18;;;5739:34;;;;5789:18;;;5782:34;;;;55071:4:0;5832:18:1;;;;5825:60;;;;54995:82:0;;;;;;;;;;5677:19:1;;;54995:82:0;;54971:117;;;;;;52153:71;55132:57;;;4789:25:1;-1:-1:-1;;;;;4850:32:1;;4830:18;;;4823:60;4899:18;;;4892:34;;;4942:18;;;;4935:34;;;55132:57:0;;;;;;;;;;4761:19:1;;;55132:57:0;;55122:68;;;;;;-1:-1:-1;;;55230:57:0;;;3241:27:1;3284:11;;;3277:27;;;3320:12;;;;3313:28;;;55230:57:0;;;;;;;;;;3357:12:1;;;55230:57:0;;;55220:68;;;;;;;;;-1:-1:-1;55321:26:0;;;;;;;;;;6123:25:1;;;6196:4;6184:17;;6164:18;;;6157:45;6218:18;;;6211:34;;;6261:18;;;6254:34;;;55321:26:0;;54971:117;;-1:-1:-1;55122:68:0;;55220;;-1:-1:-1;;;;6095:19:1;;;;;-1:-1:-1;;55321:26:0;;;;;;;;;;;-1:-1:-1;55321:26:0;;;;;;;;;;;;;;;-1:-1:-1;;55321:26:0;;-1:-1:-1;;55321:26:0;;;-1:-1:-1;;;;;;;55366:23:0;;55358:73;;;;-1:-1:-1;;;55358:73:0;;10250:2:1;55358:73:0;;;10232:21:1;10289:2;10269:18;;;10262:30;10328:34;10308:18;;;10301:62;-1:-1:-1;;;10379:18:1;;;10372:35;10424:19;;55358:73:0;10222:227:1;55358:73:0;55459:20;55469:9;55459;:20::i;:::-;55450:5;:29;55442:75;;;;-1:-1:-1;;;55442:75:0;;13740:2:1;55442:75:0;;;13722:21:1;13779:2;13759:18;;;13752:30;13818:34;13798:18;;;13791:62;-1:-1:-1;;;13869:18:1;;;13862:31;13910:19;;55442:75:0;13712:223:1;55442:75:0;55555:6;55536:15;:25;;55528:75;;;;-1:-1:-1;;;55528:75:0;;8676:2:1;55528:75:0;;;8658:21:1;8715:2;8695:18;;;8688:30;8754:34;8734:18;;;8727:62;-1:-1:-1;;;8805:18:1;;;8798:35;8850:19;;55528:75:0;8648:227:1;55528:75:0;55621:31;55631:9;55642;55621;:31::i;:::-;55614:38;;;;54760:900;;;;;;;:::o;49056:691::-;49346:8;49327:15;:27;;49319:69;;;;-1:-1:-1;;;49319:69:0;;9082:2:1;49319:69:0;;;9064:21:1;9121:2;9101:18;;;9094:30;9160:31;9140:18;;;9133:59;9209:18;;49319:69:0;9054:179:1;49319:69:0;49401:18;49443:16;49461:5;49468:7;49477:5;49484:16;49494:5;49484:9;:16::i;:::-;49432:79;;;;;;4249:25:1;;;;-1:-1:-1;;;;;4348:15:1;;;4328:18;;;4321:43;4400:15;;;;4380:18;;;4373:43;4432:18;;;4425:34;4475:19;;;4468:35;4519:19;;;4512:35;;;4221:19;;49432:79:0;;;;;;;;;;;;49422:90;;;;;;49401:111;;49525:12;49540:28;49557:10;49540:16;:28::i;:::-;49525:43;;49581:14;49598:28;49612:4;49618:1;49621;49624;49598:13;:28::i;:::-;49581:45;-1:-1:-1;;;;;;49645:15:0;;;;;;;49637:58;;;;-1:-1:-1;;;49637:58:0;;11059:2:1;49637:58:0;;;11041:21:1;11098:2;11078:18;;;11071:30;11137:32;11117:18;;;11110:60;11187:18;;49637:58:0;11031:180:1;49637:58:0;49708:31;49717:5;49724:7;49733:5;49708:8;:31::i;2851:192::-;2024:6;;-1:-1:-1;;;;;2024:6:0;749:10;2171:23;2163:68;;;;-1:-1:-1;;;2163:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;2940:22:0;::::1;2932:73;;;::::0;-1:-1:-1;;;2932:73:0;;7866:2:1;2932:73:0::1;::::0;::::1;7848:21:1::0;7905:2;7885:18;;;7878:30;7944:34;7924:18;;;7917:62;-1:-1:-1;;;7995:18:1;;;7988:36;8041:19;;2932:73:0::1;7838:228:1::0;2932:73:0::1;3016:19;3026:8;3016:9;:19::i;38829:380::-:0;-1:-1:-1;;;;;38965:19:0;;38957:68;;;;-1:-1:-1;;;38957:68:0;;13335:2:1;38957:68:0;;;13317:21:1;13374:2;13354:18;;;13347:30;13413:34;13393:18;;;13386:62;-1:-1:-1;;;13464:18:1;;;13457:34;13508:19;;38957:68:0;13307:226:1;38957:68:0;-1:-1:-1;;;;;39044:21:0;;39036:68;;;;-1:-1:-1;;;39036:68:0;;8273:2:1;39036:68:0;;;8255:21:1;8312:2;8292:18;;;8285:30;8351:34;8331:18;;;8324:62;-1:-1:-1;;;8402:18:1;;;8395:32;8444:19;;39036:68:0;8245:224:1;39036:68:0;-1:-1:-1;;;;;39117:18:0;;;;;;;-1:-1:-1;39117:18:0;;;;;;;;:27;;;;;;;;;;;;;:36;;;39169:32;;3926:25:1;;;39169:32:0;;;;;;;;;;;;38829:380;;;:::o;33526:492::-;33666:4;33683:36;33693:6;33701:9;33712:6;33683:9;:36::i;:::-;-1:-1:-1;;;;;33759:19:0;;33732:24;33759:19;;;-1:-1:-1;33759:19:0;;;;;;;;749:10;33759:33;;;;;;;;33811:26;;;;33803:79;;;;-1:-1:-1;;;33803:79:0;;11418:2:1;33803:79:0;;;11400:21:1;11457:2;11437:18;;;11430:30;11496:34;11476:18;;;11469:62;-1:-1:-1;;;11547:18:1;;;11540:38;11595:19;;33803:79:0;11390:230:1;33803:79:0;33918:57;33927:6;749:10;33968:6;33949:16;:25;33918:8;:57::i;:::-;-1:-1:-1;34006:4:0;;33526:492;-1:-1:-1;;;;33526:492:0:o;58179:975::-;-1:-1:-1;;;;;58309:16:0;;;;;;;;;;:30;;;58338:1;58329:6;:10;58309:30;58305:842;;;-1:-1:-1;;;;;58360:20:0;;;58356:382;;-1:-1:-1;;;;;58468:22:0;;58449:16;58468:22;;;:14;:22;;;;;;;;;;58529:60;;58588:1;58529:60;;;-1:-1:-1;;;;;58545:19:0;;;;;;:11;:19;;;;;;58565:13;-1:-1:-1;58565:9:0;:13;:::i;:::-;58545:34;;;;;;;;;;;;;;;:40;;;58529:60;58509:80;-1:-1:-1;58608:17:0;58628:18;58640:6;58509:80;58628:18;:::i;:::-;58608:38;;58665:57;58682:6;58690:9;58701;58712;58665:16;:57::i;:::-;58356:382;;;;-1:-1:-1;;;;;58758:20:0;;;58754:382;;-1:-1:-1;;;;;58866:22:0;;58847:16;58866:22;;;:14;:22;;;;;;;;;;58927:60;;58986:1;58927:60;;;-1:-1:-1;;;;;58943:19:0;;;;;;:11;:19;;;;;;58963:13;-1:-1:-1;58963:9:0;:13;:::i;:::-;58943:34;;;;;;;;;;;;;;;:40;;;58927:60;58907:80;-1:-1:-1;59006:17:0;59026:18;59038:6;58907:80;59026:18;:::i;:::-;59006:38;;59063:57;59080:6;59088:9;59099;59110;59063:16;:57::i;47961:281::-;48014:7;48055:16;48038:13;:33;48034:201;;;-1:-1:-1;48095:24:0;;47961:281::o;48034:201::-;-1:-1:-1;48423:65:0;;;48181:10;48423:65;;;;5239:25:1;;;;48193:12:0;5280:18:1;;;5273:34;48207:15:0;5323:18:1;;;5316:34;48459:13:0;5366:18:1;;;5359:34;48482:4:0;5409:19:1;;;;5402:61;;;;48423:65:0;;;;;;;;;;5211:19:1;;;;48423:65:0;;;48413:76;;;;;;49882:106::o;6418:98::-;6476:7;6503:5;6507:1;6503;:5;:::i;37068:399::-;-1:-1:-1;;;;;37152:21:0;;37144:65;;;;-1:-1:-1;;;37144:65:0;;14548:2:1;37144:65:0;;;14530:21:1;14587:2;14567:18;;;14560:30;14626:33;14606:18;;;14599:61;14677:18;;37144:65:0;14520:181:1;37144:65:0;37300:6;37284:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;37317:18:0;;:9;:18;;;;;;;;;;:28;;37339:6;;37317:9;:28;;37339:6;;37317:28;:::i;:::-;;;;-1:-1:-1;;37361:37:0;;;3926:25:1;;;37361:37:0;;-1:-1:-1;;;;;37361:37:0;;;37378:1;;37361:37;;;;;3914:2:1;37361:37:0;;;37068:399;;:::o;57746:425::-;-1:-1:-1;;;;;57849:21:0;;;57823:23;57849:21;;;:10;:21;;;;;;;;;;32100:18;;;;;;;57985:21;;;;:33;;;-1:-1:-1;;;;;;57985:33:0;;;;;;;58036:54;;57849:21;;;;;32100:18;;57985:33;;57849:21;;;58036:54;;57823:23;58036:54;58103:60;58118:15;58135:9;58146:16;58103:14;:60::i;:::-;57746:425;;;;:::o;3051:173::-;3126:6;;;-1:-1:-1;;;;;3143:17:0;;;-1:-1:-1;;;;;;3143:17:0;;;;;;;3176:40;;3126:6;;;3143:17;3126:6;;3176:40;;-1:-1:-1;;3176:40:0;3051:173;;:::o;32339:175::-;32425:4;32442:42;749:10;32466:9;32477:6;32442:9;:42::i;49996:207::-;-1:-1:-1;;;;;50117:14:0;;50056:15;50117:14;;;:7;:14;;;;;45692;;-1:-1:-1;45811:19:0;;;;45692:14;50178:17;49996:207;;;;:::o;48505:167::-;48582:7;48609:55;48631:20;:18;:20::i;:::-;45029:57;;;-1:-1:-1;;;45029:57:0;;;;3241:27:1;;;;3284:11;;;3277:27;;;;3320:12;;;;3313:28;;;45029:57:0;;;;;;;;;;3357:12:1;;;;45029:57:0;;;45019:68;;;;;;44899:196;42468:1512;42596:7;43535:66;43521:80;;;43499:164;;;;-1:-1:-1;;;43499:164:0;;9847:2:1;43499:164:0;;;9829:21:1;9886:2;9866:18;;;9859:30;9925:34;9905:18;;;9898:62;-1:-1:-1;;;9976:18:1;;;9969:32;10018:19;;43499:164:0;9819:224:1;43499:164:0;43682:1;:7;;43687:2;43682:7;:18;;;;43693:1;:7;;43698:2;43693:7;43682:18;43674:65;;;;-1:-1:-1;;;43674:65:0;;10656:2:1;43674:65:0;;;10638:21:1;10695:2;10675:18;;;10668:30;10734:34;10714:18;;;10707:62;-1:-1:-1;;;10785:18:1;;;10778:32;10827:19;;43674:65:0;10628:224:1;43674:65:0;43854:24;;;43837:14;43854:24;;;;;;;;;6123:25:1;;;6196:4;6184:17;;6164:18;;;6157:45;;;;6218:18;;;6211:34;;;6261:18;;;6254:34;;;43854:24:0;;6095:19:1;;43854:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43854:24:0;;-1:-1:-1;;43854:24:0;;;-1:-1:-1;;;;;;;43897:20:0;;43889:57;;;;-1:-1:-1;;;43889:57:0;;7109:2:1;43889:57:0;;;7091:21:1;7148:2;7128:18;;;7121:30;7187:26;7167:18;;;7160:54;7231:18;;43889:57:0;7081:174:1;43889:57:0;43966:6;42468:1512;-1:-1:-1;;;;;42468:1512:0:o;36048:733::-;-1:-1:-1;;;;;36188:20:0;;36180:70;;;;-1:-1:-1;;;36180:70:0;;12929:2:1;36180:70:0;;;12911:21:1;12968:2;12948:18;;;12941:30;13007:34;12987:18;;;12980:62;-1:-1:-1;;;13058:18:1;;;13051:35;13103:19;;36180:70:0;12901:227:1;36180:70:0;-1:-1:-1;;;;;36269:23:0;;36261:71;;;;-1:-1:-1;;;36261:71:0;;7462:2:1;36261:71:0;;;7444:21:1;7501:2;7481:18;;;7474:30;7540:34;7520:18;;;7513:62;-1:-1:-1;;;7591:18:1;;;7584:33;7634:19;;36261:71:0;7434:225:1;36261:71:0;-1:-1:-1;;;;;36429:17:0;;36405:21;36429:17;;;;;;;;;;;36465:23;;;;36457:74;;;;-1:-1:-1;;;36457:74:0;;9440:2:1;36457:74:0;;;9422:21:1;9479:2;9459:18;;;9452:30;9518:34;9498:18;;;9491:62;-1:-1:-1;;;9569:18:1;;;9562:36;9615:19;;36457:74:0;9412:228:1;36457:74:0;-1:-1:-1;;;;;36567:17:0;;;:9;:17;;;;;;;;;;;36587:22;;;36567:42;;36631:20;;;;;;;;:30;;36587:22;;36567:9;36631:30;;36587:22;;36631:30;:::i;:::-;;;;-1:-1:-1;;36679:35:0;;3926:25:1;;;-1:-1:-1;;;;;36679:35:0;;;;;;;;;;3914:2:1;3899:18;36679:35:0;;;;;;;36727:46;50488:380;59162:689;59327:18;59348:75;59355:12;59348:75;;;;;;;;;;;;;;;;;:6;:75::i;:::-;59327:96;;59455:1;59440:12;:16;;;:85;;;;-1:-1:-1;;;;;;59460:22:0;;;;;;:11;:22;;;;;:65;;;;59483:16;-1:-1:-1;59483:12:0;:16;:::i;:::-;59460:40;;;;;;;;;;;;;;;-1:-1:-1;59460:40:0;:50;;:65;59440:85;59436:339;;;-1:-1:-1;;;;;59542:22:0;;;;;;:11;:22;;;;;59591:8;;59565:16;-1:-1:-1;59565:12:0;:16;:::i;:::-;59542:40;;;;;;;;;;;;;-1:-1:-1;59542:40:0;:46;;:57;59436:339;;;59671:33;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59632:22:0;;-1:-1:-1;59632:22:0;;;:11;:22;;;;;:36;;;;;;;;;;;:72;;;;-1:-1:-1;;59632:72:0;;;;;;;;-1:-1:-1;59632:72:0;;;;59747:16;;59632:36;;59747:16;:::i;:::-;-1:-1:-1;;;;;59719:25:0;;;;;;:14;:25;;;;;:44;;-1:-1:-1;;59719:44:0;-1:-1:-1;59719:44:0;;;;;;;;;;59436:339;59792:51;;;15062:25:1;;;15118:2;15103:18;;15096:34;;;59792:51:0;;-1:-1:-1;;;;;59792:51:0;;;;;;;;;;;59162:689;;;;;:::o;59859:164::-;59937:6;59975:12;59968:5;59964:9;;59956:32;;;;-1:-1:-1;;;59956:32:0;;;;;;;;:::i;:::-;-1:-1:-1;60013:1:0;;59859:164;-1:-1:-1;;59859:164:0:o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:2;;177:1;174;167:12;111:2;63:124;;;:::o;192:156::-;258:20;;318:4;307:16;;297:27;;287:2;;338:1;335;328:12;353:196;412:6;465:2;453:9;444:7;440:23;436:32;433:2;;;486:6;478;471:22;433:2;514:29;533:9;514:29;:::i;554:270::-;622:6;630;683:2;671:9;662:7;658:23;654:32;651:2;;;704:6;696;689:22;651:2;732:29;751:9;732:29;:::i;:::-;722:39;;780:38;814:2;803:9;799:18;780:38;:::i;:::-;770:48;;641:183;;;;;:::o;829:338::-;906:6;914;922;975:2;963:9;954:7;950:23;946:32;943:2;;;996:6;988;981:22;943:2;1024:29;1043:9;1024:29;:::i;:::-;1014:39;;1072:38;1106:2;1095:9;1091:18;1072:38;:::i;:::-;1062:48;;1157:2;1146:9;1142:18;1129:32;1119:42;;933:234;;;;;:::o;1172:616::-;1283:6;1291;1299;1307;1315;1323;1331;1384:3;1372:9;1363:7;1359:23;1355:33;1352:2;;;1406:6;1398;1391:22;1352:2;1434:29;1453:9;1434:29;:::i;:::-;1424:39;;1482:38;1516:2;1505:9;1501:18;1482:38;:::i;:::-;1472:48;;1567:2;1556:9;1552:18;1539:32;1529:42;;1618:2;1607:9;1603:18;1590:32;1580:42;;1641:37;1673:3;1662:9;1658:19;1641:37;:::i;:::-;1631:47;;1725:3;1714:9;1710:19;1697:33;1687:43;;1777:3;1766:9;1762:19;1749:33;1739:43;;1342:446;;;;;;;;;;:::o;1793:264::-;1861:6;1869;1922:2;1910:9;1901:7;1897:23;1893:32;1890:2;;;1943:6;1935;1928:22;1890:2;1971:29;1990:9;1971:29;:::i;:::-;1961:39;2047:2;2032:18;;;;2019:32;;-1:-1:-1;;;1880:177:1:o;2062:541::-;2164:6;2172;2180;2188;2196;2204;2257:3;2245:9;2236:7;2232:23;2228:33;2225:2;;;2279:6;2271;2264:22;2225:2;2307:29;2326:9;2307:29;:::i;:::-;2297:39;;2383:2;2372:9;2368:18;2355:32;2345:42;;2434:2;2423:9;2419:18;2406:32;2396:42;;2457:36;2489:2;2478:9;2474:18;2457:36;:::i;:::-;2447:46;;2540:3;2529:9;2525:19;2512:33;2502:43;;2592:3;2581:9;2577:19;2564:33;2554:43;;2215:388;;;;;;;;:::o;2608:370::-;2675:6;2683;2736:2;2724:9;2715:7;2711:23;2707:32;2704:2;;;2757:6;2749;2742:22;2704:2;2785:29;2804:9;2785:29;:::i;:::-;2775:39;;2864:2;2853:9;2849:18;2836:32;2908:10;2901:5;2897:22;2890:5;2887:33;2877:2;;2939:6;2931;2924:22;2877:2;2967:5;2957:15;;;2694:284;;;;;:::o;6299:603::-;6411:4;6440:2;6469;6458:9;6451:21;6501:6;6495:13;6544:6;6539:2;6528:9;6524:18;6517:34;6569:4;6582:140;6596:6;6593:1;6590:13;6582:140;;;6691:14;;;6687:23;;6681:30;6657:17;;;6676:2;6653:26;6646:66;6611:10;;6582:140;;;6740:6;6737:1;6734:13;6731:2;;;6810:4;6805:2;6796:6;6785:9;6781:22;6777:31;6770:45;6731:2;-1:-1:-1;6886:2:1;6865:15;-1:-1:-1;;6861:29:1;6846:45;;;;6893:2;6842:54;;6420:482;-1:-1:-1;;;6420:482:1:o;11625:356::-;11827:2;11809:21;;;11846:18;;;11839:30;11905:34;11900:2;11885:18;;11878:62;11972:2;11957:18;;11799:182::o;15795:128::-;15835:3;15866:1;15862:6;15859:1;15856:13;15853:2;;;15872:18;;:::i;:::-;-1:-1:-1;15908:9:1;;15843:80::o;15928:228::-;15967:3;15995:10;16032:2;16029:1;16025:10;16062:2;16059:1;16055:10;16093:3;16089:2;16085:12;16080:3;16077:21;16074:2;;;16101:18;;:::i;:::-;16137:13;;15975:181;-1:-1:-1;;;;15975:181:1:o;16161:288::-;16200:1;16226:10;16263:2;16260:1;16256:10;16285:3;16275:2;;-1:-1:-1;;;16312:31:1;;16366:4;16363:1;16356:15;16394:4;16312:31;16384:15;16275:2;16427:10;;16423:20;;;;;16206:243;-1:-1:-1;;16206:243:1:o;16454:125::-;16494:4;16522:1;16519;16516:8;16513:2;;;16527:18;;:::i;:::-;-1:-1:-1;16564:9:1;;16503:76::o;16584:221::-;16623:4;16652:10;16712;;;;16682;;16734:12;;;16731:2;;;16749:18;;:::i;:::-;16786:13;;16632:173;-1:-1:-1;;;16632:173:1:o;16810:380::-;16889:1;16885:12;;;;16932;;;16953:2;;17007:4;16999:6;16995:17;16985:27;;16953:2;17060;17052:6;17049:14;17029:18;17026:38;17023:2;;;17106:10;17101:3;17097:20;17094:1;17087:31;17141:4;17138:1;17131:15;17169:4;17166:1;17159:15;17195:127;17256:10;17251:3;17247:20;17244:1;17237:31;17287:4;17284:1;17277:15;17311:4;17308:1;17301:15
Swarm Source
ipfs://7df15a1377325f17720fafc220605045deef4ff0e0777b13bc84ed60cac1b03e
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.