- Contract name:
- DoKEN
- Optimization enabled
- true
- Compiler version
- v0.8.6+commit.11564f7e
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2022-04-08T17:29:38.728365Z
Contract source code
// SPDX-License-Identifier: MIT License // File: contracts/SafeMath.sol pragma solidity ^0.8.6; library SafeMath { /** * @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) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @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 sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @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) { // 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 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts 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) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts 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) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts 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 mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message 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, string memory errorMessage ) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: contracts/Context.sol pragma solidity ^0.8.6; /* * @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) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: contracts/Ownable.sol pragma solidity ^0.8.6; contract Ownable is Context { address private _owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: contracts/IERC20.sol pragma solidity ^0.8.6; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: contracts/IERC20Metadata.sol pragma solidity ^0.8.6; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: contracts/ERC20.sol pragma solidity ^0.8.6; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { using SafeMath for uint256; mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve( sender, _msgSender(), _allowances[sender][_msgSender()].sub( amount, "ERC20: transfer amount exceeds allowance" ) ); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve( _msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue) ); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve( _msgSender(), spender, _allowances[_msgSender()][spender].sub( subtractedValue, "ERC20: decreased allowance below zero" ) ); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub( amount, "ERC20: transfer amount exceeds balance" ); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { //require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub( amount, "ERC20: burn amount exceeds balance" ); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // File: contracts/IUniswapV2Factory.sol pragma solidity ^0.8.6; interface IUniswapV2Factory { event PairCreated( address indexed token0, address indexed token1, address pair, uint256 ); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint256) external view returns (address pair); function allPairsLength() external view returns (uint256); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; } // File: contracts/IUniswapRouter.sol pragma solidity ^0.8.6; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns ( uint256 amountA, uint256 amountB, uint256 liquidity ); function addLiquidityETH( address token, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable returns ( uint256 amountToken, uint256 amountETH, uint256 liquidity ); function removeLiquidity( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns (uint256 amountA, uint256 amountB); function removeLiquidityETH( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountToken, uint256 amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountA, uint256 amountB); function removeLiquidityETHWithPermit( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountToken, uint256 amountETH); function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactETHForTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function swapTokensForExactETH( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactTokensForETH( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapETHForExactTokens( uint256 amountOut, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function quote( uint256 amountA, uint256 reserveA, uint256 reserveB ) external pure returns (uint256 amountB); function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) external pure returns (uint256 amountOut); function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut ) external pure returns (uint256 amountIn); 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); } // pragma solidity >=0.6.2; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; 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; } // File: contracts/IUniswapV2Pair.sol pragma solidity ^0.8.6; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint256 value); event Transfer(address indexed from, address indexed to, uint256 value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint256); function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; event Mint(address indexed sender, uint256 amount0, uint256 amount1); event Burn( address indexed sender, uint256 amount0, uint256 amount1, address indexed to ); event Swap( address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint256); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns ( uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast ); function price0CumulativeLast() external view returns (uint256); function price1CumulativeLast() external view returns (uint256); function kLast() external view returns (uint256); function mint(address to) external returns (uint256 liquidity); function burn(address to) external returns (uint256 amount0, uint256 amount1); function swap( uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data ) external; function skim(address to) external; function sync() external; function initialize(address, address) external; } // File: contracts/DoKEN.sol //import "./DoKENDividendTracker.sol"; //import "./DividendPayingToken.sol"; pragma solidity ^0.8.6; contract DoKEN is ERC20, Ownable { using SafeMath for uint256; // Events Declarations event EnableTrading(uint256 indexed blockNumber); event UpdateDividendTracker( address indexed newAddress, address indexed oldAddress ); event UpdateUniswapV2Router( address indexed newAddress, address indexed oldAddress ); event UpdateMarketingWallet( address indexed newWallet, address indexed oldWallet ); event UpdateBuybackWallet( address indexed newWallet, address indexed oldWallet ); event UpdatePresaleWallet( address indexed newWallet, address indexed oldWallet ); event UpdateGasForProcessing( uint256 indexed newValue, uint256 indexed oldValue ); event UpdateMarketingFee(uint256 indexed newValue, uint256 indexed oldValue); event UpdateBuybackFee(uint256 indexed newValue, uint256 indexed oldValue); event UpdateLiquidityFee(uint256 indexed newValue, uint256 indexed oldValue); event UpdateRewardsFee(uint256 indexed newValue, uint256 indexed oldValue); event UpdateSellFee(uint256 indexed newValue, uint256 indexed oldValue); event UpdateMaxBuyTransactionAmount( uint256 indexed newValue, uint256 indexed oldValue ); event UpdateMaxSellTransactionAmount( uint256 indexed newValue, uint256 indexed oldValue ); event UpdateSwapTokensAtAmount( uint256 indexed newValue, uint256 indexed oldValue ); event UpdateSwapAndLiquify(bool enabled); event WhitelistAccount(address indexed account, bool isWhitelisted); event ExcludeFromFees(address indexed account, bool isExcluded); event ExcludeMultipleAccountsFromFees(address[] accounts, bool isExcluded); event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value); event SwapAndLiquify( uint256 tokensSwapped, uint256 ethReceived, uint256 tokensIntoLiqudity ); event SendDividends(uint256 tokensSwapped, uint256 amount); event ProcessedDividendTracker( uint256 iterations, uint256 claims, uint256 lastProcessedIndex, bool indexed automatic, uint256 gas, address indexed processor ); event TransferETHToMarketingWallet(address indexed wallet, uint256 amount); event TransferETHToDevWallet(address indexed wallet, uint256 amount); event TransferTokensToMarketingWallet(address indexed wallet, uint256 amount); event TransferTokensToDevWallet(address indexed wallet, uint256 amount); event TransferETHToBuybackWallet(address indexed wallet, uint256 amount); event TransferTokensToBuybackWallet(address indexed wallet, uint256 amount); event ExcludeAccountFromDividends(address indexed account); // IUniswapV2Router02 public uniswapV2Router; address public immutable uniswapV2Pair; bool private swapping; bool public swapAndLiquifyEnabled = true; // DoKENDividendTracker public dividendTracker; // Constraints for changing various buy/sell thresholds - in practice // actual values should be reasonable uint256 public immutable MIN_BUY_TRANSACTION_AMOUNT = 500000000 * (10**18); // 0.05% of supply uint256 public immutable MAX_BUY_TRANSACTION_AMOUNT = 50000000000 * (10**18); // 5% of supply uint256 public immutable MIN_SELL_TRANSACTION_AMOUNT = 100000000 * (10**18); // 0.01% of total supply uint256 public immutable MAX_SELL_TRANSACTION_AMOUNT = 50000000000 * (10**18); // 5% of total supply uint256 public immutable MIN_SWAP_TOKENS_AT_AMOUNT = 200000000 * (10**18); // 0.02% of total supply uint256 public immutable MAX_SWAP_TOKENS_AT_AMOUNT = 20000000000 * (10**18); // 2% of total supply uint256 public maxBuyTransactionAmount = 10000000000 * (10**18); // 1% of supply uint256 public maxSellTransactionAmount = 10000000000 * (10**18); // 1% of supply uint256 public swapTokensAtAmount = 200000000 * (10**18); // 0.02 % of supply // Max fees to avoid owner greed - in practice the actual fees should be much lower uint256 public immutable MAX_MARKETING_FEE = 10; uint256 public immutable MAX_DEV_FEE = 10; uint256 public immutable MAX_BUYBACK_FEE = 10; uint256 public immutable MAX_REWARDS_FEE = 10; uint256 public immutable MAX_LIQUIDITY_FEE = 5; uint256 public immutable MAX_TOTAL_FEES = 30; uint256 public immutable MAX_SELL_FEE = 5; uint256 public marketingFee = 2; uint256 public devFee = 2; uint256 public buybackFee = 7; uint256 public rewardsFee = 0; uint256 public liquidityFee = 2; uint256 public sellFee = 0; // fees are increased by 3% for sells // Trading can only be enabled, not disabled. Used so that contract can be deployed / liq added // without bots interfering. bool internal tradingEnabled = false; address payable public marketingWallet = payable(0x53cA2a894406848fbB34444859013F068F52FBe1); address payable public devWallet = payable(0x5311c06B4cde0e823d9821DE1fFd24485e9c3F2f); address payable public buybackWallet = payable(0xD92167036635E11931c0b9c08Ff3c2cDB0F46E2D); address payable public preSaleWallet = payable(0xE5988df0403E635349423838d99234515cA0a162); // BUSD Token address public rewardToken = 0xc21223249CA28397B4B6541dfFaEcC539BfF0c59; // mainnet BUSD //address public rewardToken = 0x78867BbEeF44f2326bF8DDd1941a4439382EF2A7; // testnet BUSD // use by default 300,000 gas to process auto-claiming dividends uint256 public gasForProcessing = 300000; // Absolute max gas amount for processing dividends uint256 public immutable MAX_GAS_FOR_PROCESSING = 5000000; // exclude from fees mapping(address => bool) private _isExcludedFromFees; // Can add LP before trading is enabled mapping(address => bool) public isWhitelisted; uint256 public totalFeesCollected; // store addresses that a automatic market maker pairs. Any transfer *to* these addresses // could be subject to a maximum transfer amount mapping(address => bool) public automatedMarketMakerPairs; constructor() ERC20("DoKEN", "DoKEN") { // dividendTracker = new DoKENDividendTracker(); IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02( 0x145677FC4d9b8F19B5D56d1820c48e0443049a30 // mainnet //0x9Ac64Cc6e4415144C455BD8E4837Fea55603e5c3 // testnet ); // Create a uniswap pair for this new token address _uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()) .createPair(address(this), _uniswapV2Router.WETH()); uniswapV2Router = _uniswapV2Router; uniswapV2Pair = _uniswapV2Pair; _setAutomatedMarketMakerPair(_uniswapV2Pair, true); // exclude from receiving dividends. We purposely don't exclude // the marketing wallet from dividends since we're going to use // those dividends for things like giveaways and marketing. These // dividends are more useful than tokens in some cases since selling // them doesnt impact token price. // dividendTracker.excludeFromDividends(address(dividendTracker)); // dividendTracker.excludeFromDividends(address(this)); // dividendTracker.excludeFromDividends(address(_uniswapV2Router)); // dividendTracker.excludeFromDividends(address(0xdEaD)); // dividendTracker.excludeFromDividends(address(0)); // dividendTracker.excludeFromDividends(owner()); // dividendTracker.excludeFromDividends(buybackWallet); // dividendTracker.excludeFromDividends(devWallet); // dividendTracker.excludeFromDividends(preSaleWallet); // exclude from paying fees or having max transaction amount excludeFromFees(address(this), true); excludeFromFees(marketingWallet, true); excludeFromFees(devWallet, true); excludeFromFees(buybackWallet, true); excludeFromFees(preSaleWallet, true); excludeFromFees(owner(), true); excludeFromFees(address(0xdEaD), true); excludeFromFees(address(0), true); // Whitelist accounts so they can transfer tokens before trading is enabled whitelistAccount(address(this), true); whitelistAccount(owner(), true); whitelistAccount(address(uniswapV2Router), true); whitelistAccount(preSaleWallet, true); /* _mint is an internal function in ERC20.sol that is only called here, and CANNOT be called ever again */ _mint(owner(), 1000000000000 * (10**18)); // 1,000,000,000,000 } receive() external payable {} function updateSwapAndLiquify(bool enabled) external onlyOwner { swapAndLiquifyEnabled = enabled; emit UpdateSwapAndLiquify(enabled); } function isTradingEnabled() public view returns (bool) { return tradingEnabled; } function whitelistAccount(address account, bool whitelisted) public onlyOwner { isWhitelisted[account] = whitelisted; emit WhitelistAccount(account, whitelisted); } function isWhitelistedAccount(address account) public view returns (bool) { return isWhitelisted[account]; } function enableTrading() external onlyOwner { require(!tradingEnabled, "trading is already enabled"); tradingEnabled = true; emit EnableTrading(block.number); } function getTotalFees() public view returns (uint256) { return marketingFee.add(buybackFee).add(liquidityFee).add(rewardsFee).add( devFee ); } function updateMarketingWallet(address payable newAddress) external onlyOwner { require(marketingWallet != newAddress, "new address required"); address oldWallet = marketingWallet; marketingWallet = newAddress; excludeFromFees(newAddress, true); emit UpdateMarketingWallet(marketingWallet, oldWallet); } function updateDevWallet(address payable newAddress) external onlyOwner { require(devWallet != newAddress, "new address required"); address oldWallet = devWallet; devWallet = newAddress; excludeFromFees(newAddress, true); emit UpdateMarketingWallet(devWallet, oldWallet); } function updateBuybackWallet(address payable newAddress) external onlyOwner { require(buybackWallet != newAddress, "new address required"); address oldWallet = buybackWallet; buybackWallet = newAddress; excludeFromFees(newAddress, true); emit UpdateBuybackWallet(buybackWallet, oldWallet); } // function updatePreSaleWallet(address payable newAddress) external onlyOwner { // require(preSaleWallet != newAddress, "new address required"); // address oldWallet = preSaleWallet; // preSaleWallet = newAddress; // excludeFromFees(newAddress, true); // dividendTracker.excludeFromDividends(preSaleWallet); // whitelistAccount(preSaleWallet, true); // emit UpdatePresaleWallet(newAddress, oldWallet); // } // function updateDividendTracker(address newAddress) public onlyOwner { // require( // newAddress != address(dividendTracker), // "DoKEN: The dividend tracker already has that address" // ); // DoKENDividendTracker newDividendTracker = DoKENDividendTracker( // payable(newAddress) // ); // require( // newDividendTracker.owner() == address(this), // "DoKEN: The new dividend tracker must be owned by the DoKEN token contract" // ); // newDividendTracker.excludeFromDividends(address(newDividendTracker)); // newDividendTracker.excludeFromDividends(address(this)); // newDividendTracker.excludeFromDividends(address(uniswapV2Router)); // newDividendTracker.excludeFromDividends(address(0xdEaD)); // newDividendTracker.excludeFromDividends(address(0)); // newDividendTracker.excludeFromDividends(owner()); // newDividendTracker.excludeFromDividends(buybackWallet); // newDividendTracker.excludeFromDividends(preSaleWallet); // emit UpdateDividendTracker(newAddress, address(dividendTracker)); // dividendTracker = newDividendTracker; // } function updateUniswapV2Router(address newAddress) public onlyOwner { require( newAddress != address(uniswapV2Router), "DoKEN: The router already has that address" ); emit UpdateUniswapV2Router(newAddress, address(uniswapV2Router)); uniswapV2Router = IUniswapV2Router02(newAddress); } // function excludeAccountFromDividends(address account) public onlyOwner { // dividendTracker.excludeFromDividends(account); // emit ExcludeAccountFromDividends(account); // } // function isExcludedFromDividends(address account) public view returns (bool) { // return dividendTracker.isExcludedFromDividends(account); // } function excludeFromFees(address account, bool excluded) public onlyOwner { _isExcludedFromFees[account] = excluded; emit ExcludeFromFees(account, excluded); } function excludeMultipleAccountsFromFees( address[] calldata accounts, bool excluded ) public onlyOwner { for (uint256 i = 0; i < accounts.length; i++) { _isExcludedFromFees[accounts[i]] = excluded; } emit ExcludeMultipleAccountsFromFees(accounts, excluded); } function setAutomatedMarketMakerPair(address pair, bool value) public onlyOwner { _setAutomatedMarketMakerPair(pair, value); } function _setAutomatedMarketMakerPair(address pair, bool value) private { automatedMarketMakerPairs[pair] = value; // if (value) { // dividendTracker.excludeFromDividends(pair); // } emit SetAutomatedMarketMakerPair(pair, value); } function _validateFees() private view { require(getTotalFees() <= MAX_TOTAL_FEES, "total fees too high"); } function updateMarketingFee(uint256 newFee) external onlyOwner { require(marketingFee != newFee, "new fee required"); require(newFee <= MAX_MARKETING_FEE, "new fee too high"); uint256 oldFee = marketingFee; marketingFee = newFee; _validateFees(); emit UpdateMarketingFee(newFee, oldFee); } function updateDevFee(uint256 newFee) external onlyOwner { require(devFee != newFee, "new fee required"); require(newFee <= MAX_DEV_FEE, "new fee too high"); uint256 oldFee = devFee; devFee = newFee; _validateFees(); emit UpdateMarketingFee(newFee, oldFee); } function updateBuybackFee(uint256 newFee) external onlyOwner { require(buybackFee != newFee, "new fee required"); require(newFee <= MAX_BUYBACK_FEE, "new fee too high"); uint256 oldFee = buybackFee; buybackFee = newFee; _validateFees(); emit UpdateBuybackFee(newFee, oldFee); } function updateLiquidityFee(uint256 newFee) external onlyOwner { require(liquidityFee != newFee, "new fee required"); require(newFee <= MAX_LIQUIDITY_FEE, "new fee too high"); uint256 oldFee = liquidityFee; liquidityFee = newFee; _validateFees(); emit UpdateLiquidityFee(newFee, oldFee); } function updateRewardsFee(uint256 newFee) external onlyOwner { require(rewardsFee != newFee, "new fee required"); require(newFee <= MAX_REWARDS_FEE, "new fee too high"); uint256 oldFee = rewardsFee; rewardsFee = newFee; _validateFees(); emit UpdateRewardsFee(newFee, oldFee); } function updateSellFee(uint256 newFee) external onlyOwner { require(sellFee != newFee, "new fee required"); require(newFee <= MAX_SELL_FEE, "new fee too high"); uint256 oldFee = sellFee; sellFee = newFee; emit UpdateSellFee(newFee, oldFee); } function updateMaxBuyTransactionAmount(uint256 newValue) external onlyOwner { require(maxBuyTransactionAmount != newValue, "new value required"); require( newValue >= MIN_BUY_TRANSACTION_AMOUNT && newValue <= MAX_BUY_TRANSACTION_AMOUNT, "new value must be >= MIN_BUY_TRANSACTION_AMOUNT and <= MAX_BUY_TRANSACTION_AMOUNT" ); uint256 oldValue = maxBuyTransactionAmount; maxBuyTransactionAmount = newValue; emit UpdateMaxBuyTransactionAmount(newValue, oldValue); } function updateMaxSellTransactionAmount(uint256 newValue) external onlyOwner { require(maxSellTransactionAmount != newValue, "new value required"); require( newValue >= MIN_SELL_TRANSACTION_AMOUNT && newValue <= MAX_SELL_TRANSACTION_AMOUNT, "new value must be >= MIN_SELL_TRANSACTION_AMOUNT and <= MAX_SELL_TRANSACTION_AMOUNT" ); uint256 oldValue = maxSellTransactionAmount; maxSellTransactionAmount = newValue; emit UpdateMaxSellTransactionAmount(newValue, oldValue); } function updateSwapTokensAtAmount(uint256 newValue) external onlyOwner { require(swapTokensAtAmount != newValue, "new value required"); require( newValue >= MIN_SWAP_TOKENS_AT_AMOUNT && newValue <= MAX_SWAP_TOKENS_AT_AMOUNT, "new value must be >= MIN_SWAP_TOKENS_AT_AMOUNT and <= MAX_SWAP_TOKENS_AT_AMOUNT" ); uint256 oldValue = swapTokensAtAmount; swapTokensAtAmount = newValue; emit UpdateSwapTokensAtAmount(newValue, oldValue); } function updateGasForProcessing(uint256 newValue) public onlyOwner { require( newValue >= 200000 && newValue <= MAX_GAS_FOR_PROCESSING, "DoKEN: gasForProcessing must be between 200,000 and MAX_GAS_FOR_PROCESSING" ); require( newValue != gasForProcessing, "DoKEN: Cannot update gasForProcessing to same value" ); emit UpdateGasForProcessing(newValue, gasForProcessing); gasForProcessing = newValue; } // function updateClaimWait(uint256 claimWait) external onlyOwner { // dividendTracker.updateClaimWait(claimWait); // } // function getClaimWait() external view returns (uint256) { // return dividendTracker.claimWait(); // } // function getTotalDividendsDistributed() external view returns (uint256) { // return dividendTracker.totalDividendsDistributed(); // } function isExcludedFromFees(address account) public view returns (bool) { return _isExcludedFromFees[account]; } // function processDividendTracker(uint256 gas) external onlyOwner { // ( // uint256 iterations, // uint256 claims, // uint256 lastProcessedIndex // ) = dividendTracker.process(gas); // emit ProcessedDividendTracker( // iterations, // claims, // lastProcessedIndex, // false, // gas, // tx.origin // ); // } function _transfer( address from, address to, uint256 amount ) internal override { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); // Prohibit buys/sells before trading is enabled. This is useful for fair launches for obvious reasons if (from == uniswapV2Pair) { require( tradingEnabled || isWhitelisted[to], "trading isnt enabled or account isnt whitelisted" ); } else if (to == uniswapV2Pair) { require( tradingEnabled || isWhitelisted[from], "trading isnt enabled or account isnt whitelisted" ); } // Enforce max buy if ( automatedMarketMakerPairs[from] && // No max buy when removing liq to != address(uniswapV2Router) ) { require( amount <= maxBuyTransactionAmount, "Transfer amount exceeds the maxTxAmount." ); } if (amount == 0) { super._transfer(from, to, 0); return; } // Enforce max sell if ( !swapping && automatedMarketMakerPairs[to] && // sells only by detecting transfer to automated market maker pair tradingEnabled // we need to be able to add liq before trading is enabled ) { require( amount <= maxSellTransactionAmount, "Sell transfer amount exceeds the maxSellTransactionAmount." ); } uint256 contractTokenBalance = balanceOf(address(this)); bool canSwap = (contractTokenBalance >= swapTokensAtAmount) && swapAndLiquifyEnabled; uint256 totalFees = getTotalFees(); // Swap and liq for sells if (canSwap && !swapping && automatedMarketMakerPairs[to]) { swapping = true; uint256 liquidityAndTeamTokens = contractTokenBalance .mul(liquidityFee.add(marketingFee).add(buybackFee).add(devFee)) .div(totalFees); swapAndLiquifyAndFundTeam(liquidityAndTeamTokens); // uint256 rewardTokens = balanceOf(address(this)); // if (rewardTokens > 0) { // swapAndSendDividends(rewardTokens); // } swapping = false; } // Only take taxes for buys/sells (and obviously dont take taxes during swap and liquify) bool takeFee = !swapping && (automatedMarketMakerPairs[from] || automatedMarketMakerPairs[to]); // if any account belongs to _isExcludedFromFee account then remove the fee if (_isExcludedFromFees[from] || _isExcludedFromFees[to]) { takeFee = false; } if (takeFee) { uint256 fees = amount.mul(totalFees).div(100); // If sell, add extra fee if (automatedMarketMakerPairs[to]) { fees += amount.mul(sellFee).div(100); } totalFeesCollected += fees; amount = amount.sub(fees); super._transfer(from, address(this), fees); } super._transfer(from, to, amount); // Trigger dividends to be paid out //try dividendTracker.setBalance(payable(from), balanceOf(from)) {} catch {} //try dividendTracker.setBalance(payable(to), balanceOf(to)) {} catch {} if (!swapping) { // uint256 gas = gasForProcessing; // try dividendTracker.process(gas) returns ( // uint256 iterations, // uint256 claims, // uint256 lastProcessedIndex // ) { // emit ProcessedDividendTracker( // iterations, // claims, // lastProcessedIndex, // true, // gas, // tx.origin // ); // } catch {} } } function swapAndLiquifyAndFundTeam(uint256 tokens) private { // split the contract balance into halves uint256 half = tokens.div(2); uint256 otherHalf = tokens.sub(half); // capture the contract's current ETH balance. // this is so that we can capture exactly the amount of ETH that the // swap creates, and not make the liquidity event include any ETH that // has been manually sent to the contract uint256 initialBalance = address(this).balance; // swap tokens for ETH swapTokensForEth(half); // <- this breaks the ETH -> HATE swap when swap+liquify is triggered // how much ETH did we just swap into? uint256 newBalance = address(this).balance.sub(initialBalance); // All fees except rewards fee uint256 totalFees = marketingFee.add(buybackFee).add(liquidityFee).add( devFee ); uint256 liquidityTokens = otherHalf.mul(liquidityFee).div(totalFees); uint256 liquidityETH = newBalance.mul(liquidityFee).div(totalFees); uint256 marketingTokens = otherHalf.mul(marketingFee).div(totalFees); uint256 marketingETH = newBalance.mul(marketingFee).div(totalFees); uint256 devTokens = otherHalf.mul(devFee).div(totalFees); uint256 devETH = newBalance.mul(devFee).div(totalFees); uint256 buybackTokens = otherHalf.mul(buybackFee).div(totalFees); uint256 buybackETH = newBalance.mul(buybackFee).div(totalFees); // add liquidity to uniswap (really PCS, duh) addLiquidity(liquidityTokens, liquidityETH); emit SwapAndLiquify(half, newBalance, otherHalf); // Transfer tokens and ETH to marketing wallet _safeTransfer(address(this), marketingWallet, marketingTokens); emit TransferTokensToMarketingWallet(marketingWallet, marketingTokens); marketingWallet.transfer(marketingETH); emit TransferETHToMarketingWallet(marketingWallet, marketingETH); // Transfer tokens and ETH to dev wallet _safeTransfer(address(this), devWallet, devTokens); emit TransferTokensToDevWallet(devWallet, devTokens); devWallet.transfer(devETH); emit TransferETHToMarketingWallet(devWallet, devETH); // Transfer tokens and ETH to buyback wallet _safeTransfer(address(this), buybackWallet, buybackTokens); emit TransferTokensToBuybackWallet(buybackWallet, buybackTokens); buybackWallet.transfer(buybackETH); emit TransferETHToBuybackWallet(buybackWallet, buybackETH); } 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(); _approve(address(this), address(uniswapV2Router), tokenAmount); // make the swap uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens( tokenAmount, 0, // accept any amount of ETH path, address(this), block.timestamp ); } function swapTokensForETH(uint256 tokenAmount, address recipient) private { // generate the uniswap pair path of tokens -> WETH address[] memory path = new address[](2); path[0] = address(this); path[1] = uniswapV2Router.WETH(); _approve(address(this), address(uniswapV2Router), tokenAmount); // make the swap uniswapV2Router.swapExactTokensForETH( tokenAmount, 0, // accept any amount of the reward token path, recipient, block.timestamp ); } function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private { // approve token transfer to cover all possible scenarios _approve(address(this), address(uniswapV2Router), tokenAmount); // add the liquidity uniswapV2Router.addLiquidityETH{ value: ethAmount }( address(this), tokenAmount, 0, // slippage is unavoidable 0, // slippage is unavoidable address(this), // lock LP tokens in this contract forever - no rugpull, SAFU!! block.timestamp ); } function swapTokensForRewards(uint256 tokenAmount, address recipient) private { // generate the uniswap pair path of weth -> reward token address[] memory path = new address[](3); path[0] = address(this); path[1] = uniswapV2Router.WETH(); path[2] = rewardToken; _approve(address(this), address(uniswapV2Router), tokenAmount); // make the swap uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens( tokenAmount, 0, // accept any amount of the reward token path, recipient, block.timestamp ); } // function sendDividends() private returns (bool, uint256) { // uint256 dividends = IERC20(rewardToken).balanceOf(address(this)); // bool success = IERC20(rewardToken).transfer( // address(dividendTracker), // dividends // ); // if (success) { // dividendTracker.distributeRewardTokenDividends(dividends); // } // return (success, dividends); // } // function swapAndSendDividends(uint256 tokens) private { // // Locks the LP tokens in this contract forever // swapTokensForRewards(tokens, address(this)); // (bool success, uint256 dividends) = sendDividends(); // if (success) { // emit SendDividends(tokens, dividends); // } // } // For withdrawing ETH accidentally sent to the contract so senders can be refunded function getETHBalance() public view returns (uint256) { return address(this).balance; } function withdrawOverFlowETH() external onlyOwner { address payable to = payable(msg.sender); to.transfer(getETHBalance()); } function _safeTransfer( address token, address to, uint256 value ) private { bytes4 SELECTOR = bytes4(keccak256(bytes("transfer(address,uint256)"))); (bool success, bytes memory data) = token.call( abi.encodeWithSelector(SELECTOR, to, value) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "TRANSFER_FAILED" ); } // DoKEN Interface for Rewards /** DoKENRewardAddress expect returns the address of your reward for example if its a cake token, then it should return the cake token address */ function DoKENRewardAddress() external view returns (address) { return rewardToken; } /** DoKENRewardOnPool expect returns the balance of reward on the dividend pool */ // function DoKENRewardOnPool() external view returns (uint256) { // return IERC20(rewardToken).balanceOf(address(dividendTracker)); // } /** * DoKENTokenFees expect returns a multiple uint256 * in a precentage , example : 10% the its 10, 20% then its 20, etc * Which represent the fees on your tokens * totalFee,rewardFee,liquidityFee,marketingFee,developerFee,additionalSellingFee * if you're not implementing one of these fee, just return 0 */ function DoKENTokenFees() external view returns ( uint256, uint256, uint256, uint256, uint256, uint256 ) { return ( getTotalFees(), rewardsFee, liquidityFee, marketingFee, devFee, sellFee ); } /** * DoKENRewardDistributed * Should return the amount of distributed Reward */ // function DoKENRewardDistributed() external view returns (uint256) { // return dividendTracker.getTotalDividendsDistributed(); // } /** DoKENGetAccountDividendsInfo Expect returns a dividend information by address, the return values should in these order address account, int256 index, int256 iterationsUntilProcessed, uint256 withdrawableDividends, uint256 withdrawnDividends, uint256 totalDividends, uint256 lastClaimTime, uint256 nextClaimTime, uint256 secondsUntilAutoClaimAvailable */ // function DoKENGetAccountDividendsInfo(address account) // public // view // returns ( // address, // int256, // int256, // uint256, // uint256, // uint256, // uint256, // uint256, // uint256 // ) // { // return dividendTracker.getAccount(account); // } /** DoKENGetAccountDividendsInfoAtIndex Expect returns a dividend information by index, the return values should in these order address account, int256 index, int256 iterationsUntilProcessed, uint256 withdrawableDividends, uint256 withdrawnDividends, uint256 totalDividends, uint256 lastClaimTime, uint256 nextClaimTime, uint256 secondsUntilAutoClaimAvailable */ // function DoKENGetAccountDividendsInfoAtIndex(uint256 index) // public // view // returns ( // address, // int256, // int256, // uint256, // uint256, // uint256, // uint256, // uint256, // uint256 // ) // { // return dividendTracker.getAccountAtIndex(index); // } /** DoKENRewardPaid expect return a uint256 value of the paid reward */ // function DoKENRewardPaid(address holder) external view returns (uint256) { // (, , , , uint256 paidAmount, , , , ) = DoKENGetAccountDividendsInfo(holder); // return paidAmount; // } /** DoKENRewardPaid expect return a uint256 value of the unpaid reward */ // function DoKENRewardUnPaid(address holder) external view returns (uint256) { // (, , , uint256 unpaidAmount, , , , , ) = DoKENGetAccountDividendsInfo( // holder // ); // return unpaidAmount; // } /** Claim Interface */ // function DoKENRewardClaim() external { // dividendTracker.processAccount(payable(msg.sender), false); // } /** Last processed index */ // function DoKENLastProcessedIndex() external view returns (uint256) { // return dividendTracker.getLastProcessedIndex(); // } /** Expect to returns the total holders of the dividend */ // function DoKENNumberOfDividendTokenHolders() external view returns (uint256) { // return dividendTracker.getNumberOfTokenHolders(); // } /** Expect to returns the balance of dividend token of an account */ // function DoKENDividendBalanceOf(address account) // public // view // returns (uint256) // { // return dividendTracker.balanceOf(account); // } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"EnableTrading","inputs":[{"type":"uint256","name":"blockNumber","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"ExcludeAccountFromDividends","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"ExcludeFromFees","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"bool","name":"isExcluded","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"ExcludeMultipleAccountsFromFees","inputs":[{"type":"address[]","name":"accounts","internalType":"address[]","indexed":false},{"type":"bool","name":"isExcluded","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"ProcessedDividendTracker","inputs":[{"type":"uint256","name":"iterations","internalType":"uint256","indexed":false},{"type":"uint256","name":"claims","internalType":"uint256","indexed":false},{"type":"uint256","name":"lastProcessedIndex","internalType":"uint256","indexed":false},{"type":"bool","name":"automatic","internalType":"bool","indexed":true},{"type":"uint256","name":"gas","internalType":"uint256","indexed":false},{"type":"address","name":"processor","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"SendDividends","inputs":[{"type":"uint256","name":"tokensSwapped","internalType":"uint256","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetAutomatedMarketMakerPair","inputs":[{"type":"address","name":"pair","internalType":"address","indexed":true},{"type":"bool","name":"value","internalType":"bool","indexed":true}],"anonymous":false},{"type":"event","name":"SwapAndLiquify","inputs":[{"type":"uint256","name":"tokensSwapped","internalType":"uint256","indexed":false},{"type":"uint256","name":"ethReceived","internalType":"uint256","indexed":false},{"type":"uint256","name":"tokensIntoLiqudity","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TransferETHToBuybackWallet","inputs":[{"type":"address","name":"wallet","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TransferETHToDevWallet","inputs":[{"type":"address","name":"wallet","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TransferETHToMarketingWallet","inputs":[{"type":"address","name":"wallet","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TransferTokensToBuybackWallet","inputs":[{"type":"address","name":"wallet","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TransferTokensToDevWallet","inputs":[{"type":"address","name":"wallet","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TransferTokensToMarketingWallet","inputs":[{"type":"address","name":"wallet","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"UpdateBuybackFee","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256","indexed":true},{"type":"uint256","name":"oldValue","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"UpdateBuybackWallet","inputs":[{"type":"address","name":"newWallet","internalType":"address","indexed":true},{"type":"address","name":"oldWallet","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"UpdateDividendTracker","inputs":[{"type":"address","name":"newAddress","internalType":"address","indexed":true},{"type":"address","name":"oldAddress","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"UpdateGasForProcessing","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256","indexed":true},{"type":"uint256","name":"oldValue","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"UpdateLiquidityFee","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256","indexed":true},{"type":"uint256","name":"oldValue","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"UpdateMarketingFee","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256","indexed":true},{"type":"uint256","name":"oldValue","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"UpdateMarketingWallet","inputs":[{"type":"address","name":"newWallet","internalType":"address","indexed":true},{"type":"address","name":"oldWallet","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"UpdateMaxBuyTransactionAmount","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256","indexed":true},{"type":"uint256","name":"oldValue","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"UpdateMaxSellTransactionAmount","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256","indexed":true},{"type":"uint256","name":"oldValue","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"UpdatePresaleWallet","inputs":[{"type":"address","name":"newWallet","internalType":"address","indexed":true},{"type":"address","name":"oldWallet","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"UpdateRewardsFee","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256","indexed":true},{"type":"uint256","name":"oldValue","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"UpdateSellFee","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256","indexed":true},{"type":"uint256","name":"oldValue","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"UpdateSwapAndLiquify","inputs":[{"type":"bool","name":"enabled","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"UpdateSwapTokensAtAmount","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256","indexed":true},{"type":"uint256","name":"oldValue","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"UpdateUniswapV2Router","inputs":[{"type":"address","name":"newAddress","internalType":"address","indexed":true},{"type":"address","name":"oldAddress","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"WhitelistAccount","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"bool","name":"isWhitelisted","internalType":"bool","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"DoKENRewardAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"DoKENTokenFees","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_BUYBACK_FEE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_BUY_TRANSACTION_AMOUNT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_DEV_FEE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_GAS_FOR_PROCESSING","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_LIQUIDITY_FEE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_MARKETING_FEE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_REWARDS_FEE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_SELL_FEE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_SELL_TRANSACTION_AMOUNT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_SWAP_TOKENS_AT_AMOUNT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_TOTAL_FEES","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MIN_BUY_TRANSACTION_AMOUNT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MIN_SELL_TRANSACTION_AMOUNT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MIN_SWAP_TOKENS_AT_AMOUNT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"automatedMarketMakerPairs","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"buybackFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"buybackWallet","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"devFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"devWallet","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableTrading","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"excludeFromFees","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"bool","name":"excluded","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"excludeMultipleAccountsFromFees","inputs":[{"type":"address[]","name":"accounts","internalType":"address[]"},{"type":"bool","name":"excluded","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"gasForProcessing","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getETHBalance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTotalFees","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isExcludedFromFees","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isTradingEnabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isWhitelisted","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isWhitelistedAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"liquidityFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"marketingFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"marketingWallet","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxBuyTransactionAmount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxSellTransactionAmount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"preSaleWallet","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"rewardToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardsFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"sellFee","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAutomatedMarketMakerPair","inputs":[{"type":"address","name":"pair","internalType":"address"},{"type":"bool","name":"value","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"swapAndLiquifyEnabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"swapTokensAtAmount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalFeesCollected","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"uniswapV2Pair","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IUniswapV2Router02"}],"name":"uniswapV2Router","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateBuybackFee","inputs":[{"type":"uint256","name":"newFee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateBuybackWallet","inputs":[{"type":"address","name":"newAddress","internalType":"address payable"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateDevFee","inputs":[{"type":"uint256","name":"newFee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateDevWallet","inputs":[{"type":"address","name":"newAddress","internalType":"address payable"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateGasForProcessing","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateLiquidityFee","inputs":[{"type":"uint256","name":"newFee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateMarketingFee","inputs":[{"type":"uint256","name":"newFee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateMarketingWallet","inputs":[{"type":"address","name":"newAddress","internalType":"address payable"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateMaxBuyTransactionAmount","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateMaxSellTransactionAmount","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateRewardsFee","inputs":[{"type":"uint256","name":"newFee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateSellFee","inputs":[{"type":"uint256","name":"newFee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateSwapAndLiquify","inputs":[{"type":"bool","name":"enabled","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateSwapTokensAtAmount","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateUniswapV2Router","inputs":[{"type":"address","name":"newAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"whitelistAccount","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"bool","name":"whitelisted","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawOverFlowETH","inputs":[]},{"type":"receive","stateMutability":"payable"}]
Contract Creation Code
0x6102606040526006805460ff60a81b1916600160a81b1790556b019d971e4fe8401e7400000060a0526ba18f07d736b90be55000000060c08190526a52b7d2dcc80cd2e400000060e052610100526aa56fa5b99019a5c80000006101208190526b409f9cbc7c4a04c220000000610140526b204fce5e3e250261100000006007818155600891909155600991909155600a6101608190526101808190526101a08190526101c081905260056101e0819052601e6102005261022052600290819055600b819055600c919091556000600d819055600e91909155600f55601080547453ca2a894406848fbb34444859013f068f52fbe1006001600160a81b0319909116179055601180546001600160a01b0319908116735311c06b4cde0e823d9821de1ffd24485e9c3f2f1790915560128054821673d92167036635e11931c0b9c08ff3c2cdb0f46e2d17905560138054821673e5988df0403e635349423838d99234515ca0a1621790556014805490911673c21223249ca28397b4b6541dffaecc539bff0c59179055620493e0601555624c4b4061024052348015620001a457600080fd5b506040805180820182526005808252642237a5a2a760d91b602080840182815285518087019096529285528401528151919291620001e5916003916200082e565b508051620001fb9060049060208401906200082e565b5050506000620002106200057560201b60201c565b600580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600073145677fc4d9b8f19b5d56d1820c48e0443049a3090506000816001600160a01b031663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b158015620002b357600080fd5b505afa158015620002c8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002ee9190620008d4565b6001600160a01b031663c9c6539630846001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b1580156200033757600080fd5b505afa1580156200034c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003729190620008d4565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381600087803b158015620003bb57600080fd5b505af1158015620003d0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003f69190620008d4565b600680546001600160a01b0319166001600160a01b038516179055606081901b6001600160601b03191660805290506200043281600162000579565b6200043f306001620005cd565b6010546200045d9061010090046001600160a01b03166001620005cd565b60115462000476906001600160a01b03166001620005cd565b6012546200048f906001600160a01b03166001620005cd565b601354620004a8906001600160a01b03166001620005cd565b620004c7620004bf6005546001600160a01b031690565b6001620005cd565b620004d661dead6001620005cd565b620004e460006001620005cd565b620004f13060016200067c565b62000510620005086005546001600160a01b031690565b60016200067c565b60065462000529906001600160a01b031660016200067c565b60135462000542906001600160a01b031660016200067c565b6200056d620005596005546001600160a01b031690565b6c0c9f2c9cd04674edea4000000062000720565b505062000963565b3390565b6001600160a01b038216600081815260196020526040808220805460ff191685151590811790915590519092917fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab91a35050565b6005546001600160a01b031633146200061c5760405162461bcd60e51b81526020600482018190526024820152600080516020620046d483398151915260448201526064015b60405180910390fd5b6001600160a01b038216600081815260166020908152604091829020805460ff191685151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df791015b60405180910390a25050565b6005546001600160a01b03163314620006c75760405162461bcd60e51b81526020600482018190526024820152600080516020620046d4833981519152604482015260640162000613565b6001600160a01b038216600081815260176020908152604091829020805460ff191685151590811790915591519182527fb8e94100c3d15375b309e7a2a3e9617478f7882eba6a26bd0e85cd2443f70761910162000670565b6200073c81600254620007c460201b6200240e1790919060201c565b6002556001600160a01b038216600090815260208181526040909120546200076f9183906200240e620007c4821b17901c565b6001600160a01b038316600081815260208181526040808320949094559251848152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600080620007d38385620008ff565b905083811015620008275760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015260640162000613565b9392505050565b8280546200083c9062000926565b90600052602060002090601f016020900481019282620008605760008555620008ab565b82601f106200087b57805160ff1916838001178555620008ab565b82800160010185558215620008ab579182015b82811115620008ab5782518255916020019190600101906200088e565b50620008b9929150620008bd565b5090565b5b80821115620008b95760008155600101620008be565b600060208284031215620008e757600080fd5b81516001600160a01b03811681146200082757600080fd5b600082198211156200092157634e487b7160e01b600052601160045260246000fd5b500190565b600181811c908216806200093b57607f821691505b602082108114156200095d57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160601c60a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e051610200516102205161024051613c4b62000a8960003960008181610ea60152611888015260008181610a1d015261129f015260008181610d6301526124760152600081816106ae0152611ad6015260008181610b1801526110fb015260008181610bed0152611ef3015260008181610e520152611bb2015260008181610a71015261211e015260008181610ca101526121e501526000818161088f01526121ba015260008181610f300152611559015260008181610612015261152e0152600081816107bd01526113f801526000818161090e01526113cd0152600081816107680152818161265601526126da0152613c4b6000f3fe6080604052600436106104565760003560e01c806375f0a8741161023f578063a9059cbb11610139578063d257b34f116100b6578063e1a606fa1161007a578063e1a606fa14610e94578063e2f4560514610ec8578063f2fde38b14610ede578063f7c618c114610efe578063fd5db2af14610f1e57600080fd5b8063d257b34f14610dc5578063d863f0e714610de5578063dd62ed3e14610dfa578063dddc4f4414610e40578063deab8aea14610e7457600080fd5b8063bf8b1473116100fd578063bf8b147314610d11578063c024666814610d31578063c3a1ed4814610d51578063c492f04614610d85578063cf38287714610da557600080fd5b8063a9059cbb14610c4f578063aacebbe314610c6f578063af21c6d314610c8f578063b51aebbb14610cc3578063b62496f514610ce157600080fd5b8063911140bb116101c75780639a7a23d61161018b5780639a7a23d614610ba55780639c1b8af514610bc5578063a1b8272314610bdb578063a457c2d714610c0f578063a716d66114610c2f57600080fd5b8063911140bb14610b0657806395d89b4114610b3a57806398118cb414610b4f57806399729ec114610b6557806399c8df1814610b8557600080fd5b80638a7a8cca1161020e5780638a7a8cca14610a5f5780638a8c523c14610a935780638da5cb5b14610aa85780638e67566314610ac65780638ea5220f14610ae657600080fd5b806375f0a874146109a457806385541cda146109c9578063867508ad14610a0b578063871c128d14610a3f57600080fd5b8063395093511161035057806360c6d8ae116102d8578063691151c51161029c578063691151c5146108fc5780636b67c4df146109305780636e9472981461094657806370a0823114610959578063715018a61461098f57600080fd5b806360c6d8ae14610867578063620dff3d1461087d578063626e1ae7146108b157806365b8dbc0146108c65780636827e764146108e657600080fd5b80634a74bb021161031f5780634a74bb021461078a5780634de18a9f146107ab5780634fbee193146107df57806354789a5e146108185780635aa821a91461085157600080fd5b806339509351146106f05780633af32abf146107105780633b2d081c1461074057806349bd5a5e1461075657600080fd5b80631d933a4a116103de5780632bb14e1d116103a25780632bb14e1d1461064a5780632c59d46414610660578063313ce5671461068057806333ced6e21461069c5780633868e419146106d057600080fd5b80631d933a4a146105a05780631fc75e41146105c057806323b872dd146105e057806328eb2dcf146106005780632b14ca561461063457600080fd5b8063084a6bff11610425578063084a6bff146104f3578063095ea7b3146105135780631694505e1461053357806318160ddd1461056b5780631816467f1461058057600080fd5b806302259e9e1461046257806304dacd501461048b578063064a59d0146104ad57806306fdde03146104d157600080fd5b3661045d57005b600080fd5b34801561046e57600080fd5b5061047860085481565b6040519081526020015b60405180910390f35b34801561049757600080fd5b506104ab6104a6366004613571565b610f52565b005b3480156104b957600080fd5b5060105460ff165b6040519015158152602001610482565b3480156104dd57600080fd5b506104e661101b565b60405161048291906137fb565b3480156104ff57600080fd5b506104ab61050e36600461373f565b6110ad565b34801561051f57600080fd5b506104c161052e366004613653565b61117a565b34801561053f57600080fd5b50600654610553906001600160a01b031681565b6040516001600160a01b039091168152602001610482565b34801561057757600080fd5b50600254610478565b34801561058c57600080fd5b506104ab61059b366004613571565b611191565b3480156105ac57600080fd5b506104ab6105bb36600461373f565b611251565b3480156105cc57600080fd5b50601354610553906001600160a01b031681565b3480156105ec57600080fd5b506104c16105fb3660046135e4565b611316565b34801561060c57600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b34801561064057600080fd5b50610478600f5481565b34801561065657600080fd5b50610478600d5481565b34801561066c57600080fd5b506104ab61067b36600461373f565b61137f565b34801561068c57600080fd5b5060405160128152602001610482565b3480156106a857600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b3480156106dc57600080fd5b506104ab6106eb36600461373f565b6114e0565b3480156106fc57600080fd5b506104c161070b366004613653565b611643565b34801561071c57600080fd5b506104c161072b366004613571565b60176020526000908152604090205460ff1681565b34801561074c57600080fd5b50610478600c5481565b34801561076257600080fd5b506105537f000000000000000000000000000000000000000000000000000000000000000081565b34801561079657600080fd5b506006546104c190600160a81b900460ff1681565b3480156107b757600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b3480156107eb57600080fd5b506104c16107fa366004613571565b6001600160a01b031660009081526016602052604090205460ff1690565b34801561082457600080fd5b506104c1610833366004613571565b6001600160a01b031660009081526017602052604090205460ff1690565b34801561085d57600080fd5b5061047860075481565b34801561087357600080fd5b5061047860185481565b34801561088957600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b3480156108bd57600080fd5b50610478611679565b3480156108d257600080fd5b506104ab6108e1366004613571565b6116af565b3480156108f257600080fd5b50610478600b5481565b34801561090857600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b34801561093c57600080fd5b50610478600a5481565b34801561095257600080fd5b5047610478565b34801561096557600080fd5b50610478610974366004613571565b6001600160a01b031660009081526020819052604090205490565b34801561099b57600080fd5b506104ab6117a7565b3480156109b057600080fd5b506010546105539061010090046001600160a01b031681565b3480156109d557600080fd5b506109de61181b565b604080519687526020870195909552938501929092526060840152608083015260a082015260c001610482565b348015610a1757600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b348015610a4b57600080fd5b506104ab610a5a36600461373f565b61184e565b348015610a6b57600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b348015610a9f57600080fd5b506104ab6119d1565b348015610ab457600080fd5b506005546001600160a01b0316610553565b348015610ad257600080fd5b506104ab610ae136600461373f565b611a88565b348015610af257600080fd5b50601154610553906001600160a01b031681565b348015610b1257600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b348015610b4657600080fd5b506104e6611b55565b348015610b5b57600080fd5b50610478600e5481565b348015610b7157600080fd5b506104ab610b8036600461373f565b611b64565b348015610b9157600080fd5b506104ab610ba0366004613625565b611c31565b348015610bb157600080fd5b506104ab610bc0366004613625565b611cbb565b348015610bd157600080fd5b5061047860155481565b348015610be757600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b348015610c1b57600080fd5b506104c1610c2a366004613653565b611cf3565b348015610c3b57600080fd5b506104ab610c4a366004613705565b611d42565b348015610c5b57600080fd5b506104c1610c6a366004613653565b611dc4565b348015610c7b57600080fd5b506104ab610c8a366004613571565b611dd1565b348015610c9b57600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b348015610ccf57600080fd5b506014546001600160a01b0316610553565b348015610ced57600080fd5b506104c1610cfc366004613571565b60196020526000908152604090205460ff1681565b348015610d1d57600080fd5b506104ab610d2c36600461373f565b611ea5565b348015610d3d57600080fd5b506104ab610d4c366004613625565b611f72565b348015610d5d57600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b348015610d9157600080fd5b506104ab610da036600461367f565b611ff4565b348015610db157600080fd5b506104ab610dc036600461373f565b6120d0565b348015610dd157600080fd5b506104ab610de036600461373f565b61216c565b348015610df157600080fd5b506104ab6122cb565b348015610e0657600080fd5b50610478610e153660046135ab565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b348015610e4c57600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b348015610e8057600080fd5b50601254610553906001600160a01b031681565b348015610ea057600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b348015610ed457600080fd5b5061047860095481565b348015610eea57600080fd5b506104ab610ef9366004613571565b612323565b348015610f0a57600080fd5b50601454610553906001600160a01b031681565b348015610f2a57600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b6005546001600160a01b03163314610f855760405162461bcd60e51b8152600401610f7c90613941565b60405180910390fd5b6012546001600160a01b0382811691161415610fb35760405162461bcd60e51b8152600401610f7c90613976565b601280546001600160a01b038381166001600160a01b031983161790925516610fdd826001611f72565b6012546040516001600160a01b038084169216907f11ef31775640906cd48f5ad1c2c79269a9f4f4b49df05c59d175d50b53c2daa590600090a35050565b60606003805461102a90613afa565b80601f016020809104026020016040519081016040528092919081815260200182805461105690613afa565b80156110a35780601f10611078576101008083540402835291602001916110a3565b820191906000526020600020905b81548152906001019060200180831161108657829003601f168201915b5050505050905090565b6005546001600160a01b031633146110d75760405162461bcd60e51b8152600401610f7c90613941565b80600d5414156110f95760405162461bcd60e51b8152600401610f7c90613871565b7f00000000000000000000000000000000000000000000000000000000000000008111156111395760405162461bcd60e51b8152600401610f7c906138c7565b600d805490829055611149612474565b604051819083907fc78f282c12d02e0b7183c178d32e56110e4dbacf8894091ac8a848bb5018afe590600090a35050565b60006111873384846124e3565b5060015b92915050565b6005546001600160a01b031633146111bb5760405162461bcd60e51b8152600401610f7c90613941565b6011546001600160a01b03828116911614156111e95760405162461bcd60e51b8152600401610f7c90613976565b601180546001600160a01b038381166001600160a01b031983161790925516611213826001611f72565b6011546040516001600160a01b038084169216907facf03c50dcf01e53e2775267d12acd0158d87c2f20fb84226837142693b36ae790600090a35050565b6005546001600160a01b0316331461127b5760405162461bcd60e51b8152600401610f7c90613941565b80600f54141561129d5760405162461bcd60e51b8152600401610f7c90613871565b7f00000000000000000000000000000000000000000000000000000000000000008111156112dd5760405162461bcd60e51b8152600401610f7c906138c7565b600f805490829055604051819083907fde4022aab72c416fa5c54f5b02a3d8ce50d8a9418a85c790d51cf759ebb4697d90600090a35050565b6000611323848484612608565b611375843361137085604051806060016040528060288152602001613bc9602891396001600160a01b038a1660009081526001602090815260408083203384529091529020549190612af3565b6124e3565b5060019392505050565b6005546001600160a01b031633146113a95760405162461bcd60e51b8152600401610f7c90613941565b8060075414156113cb5760405162461bcd60e51b8152600401610f7c9061389b565b7f0000000000000000000000000000000000000000000000000000000000000000811015801561141b57507f00000000000000000000000000000000000000000000000000000000000000008111155b6114a75760405162461bcd60e51b815260206004820152605160248201527f6e65772076616c7565206d757374206265203e3d204d494e5f4255595f54524160448201527f4e53414354494f4e5f414d4f554e5420616e64203c3d204d41585f4255595f5460648201527014905394d050d51253d397d05353d55395607a1b608482015260a401610f7c565b6007805490829055604051819083907faa209eb5afb6ff458141497695fb05bfc2c447ac2a5806592df3d6e03857060790600090a35050565b6005546001600160a01b0316331461150a5760405162461bcd60e51b8152600401610f7c90613941565b80600854141561152c5760405162461bcd60e51b8152600401610f7c9061389b565b7f0000000000000000000000000000000000000000000000000000000000000000811015801561157c57507f00000000000000000000000000000000000000000000000000000000000000008111155b61160a5760405162461bcd60e51b815260206004820152605360248201527f6e65772076616c7565206d757374206265203e3d204d494e5f53454c4c5f545260448201527f414e53414354494f4e5f414d4f554e5420616e64203c3d204d41585f53454c4c60648201527217d514905394d050d51253d397d05353d55395606a1b608482015260a401610f7c565b6008805490829055604051819083907faa0c87acaf40080121dd0db81a6a1c8f73f141d0af1ee48ac1ca402473ec5e9690600090a35050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091611187918590611370908661240e565b60006116aa600b546116a4600d546116a4600e546116a4600c54600a5461240e90919063ffffffff16565b9061240e565b905090565b6005546001600160a01b031633146116d95760405162461bcd60e51b8152600401610f7c90613941565b6006546001600160a01b038281169116141561174a5760405162461bcd60e51b815260206004820152602a60248201527f446f4b454e3a2054686520726f7574657220616c7265616479206861732074686044820152696174206164647265737360b01b6064820152608401610f7c565b6006546040516001600160a01b03918216918316907f8fc842bbd331dfa973645f4ed48b11683d501ebf1352708d77a5da2ab49a576e90600090a3600680546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b031633146117d15760405162461bcd60e51b8152600401610f7c90613941565b6005546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580546001600160a01b0319169055565b60008060008060008061182c611679565b600d54600e54600a54600b54600f54949b939a50919850965094509092509050565b6005546001600160a01b031633146118785760405162461bcd60e51b8152600401610f7c90613941565b62030d4081101580156118ab57507f00000000000000000000000000000000000000000000000000000000000000008111155b6119305760405162461bcd60e51b815260206004820152604a60248201527f446f4b454e3a20676173466f7250726f63657373696e67206d7573742062652060448201527f6265747765656e203230302c30303020616e64204d41585f4741535f464f525f60648201526950524f43455353494e4760b01b608482015260a401610f7c565b60155481141561199e5760405162461bcd60e51b815260206004820152603360248201527f446f4b454e3a2043616e6e6f742075706461746520676173466f7250726f63656044820152727373696e6720746f2073616d652076616c756560681b6064820152608401610f7c565b60155460405182907f86abf19b93006da5f33a92bcf64ec9a9f116166bcba5a1af6123d5a69eeaab0890600090a3601555565b6005546001600160a01b031633146119fb5760405162461bcd60e51b8152600401610f7c90613941565b60105460ff1615611a4e5760405162461bcd60e51b815260206004820152601a60248201527f74726164696e6720697320616c726561647920656e61626c65640000000000006044820152606401610f7c565b6010805460ff1916600117905560405143907f68a240f91e5b394de2084f3f756296fb39b577fde5e53a8f226c1ca5f308e8f890600090a2565b6005546001600160a01b03163314611ab25760405162461bcd60e51b8152600401610f7c90613941565b80600e541415611ad45760405162461bcd60e51b8152600401610f7c90613871565b7f0000000000000000000000000000000000000000000000000000000000000000811115611b145760405162461bcd60e51b8152600401610f7c906138c7565b600e805490829055611b24612474565b604051819083907fc09bba22c83c2fe84cd31b6fa35a826e2d7ad60ae3c8d135dab825556baee73890600090a35050565b60606004805461102a90613afa565b6005546001600160a01b03163314611b8e5760405162461bcd60e51b8152600401610f7c90613941565b80600b541415611bb05760405162461bcd60e51b8152600401610f7c90613871565b7f0000000000000000000000000000000000000000000000000000000000000000811115611bf05760405162461bcd60e51b8152600401610f7c906138c7565b600b805490829055611c00612474565b604051819083907f16d83edfca27a95b3a9be436199cca08d3b65d5f9a25264391be22e9cdbb45b690600090a35050565b6005546001600160a01b03163314611c5b5760405162461bcd60e51b8152600401610f7c90613941565b6001600160a01b038216600081815260176020908152604091829020805460ff191685151590811790915591519182527fb8e94100c3d15375b309e7a2a3e9617478f7882eba6a26bd0e85cd2443f7076191015b60405180910390a25050565b6005546001600160a01b03163314611ce55760405162461bcd60e51b8152600401610f7c90613941565b611cef8282612b2d565b5050565b6000611187338461137085604051806060016040528060258152602001613bf1602591393360009081526001602090815260408083206001600160a01b038d1684529091529020549190612af3565b6005546001600160a01b03163314611d6c5760405162461bcd60e51b8152600401610f7c90613941565b60068054821515600160a81b0260ff60a81b199091161790556040517f701507a13d5701687328d70ea5a717a33a062f46c229a785b315fb4517fef06990611db990831515815260200190565b60405180910390a150565b6000611187338484612608565b6005546001600160a01b03163314611dfb5760405162461bcd60e51b8152600401610f7c90613941565b6010546001600160a01b03828116610100909204161415611e2e5760405162461bcd60e51b8152600401610f7c90613976565b601080546001600160a01b03838116610100908102610100600160a81b031984161790935591900416611e62826001611f72565b6010546040516001600160a01b0380841692610100900416907facf03c50dcf01e53e2775267d12acd0158d87c2f20fb84226837142693b36ae790600090a35050565b6005546001600160a01b03163314611ecf5760405162461bcd60e51b8152600401610f7c90613941565b80600c541415611ef15760405162461bcd60e51b8152600401610f7c90613871565b7f0000000000000000000000000000000000000000000000000000000000000000811115611f315760405162461bcd60e51b8152600401610f7c906138c7565b600c805490829055611f41612474565b604051819083907f0a45c4d096a8b955abedb6a180bf61cff0a8aff3f57819ee58cceb87df435ca390600090a35050565b6005546001600160a01b03163314611f9c5760405162461bcd60e51b8152600401610f7c90613941565b6001600160a01b038216600081815260166020908152604091829020805460ff191685151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df79101611caf565b6005546001600160a01b0316331461201e5760405162461bcd60e51b8152600401610f7c90613941565b60005b8281101561208f57816016600086868581811061204057612040613b66565b90506020020160208101906120559190613571565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558061208781613b35565b915050612021565b507f7fdaf542373fa84f4ee8d662c642f44e4c2276a217d7d29e548b6eb29a233b358383836040516120c3939291906137a2565b60405180910390a1505050565b6005546001600160a01b031633146120fa5760405162461bcd60e51b8152600401610f7c90613941565b80600a54141561211c5760405162461bcd60e51b8152600401610f7c90613871565b7f000000000000000000000000000000000000000000000000000000000000000081111561215c5760405162461bcd60e51b8152600401610f7c906138c7565b600a805490829055611c00612474565b6005546001600160a01b031633146121965760405162461bcd60e51b8152600401610f7c90613941565b8060095414156121b85760405162461bcd60e51b8152600401610f7c9061389b565b7f0000000000000000000000000000000000000000000000000000000000000000811015801561220857507f00000000000000000000000000000000000000000000000000000000000000008111155b6122925760405162461bcd60e51b815260206004820152604f60248201527f6e65772076616c7565206d757374206265203e3d204d494e5f535741505f544f60448201527f4b454e535f41545f414d4f554e5420616e64203c3d204d41585f535741505f5460648201526e13d2d15394d7d05517d05353d55395608a1b608482015260a401610f7c565b6009805490829055604051819083907f1d3afd1a2942d06995fdb024306050a7b24ad00572be70ce8b1bea325780d28b90600090a35050565b6005546001600160a01b031633146122f55760405162461bcd60e51b8152600401610f7c90613941565b33806108fc476040518115909202916000818181858888f19350505050158015611cef573d6000803e3d6000fd5b6005546001600160a01b0316331461234d5760405162461bcd60e51b8152600401610f7c90613941565b6001600160a01b0381166123b25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610f7c565b6005546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b60008061241b8385613a5a565b90508381101561246d5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610f7c565b9392505050565b7f000000000000000000000000000000000000000000000000000000000000000061249d611679565b11156124e15760405162461bcd60e51b81526020600482015260136024820152720e8dee8c2d840cccacae640e8dede40d0d2ced606b1b6044820152606401610f7c565b565b6001600160a01b0383166125455760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610f7c565b6001600160a01b0382166125a65760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610f7c565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b03831661262e5760405162461bcd60e51b8152600401610f7c906139a4565b6001600160a01b0382166126545760405162461bcd60e51b8152600401610f7c9061382e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614156126d85760105460ff16806126b757506001600160a01b03821660009081526017602052604090205460ff165b6126d35760405162461bcd60e51b8152600401610f7c906138f1565b612757565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156127575760105460ff168061273b57506001600160a01b03831660009081526017602052604090205460ff165b6127575760405162461bcd60e51b8152600401610f7c906138f1565b6001600160a01b03831660009081526019602052604090205460ff16801561278d57506006546001600160a01b03838116911614155b156127f5576007548111156127f55760405162461bcd60e51b815260206004820152602860248201527f5472616e7366657220616d6f756e74206578636565647320746865206d6178546044820152673c20b6b7bab73a1760c11b6064820152608401610f7c565b8061280b5761280683836000612b81565b505050565b600654600160a01b900460ff1615801561283d57506001600160a01b03821660009081526019602052604090205460ff165b801561284b575060105460ff165b156128c8576008548111156128c85760405162461bcd60e51b815260206004820152603a60248201527f53656c6c207472616e7366657220616d6f756e7420657863656564732074686560448201527f206d617853656c6c5472616e73616374696f6e416d6f756e742e0000000000006064820152608401610f7c565b306000908152602081905260408120549050600060095482101580156128f75750600654600160a81b900460ff165b90506000612903611679565b905081801561291c5750600654600160a01b900460ff16155b801561294057506001600160a01b03851660009081526019602052604090205460ff165b156129aa576006805460ff60a01b1916600160a01b179055600b54600c54600a54600e5460009361299093869361298a9361298393926116a4929091839161240e565b8790612c8a565b90612d09565b905061299b81612d4b565b506006805460ff60a01b191690555b600654600090600160a01b900460ff16158015612a0157506001600160a01b03871660009081526019602052604090205460ff1680612a0157506001600160a01b03861660009081526019602052604090205460ff165b6001600160a01b03881660009081526016602052604090205490915060ff1680612a4357506001600160a01b03861660009081526016602052604090205460ff165b15612a4c575060005b8015612adf576000612a63606461298a8886612c8a565b6001600160a01b03881660009081526019602052604090205490915060ff1615612aae57612aa1606461298a600f5489612c8a90919063ffffffff16565b612aab9082613a5a565b90505b8060186000828254612ac09190613a5a565b90915550612ad090508682613180565b9550612add883083612b81565b505b612aea878787612b81565b50505050505050565b60008184841115612b175760405162461bcd60e51b8152600401610f7c91906137fb565b506000612b248486613ab3565b95945050505050565b6001600160a01b038216600081815260196020526040808220805460ff191685151590811790915590519092917fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab91a35050565b6001600160a01b038316612ba75760405162461bcd60e51b8152600401610f7c906139a4565b6001600160a01b038216612bcd5760405162461bcd60e51b8152600401610f7c9061382e565b612c0a81604051806060016040528060268152602001613ba3602691396001600160a01b0386166000908152602081905260409020549190612af3565b6001600160a01b038085166000908152602081905260408082209390935590841681522054612c39908261240e565b6001600160a01b038381166000818152602081815260409182902094909455518481529092918616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016125fb565b600082612c995750600061118b565b6000612ca58385613a94565b905082612cb28583613a72565b1461246d5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610f7c565b600061246d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506131c2565b6000612d58826002612d09565b90506000612d668383613180565b905047612d72836131f0565b6000612d7e4783613180565b90506000612da5600b546116a4600e546116a4600c54600a5461240e90919063ffffffff16565b90506000612dc28261298a600e5488612c8a90919063ffffffff16565b90506000612ddf8361298a600e5487612c8a90919063ffffffff16565b90506000612dfc8461298a600a548a612c8a90919063ffffffff16565b90506000612e198561298a600a5489612c8a90919063ffffffff16565b90506000612e368661298a600b548c612c8a90919063ffffffff16565b90506000612e538761298a600b548b612c8a90919063ffffffff16565b90506000612e708861298a600c548e612c8a90919063ffffffff16565b90506000612e8d8961298a600c548d612c8a90919063ffffffff16565b9050612e998888613359565b604080518e8152602081018c90529081018d90527f17bbfb9a6069321b6ded73bd96327c9e6b7212a5cd51ff219cd61370acafb5619060600160405180910390a1601054612ef790309061010090046001600160a01b031688613419565b6010546040518781526101009091046001600160a01b0316907f1fc0906e43d20ecbfc276841a8ad0f39e2fd5bb4b04c0723246bee6464cf3ec09060200160405180910390a26010546040516101009091046001600160a01b0316906108fc8715029087906000818181858888f19350505050158015612f7b573d6000803e3d6000fd5b506010546040518681526101009091046001600160a01b0316907f5dece990975df7c3462bfa088616cac067f44af0a3582f7eff48bf8182ef67c19060200160405180910390a2601154612fda9030906001600160a01b031686613419565b6011546040518581526001600160a01b03909116907f51be043b9c07f89fb205e8201787cea9a99d2aa092e49caf3a023675fd67f5a79060200160405180910390a26011546040516001600160a01b039091169084156108fc029085906000818181858888f19350505050158015613056573d6000803e3d6000fd5b506011546040518481526001600160a01b03909116907f5dece990975df7c3462bfa088616cac067f44af0a3582f7eff48bf8182ef67c19060200160405180910390a26012546130b19030906001600160a01b031684613419565b6012546040518381526001600160a01b03909116907fdce3a5ca37c9631940db369229f6152ccbd7c9bc7de8108ddf47e546db5e51699060200160405180910390a26012546040516001600160a01b039091169082156108fc029083906000818181858888f1935050505015801561312d573d6000803e3d6000fd5b506012546040518281526001600160a01b03909116907f8c59ec58b16b7f170f37ab21bf1cb4855feb2ebe10ee17b2c973ebd51504b1829060200160405180910390a25050505050505050505050505050565b600061246d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612af3565b600081836131e35760405162461bcd60e51b8152600401610f7c91906137fb565b506000612b248486613a72565b604080516002808252606082018352600092602083019080368337019050509050308160008151811061322557613225613b66565b6001600160a01b03928316602091820292909201810191909152600654604080516315ab88c960e31b81529051919093169263ad5c4648926004808301939192829003018186803b15801561327957600080fd5b505afa15801561328d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b1919061358e565b816001815181106132c4576132c4613b66565b6001600160a01b0392831660209182029290920101526006546132ea91309116846124e3565b60065460405163791ac94760e01b81526001600160a01b039091169063791ac947906133239085906000908690309042906004016139e9565b600060405180830381600087803b15801561333d57600080fd5b505af1158015613351573d6000803e3d6000fd5b505050505050565b6006546133719030906001600160a01b0316846124e3565b60065460405163f305d71960e01b8152306004820181905260248201859052600060448301819052606483015260848201524260a48201526001600160a01b039091169063f305d71990839060c4016060604051808303818588803b1580156133d957600080fd5b505af11580156133ed573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906134129190613758565b5050505050565b604080518082018252601981527f7472616e7366657228616464726573732c75696e74323536290000000000000060209182015281516001600160a01b0385811660248301526044808301869052845180840390910181526064909201845291810180516001600160e01b031663a9059cbb60e01b17905291517fa9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b926000928392908816916134c791613786565b6000604051808303816000865af19150503d8060008114613504576040519150601f19603f3d011682016040523d82523d6000602084013e613509565b606091505b50915091508180156135335750805115806135335750808060200190518101906135339190613722565b6133515760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610f7c565b60006020828403121561358357600080fd5b813561246d81613b7c565b6000602082840312156135a057600080fd5b815161246d81613b7c565b600080604083850312156135be57600080fd5b82356135c981613b7c565b915060208301356135d981613b7c565b809150509250929050565b6000806000606084860312156135f957600080fd5b833561360481613b7c565b9250602084013561361481613b7c565b929592945050506040919091013590565b6000806040838503121561363857600080fd5b823561364381613b7c565b915060208301356135d981613b94565b6000806040838503121561366657600080fd5b823561367181613b7c565b946020939093013593505050565b60008060006040848603121561369457600080fd5b833567ffffffffffffffff808211156136ac57600080fd5b818601915086601f8301126136c057600080fd5b8135818111156136cf57600080fd5b8760208260051b85010111156136e457600080fd5b602092830195509350508401356136fa81613b94565b809150509250925092565b60006020828403121561371757600080fd5b813561246d81613b94565b60006020828403121561373457600080fd5b815161246d81613b94565b60006020828403121561375157600080fd5b5035919050565b60008060006060848603121561376d57600080fd5b8351925060208401519150604084015190509250925092565b60008251613798818460208701613aca565b9190910192915050565b6040808252810183905260008460608301825b868110156137e55782356137c881613b7c565b6001600160a01b03168252602092830192909101906001016137b5565b5080925050508215156020830152949350505050565b602081526000825180602084015261381a816040850160208701613aca565b601f01601f19169190910160400192915050565b60208082526023908201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260408201526265737360e81b606082015260800190565b60208082526010908201526f1b995dc8199959481c995c5d5a5c995960821b604082015260600190565b6020808252601290820152711b995dc81d985b1d59481c995c5d5a5c995960721b604082015260600190565b60208082526010908201526f0dccaee40cccaca40e8dede40d0d2ced60831b604082015260600190565b60208082526030908201527f74726164696e672069736e7420656e61626c6564206f72206163636f756e742060408201526f1a5cdb9d081dda1a5d195b1a5cdd195960821b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601490820152731b995dc81859191c995cdcc81c995c5d5a5c995960621b604082015260600190565b60208082526025908201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604082015264647265737360d81b606082015260800190565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b81811015613a395784516001600160a01b031683529383019391830191600101613a14565b50506001600160a01b03969096166060850152505050608001529392505050565b60008219821115613a6d57613a6d613b50565b500190565b600082613a8f57634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615613aae57613aae613b50565b500290565b600082821015613ac557613ac5613b50565b500390565b60005b83811015613ae5578181015183820152602001613acd565b83811115613af4576000848401525b50505050565b600181811c90821680613b0e57607f821691505b60208210811415613b2f57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415613b4957613b49613b50565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114613b9157600080fd5b50565b8015158114613b9157600080fdfe45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122072728bb602de9b16b5794b58a56bb563b5402c44e5548786a884b2bfa4c7be2264736f6c634300080600334f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572
Deployed ByteCode
0x6080604052600436106104565760003560e01c806375f0a8741161023f578063a9059cbb11610139578063d257b34f116100b6578063e1a606fa1161007a578063e1a606fa14610e94578063e2f4560514610ec8578063f2fde38b14610ede578063f7c618c114610efe578063fd5db2af14610f1e57600080fd5b8063d257b34f14610dc5578063d863f0e714610de5578063dd62ed3e14610dfa578063dddc4f4414610e40578063deab8aea14610e7457600080fd5b8063bf8b1473116100fd578063bf8b147314610d11578063c024666814610d31578063c3a1ed4814610d51578063c492f04614610d85578063cf38287714610da557600080fd5b8063a9059cbb14610c4f578063aacebbe314610c6f578063af21c6d314610c8f578063b51aebbb14610cc3578063b62496f514610ce157600080fd5b8063911140bb116101c75780639a7a23d61161018b5780639a7a23d614610ba55780639c1b8af514610bc5578063a1b8272314610bdb578063a457c2d714610c0f578063a716d66114610c2f57600080fd5b8063911140bb14610b0657806395d89b4114610b3a57806398118cb414610b4f57806399729ec114610b6557806399c8df1814610b8557600080fd5b80638a7a8cca1161020e5780638a7a8cca14610a5f5780638a8c523c14610a935780638da5cb5b14610aa85780638e67566314610ac65780638ea5220f14610ae657600080fd5b806375f0a874146109a457806385541cda146109c9578063867508ad14610a0b578063871c128d14610a3f57600080fd5b8063395093511161035057806360c6d8ae116102d8578063691151c51161029c578063691151c5146108fc5780636b67c4df146109305780636e9472981461094657806370a0823114610959578063715018a61461098f57600080fd5b806360c6d8ae14610867578063620dff3d1461087d578063626e1ae7146108b157806365b8dbc0146108c65780636827e764146108e657600080fd5b80634a74bb021161031f5780634a74bb021461078a5780634de18a9f146107ab5780634fbee193146107df57806354789a5e146108185780635aa821a91461085157600080fd5b806339509351146106f05780633af32abf146107105780633b2d081c1461074057806349bd5a5e1461075657600080fd5b80631d933a4a116103de5780632bb14e1d116103a25780632bb14e1d1461064a5780632c59d46414610660578063313ce5671461068057806333ced6e21461069c5780633868e419146106d057600080fd5b80631d933a4a146105a05780631fc75e41146105c057806323b872dd146105e057806328eb2dcf146106005780632b14ca561461063457600080fd5b8063084a6bff11610425578063084a6bff146104f3578063095ea7b3146105135780631694505e1461053357806318160ddd1461056b5780631816467f1461058057600080fd5b806302259e9e1461046257806304dacd501461048b578063064a59d0146104ad57806306fdde03146104d157600080fd5b3661045d57005b600080fd5b34801561046e57600080fd5b5061047860085481565b6040519081526020015b60405180910390f35b34801561049757600080fd5b506104ab6104a6366004613571565b610f52565b005b3480156104b957600080fd5b5060105460ff165b6040519015158152602001610482565b3480156104dd57600080fd5b506104e661101b565b60405161048291906137fb565b3480156104ff57600080fd5b506104ab61050e36600461373f565b6110ad565b34801561051f57600080fd5b506104c161052e366004613653565b61117a565b34801561053f57600080fd5b50600654610553906001600160a01b031681565b6040516001600160a01b039091168152602001610482565b34801561057757600080fd5b50600254610478565b34801561058c57600080fd5b506104ab61059b366004613571565b611191565b3480156105ac57600080fd5b506104ab6105bb36600461373f565b611251565b3480156105cc57600080fd5b50601354610553906001600160a01b031681565b3480156105ec57600080fd5b506104c16105fb3660046135e4565b611316565b34801561060c57600080fd5b506104787f00000000000000000000000000000000000000000052b7d2dcc80cd2e400000081565b34801561064057600080fd5b50610478600f5481565b34801561065657600080fd5b50610478600d5481565b34801561066c57600080fd5b506104ab61067b36600461373f565b61137f565b34801561068c57600080fd5b5060405160128152602001610482565b3480156106a857600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000581565b3480156106dc57600080fd5b506104ab6106eb36600461373f565b6114e0565b3480156106fc57600080fd5b506104c161070b366004613653565b611643565b34801561071c57600080fd5b506104c161072b366004613571565b60176020526000908152604090205460ff1681565b34801561074c57600080fd5b50610478600c5481565b34801561076257600080fd5b506105537f00000000000000000000000096015be16aa7f569f4ff638a18dbd3e6bf182eaf81565b34801561079657600080fd5b506006546104c190600160a81b900460ff1681565b3480156107b757600080fd5b506104787f0000000000000000000000000000000000000000a18f07d736b90be55000000081565b3480156107eb57600080fd5b506104c16107fa366004613571565b6001600160a01b031660009081526016602052604090205460ff1690565b34801561082457600080fd5b506104c1610833366004613571565b6001600160a01b031660009081526017602052604090205460ff1690565b34801561085d57600080fd5b5061047860075481565b34801561087357600080fd5b5061047860185481565b34801561088957600080fd5b506104787f000000000000000000000000000000000000000000a56fa5b99019a5c800000081565b3480156108bd57600080fd5b50610478611679565b3480156108d257600080fd5b506104ab6108e1366004613571565b6116af565b3480156108f257600080fd5b50610478600b5481565b34801561090857600080fd5b506104787f0000000000000000000000000000000000000000019d971e4fe8401e7400000081565b34801561093c57600080fd5b50610478600a5481565b34801561095257600080fd5b5047610478565b34801561096557600080fd5b50610478610974366004613571565b6001600160a01b031660009081526020819052604090205490565b34801561099b57600080fd5b506104ab6117a7565b3480156109b057600080fd5b506010546105539061010090046001600160a01b031681565b3480156109d557600080fd5b506109de61181b565b604080519687526020870195909552938501929092526060840152608083015260a082015260c001610482565b348015610a1757600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000581565b348015610a4b57600080fd5b506104ab610a5a36600461373f565b61184e565b348015610a6b57600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000a81565b348015610a9f57600080fd5b506104ab6119d1565b348015610ab457600080fd5b506005546001600160a01b0316610553565b348015610ad257600080fd5b506104ab610ae136600461373f565b611a88565b348015610af257600080fd5b50601154610553906001600160a01b031681565b348015610b1257600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000a81565b348015610b4657600080fd5b506104e6611b55565b348015610b5b57600080fd5b50610478600e5481565b348015610b7157600080fd5b506104ab610b8036600461373f565b611b64565b348015610b9157600080fd5b506104ab610ba0366004613625565b611c31565b348015610bb157600080fd5b506104ab610bc0366004613625565b611cbb565b348015610bd157600080fd5b5061047860155481565b348015610be757600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000a81565b348015610c1b57600080fd5b506104c1610c2a366004613653565b611cf3565b348015610c3b57600080fd5b506104ab610c4a366004613705565b611d42565b348015610c5b57600080fd5b506104c1610c6a366004613653565b611dc4565b348015610c7b57600080fd5b506104ab610c8a366004613571565b611dd1565b348015610c9b57600080fd5b506104787f0000000000000000000000000000000000000000409f9cbc7c4a04c22000000081565b348015610ccf57600080fd5b506014546001600160a01b0316610553565b348015610ced57600080fd5b506104c1610cfc366004613571565b60196020526000908152604090205460ff1681565b348015610d1d57600080fd5b506104ab610d2c36600461373f565b611ea5565b348015610d3d57600080fd5b506104ab610d4c366004613625565b611f72565b348015610d5d57600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000001e81565b348015610d9157600080fd5b506104ab610da036600461367f565b611ff4565b348015610db157600080fd5b506104ab610dc036600461373f565b6120d0565b348015610dd157600080fd5b506104ab610de036600461373f565b61216c565b348015610df157600080fd5b506104ab6122cb565b348015610e0657600080fd5b50610478610e153660046135ab565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b348015610e4c57600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000a81565b348015610e8057600080fd5b50601254610553906001600160a01b031681565b348015610ea057600080fd5b506104787f00000000000000000000000000000000000000000000000000000000004c4b4081565b348015610ed457600080fd5b5061047860095481565b348015610eea57600080fd5b506104ab610ef9366004613571565b612323565b348015610f0a57600080fd5b50601454610553906001600160a01b031681565b348015610f2a57600080fd5b506104787f0000000000000000000000000000000000000000a18f07d736b90be55000000081565b6005546001600160a01b03163314610f855760405162461bcd60e51b8152600401610f7c90613941565b60405180910390fd5b6012546001600160a01b0382811691161415610fb35760405162461bcd60e51b8152600401610f7c90613976565b601280546001600160a01b038381166001600160a01b031983161790925516610fdd826001611f72565b6012546040516001600160a01b038084169216907f11ef31775640906cd48f5ad1c2c79269a9f4f4b49df05c59d175d50b53c2daa590600090a35050565b60606003805461102a90613afa565b80601f016020809104026020016040519081016040528092919081815260200182805461105690613afa565b80156110a35780601f10611078576101008083540402835291602001916110a3565b820191906000526020600020905b81548152906001019060200180831161108657829003601f168201915b5050505050905090565b6005546001600160a01b031633146110d75760405162461bcd60e51b8152600401610f7c90613941565b80600d5414156110f95760405162461bcd60e51b8152600401610f7c90613871565b7f000000000000000000000000000000000000000000000000000000000000000a8111156111395760405162461bcd60e51b8152600401610f7c906138c7565b600d805490829055611149612474565b604051819083907fc78f282c12d02e0b7183c178d32e56110e4dbacf8894091ac8a848bb5018afe590600090a35050565b60006111873384846124e3565b5060015b92915050565b6005546001600160a01b031633146111bb5760405162461bcd60e51b8152600401610f7c90613941565b6011546001600160a01b03828116911614156111e95760405162461bcd60e51b8152600401610f7c90613976565b601180546001600160a01b038381166001600160a01b031983161790925516611213826001611f72565b6011546040516001600160a01b038084169216907facf03c50dcf01e53e2775267d12acd0158d87c2f20fb84226837142693b36ae790600090a35050565b6005546001600160a01b0316331461127b5760405162461bcd60e51b8152600401610f7c90613941565b80600f54141561129d5760405162461bcd60e51b8152600401610f7c90613871565b7f00000000000000000000000000000000000000000000000000000000000000058111156112dd5760405162461bcd60e51b8152600401610f7c906138c7565b600f805490829055604051819083907fde4022aab72c416fa5c54f5b02a3d8ce50d8a9418a85c790d51cf759ebb4697d90600090a35050565b6000611323848484612608565b611375843361137085604051806060016040528060288152602001613bc9602891396001600160a01b038a1660009081526001602090815260408083203384529091529020549190612af3565b6124e3565b5060019392505050565b6005546001600160a01b031633146113a95760405162461bcd60e51b8152600401610f7c90613941565b8060075414156113cb5760405162461bcd60e51b8152600401610f7c9061389b565b7f0000000000000000000000000000000000000000019d971e4fe8401e74000000811015801561141b57507f0000000000000000000000000000000000000000a18f07d736b90be5500000008111155b6114a75760405162461bcd60e51b815260206004820152605160248201527f6e65772076616c7565206d757374206265203e3d204d494e5f4255595f54524160448201527f4e53414354494f4e5f414d4f554e5420616e64203c3d204d41585f4255595f5460648201527014905394d050d51253d397d05353d55395607a1b608482015260a401610f7c565b6007805490829055604051819083907faa209eb5afb6ff458141497695fb05bfc2c447ac2a5806592df3d6e03857060790600090a35050565b6005546001600160a01b0316331461150a5760405162461bcd60e51b8152600401610f7c90613941565b80600854141561152c5760405162461bcd60e51b8152600401610f7c9061389b565b7f00000000000000000000000000000000000000000052b7d2dcc80cd2e4000000811015801561157c57507f0000000000000000000000000000000000000000a18f07d736b90be5500000008111155b61160a5760405162461bcd60e51b815260206004820152605360248201527f6e65772076616c7565206d757374206265203e3d204d494e5f53454c4c5f545260448201527f414e53414354494f4e5f414d4f554e5420616e64203c3d204d41585f53454c4c60648201527217d514905394d050d51253d397d05353d55395606a1b608482015260a401610f7c565b6008805490829055604051819083907faa0c87acaf40080121dd0db81a6a1c8f73f141d0af1ee48ac1ca402473ec5e9690600090a35050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091611187918590611370908661240e565b60006116aa600b546116a4600d546116a4600e546116a4600c54600a5461240e90919063ffffffff16565b9061240e565b905090565b6005546001600160a01b031633146116d95760405162461bcd60e51b8152600401610f7c90613941565b6006546001600160a01b038281169116141561174a5760405162461bcd60e51b815260206004820152602a60248201527f446f4b454e3a2054686520726f7574657220616c7265616479206861732074686044820152696174206164647265737360b01b6064820152608401610f7c565b6006546040516001600160a01b03918216918316907f8fc842bbd331dfa973645f4ed48b11683d501ebf1352708d77a5da2ab49a576e90600090a3600680546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b031633146117d15760405162461bcd60e51b8152600401610f7c90613941565b6005546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580546001600160a01b0319169055565b60008060008060008061182c611679565b600d54600e54600a54600b54600f54949b939a50919850965094509092509050565b6005546001600160a01b031633146118785760405162461bcd60e51b8152600401610f7c90613941565b62030d4081101580156118ab57507f00000000000000000000000000000000000000000000000000000000004c4b408111155b6119305760405162461bcd60e51b815260206004820152604a60248201527f446f4b454e3a20676173466f7250726f63657373696e67206d7573742062652060448201527f6265747765656e203230302c30303020616e64204d41585f4741535f464f525f60648201526950524f43455353494e4760b01b608482015260a401610f7c565b60155481141561199e5760405162461bcd60e51b815260206004820152603360248201527f446f4b454e3a2043616e6e6f742075706461746520676173466f7250726f63656044820152727373696e6720746f2073616d652076616c756560681b6064820152608401610f7c565b60155460405182907f86abf19b93006da5f33a92bcf64ec9a9f116166bcba5a1af6123d5a69eeaab0890600090a3601555565b6005546001600160a01b031633146119fb5760405162461bcd60e51b8152600401610f7c90613941565b60105460ff1615611a4e5760405162461bcd60e51b815260206004820152601a60248201527f74726164696e6720697320616c726561647920656e61626c65640000000000006044820152606401610f7c565b6010805460ff1916600117905560405143907f68a240f91e5b394de2084f3f756296fb39b577fde5e53a8f226c1ca5f308e8f890600090a2565b6005546001600160a01b03163314611ab25760405162461bcd60e51b8152600401610f7c90613941565b80600e541415611ad45760405162461bcd60e51b8152600401610f7c90613871565b7f0000000000000000000000000000000000000000000000000000000000000005811115611b145760405162461bcd60e51b8152600401610f7c906138c7565b600e805490829055611b24612474565b604051819083907fc09bba22c83c2fe84cd31b6fa35a826e2d7ad60ae3c8d135dab825556baee73890600090a35050565b60606004805461102a90613afa565b6005546001600160a01b03163314611b8e5760405162461bcd60e51b8152600401610f7c90613941565b80600b541415611bb05760405162461bcd60e51b8152600401610f7c90613871565b7f000000000000000000000000000000000000000000000000000000000000000a811115611bf05760405162461bcd60e51b8152600401610f7c906138c7565b600b805490829055611c00612474565b604051819083907f16d83edfca27a95b3a9be436199cca08d3b65d5f9a25264391be22e9cdbb45b690600090a35050565b6005546001600160a01b03163314611c5b5760405162461bcd60e51b8152600401610f7c90613941565b6001600160a01b038216600081815260176020908152604091829020805460ff191685151590811790915591519182527fb8e94100c3d15375b309e7a2a3e9617478f7882eba6a26bd0e85cd2443f7076191015b60405180910390a25050565b6005546001600160a01b03163314611ce55760405162461bcd60e51b8152600401610f7c90613941565b611cef8282612b2d565b5050565b6000611187338461137085604051806060016040528060258152602001613bf1602591393360009081526001602090815260408083206001600160a01b038d1684529091529020549190612af3565b6005546001600160a01b03163314611d6c5760405162461bcd60e51b8152600401610f7c90613941565b60068054821515600160a81b0260ff60a81b199091161790556040517f701507a13d5701687328d70ea5a717a33a062f46c229a785b315fb4517fef06990611db990831515815260200190565b60405180910390a150565b6000611187338484612608565b6005546001600160a01b03163314611dfb5760405162461bcd60e51b8152600401610f7c90613941565b6010546001600160a01b03828116610100909204161415611e2e5760405162461bcd60e51b8152600401610f7c90613976565b601080546001600160a01b03838116610100908102610100600160a81b031984161790935591900416611e62826001611f72565b6010546040516001600160a01b0380841692610100900416907facf03c50dcf01e53e2775267d12acd0158d87c2f20fb84226837142693b36ae790600090a35050565b6005546001600160a01b03163314611ecf5760405162461bcd60e51b8152600401610f7c90613941565b80600c541415611ef15760405162461bcd60e51b8152600401610f7c90613871565b7f000000000000000000000000000000000000000000000000000000000000000a811115611f315760405162461bcd60e51b8152600401610f7c906138c7565b600c805490829055611f41612474565b604051819083907f0a45c4d096a8b955abedb6a180bf61cff0a8aff3f57819ee58cceb87df435ca390600090a35050565b6005546001600160a01b03163314611f9c5760405162461bcd60e51b8152600401610f7c90613941565b6001600160a01b038216600081815260166020908152604091829020805460ff191685151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df79101611caf565b6005546001600160a01b0316331461201e5760405162461bcd60e51b8152600401610f7c90613941565b60005b8281101561208f57816016600086868581811061204057612040613b66565b90506020020160208101906120559190613571565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558061208781613b35565b915050612021565b507f7fdaf542373fa84f4ee8d662c642f44e4c2276a217d7d29e548b6eb29a233b358383836040516120c3939291906137a2565b60405180910390a1505050565b6005546001600160a01b031633146120fa5760405162461bcd60e51b8152600401610f7c90613941565b80600a54141561211c5760405162461bcd60e51b8152600401610f7c90613871565b7f000000000000000000000000000000000000000000000000000000000000000a81111561215c5760405162461bcd60e51b8152600401610f7c906138c7565b600a805490829055611c00612474565b6005546001600160a01b031633146121965760405162461bcd60e51b8152600401610f7c90613941565b8060095414156121b85760405162461bcd60e51b8152600401610f7c9061389b565b7f000000000000000000000000000000000000000000a56fa5b99019a5c8000000811015801561220857507f0000000000000000000000000000000000000000409f9cbc7c4a04c2200000008111155b6122925760405162461bcd60e51b815260206004820152604f60248201527f6e65772076616c7565206d757374206265203e3d204d494e5f535741505f544f60448201527f4b454e535f41545f414d4f554e5420616e64203c3d204d41585f535741505f5460648201526e13d2d15394d7d05517d05353d55395608a1b608482015260a401610f7c565b6009805490829055604051819083907f1d3afd1a2942d06995fdb024306050a7b24ad00572be70ce8b1bea325780d28b90600090a35050565b6005546001600160a01b031633146122f55760405162461bcd60e51b8152600401610f7c90613941565b33806108fc476040518115909202916000818181858888f19350505050158015611cef573d6000803e3d6000fd5b6005546001600160a01b0316331461234d5760405162461bcd60e51b8152600401610f7c90613941565b6001600160a01b0381166123b25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610f7c565b6005546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b60008061241b8385613a5a565b90508381101561246d5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610f7c565b9392505050565b7f000000000000000000000000000000000000000000000000000000000000001e61249d611679565b11156124e15760405162461bcd60e51b81526020600482015260136024820152720e8dee8c2d840cccacae640e8dede40d0d2ced606b1b6044820152606401610f7c565b565b6001600160a01b0383166125455760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610f7c565b6001600160a01b0382166125a65760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610f7c565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b03831661262e5760405162461bcd60e51b8152600401610f7c906139a4565b6001600160a01b0382166126545760405162461bcd60e51b8152600401610f7c9061382e565b7f00000000000000000000000096015be16aa7f569f4ff638a18dbd3e6bf182eaf6001600160a01b0316836001600160a01b031614156126d85760105460ff16806126b757506001600160a01b03821660009081526017602052604090205460ff165b6126d35760405162461bcd60e51b8152600401610f7c906138f1565b612757565b7f00000000000000000000000096015be16aa7f569f4ff638a18dbd3e6bf182eaf6001600160a01b0316826001600160a01b031614156127575760105460ff168061273b57506001600160a01b03831660009081526017602052604090205460ff165b6127575760405162461bcd60e51b8152600401610f7c906138f1565b6001600160a01b03831660009081526019602052604090205460ff16801561278d57506006546001600160a01b03838116911614155b156127f5576007548111156127f55760405162461bcd60e51b815260206004820152602860248201527f5472616e7366657220616d6f756e74206578636565647320746865206d6178546044820152673c20b6b7bab73a1760c11b6064820152608401610f7c565b8061280b5761280683836000612b81565b505050565b600654600160a01b900460ff1615801561283d57506001600160a01b03821660009081526019602052604090205460ff165b801561284b575060105460ff165b156128c8576008548111156128c85760405162461bcd60e51b815260206004820152603a60248201527f53656c6c207472616e7366657220616d6f756e7420657863656564732074686560448201527f206d617853656c6c5472616e73616374696f6e416d6f756e742e0000000000006064820152608401610f7c565b306000908152602081905260408120549050600060095482101580156128f75750600654600160a81b900460ff165b90506000612903611679565b905081801561291c5750600654600160a01b900460ff16155b801561294057506001600160a01b03851660009081526019602052604090205460ff165b156129aa576006805460ff60a01b1916600160a01b179055600b54600c54600a54600e5460009361299093869361298a9361298393926116a4929091839161240e565b8790612c8a565b90612d09565b905061299b81612d4b565b506006805460ff60a01b191690555b600654600090600160a01b900460ff16158015612a0157506001600160a01b03871660009081526019602052604090205460ff1680612a0157506001600160a01b03861660009081526019602052604090205460ff165b6001600160a01b03881660009081526016602052604090205490915060ff1680612a4357506001600160a01b03861660009081526016602052604090205460ff165b15612a4c575060005b8015612adf576000612a63606461298a8886612c8a565b6001600160a01b03881660009081526019602052604090205490915060ff1615612aae57612aa1606461298a600f5489612c8a90919063ffffffff16565b612aab9082613a5a565b90505b8060186000828254612ac09190613a5a565b90915550612ad090508682613180565b9550612add883083612b81565b505b612aea878787612b81565b50505050505050565b60008184841115612b175760405162461bcd60e51b8152600401610f7c91906137fb565b506000612b248486613ab3565b95945050505050565b6001600160a01b038216600081815260196020526040808220805460ff191685151590811790915590519092917fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab91a35050565b6001600160a01b038316612ba75760405162461bcd60e51b8152600401610f7c906139a4565b6001600160a01b038216612bcd5760405162461bcd60e51b8152600401610f7c9061382e565b612c0a81604051806060016040528060268152602001613ba3602691396001600160a01b0386166000908152602081905260409020549190612af3565b6001600160a01b038085166000908152602081905260408082209390935590841681522054612c39908261240e565b6001600160a01b038381166000818152602081815260409182902094909455518481529092918616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016125fb565b600082612c995750600061118b565b6000612ca58385613a94565b905082612cb28583613a72565b1461246d5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610f7c565b600061246d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506131c2565b6000612d58826002612d09565b90506000612d668383613180565b905047612d72836131f0565b6000612d7e4783613180565b90506000612da5600b546116a4600e546116a4600c54600a5461240e90919063ffffffff16565b90506000612dc28261298a600e5488612c8a90919063ffffffff16565b90506000612ddf8361298a600e5487612c8a90919063ffffffff16565b90506000612dfc8461298a600a548a612c8a90919063ffffffff16565b90506000612e198561298a600a5489612c8a90919063ffffffff16565b90506000612e368661298a600b548c612c8a90919063ffffffff16565b90506000612e538761298a600b548b612c8a90919063ffffffff16565b90506000612e708861298a600c548e612c8a90919063ffffffff16565b90506000612e8d8961298a600c548d612c8a90919063ffffffff16565b9050612e998888613359565b604080518e8152602081018c90529081018d90527f17bbfb9a6069321b6ded73bd96327c9e6b7212a5cd51ff219cd61370acafb5619060600160405180910390a1601054612ef790309061010090046001600160a01b031688613419565b6010546040518781526101009091046001600160a01b0316907f1fc0906e43d20ecbfc276841a8ad0f39e2fd5bb4b04c0723246bee6464cf3ec09060200160405180910390a26010546040516101009091046001600160a01b0316906108fc8715029087906000818181858888f19350505050158015612f7b573d6000803e3d6000fd5b506010546040518681526101009091046001600160a01b0316907f5dece990975df7c3462bfa088616cac067f44af0a3582f7eff48bf8182ef67c19060200160405180910390a2601154612fda9030906001600160a01b031686613419565b6011546040518581526001600160a01b03909116907f51be043b9c07f89fb205e8201787cea9a99d2aa092e49caf3a023675fd67f5a79060200160405180910390a26011546040516001600160a01b039091169084156108fc029085906000818181858888f19350505050158015613056573d6000803e3d6000fd5b506011546040518481526001600160a01b03909116907f5dece990975df7c3462bfa088616cac067f44af0a3582f7eff48bf8182ef67c19060200160405180910390a26012546130b19030906001600160a01b031684613419565b6012546040518381526001600160a01b03909116907fdce3a5ca37c9631940db369229f6152ccbd7c9bc7de8108ddf47e546db5e51699060200160405180910390a26012546040516001600160a01b039091169082156108fc029083906000818181858888f1935050505015801561312d573d6000803e3d6000fd5b506012546040518281526001600160a01b03909116907f8c59ec58b16b7f170f37ab21bf1cb4855feb2ebe10ee17b2c973ebd51504b1829060200160405180910390a25050505050505050505050505050565b600061246d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612af3565b600081836131e35760405162461bcd60e51b8152600401610f7c91906137fb565b506000612b248486613a72565b604080516002808252606082018352600092602083019080368337019050509050308160008151811061322557613225613b66565b6001600160a01b03928316602091820292909201810191909152600654604080516315ab88c960e31b81529051919093169263ad5c4648926004808301939192829003018186803b15801561327957600080fd5b505afa15801561328d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b1919061358e565b816001815181106132c4576132c4613b66565b6001600160a01b0392831660209182029290920101526006546132ea91309116846124e3565b60065460405163791ac94760e01b81526001600160a01b039091169063791ac947906133239085906000908690309042906004016139e9565b600060405180830381600087803b15801561333d57600080fd5b505af1158015613351573d6000803e3d6000fd5b505050505050565b6006546133719030906001600160a01b0316846124e3565b60065460405163f305d71960e01b8152306004820181905260248201859052600060448301819052606483015260848201524260a48201526001600160a01b039091169063f305d71990839060c4016060604051808303818588803b1580156133d957600080fd5b505af11580156133ed573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906134129190613758565b5050505050565b604080518082018252601981527f7472616e7366657228616464726573732c75696e74323536290000000000000060209182015281516001600160a01b0385811660248301526044808301869052845180840390910181526064909201845291810180516001600160e01b031663a9059cbb60e01b17905291517fa9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b926000928392908816916134c791613786565b6000604051808303816000865af19150503d8060008114613504576040519150601f19603f3d011682016040523d82523d6000602084013e613509565b606091505b50915091508180156135335750805115806135335750808060200190518101906135339190613722565b6133515760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610f7c565b60006020828403121561358357600080fd5b813561246d81613b7c565b6000602082840312156135a057600080fd5b815161246d81613b7c565b600080604083850312156135be57600080fd5b82356135c981613b7c565b915060208301356135d981613b7c565b809150509250929050565b6000806000606084860312156135f957600080fd5b833561360481613b7c565b9250602084013561361481613b7c565b929592945050506040919091013590565b6000806040838503121561363857600080fd5b823561364381613b7c565b915060208301356135d981613b94565b6000806040838503121561366657600080fd5b823561367181613b7c565b946020939093013593505050565b60008060006040848603121561369457600080fd5b833567ffffffffffffffff808211156136ac57600080fd5b818601915086601f8301126136c057600080fd5b8135818111156136cf57600080fd5b8760208260051b85010111156136e457600080fd5b602092830195509350508401356136fa81613b94565b809150509250925092565b60006020828403121561371757600080fd5b813561246d81613b94565b60006020828403121561373457600080fd5b815161246d81613b94565b60006020828403121561375157600080fd5b5035919050565b60008060006060848603121561376d57600080fd5b8351925060208401519150604084015190509250925092565b60008251613798818460208701613aca565b9190910192915050565b6040808252810183905260008460608301825b868110156137e55782356137c881613b7c565b6001600160a01b03168252602092830192909101906001016137b5565b5080925050508215156020830152949350505050565b602081526000825180602084015261381a816040850160208701613aca565b601f01601f19169190910160400192915050565b60208082526023908201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260408201526265737360e81b606082015260800190565b60208082526010908201526f1b995dc8199959481c995c5d5a5c995960821b604082015260600190565b6020808252601290820152711b995dc81d985b1d59481c995c5d5a5c995960721b604082015260600190565b60208082526010908201526f0dccaee40cccaca40e8dede40d0d2ced60831b604082015260600190565b60208082526030908201527f74726164696e672069736e7420656e61626c6564206f72206163636f756e742060408201526f1a5cdb9d081dda1a5d195b1a5cdd195960821b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601490820152731b995dc81859191c995cdcc81c995c5d5a5c995960621b604082015260600190565b60208082526025908201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604082015264647265737360d81b606082015260800190565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b81811015613a395784516001600160a01b031683529383019391830191600101613a14565b50506001600160a01b03969096166060850152505050608001529392505050565b60008219821115613a6d57613a6d613b50565b500190565b600082613a8f57634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615613aae57613aae613b50565b500290565b600082821015613ac557613ac5613b50565b500390565b60005b83811015613ae5578181015183820152602001613acd565b83811115613af4576000848401525b50505050565b600181811c90821680613b0e57607f821691505b60208210811415613b2f57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415613b4957613b49613b50565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114613b9157600080fd5b50565b8015158114613b9157600080fdfe45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122072728bb602de9b16b5794b58a56bb563b5402c44e5548786a884b2bfa4c7be2264736f6c63430008060033