Feature Tip: Add private address tag to any address under My Name Tag !
ERC-20
Overview
Max Total Supply
500,000,000 Spyral
Holders
35
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
2,294,997.708389195239706971 SpyralValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Spyral
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-12-11 */ ///SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance( address sender, uint256 balance, uint256 needed ); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance( address spender, uint256 allowance, uint256 needed ); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @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; } } /** * @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. * * The initial owner is set to the address provided by the deployer. 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; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval( address indexed owner, address indexed spender, uint256 value ); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 value ) external returns (bool); } /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ 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); } abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { 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}. * * 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 returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual 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 default value returned by this function, unless * it's 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 returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `value`. */ function transfer(address to, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _transfer(owner, to, value); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, value); 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}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `value`. * - the caller must have allowance for ``from``'s tokens of at least * `value`. */ function transferFrom( address from, address to, uint256 value ) public virtual returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @dev Moves a `value` amount of tokens from `from` to `to`. * * 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. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _transfer( address from, address to, uint256 value ) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value); } /** * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * * Emits a {Transfer} event. */ function _update( address from, address to, uint256 value ) internal virtual { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. _totalSupply -= value; } } else { unchecked { // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] += value; } } emit Transfer(from, to, value); } /** * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } /** * @dev Sets `value` 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. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve( address owner, address spender, uint256 value ) internal { _approve(owner, spender, value, true); } /** * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any * `Approval` event during `transferFrom` operations. * * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to * true using the following override: * ``` * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { * super._approve(owner, spender, value, true); * } * ``` * * Requirements are the same as {_approve}. */ function _approve( address owner, address spender, uint256 value, bool emitEvent ) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } /** * @dev Updates `owner` s allowance for `spender` based on spent `value`. * * Does not update the allowance value in case of infinite allowance. * Revert if not enough allowance is available. * * Does not emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 value ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance( spender, currentAllowance, value ); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } } // uniswap v2 factory iterface interface IUniswapV2Factory { function createPair(address tokenA, address tokenB) external returns (address pair); function getPair(address tokenA, address tokenB) external view returns (address pair); } /// uniswap v2 router interface interface IUniswapV2Router02 { function factory() external pure returns (address); function WETH() external pure returns (address); function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); function addLiquidityETH( address token, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable returns ( uint256 amountToken, uint256 amountETH, uint256 liquidity ); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function swapExactETHForTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function swapExactETHForTokensSupportingFeeOnTransferTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; } /// iterable mapping library IterableMapping { // Iterable mapping from address to uint; struct Map { address[] keys; mapping(address => uint256) values; mapping(address => uint256) indexOf; mapping(address => bool) inserted; } function get(Map storage map, address key) internal view returns (uint256) { return map.values[key]; } function getIndexOfKey(Map storage map, address key) internal view returns (int256) { if (!map.inserted[key]) { return -1; } return int256(map.indexOf[key]); } function getKeyAtIndex(Map storage map, uint256 index) internal view returns (address) { return map.keys[index]; } function size(Map storage map) internal view returns (uint256) { return map.keys.length; } function set( Map storage map, address key, uint256 val ) internal { if (map.inserted[key]) { map.values[key] = val; } else { map.inserted[key] = true; map.values[key] = val; map.indexOf[key] = map.keys.length; map.keys.push(key); } } function remove(Map storage map, address key) internal { if (!map.inserted[key]) { return; } delete map.inserted[key]; delete map.values[key]; uint256 index = map.indexOf[key]; uint256 lastIndex = map.keys.length - 1; address lastKey = map.keys[lastIndex]; map.indexOf[lastKey] = index; delete map.indexOf[key]; map.keys[index] = lastKey; map.keys.pop(); } } /// @title Dividend-Paying Token Optional Interface /// @author Roger Wu (https://github.com/roger-wu) /// @dev OPTIONAL functions for a dividend-paying token contract. interface DividendPayingTokenOptionalInterface { /// @notice View the amount of dividend in wei that an address can withdraw. /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` can withdraw. function withdrawableDividendOf(address _owner) external view returns (uint256); /// @notice View the amount of dividend in wei that an address has withdrawn. /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` has withdrawn. function withdrawnDividendOf(address _owner) external view returns (uint256); /// @notice View the amount of dividend in wei that an address has earned in total. /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner) /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` has earned in total. function accumulativeDividendOf(address _owner) external view returns (uint256); } /// @title Dividend-Paying Token Interface /// @author Roger Wu (https://github.com/roger-wu) /// @dev An interface for a dividend-paying token contract. interface DividendPayingTokenInterface { /// @notice View the amount of dividend in wei that an address can withdraw. /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` can withdraw. function dividendOf(address _owner) external view returns (uint256); /// @notice Distributes ether to token holders as dividends. /// @dev SHOULD distribute the paid ether to token holders as dividends. /// SHOULD NOT directly transfer ether to token holders in this function. /// MUST emit a `DividendsDistributed` event when the amount of distributed ether is greater than 0. function distributeDividends() external payable; /// @notice Withdraws the ether distributed to the sender. /// @dev SHOULD transfer `dividendOf(msg.sender)` wei to `msg.sender`, and `dividendOf(msg.sender)` SHOULD be 0 after the transfer. /// MUST emit a `DividendWithdrawn` event if the amount of ether transferred is greater than 0. function withdrawDividend() external; /// @dev This event MUST emit when ether is distributed to token holders. /// @param from The address which sends ether to this contract. /// @param weiAmount The amount of distributed ether in wei. event DividendsDistributed(address indexed from, uint256 weiAmount); /// @dev This event MUST emit when an address withdraws their dividend. /// @param to The address which withdraws ether from this contract. /// @param weiAmount The amount of withdrawn ether in wei. event DividendWithdrawn(address indexed to, uint256 weiAmount); } /** * @title SafeMathInt * @dev Math operations for int256 with overflow safety checks. */ library SafeMathInt { int256 private constant MIN_INT256 = int256(1) << 255; int256 private constant MAX_INT256 = ~(int256(1) << 255); /** * @dev Multiplies two int256 variables and fails on overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { int256 c = a * b; // Detect overflow when multiplying MIN_INT256 with -1 require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256)); require((b == 0) || (c / b == a)); return c; } /** * @dev Division of two int256 variables and fails on overflow. */ function div(int256 a, int256 b) internal pure returns (int256) { // Prevent overflow when dividing MIN_INT256 by -1 require(b != -1 || a != MIN_INT256); // Solidity already throws when dividing by 0. return a / b; } /** * @dev Subtracts two int256 variables and fails on overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { int256 c = a - b; require((b >= 0 && c <= a) || (b < 0 && c > a)); return c; } /** * @dev Adds two int256 variables and fails on overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { int256 c = a + b; require((b >= 0 && c >= a) || (b < 0 && c < a)); return c; } /** * @dev Converts to absolute value, and fails on overflow. */ function abs(int256 a) internal pure returns (int256) { require(a != MIN_INT256); return a < 0 ? -a : a; } function toUint256Safe(int256 a) internal pure returns (uint256) { require(a >= 0); return uint256(a); } } /** * @title SafeMathUint * @dev Math operations with safety checks that revert on error */ library SafeMathUint { function toInt256Safe(uint256 a) internal pure returns (int256) { int256 b = int256(a); require(b >= 0); return b; } } // 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 generally not needed starting with Solidity 0.8, since 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; } } } /// @title Dividend-Paying Token /// @author Roger Wu (https://github.com/roger-wu) /// @dev modified to make more gas efficient contract DividendPayingToken is Ownable, DividendPayingTokenInterface, DividendPayingTokenOptionalInterface { using SafeMath for uint256; using SafeMathUint for uint256; using SafeMathInt for int256; // With `magnitude`, we can properly distribute dividends even if the amount of received ether is small. // For more discussion about choosing the value of `magnitude`, // see https://github.com/ethereum/EIPs/issues/1726#issuecomment-472352728 uint256 internal constant magnitude = 2**128; uint256 internal magnifiedDividendPerShare; // About dividendCorrection: // If the token balance of a `_user` is never changed, the dividend of `_user` can be computed with: // `dividendOf(_user) = dividendPerShare * balanceOf(_user)`. // When `balanceOf(_user)` is changed (via minting/burning/transferring tokens), // `dividendOf(_user)` should not be changed, // but the computed value of `dividendPerShare * balanceOf(_user)` is changed. // To keep the `dividendOf(_user)` unchanged, we add a correction term: // `dividendOf(_user) = dividendPerShare * balanceOf(_user) + dividendCorrectionOf(_user)`, // where `dividendCorrectionOf(_user)` is updated whenever `balanceOf(_user)` is changed: // `dividendCorrectionOf(_user) = dividendPerShare * (old balanceOf(_user)) - (new balanceOf(_user))`. // So now `dividendOf(_user)` returns the same value before and after `balanceOf(_user)` is changed. mapping(address => int256) internal magnifiedDividendCorrections; mapping(address => uint256) internal withdrawnDividends; mapping(address => uint256) internal balanceOf; uint256 private totalSupply; uint256 public totalDividendsDistributed; constructor() Ownable(msg.sender) {} /// @dev Distributes dividends whenever ether is paid to this contract. receive() external payable { distributeDividends(); } /// @notice Distributes ether to token holders as dividends. /// @dev It reverts if the total supply of tokens is 0. /// It emits the `DividendsDistributed` event if the amount of received ether is greater than 0. /// About undistributed ether: /// In each distribution, there is a small amount of ether not distributed, /// the magnified amount of which is /// `(msg.value * magnitude) % totalSupply()`. /// With a well-chosen `magnitude`, the amount of undistributed ether /// (de-magnified) in a distribution can be less than 1 wei. /// We can actually keep track of the undistributed ether in a distribution /// and try to distribute it in the next distribution, /// but keeping track of such data on-chain costs much more than /// the saved ether, so we don't do that. function distributeDividends() public payable override { require(totalSupply > 0); if (msg.value > 0) { magnifiedDividendPerShare = magnifiedDividendPerShare.add( (msg.value).mul(magnitude) / totalSupply ); emit DividendsDistributed(msg.sender, msg.value); totalDividendsDistributed = totalDividendsDistributed.add( msg.value ); } } /// @notice Withdraws the ether distributed to the sender. /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0. function withdrawDividend() public virtual override { _withdrawDividendOfUser(payable(msg.sender)); } /// @notice Withdraws the ether distributed to the sender. /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0. function _withdrawDividendOfUser(address payable user) internal returns (uint256) { uint256 _withdrawableDividend = withdrawableDividendOf(user); if (_withdrawableDividend > 0) { withdrawnDividends[user] = withdrawnDividends[user].add( _withdrawableDividend ); emit DividendWithdrawn(user, _withdrawableDividend); (bool success, ) = user.call{ value: _withdrawableDividend, gas: 3000 }(""); if (!success) { withdrawnDividends[user] = withdrawnDividends[user].sub( _withdrawableDividend ); return 0; } return _withdrawableDividend; } return 0; } /// @notice View the amount of dividend in wei that an address can withdraw. /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` can withdraw. function dividendOf(address _owner) public view override returns (uint256) { return withdrawableDividendOf(_owner); } /// @notice View the amount of dividend in wei that an address can withdraw. /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` can withdraw. function withdrawableDividendOf(address _owner) public view override returns (uint256) { return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]); } /// @notice View the amount of dividend in wei that an address has withdrawn. /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` has withdrawn. function withdrawnDividendOf(address _owner) public view override returns (uint256) { return withdrawnDividends[_owner]; } /// @notice View the amount of dividend in wei that an address has earned in total. /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner) /// = (magnifiedDividendPerShare * balanceOf(_owner) + magnifiedDividendCorrections[_owner]) / magnitude /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` has earned in total. function accumulativeDividendOf(address _owner) public view override returns (uint256) { return magnifiedDividendPerShare .mul(balanceOf[_owner]) .toInt256Safe() .add(magnifiedDividendCorrections[_owner]) .toUint256Safe() / magnitude; } /// @dev set the user shares as per there balance, once they have bought more than minimum /// required /// @param account: user address /// @param newBalance: user balance function _setBalance(address account, uint256 newBalance) internal { uint256 currentBalance = balanceOf[account]; if (newBalance > currentBalance) { uint256 amount = newBalance.sub(currentBalance); balanceOf[account] += amount; totalSupply += amount; magnifiedDividendCorrections[ account ] = magnifiedDividendCorrections[account].sub( (magnifiedDividendPerShare.mul(amount)).toInt256Safe() ); } else if (newBalance < currentBalance) { uint256 amount = currentBalance.sub(newBalance); balanceOf[account] -= amount; totalSupply -= amount; magnifiedDividendCorrections[ account ] = magnifiedDividendCorrections[account].add( (magnifiedDividendPerShare.mul(amount)).toInt256Safe() ); } } } contract Spyral is ERC20, Ownable { ///Custom errors error TryAfterNextClaimTime(); error TradingIsAlreadyLive(); error CannotClaimNativeToken(); error TradingIsNotActiveYet(); error CannotModifyMainPair(); error OnlyMarketingWalletCanClaim(); error EthClaimFailed(); error MAX_FEE_LIMIT_EXCEEDS(); error NoRewardsAvailableYet(); /// uniswap v2 router IUniswapV2Router02 public uniswapV2Router; /// uniswap v2 pair address address public uniswapV2Pair; /// swapping is active bool private swapping; /// dividend tracker SpyralDividendTracker public dividendTracker; /// global burn wallet address private constant deadWallet = address(0xdead); /// swap threshold at which collected tax is swapped for ether uint256 public swapTokensAtAmount = 1e4 * 1e18; /// marketing wallet address address public marketingWallet = 0xf3cfd872c8E5F2A7Fd615b7E38Ef919D557B396b; /// fees variables struct BuyFee { uint256 ethReward; uint256 marketing; } struct SellFee { uint256 ethReward; uint256 marketing; } BuyFee public buyFee; SellFee public sellFee; // exlcude from fees and max transaction amount mapping(address => bool) private _isExcludedFromFees; /// events event ExcludeFromFees(address indexed account, bool isExcluded); event SellFeesUpdated( uint256 indexed rewardFee, uint256 indexed marketingFee ); event BuyFeesUpdated(uint256 indexed rewardFee, uint256 marketingFee); event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value); event MarketingWalletUpdated( address indexed newMarketingWallet, address indexed oldMarketingWallet ); event SwapAndLiquify( uint256 tokensSwapped, uint256 ethReceived, uint256 ethForDividends ); constructor() ERC20("Spyral", "Spyral") Ownable(msg.sender) { dividendTracker = new SpyralDividendTracker(); IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02( 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D /// uniswap v2 router ); // Create a uniswap pair for this token address _uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()) .createPair(address(this), _uniswapV2Router.WETH()); /// intializes the router and pair values uniswapV2Router = _uniswapV2Router; uniswapV2Pair = _uniswapV2Pair; /// initializes the fees values for buy / sell buyFee.ethReward = 2; buyFee.marketing = 28; sellFee.ethReward = 2; sellFee.marketing = 28; // exclude from receiving dividends dividendTracker.excludeFromDividends(address(dividendTracker)); dividendTracker.excludeFromDividends(uniswapV2Pair); dividendTracker.excludeFromDividends(address(this)); dividendTracker.excludeFromDividends(owner()); dividendTracker.excludeFromDividends(deadWallet); dividendTracker.excludeFromDividends(address(_uniswapV2Router)); // exclude from paying fees or having max transaction amount _isExcludedFromFees[owner()] = true; _isExcludedFromFees[address(this)] = true; /// mint the max supply to owner address upon deployment _mint(owner(), 5e8 * 1e18); } receive() external payable {} /// @dev set marketing wallet /// @param wallet: new marketing wallet function setMarketingWallet(address wallet) external onlyOwner { address oldWallet = marketingWallet; marketingWallet = wallet; emit MarketingWalletUpdated(wallet, oldWallet); } /// @dev claim eth rewards /// @notice users have to wait as per claimTime b/w two consequitve claims function claimEthReward() external { bool claiming = true; (, , , uint256 claimable, , , uint256 nextClaimTime, ) = dividendTracker .getAccount(msg.sender); if (claimable == 0) { revert NoRewardsAvailableYet(); } if (block.timestamp < nextClaimTime) { revert TryAfterNextClaimTime(); } dividendTracker.processAccount(payable(msg.sender), false); claiming = false; } /// @dev update duration b/w two consequtive claims /// @param claimWait: time in seconds (must be within 3600 and 86400) function updateClaimWait(uint256 claimWait) external onlyOwner { dividendTracker.updateClaimWait(claimWait); } /// @notice returns how many eth has been contributed to eth rewards so far function getTotalDividendsDistributed() external view returns (uint256) { return dividendTracker.totalDividendsDistributed(); } /// @dev set fees for buy /// max fees can be 30% combined for reward and marketing buy tax function setBuyFees(uint256 reward, uint256 marketing) external onlyOwner { if (reward + marketing > 30) { revert MAX_FEE_LIMIT_EXCEEDS(); } buyFee.ethReward = reward; buyFee.marketing = marketing; emit BuyFeesUpdated(reward, marketing); } /// @dev set sell fees /// max fees can be 30% combined for reward and marketing sell tax function setSellFees(uint256 reward, uint256 marketing) external onlyOwner { if (reward + marketing > 30) { revert MAX_FEE_LIMIT_EXCEEDS(); } sellFee.ethReward = reward; sellFee.marketing = marketing; emit SellFeesUpdated(reward, marketing); } /// @notice return user info, how much he can claim /// total rewards alloted to him in lifetime(including unclaimed), /// last claim time, /// next claim time etc function getUserDividendsInfo(address account) external view returns ( uint256 claimable, uint256 totalEthEarned, uint256 lastClaimTime, uint256 nextClaimTime ) { ( , , , claimable, totalEthEarned, lastClaimTime, nextClaimTime, ) = dividendTracker.getAccount(account); } /// @notice return number of eligible reward holders function getNumberOfRewardHolders() external view returns (uint256) { return dividendTracker.getNumberOfTokenHolders(); } /// @notice manage the transfer / fees of token /// override required by solidity function _update( address from, address to, uint256 amount ) internal override { if (amount == 0) { super._update(from, to, 0); return; } uint256 contractTokenBalance = balanceOf(address(this)); bool canSwap = contractTokenBalance >= swapTokensAtAmount; if ( canSwap && !swapping && from != uniswapV2Pair && from != owner() && to != owner() ) { swapping = true; swapAndLiquify(contractTokenBalance); swapping = false; } bool takeFee = !swapping; // if any account belongs to _isExcludedFromFee account then remove the fee // when liquidity is added for first 10 minutes tax is 30% on buy/sell // , for subsequent 10 minutes it's 15% on buy/sell // afterwards, it's 3% on buy/sell if (_isExcludedFromFees[from] || _isExcludedFromFees[to]) { takeFee = false; } if (takeFee) { uint256 fees = 0; /// if it's a buy if (from == uniswapV2Pair) { fees = (amount * (buyFee.marketing + buyFee.ethReward)) / 100; } /// if it's a sell if (to == uniswapV2Pair) { fees = (amount * (sellFee.marketing + sellFee.ethReward)) / 100; } amount = amount - fees; if (fees > 0) { super._update(from, address(this), fees); } } super._update(from, to, amount); try dividendTracker.setBalance(payable(from), balanceOf(from)) {} catch {} try dividendTracker.setBalance(payable(to), balanceOf(to)) {} catch {} } /// @notice swap the input tokens for eth and send to /// marketing wallet as well as to dividend tracker function swapAndLiquify(uint256 tokens) private { uint256 initialBalance = address(this).balance; // swap tokens for ETH swapTokensForEth(tokens); // how much ETH did we just swap into? uint256 newBalance = address(this).balance - initialBalance; uint256 totalFees = buyFee.marketing + buyFee.ethReward + sellFee.marketing + sellFee.ethReward; if (totalFees > 0) { uint256 marketingPart = (newBalance * (buyFee.marketing + sellFee.marketing)) / totalFees; (bool sent, ) = payable(address(dividendTracker)).call{ value: newBalance - marketingPart }(""); (bool sent2, ) = payable(marketingWallet).call{ value: address(this).balance }(""); if (sent || sent2) { emit SwapAndLiquify( tokens, marketingPart, newBalance - marketingPart ); } } else { bool s; (s,) = payable(address(marketingWallet)).call{ value: address(this).balance }(""); } } /// @notice swap the tokens for eth function swapTokensForEth(uint256 tokenAmount) private { // generate the uniswap pair path of token -> weth address[] memory path = new address[](2); path[0] = address(this); path[1] = uniswapV2Router.WETH(); uint256 out = uniswapV2Router.getAmountsOut(tokenAmount, path)[1]; if (allowance(address(this), address(uniswapV2Router)) < tokenAmount) { _approve( address(this), address(uniswapV2Router), type(uint256).max ); } // make the swap uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens( tokenAmount, (out * (100 - 20)) / 100, // 20% slippage path, address(this), block.timestamp + 360 ); } } //// Spyral dividend tracker, manage eth rewards ////{ see: DividendPayingToken } contract SpyralDividendTracker is DividendPayingToken { using SafeMath for uint256; using SafeMathInt for int256; using IterableMapping for IterableMapping.Map; error TimeLimitMustBeBetween1to24Hours(); IterableMapping.Map private tokenHoldersMap; uint256 public lastProcessedIndex; mapping(address => bool) public excludedFromDividends; mapping(address => uint256) public lastClaimTimes; uint256 public claimWait; uint256 public immutable minimumTokenBalanceForDividends; event ExcludeFromDividends(address indexed account); event ClaimWaitUpdated(uint256 indexed newValue, uint256 indexed oldValue); event Claim( address indexed account, uint256 amount, bool indexed automatic ); constructor() { claimWait = 12 hours; // cooldown b/w two consequtive claims for user minimumTokenBalanceForDividends = 100 * (10**18); //must hold 100+ tokens } function withdrawDividend() public pure override { require(false); } function excludeFromDividends(address account) external onlyOwner { require(!excludedFromDividends[account]); excludedFromDividends[account] = true; _setBalance(account, 0); tokenHoldersMap.remove(account); emit ExcludeFromDividends(account); } function updateClaimWait(uint256 newClaimWait) external onlyOwner { if (newClaimWait < 3600 || newClaimWait > 86400) { revert TimeLimitMustBeBetween1to24Hours(); } emit ClaimWaitUpdated(newClaimWait, claimWait); claimWait = newClaimWait; } function getLastProcessedIndex() external view returns (uint256) { return lastProcessedIndex; } function getNumberOfTokenHolders() external view returns (uint256) { return tokenHoldersMap.keys.length; } function getAccount(address _account) public view returns ( address account, int256 index, int256 iterationsUntilProcessed, uint256 withdrawableDividends, uint256 totalDividends, uint256 lastClaimTime, uint256 nextClaimTime, uint256 secondsUntilAutoClaimAvailable ) { account = _account; index = tokenHoldersMap.getIndexOfKey(account); iterationsUntilProcessed = -1; if (index >= 0) { if (uint256(index) > lastProcessedIndex) { iterationsUntilProcessed = index.sub( int256(lastProcessedIndex) ); } else { uint256 processesUntilEndOfArray = tokenHoldersMap.keys.length > lastProcessedIndex ? tokenHoldersMap.keys.length.sub(lastProcessedIndex) : 0; iterationsUntilProcessed = index.add( int256(processesUntilEndOfArray) ); } } withdrawableDividends = withdrawableDividendOf(account); totalDividends = accumulativeDividendOf(account); lastClaimTime = lastClaimTimes[account]; nextClaimTime = lastClaimTime > 0 ? lastClaimTime.add(claimWait) : 0; secondsUntilAutoClaimAvailable = nextClaimTime > block.timestamp ? nextClaimTime.sub(block.timestamp) : 0; } function getAccountAtIndex(uint256 index) public view returns ( address, int256, int256, uint256, uint256, uint256, uint256, uint256 ) { if (index >= tokenHoldersMap.size()) { return ( 0x0000000000000000000000000000000000000000, -1, -1, 0, 0, 0, 0, 0 ); } address account = tokenHoldersMap.getKeyAtIndex(index); return getAccount(account); } function setBalance(address payable account, uint256 newBalance) external onlyOwner { if (excludedFromDividends[account]) { return; } if (newBalance >= minimumTokenBalanceForDividends) { _setBalance(account, newBalance); tokenHoldersMap.set(account, newBalance); } else { _setBalance(account, 0); tokenHoldersMap.remove(account); } } function processAccount(address payable account, bool automatic) public onlyOwner returns (bool) { uint256 amount = _withdrawDividendOfUser(account); if (amount > 0) { lastClaimTimes[account] = block.timestamp; emit Claim(account, amount, automatic); return true; } return false; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CannotClaimNativeToken","type":"error"},{"inputs":[],"name":"CannotModifyMainPair","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"EthClaimFailed","type":"error"},{"inputs":[],"name":"MAX_FEE_LIMIT_EXCEEDS","type":"error"},{"inputs":[],"name":"NoRewardsAvailableYet","type":"error"},{"inputs":[],"name":"OnlyMarketingWalletCanClaim","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"TradingIsAlreadyLive","type":"error"},{"inputs":[],"name":"TradingIsNotActiveYet","type":"error"},{"inputs":[],"name":"TryAfterNextClaimTime","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"rewardFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"marketingFee","type":"uint256"}],"name":"BuyFeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"ExcludeFromFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newMarketingWallet","type":"address"},{"indexed":true,"internalType":"address","name":"oldMarketingWallet","type":"address"}],"name":"MarketingWalletUpdated","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":"uint256","name":"rewardFee","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"marketingFee","type":"uint256"}],"name":"SellFeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pair","type":"address"},{"indexed":true,"internalType":"bool","name":"value","type":"bool"}],"name":"SetAutomatedMarketMakerPair","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokensSwapped","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethReceived","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethForDividends","type":"uint256"}],"name":"SwapAndLiquify","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":[{"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":"value","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":[],"name":"buyFee","outputs":[{"internalType":"uint256","name":"ethReward","type":"uint256"},{"internalType":"uint256","name":"marketing","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimEthReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dividendTracker","outputs":[{"internalType":"contract SpyralDividendTracker","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumberOfRewardHolders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDividendsDistributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getUserDividendsInfo","outputs":[{"internalType":"uint256","name":"claimable","type":"uint256"},{"internalType":"uint256","name":"totalEthEarned","type":"uint256"},{"internalType":"uint256","name":"lastClaimTime","type":"uint256"},{"internalType":"uint256","name":"nextClaimTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketingWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sellFee","outputs":[{"internalType":"uint256","name":"ethReward","type":"uint256"},{"internalType":"uint256","name":"marketing","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"marketing","type":"uint256"}],"name":"setBuyFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"setMarketingWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"marketing","type":"uint256"}],"name":"setSellFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapTokensAtAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV2Pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV2Router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"claimWait","type":"uint256"}],"name":"updateClaimWait","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405269021e19e0c9bab2400000600955600a80546001600160a01b03191673f3cfd872c8e5f2a7fd615b7e38ef919d557b396b17905534801562000044575f80fd5b5060408051808201825260068082526514dc1e5c985b60d21b60208084018290528451808601909552918452908301523391600362000084838262001044565b50600462000093828262001044565b5050506001600160a01b038116620000c557604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b620000d08162000589565b50604051620000df9062000f9f565b604051809103905ff080158015620000f9573d5f803e3d5ffd5b5060085f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505f737a250d5630b4cf539739df2c5dacb4c659f2488d90505f816001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000175573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200019b91906200110c565b6001600160a01b031663c9c6539630846001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200020d91906200110c565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303815f875af115801562000258573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200027e91906200110c565b600680546001600160a01b038581166001600160a01b0319928316179092556007805484841692169190911790556002600b819055601c600c819055600d91909155600e5560085460405163031e79db60e41b81529116600482018190529192506331e79db0906024015f604051808303815f87803b15801562000300575f80fd5b505af115801562000313573d5f803e3d5ffd5b505060085460075460405163031e79db60e41b81526001600160a01b039182166004820152911692506331e79db091506024015f604051808303815f87803b1580156200035e575f80fd5b505af115801562000371573d5f803e3d5ffd5b505060085460405163031e79db60e41b81523060048201526001600160a01b0390911692506331e79db091506024015f604051808303815f87803b158015620003b8575f80fd5b505af1158015620003cb573d5f803e3d5ffd5b50506008546001600160a01b031691506331e79db09050620003f56005546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024015f604051808303815f87803b15801562000434575f80fd5b505af115801562000447573d5f803e3d5ffd5b505060085460405163031e79db60e41b815261dead60048201526001600160a01b0390911692506331e79db091506024015f604051808303815f87803b15801562000490575f80fd5b505af1158015620004a3573d5f803e3d5ffd5b505060085460405163031e79db60e41b81526001600160a01b03868116600483015290911692506331e79db091506024015f604051808303815f87803b158015620004ec575f80fd5b505af1158015620004ff573d5f803e3d5ffd5b505050506001600f5f62000518620005da60201b60201c565b6001600160a01b0316815260208082019290925260409081015f908120805494151560ff19958616179055308152600f909252902080549091166001179055620005816200056e6005546001600160a01b031690565b6b019d971e4fe8401e74000000620005e9565b505062001330565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6005546001600160a01b031690565b6001600160a01b038216620006145760405163ec442f0560e01b81525f6004820152602401620000bc565b620006215f838362000625565b5050565b805f036200063f576200063a83835f62000925565b505050565b305f90815260208190526040902054600954811080159081906200066d5750600754600160a01b900460ff16155b80156200068857506007546001600160a01b03868116911614155b8015620006a357506005546001600160a01b03868116911614155b8015620006be57506005546001600160a01b03858116911614155b15620006f0576007805460ff60a01b1916600160a01b179055620006e28262000a54565b6007805460ff60a01b191690555b6007546001600160a01b0386165f908152600f602052604090205460ff600160a01b9092048216159116806200073d57506001600160a01b0385165f908152600f602052604090205460ff165b156200074657505f5b8015620007ff576007545f906001600160a01b03908116908816036200079557600b54600c546064916200077a916200114f565b62000786908762001165565b6200079291906200117f565b90505b6007546001600160a01b0390811690871603620007db57600d54600e54606491620007c0916200114f565b620007cc908762001165565b620007d891906200117f565b90505b620007e781866200119f565b94508015620007fd57620007fd87308362000925565b505b6200080c86868662000925565b6008546001600160a01b031663e30443bc876200083d816001600160a01b03165f9081526020819052604090205490565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044015f604051808303815f87803b15801562000881575f80fd5b505af192505050801562000893575060015b506008546001600160a01b031663e30443bc86620008c5816001600160a01b03165f9081526020819052604090205490565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044015f604051808303815f87803b15801562000909575f80fd5b505af19250505080156200091b575060015b505b505050505050565b6001600160a01b03831662000953578060025f8282546200094791906200114f565b90915550620009c59050565b6001600160a01b0383165f9081526020819052604090205481811015620009a75760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401620000bc565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216620009e35760028054829003905562000a01565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405162000a4791815260200190565b60405180910390a3505050565b4762000a608262000c55565b5f62000a6d82476200119f565b600d54600e54600b54600c549394505f9362000a8a91906200114f565b62000a9691906200114f565b62000aa291906200114f565b9050801562000bf957600e54600c545f91839162000ac191906200114f565b62000acd908562001165565b62000ad991906200117f565b6008549091505f906001600160a01b031662000af683866200119f565b6040515f81818185875af1925050503d805f811462000b31576040519150601f19603f3d011682016040523d82523d5f602084013e62000b36565b606091505b5050600a546040519192505f916001600160a01b039091169047908381818185875af1925050503d805f811462000b89576040519150601f19603f3d011682016040523d82523d5f602084013e62000b8e565b606091505b50509050818062000b9c5750805b1562000bf0577f17bbfb9a6069321b6ded73bd96327c9e6b7212a5cd51ff219cd61370acafb561878462000bd181896200119f565b6040805193845260208401929092529082015260600160405180910390a15b50505062000c4f565b600a546040515f916001600160a01b03169047908381818185875af1925050503d805f811462000c45576040519150601f19603f3d011682016040523d82523d5f602084013e62000c4a565b606091505b505050505b50505050565b6040805160028082526060820183525f9260208301908036833701905050905030815f8151811062000c8b5762000c8b620011b5565b6001600160a01b03928316602091820292909201810191909152600654604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa15801562000ce3573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000d0991906200110c565b8160018151811062000d1f5762000d1f620011b5565b6001600160a01b03928316602091820292909201015260065460405163d06ca61f60e01b81525f92919091169063d06ca61f9062000d6490869086906004016200120d565b5f60405180830381865afa15801562000d7f573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405262000da891908101906200122f565b60018151811062000dbd5762000dbd620011b5565b6020908102919091010151600654909150839062000de69030906001600160a01b031662000e92565b101562000e085760065462000e089030906001600160a01b03165f1962000ebe565b6006546001600160a01b031663791ac94784606462000e2985605062001165565b62000e3591906200117f565b853062000e45426101686200114f565b6040518663ffffffff1660e01b815260040162000e67959493929190620012f3565b5f604051808303815f87803b15801562000e7f575f80fd5b505af11580156200091b573d5f803e3d5ffd5b6001600160a01b038083165f908152600160209081526040808320938516835292905220545b92915050565b6200063a83838360016001600160a01b03841662000ef25760405163e602df0560e01b81525f6004820152602401620000bc565b6001600160a01b03831662000f1d57604051634a1406b160e11b81525f6004820152602401620000bc565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801562000c4f57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405162000f9191815260200190565b60405180910390a350505050565b6111c48062002c4683390190565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168062000fd657607f821691505b60208210810362000ff557634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156200063a575f81815260208120601f850160051c81016020861015620010235750805b601f850160051c820191505b818110156200091d578281556001016200102f565b81516001600160401b0381111562001060576200106062000fad565b620010788162001071845462000fc1565b8462000ffb565b602080601f831160018114620010ae575f8415620010965750858301515b5f19600386901b1c1916600185901b1785556200091d565b5f85815260208120601f198616915b82811015620010de57888601518255948401946001909101908401620010bd565b5085821015620010fc57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f602082840312156200111d575f80fd5b81516001600160a01b038116811462001134575f80fd5b9392505050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111562000eb85762000eb86200113b565b808202811582820484141762000eb85762000eb86200113b565b5f826200119a57634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111562000eb85762000eb86200113b565b634e487b7160e01b5f52603260045260245ffd5b5f8151808452602080850194508084015f5b83811015620012025781516001600160a01b031687529582019590820190600101620011db565b509495945050505050565b828152604060208201525f620012276040830184620011c9565b949350505050565b5f602080838503121562001241575f80fd5b82516001600160401b038082111562001258575f80fd5b818501915085601f8301126200126c575f80fd5b81518181111562001281576200128162000fad565b8060051b604051601f19603f83011681018181108582111715620012a957620012a962000fad565b604052918252848201925083810185019188831115620012c7575f80fd5b938501935b82851015620012e757845184529385019392850192620012cc565b98975050505050505050565b85815284602082015260a060408201525f6200131360a0830186620011c9565b6001600160a01b0394909416606083015250608001529392505050565b611908806200133e5f395ff3fe608060405260043610610198575f3560e01c8063715018a6116100e7578063a9059cbb11610087578063e2f4560511610062578063e2f45605146104ae578063e98030c7146104c3578063ecc41ee5146104e2578063f2fde38b146104f6575f80fd5b8063a9059cbb14610451578063b2d8f20814610470578063dd62ed3e1461048f575f80fd5b806395d89b41116100c257806395d89b41146103cb5780639fd8234e146103df578063a0a0c465146103fe578063a35c85b014610412575f80fd5b8063715018a61461037b57806375f0a8741461038f5780638da5cb5b146103ae575f80fd5b80632c1f521611610152578063470624021161012d57806347062402146102ed57806349bd5a5e146103075780635d098b381461032657806370a0823114610347575f80fd5b80632c1f52161461029f57806330bb4cff146102be578063313ce567146102d2575f80fd5b806306fdde03146101a3578063095ea7b3146101cd5780631694505e146101fc57806318160ddd1461023357806323b872dd146102515780632b14ca5614610270575f80fd5b3661019f57005b5f80fd5b3480156101ae575f80fd5b506101b7610515565b6040516101c4919061149f565b60405180910390f35b3480156101d8575f80fd5b506101ec6101e73660046114fe565b6105a5565b60405190151581526020016101c4565b348015610207575f80fd5b5060065461021b906001600160a01b031681565b6040516001600160a01b0390911681526020016101c4565b34801561023e575f80fd5b506002545b6040519081526020016101c4565b34801561025c575f80fd5b506101ec61026b366004611528565b6105be565b34801561027b575f80fd5b50600d54600e5461028a919082565b604080519283526020830191909152016101c4565b3480156102aa575f80fd5b5060085461021b906001600160a01b031681565b3480156102c9575f80fd5b506102436105e1565b3480156102dd575f80fd5b50604051601281526020016101c4565b3480156102f8575f80fd5b50600b54600c5461028a919082565b348015610312575f80fd5b5060075461021b906001600160a01b031681565b348015610331575f80fd5b50610345610340366004611566565b610651565b005b348015610352575f80fd5b50610243610361366004611566565b6001600160a01b03165f9081526020819052604090205490565b348015610386575f80fd5b506103456106a9565b34801561039a575f80fd5b50600a5461021b906001600160a01b031681565b3480156103b9575f80fd5b506005546001600160a01b031661021b565b3480156103d6575f80fd5b506101b76106bc565b3480156103ea575f80fd5b506103456103f9366004611588565b6106cb565b348015610409575f80fd5b50610345610738565b34801561041d575f80fd5b5061043161042c366004611566565b61086a565b6040805194855260208501939093529183015260608201526080016101c4565b34801561045c575f80fd5b506101ec61046b3660046114fe565b6108f0565b34801561047b575f80fd5b5061034561048a366004611588565b6108fd565b34801561049a575f80fd5b506102436104a93660046115a8565b610973565b3480156104b9575f80fd5b5061024360095481565b3480156104ce575f80fd5b506103456104dd3660046115df565b61099d565b3480156104ed575f80fd5b50610243610a01565b348015610501575f80fd5b50610345610510366004611566565b610a48565b606060038054610524906115f6565b80601f0160208091040260200160405190810160405280929190818152602001828054610550906115f6565b801561059b5780601f106105725761010080835404028352916020019161059b565b820191905f5260205f20905b81548152906001019060200180831161057e57829003601f168201915b5050505050905090565b5f336105b2818585610a8a565b60019150505b92915050565b5f336105cb858285610a9c565b6105d6858585610af9565b506001949350505050565b600854604080516342d359d760e11b815290515f926001600160a01b0316916385a6b3ae9160048083019260209291908290030181865afa158015610628573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061064c919061162e565b905090565b610659610b56565b600a80546001600160a01b038381166001600160a01b03198316811790935560405191169182917f8616c7a330e3cf61290821331585511f1e2778171e2b005fb5ec60cfe874dc67905f90a35050565b6106b1610b56565b6106ba5f610b83565b565b606060048054610524906115f6565b6106d3610b56565b601e6106df8284611659565b11156106fe57604051631255745b60e31b815260040160405180910390fd5b600d829055600e819055604051819083907f2c7448b63380296b372453c5287509524b5b645dc6a93ffe09e0af53e6b8935b905f90a35050565b60085460405163fbcbc0f160e01b81523360048201526001915f9182916001600160a01b03169063fbcbc0f19060240161010060405180830381865afa158015610784573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107a8919061166c565b50965050509450505050815f036107d25760405163b5596c7560e01b815260040160405180910390fd5b804210156107f3576040516394424e4560e01b815260040160405180910390fd5b60085460405163bc4c4b3760e01b81523360048201525f60248201526001600160a01b039091169063bc4c4b37906044016020604051808303815f875af1158015610840573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061086491906116d1565b50505050565b60085460405163fbcbc0f160e01b81526001600160a01b0383811660048301525f92839283928392169063fbcbc0f19060240161010060405180830381865afa1580156108b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108dd919061166c565b50929b919a509850909650945050505050565b5f336105b2818585610af9565b610905610b56565b601e6109118284611659565b111561093057604051631255745b60e31b815260040160405180910390fd5b600b829055600c81905560405181815282907f480af1f773972b1df72af32ec463e0fdeb1b49f1ca37d07982f677919d5fdd0c9060200160405180910390a25050565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6109a5610b56565b60085460405163e98030c760e01b8152600481018390526001600160a01b039091169063e98030c7906024015f604051808303815f87803b1580156109e8575f80fd5b505af11580156109fa573d5f803e3d5ffd5b5050505050565b600854604080516304ddf6ef60e11b815290515f926001600160a01b0316916309bbedde9160048083019260209291908290030181865afa158015610628573d5f803e3d5ffd5b610a50610b56565b6001600160a01b038116610a7e57604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b610a8781610b83565b50565b610a978383836001610bd4565b505050565b5f610aa78484610973565b90505f1981146108645781811015610aeb57604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610a75565b61086484848484035f610bd4565b6001600160a01b038316610b2257604051634b637e8f60e11b81525f6004820152602401610a75565b6001600160a01b038216610b4b5760405163ec442f0560e01b81525f6004820152602401610a75565b610a97838383610ca6565b6005546001600160a01b031633146106ba5760405163118cdaa760e01b8152336004820152602401610a75565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6001600160a01b038416610bfd5760405163e602df0560e01b81525f6004820152602401610a75565b6001600160a01b038316610c2657604051634a1406b160e11b81525f6004820152602401610a75565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561086457826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610c9891815260200190565b60405180910390a350505050565b805f03610cb857610a9783835f610f78565b305f9081526020819052604090205460095481108015908190610ce55750600754600160a01b900460ff16155b8015610cff57506007546001600160a01b03868116911614155b8015610d1957506005546001600160a01b03868116911614155b8015610d3357506005546001600160a01b03858116911614155b15610d62576007805460ff60a01b1916600160a01b179055610d548261109e565b6007805460ff60a01b191690555b6007546001600160a01b0386165f908152600f602052604090205460ff600160a01b909204821615911680610dae57506001600160a01b0385165f908152600f602052604090205460ff165b15610db657505f5b8015610e5b576007545f906001600160a01b0390811690881603610dfd57600b54600c54606491610de691611659565b610df090876116f0565b610dfa9190611707565b90505b6007546001600160a01b0390811690871603610e3c57600d54600e54606491610e2591611659565b610e2f90876116f0565b610e399190611707565b90505b610e468186611726565b94508015610e5957610e59873083610f78565b505b610e66868686610f78565b6008546001600160a01b031663e30443bc87610e96816001600160a01b03165f9081526020819052604090205490565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044015f604051808303815f87803b158015610ed9575f80fd5b505af1925050508015610eea575060015b506008546001600160a01b031663e30443bc86610f1b816001600160a01b03165f9081526020819052604090205490565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044015f604051808303815f87803b158015610f5e575f80fd5b505af1925050508015610f6f575060015b50505050505050565b6001600160a01b038316610fa2578060025f828254610f979190611659565b909155506110129050565b6001600160a01b0383165f9081526020819052604090205481811015610ff45760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610a75565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661102e5760028054829003905561104c565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161109191815260200190565b60405180910390a3505050565b476110a882611280565b5f6110b38247611726565b600d54600e54600b54600c549394505f936110ce9190611659565b6110d89190611659565b6110e29190611659565b9050801561122757600e54600c545f9183916110fe9190611659565b61110890856116f0565b6111129190611707565b6008549091505f906001600160a01b031661112d8386611726565b6040515f81818185875af1925050503d805f8114611166576040519150601f19603f3d011682016040523d82523d5f602084013e61116b565b606091505b5050600a546040519192505f916001600160a01b039091169047908381818185875af1925050503d805f81146111bc576040519150601f19603f3d011682016040523d82523d5f602084013e6111c1565b606091505b5050905081806111ce5750805b1561121f577f17bbfb9a6069321b6ded73bd96327c9e6b7212a5cd51ff219cd61370acafb56187846112008189611726565b6040805193845260208401929092529082015260600160405180910390a15b505050610864565b600a546040515f916001600160a01b03169047908381818185875af1925050503d805f8114611271576040519150601f19603f3d011682016040523d82523d5f602084013e611276565b606091505b5050505050505050565b6040805160028082526060820183525f9260208301908036833701905050905030815f815181106112b3576112b361174d565b6001600160a01b03928316602091820292909201810191909152600654604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa15801561130a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061132e9190611761565b816001815181106113415761134161174d565b6001600160a01b03928316602091820292909201015260065460405163d06ca61f60e01b81525f92919091169063d06ca61f9061138490869086906004016117be565b5f60405180830381865afa15801561139e573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526113c591908101906117de565b6001815181106113d7576113d761174d565b60200260200101519050826114003060065f9054906101000a90046001600160a01b0316610973565b101561141f5760065461141f9030906001600160a01b03165f19610a8a565b6006546001600160a01b031663791ac94784606461143e8560506116f0565b6114489190611707565b853061145642610168611659565b6040518663ffffffff1660e01b8152600401611476959493929190611897565b5f604051808303815f87803b15801561148d575f80fd5b505af1158015610f6f573d5f803e3d5ffd5b5f6020808352835180828501525f5b818110156114ca578581018301518582016040015282016114ae565b505f604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b0381168114610a87575f80fd5b5f806040838503121561150f575f80fd5b823561151a816114ea565b946020939093013593505050565b5f805f6060848603121561153a575f80fd5b8335611545816114ea565b92506020840135611555816114ea565b929592945050506040919091013590565b5f60208284031215611576575f80fd5b8135611581816114ea565b9392505050565b5f8060408385031215611599575f80fd5b50508035926020909101359150565b5f80604083850312156115b9575f80fd5b82356115c4816114ea565b915060208301356115d4816114ea565b809150509250929050565b5f602082840312156115ef575f80fd5b5035919050565b600181811c9082168061160a57607f821691505b60208210810361162857634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6020828403121561163e575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156105b8576105b8611645565b5f805f805f805f80610100898b031215611684575f80fd5b885161168f816114ea565b809850506020890151965060408901519550606089015194506080890151935060a0890151925060c0890151915060e089015190509295985092959890939650565b5f602082840312156116e1575f80fd5b81518015158114611581575f80fd5b80820281158282048414176105b8576105b8611645565b5f8261172157634e487b7160e01b5f52601260045260245ffd5b500490565b818103818111156105b8576105b8611645565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215611771575f80fd5b8151611581816114ea565b5f8151808452602080850194508084015f5b838110156117b35781516001600160a01b03168752958201959082019060010161178e565b509495945050505050565b828152604060208201525f6117d6604083018461177c565b949350505050565b5f60208083850312156117ef575f80fd5b825167ffffffffffffffff80821115611806575f80fd5b818501915085601f830112611819575f80fd5b81518181111561182b5761182b611739565b8060051b604051601f19603f8301168101818110858211171561185057611850611739565b60405291825284820192508381018501918883111561186d575f80fd5b938501935b8285101561188b57845184529385019392850192611872565b98975050505050505050565b85815284602082015260a060408201525f6118b560a083018661177c565b6001600160a01b039490941660608301525060800152939250505056fea26469706673582212203e19f995260af59be03184a9d273d9c2f7a2e774c67533f814298c87945b6e8a64736f6c6343000814003360a060405234801561000f575f80fd5b50338061003557604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b61003e81610057565b5061a8c0600e5568056bc75e2d631000006080526100a6565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6080516110ff6100c55f395f81816103b6015261074401526110ff5ff3fe60806040526004361061013f575f3560e01c806385a6b3ae116100b3578063be10b6141161006d578063be10b614146103a5578063e30443bc146103d8578063e7841ec0146103f7578063e98030c71461040b578063f2fde38b1461042a578063fbcbc0f114610449575f80fd5b806385a6b3ae146102d95780638da5cb5b146102ee57806391b89fba14610314578063a8b9d24014610333578063aafd847a14610352578063bc4c4b3714610386575f80fd5b806331e79db01161010457806331e79db0146101dc5780634e7b827f146101fb5780635183d6fd146102395780636a4740021461029d5780636f2789ec146102b0578063715018a6146102c5575f80fd5b806303c833021461015257806309bbedde1461015a578063226cfa3d1461017d57806327ce0147146101a85780633009a609146101c7575f80fd5b3661014e5761014c610468565b005b5f80fd5b61014c610468565b348015610165575f80fd5b506007545b6040519081526020015b60405180910390f35b348015610188575f80fd5b5061016a610197366004610f54565b600d6020525f908152604090205481565b3480156101b3575f80fd5b5061016a6101c2366004610f54565b6104ee565b3480156101d2575f80fd5b5061016a600b5481565b3480156101e7575f80fd5b5061014c6101f6366004610f54565b610550565b348015610206575f80fd5b50610229610215366004610f54565b600c6020525f908152604090205460ff1681565b6040519015158152602001610174565b348015610244575f80fd5b50610258610253366004610f6f565b6105ea565b604080516001600160a01b0390991689526020890197909752958701949094526060860192909252608085015260a084015260c083015260e082015261010001610174565b3480156102a8575f80fd5b5061014c5f80fd5b3480156102bb575f80fd5b5061016a600e5481565b3480156102d0575f80fd5b5061014c610652565b3480156102e4575f80fd5b5061016a60065481565b3480156102f9575f80fd5b505f546040516001600160a01b039091168152602001610174565b34801561031f575f80fd5b5061016a61032e366004610f54565b610663565b34801561033e575f80fd5b5061016a61034d366004610f54565b610669565b34801561035d575f80fd5b5061016a61036c366004610f54565b6001600160a01b03165f9081526003602052604090205490565b348015610391575f80fd5b506102296103a0366004610f86565b610694565b3480156103b0575f80fd5b5061016a7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103e3575f80fd5b5061014c6103f2366004610fc1565b61071b565b348015610402575f80fd5b50600b5461016a565b348015610416575f80fd5b5061014c610425366004610f6f565b610798565b348015610435575f80fd5b5061014c610444366004610f54565b610802565b348015610454575f80fd5b50610258610463366004610f54565b610844565b5f60055411610475575f80fd5b34156104ec576005546104a39061049034600160801b610925565b61049a9190610fff565b60015490610937565b60015560405134815233907fa493a9229478c3fcd73f66d2cdeb7f94fd0f341da924d1054236d784541165119060200160405180910390a26006546104e89034610937565b6006555b565b6001600160a01b0381165f908152600260209081526040808320546004909252822054600154600160801b926105409261053b92610535916105309190610925565b610942565b90610950565b61098a565b61054a9190610fff565b92915050565b61055861099b565b6001600160a01b0381165f908152600c602052604090205460ff161561057c575f80fd5b6001600160a01b0381165f908152600c60205260408120805460ff191660011790556105a99082906109c7565b6105b4600782610b20565b6040516001600160a01b038216907fa878b31040b2e6d0a9a3d3361209db3908ba62014b0dca52adbaee451d128b25905f90a250565b5f805f805f805f806105fb60075490565b891061061e57505f96505f19955085945086935083925082915081905080610647565b5f61062a60078b610c53565b905061063581610844565b98509850985098509850985098509850505b919395975091939597565b61065a61099b565b6104ec5f610c83565b5f61054a825b6001600160a01b0381165f9081526003602052604081205461054a9061068e846104ee565b90610cd2565b5f61069d61099b565b5f6106a784610cdd565b90508015610712576001600160a01b0384165f818152600d6020526040908190204290555184151591907fa2c38e2d2fb7e3e1912d937fd1ca11ed6d51864dee4cfa7a7bf02becd7acf092906107009085815260200190565b60405180910390a3600191505061054a565b505f9392505050565b61072361099b565b6001600160a01b0382165f908152600c602052604090205460ff1661077f577f000000000000000000000000000000000000000000000000000000000000000081106107835761077382826109c7565b61077f60078383610e19565b5050565b61078d825f6109c7565b61077f600783610b20565b6107a061099b565b610e108110806107b257506201518081115b156107d057604051633ff1100360e01b815260040160405180910390fd5b600e5460405182907f474ea64804364a1e29a4487ddb63c3342a2dd826ccd8acf48825e680a0e6f20f905f90a3600e55565b61080a61099b565b6001600160a01b03811661083857604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b61084181610c83565b50565b805f808080808080610857600789610ebf565b96505f1995505f87126108b557600b5487111561088357600b5461087c908890610f07565b95506108b5565b600b546007545f9110610896575f6108a5565b600b546007546108a591610cd2565b90506108b18882610950565b9650505b6108be88610669565b94506108c9886104ee565b6001600160a01b0389165f908152600d60205260409020549094509250826108f1575f6108ff565b600e546108ff908490610937565b915042821161090e575f610918565b6109188242610cd2565b9050919395975091939597565b5f610930828461101e565b9392505050565b5f6109308284611035565b5f818181121561054a575f80fd5b5f8061095c8385611048565b90505f831215801561096e5750838112155b8061098257505f8312801561098257508381125b610930575f80fd5b5f80821215610997575f80fd5b5090565b5f546001600160a01b031633146104ec5760405163118cdaa760e01b815233600482015260240161082f565b6001600160a01b0382165f9081526004602052604090205480821115610a8c575f6109f28383610cd2565b6001600160a01b0385165f90815260046020526040812080549293508392909190610a1e908490611035565b925050819055508060055f828254610a369190611035565b9091555050600154610a6e90610a50906105309084610925565b6001600160a01b0386165f9081526002602052604090205490610f07565b6001600160a01b0385165f9081526002602052604090205550505050565b80821015610b1b575f610a9f8284610cd2565b6001600160a01b0385165f90815260046020526040812080549293508392909190610acb90849061106f565b925050819055508060055f828254610ae3919061106f565b9091555050600154610a6e90610afd906105309084610925565b6001600160a01b0386165f9081526002602052604090205490610950565b505050565b6001600160a01b0381165f90815260038301602052604090205460ff16610b45575050565b6001600160a01b0381165f9081526003830160209081526040808320805460ff1916905560018086018352818420849055600286019092528220548454909291610b8e9161106f565b90505f845f018281548110610ba557610ba5611082565b5f9182526020808320909101546001600160a01b03908116808452600289019092526040808420879055908716835282209190915585549091508190869085908110610bf357610bf3611082565b5f91825260209091200180546001600160a01b0319166001600160a01b03929092169190911790558454859080610c2c57610c2c611096565b5f8281526020902081015f1990810180546001600160a01b03191690550190555050505050565b5f825f018281548110610c6857610c68611082565b5f918252602090912001546001600160a01b03169392505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f610930828461106f565b5f80610ce883610669565b90508015610e11576001600160a01b0383165f90815260036020526040902054610d129082610937565b6001600160a01b0384165f81815260036020526040908190209290925590517fee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d90610d609084815260200190565b60405180910390a25f836001600160a01b031682610bb8906040515f60405180830381858888f193505050503d805f8114610db6576040519150601f19603f3d011682016040523d82523d5f602084013e610dbb565b606091505b5050905080610e0a576001600160a01b0384165f90815260036020526040902054610de69083610cd2565b6001600160a01b039094165f90815260036020526040812094909455509192915050565b5092915050565b505f92915050565b6001600160a01b0382165f90815260038401602052604090205460ff1615610e5c576001600160a01b0382165f9081526001840160205260409020819055505050565b6001600160a01b0382165f8181526003850160209081526040808320805460ff19166001908117909155878101835281842086905587546002890184529184208290558101875586835291200180546001600160a01b0319169091179055505050565b6001600160a01b0381165f90815260038301602052604081205460ff16610ee857505f1961054a565b506001600160a01b03165f908152600291909101602052604090205490565b5f80610f1383856110aa565b90505f8312158015610f255750838113155b8061098257505f831280156109825750838113610930575f80fd5b6001600160a01b0381168114610841575f80fd5b5f60208284031215610f64575f80fd5b813561093081610f40565b5f60208284031215610f7f575f80fd5b5035919050565b5f8060408385031215610f97575f80fd5b8235610fa281610f40565b915060208301358015158114610fb6575f80fd5b809150509250929050565b5f8060408385031215610fd2575f80fd5b8235610fdd81610f40565b946020939093013593505050565b634e487b7160e01b5f52601160045260245ffd5b5f8261101957634e487b7160e01b5f52601260045260245ffd5b500490565b808202811582820484141761054a5761054a610feb565b8082018082111561054a5761054a610feb565b8082018281125f83128015821682158216171561106757611067610feb565b505092915050565b8181038181111561054a5761054a610feb565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52603160045260245ffd5b8181035f831280158383131683831282161715610e0a57610e0a610feb56fea26469706673582212200589d0e5c32d8c73f9ad1e9b97102c0d9415a29951bd0fdaad32d6040b68e36564736f6c63430008140033
Deployed Bytecode
0x608060405260043610610198575f3560e01c8063715018a6116100e7578063a9059cbb11610087578063e2f4560511610062578063e2f45605146104ae578063e98030c7146104c3578063ecc41ee5146104e2578063f2fde38b146104f6575f80fd5b8063a9059cbb14610451578063b2d8f20814610470578063dd62ed3e1461048f575f80fd5b806395d89b41116100c257806395d89b41146103cb5780639fd8234e146103df578063a0a0c465146103fe578063a35c85b014610412575f80fd5b8063715018a61461037b57806375f0a8741461038f5780638da5cb5b146103ae575f80fd5b80632c1f521611610152578063470624021161012d57806347062402146102ed57806349bd5a5e146103075780635d098b381461032657806370a0823114610347575f80fd5b80632c1f52161461029f57806330bb4cff146102be578063313ce567146102d2575f80fd5b806306fdde03146101a3578063095ea7b3146101cd5780631694505e146101fc57806318160ddd1461023357806323b872dd146102515780632b14ca5614610270575f80fd5b3661019f57005b5f80fd5b3480156101ae575f80fd5b506101b7610515565b6040516101c4919061149f565b60405180910390f35b3480156101d8575f80fd5b506101ec6101e73660046114fe565b6105a5565b60405190151581526020016101c4565b348015610207575f80fd5b5060065461021b906001600160a01b031681565b6040516001600160a01b0390911681526020016101c4565b34801561023e575f80fd5b506002545b6040519081526020016101c4565b34801561025c575f80fd5b506101ec61026b366004611528565b6105be565b34801561027b575f80fd5b50600d54600e5461028a919082565b604080519283526020830191909152016101c4565b3480156102aa575f80fd5b5060085461021b906001600160a01b031681565b3480156102c9575f80fd5b506102436105e1565b3480156102dd575f80fd5b50604051601281526020016101c4565b3480156102f8575f80fd5b50600b54600c5461028a919082565b348015610312575f80fd5b5060075461021b906001600160a01b031681565b348015610331575f80fd5b50610345610340366004611566565b610651565b005b348015610352575f80fd5b50610243610361366004611566565b6001600160a01b03165f9081526020819052604090205490565b348015610386575f80fd5b506103456106a9565b34801561039a575f80fd5b50600a5461021b906001600160a01b031681565b3480156103b9575f80fd5b506005546001600160a01b031661021b565b3480156103d6575f80fd5b506101b76106bc565b3480156103ea575f80fd5b506103456103f9366004611588565b6106cb565b348015610409575f80fd5b50610345610738565b34801561041d575f80fd5b5061043161042c366004611566565b61086a565b6040805194855260208501939093529183015260608201526080016101c4565b34801561045c575f80fd5b506101ec61046b3660046114fe565b6108f0565b34801561047b575f80fd5b5061034561048a366004611588565b6108fd565b34801561049a575f80fd5b506102436104a93660046115a8565b610973565b3480156104b9575f80fd5b5061024360095481565b3480156104ce575f80fd5b506103456104dd3660046115df565b61099d565b3480156104ed575f80fd5b50610243610a01565b348015610501575f80fd5b50610345610510366004611566565b610a48565b606060038054610524906115f6565b80601f0160208091040260200160405190810160405280929190818152602001828054610550906115f6565b801561059b5780601f106105725761010080835404028352916020019161059b565b820191905f5260205f20905b81548152906001019060200180831161057e57829003601f168201915b5050505050905090565b5f336105b2818585610a8a565b60019150505b92915050565b5f336105cb858285610a9c565b6105d6858585610af9565b506001949350505050565b600854604080516342d359d760e11b815290515f926001600160a01b0316916385a6b3ae9160048083019260209291908290030181865afa158015610628573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061064c919061162e565b905090565b610659610b56565b600a80546001600160a01b038381166001600160a01b03198316811790935560405191169182917f8616c7a330e3cf61290821331585511f1e2778171e2b005fb5ec60cfe874dc67905f90a35050565b6106b1610b56565b6106ba5f610b83565b565b606060048054610524906115f6565b6106d3610b56565b601e6106df8284611659565b11156106fe57604051631255745b60e31b815260040160405180910390fd5b600d829055600e819055604051819083907f2c7448b63380296b372453c5287509524b5b645dc6a93ffe09e0af53e6b8935b905f90a35050565b60085460405163fbcbc0f160e01b81523360048201526001915f9182916001600160a01b03169063fbcbc0f19060240161010060405180830381865afa158015610784573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107a8919061166c565b50965050509450505050815f036107d25760405163b5596c7560e01b815260040160405180910390fd5b804210156107f3576040516394424e4560e01b815260040160405180910390fd5b60085460405163bc4c4b3760e01b81523360048201525f60248201526001600160a01b039091169063bc4c4b37906044016020604051808303815f875af1158015610840573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061086491906116d1565b50505050565b60085460405163fbcbc0f160e01b81526001600160a01b0383811660048301525f92839283928392169063fbcbc0f19060240161010060405180830381865afa1580156108b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108dd919061166c565b50929b919a509850909650945050505050565b5f336105b2818585610af9565b610905610b56565b601e6109118284611659565b111561093057604051631255745b60e31b815260040160405180910390fd5b600b829055600c81905560405181815282907f480af1f773972b1df72af32ec463e0fdeb1b49f1ca37d07982f677919d5fdd0c9060200160405180910390a25050565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6109a5610b56565b60085460405163e98030c760e01b8152600481018390526001600160a01b039091169063e98030c7906024015f604051808303815f87803b1580156109e8575f80fd5b505af11580156109fa573d5f803e3d5ffd5b5050505050565b600854604080516304ddf6ef60e11b815290515f926001600160a01b0316916309bbedde9160048083019260209291908290030181865afa158015610628573d5f803e3d5ffd5b610a50610b56565b6001600160a01b038116610a7e57604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b610a8781610b83565b50565b610a978383836001610bd4565b505050565b5f610aa78484610973565b90505f1981146108645781811015610aeb57604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610a75565b61086484848484035f610bd4565b6001600160a01b038316610b2257604051634b637e8f60e11b81525f6004820152602401610a75565b6001600160a01b038216610b4b5760405163ec442f0560e01b81525f6004820152602401610a75565b610a97838383610ca6565b6005546001600160a01b031633146106ba5760405163118cdaa760e01b8152336004820152602401610a75565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6001600160a01b038416610bfd5760405163e602df0560e01b81525f6004820152602401610a75565b6001600160a01b038316610c2657604051634a1406b160e11b81525f6004820152602401610a75565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561086457826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610c9891815260200190565b60405180910390a350505050565b805f03610cb857610a9783835f610f78565b305f9081526020819052604090205460095481108015908190610ce55750600754600160a01b900460ff16155b8015610cff57506007546001600160a01b03868116911614155b8015610d1957506005546001600160a01b03868116911614155b8015610d3357506005546001600160a01b03858116911614155b15610d62576007805460ff60a01b1916600160a01b179055610d548261109e565b6007805460ff60a01b191690555b6007546001600160a01b0386165f908152600f602052604090205460ff600160a01b909204821615911680610dae57506001600160a01b0385165f908152600f602052604090205460ff165b15610db657505f5b8015610e5b576007545f906001600160a01b0390811690881603610dfd57600b54600c54606491610de691611659565b610df090876116f0565b610dfa9190611707565b90505b6007546001600160a01b0390811690871603610e3c57600d54600e54606491610e2591611659565b610e2f90876116f0565b610e399190611707565b90505b610e468186611726565b94508015610e5957610e59873083610f78565b505b610e66868686610f78565b6008546001600160a01b031663e30443bc87610e96816001600160a01b03165f9081526020819052604090205490565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044015f604051808303815f87803b158015610ed9575f80fd5b505af1925050508015610eea575060015b506008546001600160a01b031663e30443bc86610f1b816001600160a01b03165f9081526020819052604090205490565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044015f604051808303815f87803b158015610f5e575f80fd5b505af1925050508015610f6f575060015b50505050505050565b6001600160a01b038316610fa2578060025f828254610f979190611659565b909155506110129050565b6001600160a01b0383165f9081526020819052604090205481811015610ff45760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610a75565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661102e5760028054829003905561104c565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161109191815260200190565b60405180910390a3505050565b476110a882611280565b5f6110b38247611726565b600d54600e54600b54600c549394505f936110ce9190611659565b6110d89190611659565b6110e29190611659565b9050801561122757600e54600c545f9183916110fe9190611659565b61110890856116f0565b6111129190611707565b6008549091505f906001600160a01b031661112d8386611726565b6040515f81818185875af1925050503d805f8114611166576040519150601f19603f3d011682016040523d82523d5f602084013e61116b565b606091505b5050600a546040519192505f916001600160a01b039091169047908381818185875af1925050503d805f81146111bc576040519150601f19603f3d011682016040523d82523d5f602084013e6111c1565b606091505b5050905081806111ce5750805b1561121f577f17bbfb9a6069321b6ded73bd96327c9e6b7212a5cd51ff219cd61370acafb56187846112008189611726565b6040805193845260208401929092529082015260600160405180910390a15b505050610864565b600a546040515f916001600160a01b03169047908381818185875af1925050503d805f8114611271576040519150601f19603f3d011682016040523d82523d5f602084013e611276565b606091505b5050505050505050565b6040805160028082526060820183525f9260208301908036833701905050905030815f815181106112b3576112b361174d565b6001600160a01b03928316602091820292909201810191909152600654604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa15801561130a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061132e9190611761565b816001815181106113415761134161174d565b6001600160a01b03928316602091820292909201015260065460405163d06ca61f60e01b81525f92919091169063d06ca61f9061138490869086906004016117be565b5f60405180830381865afa15801561139e573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526113c591908101906117de565b6001815181106113d7576113d761174d565b60200260200101519050826114003060065f9054906101000a90046001600160a01b0316610973565b101561141f5760065461141f9030906001600160a01b03165f19610a8a565b6006546001600160a01b031663791ac94784606461143e8560506116f0565b6114489190611707565b853061145642610168611659565b6040518663ffffffff1660e01b8152600401611476959493929190611897565b5f604051808303815f87803b15801561148d575f80fd5b505af1158015610f6f573d5f803e3d5ffd5b5f6020808352835180828501525f5b818110156114ca578581018301518582016040015282016114ae565b505f604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b0381168114610a87575f80fd5b5f806040838503121561150f575f80fd5b823561151a816114ea565b946020939093013593505050565b5f805f6060848603121561153a575f80fd5b8335611545816114ea565b92506020840135611555816114ea565b929592945050506040919091013590565b5f60208284031215611576575f80fd5b8135611581816114ea565b9392505050565b5f8060408385031215611599575f80fd5b50508035926020909101359150565b5f80604083850312156115b9575f80fd5b82356115c4816114ea565b915060208301356115d4816114ea565b809150509250929050565b5f602082840312156115ef575f80fd5b5035919050565b600181811c9082168061160a57607f821691505b60208210810361162857634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6020828403121561163e575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156105b8576105b8611645565b5f805f805f805f80610100898b031215611684575f80fd5b885161168f816114ea565b809850506020890151965060408901519550606089015194506080890151935060a0890151925060c0890151915060e089015190509295985092959890939650565b5f602082840312156116e1575f80fd5b81518015158114611581575f80fd5b80820281158282048414176105b8576105b8611645565b5f8261172157634e487b7160e01b5f52601260045260245ffd5b500490565b818103818111156105b8576105b8611645565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215611771575f80fd5b8151611581816114ea565b5f8151808452602080850194508084015f5b838110156117b35781516001600160a01b03168752958201959082019060010161178e565b509495945050505050565b828152604060208201525f6117d6604083018461177c565b949350505050565b5f60208083850312156117ef575f80fd5b825167ffffffffffffffff80821115611806575f80fd5b818501915085601f830112611819575f80fd5b81518181111561182b5761182b611739565b8060051b604051601f19603f8301168101818110858211171561185057611850611739565b60405291825284820192508381018501918883111561186d575f80fd5b938501935b8285101561188b57845184529385019392850192611872565b98975050505050505050565b85815284602082015260a060408201525f6118b560a083018661177c565b6001600160a01b039490941660608301525060800152939250505056fea26469706673582212203e19f995260af59be03184a9d273d9c2f7a2e774c67533f814298c87945b6e8a64736f6c63430008140033
Deployed Bytecode Sourcemap
43662:10890:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9887:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;12221:222;;;;;;;;;;-1:-1:-1;12221:222:0;;;;;:::i;:::-;;:::i;:::-;;;1188:14:1;;1181:22;1163:41;;1151:2;1136:18;12221:222:0;1023:187:1;44076:41:0;;;;;;;;;;-1:-1:-1;44076:41:0;;;;-1:-1:-1;;;;;44076:41:0;;;;;;-1:-1:-1;;;;;1405:32:1;;;1387:51;;1375:2;1360:18;44076:41:0;1215:229:1;10989:99:0;;;;;;;;;;-1:-1:-1;11068:12:0;;10989:99;;;1595:25:1;;;1583:2;1568:18;10989:99:0;1449:177:1;13021:283:0;;;;;;;;;;-1:-1:-1;13021:283:0;;;;;:::i;:::-;;:::i;44878:22::-;;;;;;;;;;-1:-1:-1;44878:22:0;;;;;;;;;;;;;2266:25:1;;;2322:2;2307:18;;2300:34;;;;2239:18;44878:22:0;2092:248:1;44274:44:0;;;;;;;;;;-1:-1:-1;44274:44:0;;;;-1:-1:-1;;;;;44274:44:0;;;48441:141;;;;;;;;;;;;;:::i;10840:84::-;;;;;;;;;;-1:-1:-1;10840:84:0;;10914:2;2733:36:1;;2721:2;2706:18;10840:84:0;2591:184:1;44851:20:0;;;;;;;;;;-1:-1:-1;44851:20:0;;;;;;;;;44157:28;;;;;;;;;;-1:-1:-1;44157:28:0;;;;-1:-1:-1;;;;;44157:28:0;;;47278:209;;;;;;;;;;-1:-1:-1;47278:209:0;;;;;:::i;:::-;;:::i;:::-;;11151:118;;;;;;;;;;-1:-1:-1;11151:118:0;;;;;:::i;:::-;-1:-1:-1;;;;;11243:18:0;11216:7;11243:18;;;;;;;;;;;;11151:118;5046:103;;;;;;;;;;;;;:::i;44570:75::-;;;;;;;;;;-1:-1:-1;44570:75:0;;;;-1:-1:-1;;;;;44570:75:0;;;4371:87;;;;;;;;;;-1:-1:-1;4444:6:0;;-1:-1:-1;;;;;4444:6:0;4371:87;;10097:95;;;;;;;;;;;;;:::i;49102:306::-;;;;;;;;;;-1:-1:-1;49102:306:0;;;;;:::i;:::-;;:::i;47607:481::-;;;;;;;;;;;;;:::i;49600:479::-;;;;;;;;;;-1:-1:-1;49600:479:0;;;;;:::i;:::-;;:::i;:::-;;;;3724:25:1;;;3780:2;3765:18;;3758:34;;;;3808:18;;;3801:34;3866:2;3851:18;;3844:34;3711:3;3696:19;49600:479:0;3493:391:1;11474:182:0;;;;;;;;;;-1:-1:-1;11474:182:0;;;;;:::i;:::-;;:::i;48692:302::-;;;;;;;;;;-1:-1:-1;48692:302:0;;;;;:::i;:::-;;:::i;11719:183::-;;;;;;;;;;-1:-1:-1;11719:183:0;;;;;:::i;:::-;;:::i;44483:46::-;;;;;;;;;;;;;;;;48228:124;;;;;;;;;;-1:-1:-1;48228:124:0;;;;;:::i;:::-;;:::i;50145:135::-;;;;;;;;;;;;;:::i;5304:220::-;;;;;;;;;;-1:-1:-1;5304:220:0;;;;;:::i;:::-;;:::i;9887:91::-;9932:13;9965:5;9958:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9887:91;:::o;12221:222::-;12321:4;2701:10;12382:31;2701:10;12398:7;12407:5;12382:8;:31::i;:::-;12431:4;12424:11;;;12221:222;;;;;:::o;13021:283::-;13142:4;2701:10;13200:37;13216:4;2701:10;13231:5;13200:15;:37::i;:::-;13248:26;13258:4;13264:2;13268:5;13248:9;:26::i;:::-;-1:-1:-1;13292:4:0;;13021:283;-1:-1:-1;;;;13021:283:0:o;48441:141::-;48531:15;;:43;;;-1:-1:-1;;;48531:43:0;;;;48504:7;;-1:-1:-1;;;;;48531:15:0;;:41;;:43;;;;;;;;;;;;;;:15;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48524:50;;48441:141;:::o;47278:209::-;4257:13;:11;:13::i;:::-;47372:15:::1;::::0;;-1:-1:-1;;;;;47398:24:0;;::::1;-1:-1:-1::0;;;;;;47398:24:0;::::1;::::0;::::1;::::0;;;47438:41:::1;::::0;47372:15;::::1;::::0;;;47438:41:::1;::::0;47352:17:::1;::::0;47438:41:::1;47341:146;47278:209:::0;:::o;5046:103::-;4257:13;:11;:13::i;:::-;5111:30:::1;5138:1;5111:18;:30::i;:::-;5046:103::o:0;10097:95::-;10144:13;10177:7;10170:14;;;;;:::i;49102:306::-;4257:13;:11;:13::i;:::-;49213:2:::1;49192:18;49201:9:::0;49192:6;:18:::1;:::i;:::-;:23;49188:86;;;49239:23;;-1:-1:-1::0;;;49239:23:0::1;;;;;;;;;;;49188:86;49284:7;:26:::0;;;49321:17;:29;;;49366:34:::1;::::0;49341:9;;49304:6;;49366:34:::1;::::0;49284:17:::1;::::0;49366:34:::1;49102:306:::0;;:::o;47607:481::-;47741:15;;:52;;-1:-1:-1;;;47741:52:0;;47782:10;47741:52;;;1387:51:1;47669:4:0;;47653:13;;;;-1:-1:-1;;;;;47741:15:0;;:40;;1360:18:1;;47741:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47684:109;;;;;;;;;;47808:9;47821:1;47808:14;47804:77;;47846:23;;-1:-1:-1;;;47846:23:0;;;;;;;;;;;47804:77;47913:13;47895:15;:31;47891:94;;;47950:23;;-1:-1:-1;;;47950:23:0;;;;;;;;;;;47891:94;47995:15;;:58;;-1:-1:-1;;;47995:58:0;;48034:10;47995:58;;;6173:51:1;47995:15:0;6240:18:1;;;6233:50;-1:-1:-1;;;;;47995:15:0;;;;:30;;6146:18:1;;47995:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;47607:481:0:o;49600:479::-;50036:15;;:35;;-1:-1:-1;;;50036:35:0;;-1:-1:-1;;;;;1405:32:1;;;50036:35:0;;;1387:51:1;49711:17:0;;;;;;;;50036:15;;:26;;1360:18:1;;50036:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;49865:206:0;;;;-1:-1:-1;49865:206:0;-1:-1:-1;49865:206:0;;-1:-1:-1;49600:479:0;-1:-1:-1;;;;;49600:479:0:o;11474:182::-;11543:4;2701:10;11599:27;2701:10;11616:2;11620:5;11599:9;:27::i;48692:302::-;4257:13;:11;:13::i;:::-;48802:2:::1;48781:18;48790:9:::0;48781:6;:18:::1;:::i;:::-;:23;48777:86;;;48828:23;;-1:-1:-1::0;;;48828:23:0::1;;;;;;;;;;;48777:86;48873:6;:25:::0;;;48909:16;:28;;;48953:33:::1;::::0;1595:25:1;;;48873::0;;48953:33:::1;::::0;1583:2:1;1568:18;48953:33:0::1;;;;;;;48692:302:::0;;:::o;11719:183::-;-1:-1:-1;;;;;11867:18:0;;;11835:7;11867:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;11719:183::o;48228:124::-;4257:13;:11;:13::i;:::-;48302:15:::1;::::0;:42:::1;::::0;-1:-1:-1;;;48302:42:0;;::::1;::::0;::::1;1595:25:1::0;;;-1:-1:-1;;;;;48302:15:0;;::::1;::::0;:31:::1;::::0;1568:18:1;;48302:42:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;48228:124:::0;:::o;50145:135::-;50231:15;;:41;;;-1:-1:-1;;;50231:41:0;;;;50204:7;;-1:-1:-1;;;;;50231:15:0;;:39;;:41;;;;;;;;;;;;;;:15;:41;;;;;;;;;;;;;;5304:220;4257:13;:11;:13::i;:::-;-1:-1:-1;;;;;5389:22:0;::::1;5385:93;;5435:31;::::0;-1:-1:-1;;;5435:31:0;;5463:1:::1;5435:31;::::0;::::1;1387:51:1::0;1360:18;;5435:31:0::1;;;;;;;;5385:93;5488:28;5507:8;5488:18;:28::i;:::-;5304:220:::0;:::o;17182:164::-;17301:37;17310:5;17317:7;17326:5;17333:4;17301:8;:37::i;:::-;17182:164;;;:::o;18975:603::-;19109:24;19136:25;19146:5;19153:7;19136:9;:25::i;:::-;19109:52;;-1:-1:-1;;19176:16:0;:37;19172:399;;19253:5;19234:16;:24;19230:214;;;19286:142;;-1:-1:-1;;;19286:142:0;;-1:-1:-1;;;;;6796:32:1;;19286:142:0;;;6778:51:1;6845:18;;;6838:34;;;6888:18;;;6881:34;;;6751:18;;19286:142:0;6576:345:1;19230:214:0;19487:57;19496:5;19503:7;19531:5;19512:16;:24;19538:5;19487:8;:57::i;13689:342::-;-1:-1:-1;;;;;13807:18:0;;13803:88;;13849:30;;-1:-1:-1;;;13849:30:0;;13876:1;13849:30;;;1387:51:1;1360:18;;13849:30:0;1215:229:1;13803:88:0;-1:-1:-1;;;;;13905:16:0;;13901:88;;13945:32;;-1:-1:-1;;;13945:32:0;;13974:1;13945:32;;;1387:51:1;1360:18;;13945:32:0;1215:229:1;13901:88:0;13999:24;14007:4;14013:2;14017:5;13999:7;:24::i;4536:166::-;4444:6;;-1:-1:-1;;;;;4444:6:0;2701:10;4596:23;4592:103;;4643:40;;-1:-1:-1;;;4643:40:0;;2701:10;4643:40;;;1387:51:1;1360:18;;4643:40:0;1215:229:1;5684:191:0;5777:6;;;-1:-1:-1;;;;;5794:17:0;;;-1:-1:-1;;;;;;5794:17:0;;;;;;;5827:40;;5777:6;;;5794:17;5777:6;;5827:40;;5758:16;;5827:40;5747:128;5684:191;:::o;18197:486::-;-1:-1:-1;;;;;18353:19:0;;18349:91;;18396:32;;-1:-1:-1;;;18396:32:0;;18425:1;18396:32;;;1387:51:1;1360:18;;18396:32:0;1215:229:1;18349:91:0;-1:-1:-1;;;;;18454:21:0;;18450:92;;18499:31;;-1:-1:-1;;;18499:31:0;;18527:1;18499:31;;;1387:51:1;1360:18;;18499:31:0;1215:229:1;18450:92:0;-1:-1:-1;;;;;18552:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;:35;;;18598:78;;;;18649:7;-1:-1:-1;;;;;18633:31:0;18642:5;-1:-1:-1;;;;;18633:31:0;;18658:5;18633:31;;;;1595:25:1;;1583:2;1568:18;;1449:177;18633:31:0;;;;;;;;18197:486;;;;:::o;50380:1873::-;50506:6;50516:1;50506:11;50502:91;;50534:26;50548:4;50554:2;50558:1;50534:13;:26::i;50502:91::-;50654:4;50605:28;11243:18;;;;;;;;;;;50712;;50688:42;;;;;;;50761:33;;-1:-1:-1;50786:8:0;;-1:-1:-1;;;50786:8:0;;;;50785:9;50761:33;:71;;;;-1:-1:-1;50819:13:0;;-1:-1:-1;;;;;50811:21:0;;;50819:13;;50811:21;;50761:71;:103;;;;-1:-1:-1;4444:6:0;;-1:-1:-1;;;;;50849:15:0;;;4444:6;;50849:15;;50761:103;:133;;;;-1:-1:-1;4444:6:0;;-1:-1:-1;;;;;50881:13:0;;;4444:6;;50881:13;;50761:133;50743:291;;;50921:8;:15;;-1:-1:-1;;;;50921:15:0;-1:-1:-1;;;50921:15:0;;;50953:36;50968:20;50953:14;:36::i;:::-;51006:8;:16;;-1:-1:-1;;;;51006:16:0;;;50743:291;51062:8;;-1:-1:-1;;;;;51357:25:0;;51046:12;51357:25;;;:19;:25;;;;;;51062:8;-1:-1:-1;;;51062:8:0;;;;;51061:9;;51357:25;;:52;;-1:-1:-1;;;;;;51386:23:0;;;;;;:19;:23;;;;;;;;51357:52;51353:100;;;-1:-1:-1;51436:5:0;51353:100;51469:7;51465:549;;;51581:13;;51493:12;;-1:-1:-1;;;;;51581:13:0;;;51573:21;;;;51569:123;;51652:6;:16;51633;;51673:3;;51633:35;;;:::i;:::-;51623:46;;:6;:46;:::i;:::-;51622:54;;;;:::i;:::-;51615:61;;51569:123;51748:13;;-1:-1:-1;;;;;51748:13:0;;;51742:19;;;;51738:123;;51820:7;:17;51800;;51842:3;;51800:37;;;:::i;:::-;51790:48;;:6;:48;:::i;:::-;51789:56;;;;:::i;:::-;51782:63;;51738:123;51886:13;51895:4;51886:6;:13;:::i;:::-;51877:22;-1:-1:-1;51918:8:0;;51914:89;;51947:40;51961:4;51975;51982;51947:13;:40::i;:::-;51478:536;51465:549;52026:31;52040:4;52046:2;52050:6;52026:13;:31::i;:::-;52087:15;;-1:-1:-1;;;;;52087:15:0;:26;52122:4;52129:15;52122:4;-1:-1:-1;;;;;11243:18:0;11216:7;11243:18;;;;;;;;;;;;11151:118;52129:15;52087:58;;-1:-1:-1;;;;;;52087:58:0;;;;;;;-1:-1:-1;;;;;7662:32:1;;;52087:58:0;;;7644:51:1;7711:18;;;7704:34;7617:18;;52087:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52070:96;52180:15;;-1:-1:-1;;;;;52180:15:0;:26;52215:2;52220:13;52215:2;-1:-1:-1;;;;;11243:18:0;11216:7;11243:18;;;;;;;;;;;;11151:118;52220:13;52180:54;;-1:-1:-1;;;;;;52180:54:0;;;;;;;-1:-1:-1;;;;;7662:32:1;;;52180:54:0;;;7644:51:1;7711:18;;;7704:34;7617:18;;52180:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52176:70;50491:1762;;;50380:1873;;;:::o;14355:1169::-;-1:-1:-1;;;;;14479:18:0;;14475:552;;14633:5;14617:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;14475:552:0;;-1:-1:-1;14475:552:0;;-1:-1:-1;;;;;14693:15:0;;14671:19;14693:15;;;;;;;;;;;14727:19;;;14723:117;;;14774:50;;-1:-1:-1;;;14774:50:0;;-1:-1:-1;;;;;6796:32:1;;14774:50:0;;;6778:51:1;6845:18;;;6838:34;;;6888:18;;;6881:34;;;6751:18;;14774:50:0;6576:345:1;14723:117:0;-1:-1:-1;;;;;14963:15:0;;:9;:15;;;;;;;;;;14981:19;;;;14963:37;;14475:552;-1:-1:-1;;;;;15043:16:0;;15039:435;;15209:12;:21;;;;;;;15039:435;;;-1:-1:-1;;;;;15425:13:0;;:9;:13;;;;;;;;;;:22;;;;;;15039:435;15506:2;-1:-1:-1;;;;;15491:25:0;15500:4;-1:-1:-1;;;;;15491:25:0;;15510:5;15491:25;;;;1595::1;;1583:2;1568:18;;1449:177;15491:25:0;;;;;;;;14355:1169;;;:::o;52377:1275::-;52461:21;52527:24;52544:6;52527:16;:24::i;:::-;52612:18;52633:38;52657:14;52633:21;:38;:::i;:::-;52799:7;:17;52766;;52734:6;:16;52702;;52612:59;;-1:-1:-1;52682:17:0;;52702:48;;52734:16;52702:48;:::i;:::-;:81;;;;:::i;:::-;:114;;;;:::i;:::-;52682:134;-1:-1:-1;52831:13:0;;52827:818;;52936:17;;52917:16;;52861:21;;52958:9;;52917:36;;52936:17;52917:36;:::i;:::-;52886:68;;:10;:68;:::i;:::-;52885:82;;;;:::i;:::-;53014:15;;52861:106;;-1:-1:-1;52983:9:0;;-1:-1:-1;;;;;53014:15:0;53062:26;52861:106;53062:10;:26;:::i;:::-;52998:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;53147:15:0;;53139:95;;52982:125;;-1:-1:-1;53123:10:0;;-1:-1:-1;;;;;53147:15:0;;;;53194:21;;53123:10;53139:95;53123:10;53139:95;53194:21;53147:15;53139:95;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53122:112;;;53253:4;:13;;;;53261:5;53253:13;53249:206;;;53292:147;53329:6;53358:13;53394:26;53358:13;53394:10;:26;:::i;:::-;53292:147;;;8161:25:1;;;8217:2;8202:18;;8195:34;;;;8245:18;;;8238:34;8149:2;8134:18;53292:147:0;;;;;;;53249:206;52846:620;;;52827:818;;;53532:15;;53516:104;;53488:6;;-1:-1:-1;;;;;53532:15:0;;53580:21;;53488:6;53516:104;53488:6;53516:104;53580:21;53532:15;53516:104;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;52425:1227:0;;;52377:1275;:::o;53701:848::-;53851:16;;;53865:1;53851:16;;;;;;;;53827:21;;53851:16;;;;;;;;;;-1:-1:-1;53851:16:0;53827:40;;53896:4;53878;53883:1;53878:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;53878:23:0;;;:7;;;;;;;;;;:23;;;;53922:15;;:22;;;-1:-1:-1;;;53922:22:0;;;;:15;;;;;:20;;:22;;;;;53878:7;;53922:22;;;;;:15;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53912:4;53917:1;53912:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;53912:32:0;;;:7;;;;;;;;;:32;53969:15;;:48;;-1:-1:-1;;;53969:48:0;;53955:11;;53969:15;;;;;:29;;:48;;53999:11;;54012:4;;53969:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;53969:48:0;;;;;;;;;;;;:::i;:::-;54018:1;53969:51;;;;;;;;:::i;:::-;;;;;;;53955:65;;54088:11;54035:50;54053:4;54068:15;;;;;;;;;-1:-1:-1;;;;;54068:15:0;54035:9;:50::i;:::-;:64;54031:231;;;54183:15;;54116:134;;54151:4;;-1:-1:-1;;;;;54183:15:0;-1:-1:-1;;54116:8:0;:134::i;:::-;54300:15;;-1:-1:-1;;;;;54300:15:0;:66;54381:11;54428:3;54408:16;:3;54415:8;54408:16;:::i;:::-;54407:24;;;;:::i;:::-;54462:4;54489;54509:21;:15;54527:3;54509:21;:::i;:::-;54300:241;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:548:1;126:4;155:2;184;173:9;166:21;216:6;210:13;259:6;254:2;243:9;239:18;232:34;284:1;294:140;308:6;305:1;302:13;294:140;;;403:14;;;399:23;;393:30;369:17;;;388:2;365:26;358:66;323:10;;294:140;;;298:3;483:1;478:2;469:6;458:9;454:22;450:31;443:42;553:2;546;542:7;537:2;529:6;525:15;521:29;510:9;506:45;502:54;494:62;;;;14:548;;;;:::o;567:131::-;-1:-1:-1;;;;;642:31:1;;632:42;;622:70;;688:1;685;678:12;703:315;771:6;779;832:2;820:9;811:7;807:23;803:32;800:52;;;848:1;845;838:12;800:52;887:9;874:23;906:31;931:5;906:31;:::i;:::-;956:5;1008:2;993:18;;;;980:32;;-1:-1:-1;;;703:315:1:o;1631:456::-;1708:6;1716;1724;1777:2;1765:9;1756:7;1752:23;1748:32;1745:52;;;1793:1;1790;1783:12;1745:52;1832:9;1819:23;1851:31;1876:5;1851:31;:::i;:::-;1901:5;-1:-1:-1;1958:2:1;1943:18;;1930:32;1971:33;1930:32;1971:33;:::i;:::-;1631:456;;2023:7;;-1:-1:-1;;;2077:2:1;2062:18;;;;2049:32;;1631:456::o;2988:247::-;3047:6;3100:2;3088:9;3079:7;3075:23;3071:32;3068:52;;;3116:1;3113;3106:12;3068:52;3155:9;3142:23;3174:31;3199:5;3174:31;:::i;:::-;3224:5;2988:247;-1:-1:-1;;;2988:247:1:o;3240:248::-;3308:6;3316;3369:2;3357:9;3348:7;3344:23;3340:32;3337:52;;;3385:1;3382;3375:12;3337:52;-1:-1:-1;;3408:23:1;;;3478:2;3463:18;;;3450:32;;-1:-1:-1;3240:248:1:o;3889:388::-;3957:6;3965;4018:2;4006:9;3997:7;3993:23;3989:32;3986:52;;;4034:1;4031;4024:12;3986:52;4073:9;4060:23;4092:31;4117:5;4092:31;:::i;:::-;4142:5;-1:-1:-1;4199:2:1;4184:18;;4171:32;4212:33;4171:32;4212:33;:::i;:::-;4264:7;4254:17;;;3889:388;;;;;:::o;4282:180::-;4341:6;4394:2;4382:9;4373:7;4369:23;4365:32;4362:52;;;4410:1;4407;4400:12;4362:52;-1:-1:-1;4433:23:1;;4282:180;-1:-1:-1;4282:180:1:o;4467:380::-;4546:1;4542:12;;;;4589;;;4610:61;;4664:4;4656:6;4652:17;4642:27;;4610:61;4717:2;4709:6;4706:14;4686:18;4683:38;4680:161;;4763:10;4758:3;4754:20;4751:1;4744:31;4798:4;4795:1;4788:15;4826:4;4823:1;4816:15;4680:161;;4467:380;;;:::o;4852:184::-;4922:6;4975:2;4963:9;4954:7;4950:23;4946:32;4943:52;;;4991:1;4988;4981:12;4943:52;-1:-1:-1;5014:16:1;;4852:184;-1:-1:-1;4852:184:1:o;5041:127::-;5102:10;5097:3;5093:20;5090:1;5083:31;5133:4;5130:1;5123:15;5157:4;5154:1;5147:15;5173:125;5238:9;;;5259:10;;;5256:36;;;5272:18;;:::i;5303:681::-;5434:6;5442;5450;5458;5466;5474;5482;5490;5543:3;5531:9;5522:7;5518:23;5514:33;5511:53;;;5560:1;5557;5550:12;5511:53;5592:9;5586:16;5611:31;5636:5;5611:31;:::i;:::-;5661:5;5651:15;;;5706:2;5695:9;5691:18;5685:25;5675:35;;5750:2;5739:9;5735:18;5729:25;5719:35;;5794:2;5783:9;5779:18;5773:25;5763:35;;5838:3;5827:9;5823:19;5817:26;5807:36;;5883:3;5872:9;5868:19;5862:26;5852:36;;5928:3;5917:9;5913:19;5907:26;5897:36;;5973:3;5962:9;5958:19;5952:26;5942:36;;5303:681;;;;;;;;;;;:::o;6294:277::-;6361:6;6414:2;6402:9;6393:7;6389:23;6385:32;6382:52;;;6430:1;6427;6420:12;6382:52;6462:9;6456:16;6515:5;6508:13;6501:21;6494:5;6491:32;6481:60;;6537:1;6534;6527:12;6926:168;6999:9;;;7030;;7047:15;;;7041:22;;7027:37;7017:71;;7068:18;;:::i;7099:217::-;7139:1;7165;7155:132;;7209:10;7204:3;7200:20;7197:1;7190:31;7244:4;7241:1;7234:15;7272:4;7269:1;7262:15;7155:132;-1:-1:-1;7301:9:1;;7099:217::o;7321:128::-;7388:9;;;7409:11;;;7406:37;;;7423:18;;:::i;8283:127::-;8344:10;8339:3;8335:20;8332:1;8325:31;8375:4;8372:1;8365:15;8399:4;8396:1;8389:15;8415:127;8476:10;8471:3;8467:20;8464:1;8457:31;8507:4;8504:1;8497:15;8531:4;8528:1;8521:15;8547:251;8617:6;8670:2;8658:9;8649:7;8645:23;8641:32;8638:52;;;8686:1;8683;8676:12;8638:52;8718:9;8712:16;8737:31;8762:5;8737:31;:::i;8803:461::-;8856:3;8894:5;8888:12;8921:6;8916:3;8909:19;8947:4;8976:2;8971:3;8967:12;8960:19;;9013:2;9006:5;9002:14;9034:1;9044:195;9058:6;9055:1;9052:13;9044:195;;;9123:13;;-1:-1:-1;;;;;9119:39:1;9107:52;;9179:12;;;;9214:15;;;;9155:1;9073:9;9044:195;;;-1:-1:-1;9255:3:1;;8803:461;-1:-1:-1;;;;;8803:461:1:o;9269:332::-;9476:6;9465:9;9458:25;9519:2;9514;9503:9;9499:18;9492:30;9439:4;9539:56;9591:2;9580:9;9576:18;9568:6;9539:56;:::i;:::-;9531:64;9269:332;-1:-1:-1;;;;9269:332:1:o;9606:1105::-;9701:6;9732:2;9775;9763:9;9754:7;9750:23;9746:32;9743:52;;;9791:1;9788;9781:12;9743:52;9824:9;9818:16;9853:18;9894:2;9886:6;9883:14;9880:34;;;9910:1;9907;9900:12;9880:34;9948:6;9937:9;9933:22;9923:32;;9993:7;9986:4;9982:2;9978:13;9974:27;9964:55;;10015:1;10012;10005:12;9964:55;10044:2;10038:9;10066:2;10062;10059:10;10056:36;;;10072:18;;:::i;:::-;10118:2;10115:1;10111:10;10150:2;10144:9;10213:2;10209:7;10204:2;10200;10196:11;10192:25;10184:6;10180:38;10268:6;10256:10;10253:22;10248:2;10236:10;10233:18;10230:46;10227:72;;;10279:18;;:::i;:::-;10315:2;10308:22;10365:18;;;10399:15;;;;-1:-1:-1;10441:11:1;;;10437:20;;;10469:19;;;10466:39;;;10501:1;10498;10491:12;10466:39;10525:11;;;;10545:135;10561:6;10556:3;10553:15;10545:135;;;10627:10;;10615:23;;10578:12;;;;10658;;;;10545:135;;;10699:6;9606:1105;-1:-1:-1;;;;;;;;9606:1105:1:o;10716:574::-;11007:6;10996:9;10989:25;11050:6;11045:2;11034:9;11030:18;11023:34;11093:3;11088:2;11077:9;11073:18;11066:31;10970:4;11114:57;11166:3;11155:9;11151:19;11143:6;11114:57;:::i;:::-;-1:-1:-1;;;;;11207:32:1;;;;11202:2;11187:18;;11180:60;-1:-1:-1;11271:3:1;11256:19;11249:35;11106:65;10716:574;-1:-1:-1;;;10716:574:1:o
Swarm Source
ipfs://0589d0e5c32d8c73f9ad1e9b97102c0d9415a29951bd0fdaad32d6040b68e365
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.