ETH Price: $3,273.09 (-11.68%)

Token

EquityCoin (EQTY)
 

Overview

Max Total Supply

50,000 EQTY

Holders

89

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 0 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
EquityCoin

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 13 : EquityCoin.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import './MintableToken.sol';
import './ERC884.sol';

/**
*    Equity Platforms, Inc.
*/

contract EquityCoin is ERC884, MintableToken {

    string public name;
    string public symbol;

    uint256 public decimals = 0;

    bytes32 constant private ZERO_BYTES = bytes32(0);
    address constant private ZERO_ADDRESS = address(0);

    mapping(address => bytes32) private verified;
    mapping(address => address) private cancellations;
    mapping(address => uint256) private holderIndices;

    address[] private shareholders;

    bool public lockingPeriodEnabled;
    uint public lockingPeriod;

    event LockingPeriodEnabled(bool indexed _enabled);
    event LockingPeriodUpdated(uint indexed _lockTimeInDays);

    modifier isVerifiedAddress(address addr) {
        require(verified[addr] != ZERO_BYTES, "address not verified");
        _;
    }

    modifier isShareholder(address addr) {
        require(holderIndices[addr] != 0, "address is not a sharedholder");
        _;
    }

    modifier isNotShareholder(address addr) {
        require(holderIndices[addr] == 0, "address is a shareholder");
        _;
    }

    modifier isNotCancelled(address addr) {
        require(cancellations[addr] == ZERO_ADDRESS, "address is canceled");
        _;
    }


    modifier isNotLockingPeriod() {
        require(!lockingPeriodEnabled || lockingPeriod < block.timestamp || msg.sender == owner(), "cannot transfer tokens during locking period of 12 months"); 
        _;
    }

    constructor() {

        name = "EquityCoin";
        symbol = "EQTY";
        lockingPeriodEnabled = true;
        lockingPeriod = block.timestamp + 365 days;

    }

    function enableLockingPeriod(bool _value) public onlyOwner {
       lockingPeriodEnabled = _value;
       emit LockingPeriodEnabled(lockingPeriodEnabled);
    }

    function setLockingPeriod(uint _lockTimeInDays) public onlyOwner {
        uint pDays =_lockTimeInDays * 1 days; //change it to days 
        lockingPeriod = block.timestamp + pDays;
        emit LockingPeriodUpdated(_lockTimeInDays);
    }

    /**
     * As each token is minted it is added to the shareholders array.
     * @param _to The address that will receive the minted tokens.
     * @param _amount The amount of tokens to mint.
     * @return A boolean that indicates if the operation was successful.
     */
    function mint(address _to, uint256 _amount)
        public
        override
        onlyOwner
        isVerifiedAddress(_to)
        returns (bool)
    {
        // if the address does not already own share then
        // add the address to the shareholders array and record the index.
        updateShareholders(_to);
        return super.mint(_to, _amount);
    }

    /**
     *  The number of addresses that own tokens.
     *  @return the number of unique addresses that own tokens.
     */
    function holderCount()
        public
        view
        returns (uint)
    {
        return shareholders.length;
    }

    /**
     *  By counting the number of token holders using `holderCount`
     *  you can retrieve the complete list of token holders, one at a time.
     *  It MUST throw if `index >= holderCount()`.
     *  @param index The zero-based index of the holder.
     *  @return the address of the token holder with the given index.
     */
    function holderAt(uint256 index)
        public
        onlyOwner
        view
        returns (address)
    {
        require(index < shareholders.length);
        return shareholders[index];
    }

    /**
     *  Add a verified address, along with an associated verification hash to the contract.
     *  Upon successful addition of a verified address, the contract must emit
     *  `VerifiedAddressAdded(addr, hash, msg.sender)`.
     *  It MUST throw if the supplied address or hash are zero, or if the address has already been supplied.
     *  @param addr The address of the person represented by the supplied hash.
     *  @param hash A cryptographic hash of the address holder's verified information.
     */
    function addVerified(address addr, bytes32 hash)
        public
        onlyOwner
        isNotCancelled(addr)    
    {
        require(addr != ZERO_ADDRESS);
        require(hash != ZERO_BYTES);
        require(verified[addr] == ZERO_BYTES);
        verified[addr] = hash;
        emit VerifiedAddressAdded(addr, hash, msg.sender);
    }

    /**
     *  Remove a verified address, and the associated verification hash. If the address is
     *  unknown to the contract then this does nothing. If the address is successfully removed, this
     *  function must emit `VerifiedAddressRemoved(addr, msg.sender)`.
     *  It MUST throw if an attempt is made to remove a verifiedAddress that owns Tokens.
     *  @param addr The verified address to be removed.
     */
    function removeVerified(address addr)
        public
        onlyOwner
    {
        require(balances.balanceOf(addr) == 0);
        if (verified[addr] != ZERO_BYTES) {
            verified[addr] = ZERO_BYTES;
            emit VerifiedAddressRemoved(addr, msg.sender);
        }
    }

    /**
     *  Update the hash for a verified address known to the contract.
     *  Upon successful update of a verified address the contract must emit
     *  `VerifiedAddressUpdated(addr, oldHash, hash, msg.sender)`.
     *  If the hash is the same as the value already stored then
     *  no `VerifiedAddressUpdated` event is to be emitted.
     *  It MUST throw if the hash is zero, or if the address is unverified.
     *  @param addr The verified address of the person represented by the supplied hash.
     *  @param hash A new cryptographic hash of the address holder's updated verified information.
     */
    function updateVerified(address addr, bytes32 hash)
        public
        onlyOwner
        isVerifiedAddress(addr)
    {
        require(hash != ZERO_BYTES);
        bytes32 oldHash = verified[addr];
        if (oldHash != hash) {
            verified[addr] = hash;
            emit VerifiedAddressUpdated(addr, oldHash, hash, msg.sender);
        }
    }

    /**
     *  Cancel the original address and reissue the Tokens to the replacement address.
     *  Access to this function MUST be strictly controlled.
     *  The `original` address MUST be removed from the set of verified addresses.
     *  Throw if the `original` address supplied is not a shareholder.
     *  Throw if the replacement address is not a verified address.
     *  This function MUST emit the `VerifiedAddressSuperseded` event.
     *  @param original The address to be superseded. This address MUST NOT be reused.
     *  @param replacement The address  that supersedes the original. This address MUST be verified.
     */
    function cancelAndReissue(address original, address replacement)
        public
        onlyOwner
        isShareholder(original)
        isNotShareholder(replacement)
        isVerifiedAddress(replacement)
    {
        // replace the original address in the shareholders array
        // and update all the associated mappings
        verified[original] = ZERO_BYTES;
        cancellations[original] = replacement;
        uint256 holderIndex = holderIndices[original] - 1;
        shareholders[holderIndex] = replacement;
        holderIndices[replacement] = holderIndices[original];
        holderIndices[original] = 0;
        balances.setBalance(replacement, balances.balanceOf(original));
        balances.setBalance(original, 0);
        emit VerifiedAddressSuperseded(original, replacement, msg.sender);
    }

    /**
     *  The `transfer` function MUST NOT allow transfers to addresses that
     *  have not been verified and added to the contract.
     *  If the `to` address is not currently a shareholder then it MUST become one.
     *  If the transfer will reduce `msg.sender`'s balance to 0 then that address
     *  MUST be removed from the list of shareholders.
     */
    function transfer(address to, uint256 value)
        public
        override(BasicToken,ERC20Basic,ERC884)
        isNotLockingPeriod
        isVerifiedAddress(to)
        returns (bool) {
            updateShareholders(to);
            pruneShareholders(msg.sender, value);
            return super.transfer(to, value);
    }

    /**
     *  The `transferFrom` function MUST NOT allow transfers to addresses that
     *  have not been verified and added to the contract.
     *  If the `to` address is not currently a shareholder then it MUST become one.
     *  If the transfer will reduce `from`'s balance to 0 then that address
     *  MUST be removed from the list of shareholders.
     */
    function transferFrom(address from, address to, uint256 value)
        public
        override(ERC884,StandardToken)
        isNotLockingPeriod
        isVerifiedAddress(to)
        returns (bool) {
            updateShareholders(to);
            pruneShareholders(from, value);
            return super.transferFrom(from, to, value);
    }

    /**
     *  Tests that the supplied address is known to the contract.
     *  @param addr The address to test.
     *  @return true if the address is known to the contract.
     */
    function isVerified(address addr)
        public
        view
        returns (bool)
    {
        return verified[addr] != ZERO_BYTES;
    }

    /**
     *  Checks to see if the supplied address is a share holder.
     *  @param addr The address to check.
     *  @return true if the supplied address owns a token.
     */
    function isHolder(address addr)
        public
        view
        returns (bool)
    {
        return holderIndices[addr] != 0;
    }

    /**
     *  Checks that the supplied hash is associated with the given address.
     *  @param addr The address to test.
     *  @param hash The hash to test.
     *  @return true if the hash matches the one supplied with the address in `addVerified`, or `updateVerified`.
     */
    function hasHash(address addr, bytes32 hash)
        public
        view
        returns (bool)
    {
        if (addr == ZERO_ADDRESS) {
            return false;
        }
        return verified[addr] == hash;
    }

    /**
     *  Checks to see if the supplied address was superseded.
     *  @param addr The address to check.
     *  @return true if the supplied address was superseded by another address.
     */
    function isSuperseded(address addr)
        public
        view
        onlyOwner
        returns (bool)
    {
        return cancellations[addr] != ZERO_ADDRESS;
    }

    /**
     *  Gets the most recent address, given a superseded one.
     *  Addresses may be superseded multiple times, so this function needs to
     *  follow the chain of addresses until it reaches the final, verified address.
     *  @param addr The superseded address.
     *  @return the verified address that ultimately holds the share.
     */
    function getCurrentFor(address addr)
        public
        view
        onlyOwner
        returns (address)
    {
        return findCurrentFor(addr);
    }

    /**
     *  Recursively find the most recent address given a superseded one.
     *  @param addr The superseded address.
     *  @return the verified address that ultimately holds the share.
     */
    function findCurrentFor(address addr)
        internal
        view
        returns (address)
    {
        address candidate = cancellations[addr];
        if (candidate == ZERO_ADDRESS) {
            return addr;
        }
        return findCurrentFor(candidate);
    }

    /**
     *  If the address is not in the `shareholders` array then push it
     *  and update the `holderIndices` mapping.
     *  @param addr The address to add as a shareholder if it's not already.
     */
    function updateShareholders(address addr)
        internal
    {
        if (holderIndices[addr] == 0) {
            shareholders.push(addr);
            holderIndices[addr] = shareholders.length;
        }
    }

    /**
     *  If the address is in the `shareholders` array and the forthcoming
     *  transfer or transferFrom will reduce their balance to 0, then
     *  we need to remove them from the shareholders array.
     *  @param addr The address to prune if their balance will be reduced to 0.
     @  @dev see https://ethereum.stackexchange.com/a/39311
     */
    function pruneShareholders(address addr, uint256 value)
        internal
    {
        uint256 balance = balances.balanceOf(addr) - value;
        if (balance > 0) {
            return;
        }
        uint256 holderIndex = holderIndices[addr] - 1;
        uint256 lastIndex = shareholders.length - 1;
        address lastHolder = shareholders[lastIndex];

        // overwrite the addr's slot with the last shareholder
        shareholders[holderIndex] = lastHolder;
        // also copy over the index (thanks @mohoff for spotting this)
        // ref https://github.com/davesag/ERC884-reference-implementation/issues/20
        holderIndices[lastHolder] = holderIndices[addr];
        // trim the shareholders array (which drops the last entry)
        shareholders.pop();
        // and zero out the index for addr
        holderIndices[addr] = 0;
    }
}

File 2 of 13 : ERC884.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import './ERC20.sol';


/**
 *  An `ERC20` compatible token that conforms to Delaware State Senate,
 *  149th General Assembly, Senate Bill No. 69: An act to Amend Title 8
 *  of the Delaware Code Relating to the General Corporation Law.
 *
 *  Implementation Details.
 *
 *  An implementation of this token standard SHOULD provide the following:
 *
 *  `name` - for use by wallets and exchanges.
 *  `symbol` - for use by wallets and exchanges.
 *
 *  The implementation MUST take care not to allow unauthorised access to share
 *  transfer functions.
 *
 *  In addition to the above the following optional `ERC20` function MUST be defined.
 *
 *  `decimals` — MUST return `0` as each token represents a single Share and Shares are non-divisible.
 *
 *  @dev Ref https://github.com/ethereum/EIPs/pull/884
 */
interface ERC884 is ERC20 {

    /**
     *  This event is emitted when a verified address and associated identity hash are
     *  added to the contract.
     *  @param addr The address that was added.
     *  @param hash The identity hash associated with the address.
     *  @param sender The address that caused the address to be added.
     */
    event VerifiedAddressAdded(
        address indexed addr,
        bytes32 hash,
        address indexed sender
    );

    /**
     *  This event is emitted when a verified address its associated identity hash are
     *  removed from the contract.
     *  @param addr The address that was removed.
     *  @param sender The address that caused the address to be removed.
     */
    event VerifiedAddressRemoved(address indexed addr, address indexed sender);

    /**
     *  This event is emitted when the identity hash associated with a verified address is updated.
     *  @param addr The address whose hash was updated.
     *  @param oldHash The identity hash that was associated with the address.
     *  @param hash The hash now associated with the address.
     *  @param sender The address that caused the hash to be updated.
     */
    event VerifiedAddressUpdated(
        address indexed addr,
        bytes32 oldHash,
        bytes32 hash,
        address indexed sender
    );

    /**
     *  This event is emitted when an address is cancelled and replaced with
     *  a new address.  This happens in the case where a shareholder has
     *  lost access to their original address and needs to have their share
     *  reissued to a new address.  This is the equivalent of issuing replacement
     *  share certificates.
     *  @param original The address being superseded.
     *  @param replacement The new address.
     *  @param sender The address that caused the address to be superseded.
     */
    event VerifiedAddressSuperseded(
        address indexed original,
        address indexed replacement,
        address indexed sender
    );

    /**
     *  Add a verified address, along with an associated verification hash to the contract.
     *  Upon successful addition of a verified address, the contract must emit
     *  `VerifiedAddressAdded(addr, hash, msg.sender)`.
     *  It MUST throw if the supplied address or hash are zero, or if the address has already been supplied.
     *  @param addr The address of the person represented by the supplied hash.
     *  @param hash A cryptographic hash of the address holder's verified information.
     */
    function addVerified(address addr, bytes32 hash) external;

    /**
     *  Remove a verified address, and the associated verification hash. If the address is
     *  unknown to the contract then this does nothing. If the address is successfully removed, this
     *  function must emit `VerifiedAddressRemoved(addr, msg.sender)`.
     *  It MUST throw if an attempt is made to remove a verifiedAddress that owns Tokens.
     *  @param addr The verified address to be removed.
     */
    function removeVerified(address addr) external;

    /**
     *  Update the hash for a verified address known to the contract.
     *  Upon successful update of a verified address the contract must emit
     *  `VerifiedAddressUpdated(addr, oldHash, hash, msg.sender)`.
     *  If the hash is the same as the value already stored then
     *  no `VerifiedAddressUpdated` event is to be emitted.
     *  It MUST throw if the hash is zero, or if the address is unverified.
     *  @param addr The verified address of the person represented by the supplied hash.
     *  @param hash A new cryptographic hash of the address holder's updated verified information.
     */
    function updateVerified(address addr, bytes32 hash) external;

    /**
     *  Cancel the original address and reissue the Tokens to the replacement address.
     *  Access to this function MUST be strictly controlled.
     *  The `original` address MUST be removed from the set of verified addresses.
     *  Throw if the `original` address supplied is not a shareholder.
     *  Throw if the `replacement` address is not a verified address.
     *  Throw if the `replacement` address already holds Tokens.
     *  This function MUST emit the `VerifiedAddressSuperseded` event.
     *  @param original The address to be superseded. This address MUST NOT be reused.
     */
    function cancelAndReissue(address original, address replacement) external;

    /**
     *  The `transfer` function MUST NOT allow transfers to addresses that
     *  have not been verified and added to the contract.
     *  If the `to` address is not currently a shareholder then it MUST become one.
     *  If the transfer will reduce `msg.sender`'s balance to 0 then that address
     *  MUST be removed from the list of shareholders.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     *  The `transferFrom` function MUST NOT allow transfers to addresses that
     *  have not been verified and added to the contract.
     *  If the `to` address is not currently a shareholder then it MUST become one.
     *  If the transfer will reduce `from`'s balance to 0 then that address
     *  MUST be removed from the list of shareholders.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);

    /**
     *  Tests that the supplied address is known to the contract.
     *  @param addr The address to test.
     *  @return true if the address is known to the contract.
     */
    function isVerified(address addr) external view returns (bool);

    /**
     *  Checks to see if the supplied address is a share holder.
     *  @param addr The address to check.
     *  @return true if the supplied address owns a token.
     */
    function isHolder(address addr) external view returns (bool);

    /**
     *  Checks that the supplied hash is associated with the given address.
     *  @param addr The address to test.
     *  @param hash The hash to test.
     *  @return true if the hash matches the one supplied with the address in `addVerified`, or `updateVerified`.
     */
    function hasHash(address addr, bytes32 hash) external view returns (bool);

    /**
     *  The number of addresses that hold tokens.
     *  @return the number of unique addresses that hold tokens.
     */
    function holderCount() external view returns (uint);

    /**
     *  By counting the number of token holders using `holderCount`
     *  you can retrieve the complete list of token holders, one at a time.
     *  It MUST throw if `index >= holderCount()`.
     *  @param index The zero-based index of the holder.
     *  @return the address of the token holder with the given index.
     */
    function holderAt(uint256 index) external view returns (address);

    /**
     *  Checks to see if the supplied address was superseded.
     *  @param addr The address to check.
     *  @return true if the supplied address was superseded by another address.
     */
    function isSuperseded(address addr) external view returns (bool);

    /**
     *  Gets the most recent address, given a superseded one.
     *  Addresses may be superseded multiple times, so this function needs to
     *  follow the chain of addresses until it reaches the final, verified address.
     *  @param addr The superseded address.
     *  @return the verified address that ultimately holds the share.
     */
    function getCurrentFor(address addr) external view returns (address);
}

File 3 of 13 : MintableToken.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import "./StandardToken.sol";


/**
 * @title Mintable token
 * @dev Simple ERC20 Token example, with mintable token creation
 * @dev Issue: * https://github.com/OpenZeppelin/zeppelin-solidity/issues/120
 * Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol
 */
contract MintableToken is StandardToken {
  event Mint(address indexed to, uint256 amount);

  /**
   * @dev Function to mint tokens
   * @param _to The address that will receive the minted tokens.
   * @param _amount The amount of tokens to mint.
   * @return A boolean that indicates if the operation was successful.
   */
  function mint(address _to, uint256 _amount) onlyOwner public virtual returns (bool) {
    totalSupply_ = totalSupply_ + (_amount);
    balances.addBalance(_to, _amount);
    emit Mint(_to, _amount);
    emit Transfer(address(0), _to, _amount);
    return true;
  }
}

File 4 of 13 : StandardToken.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import "./BasicToken.sol";
import "./ERC20.sol";
import "./AllowanceSheet.sol";


/**
 * @title Standard ERC20 token
 *
 * @dev Implementation of the basic standard token.
 * @dev https://github.com/ethereum/EIPs/issues/20
 * @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
 */
contract StandardToken is ERC20, BasicToken {

  AllowanceSheet public allowances;

  function setAllowanceSheet(address sheet) external onlyOwner {
    allowances = AllowanceSheet(sheet);
    allowances.claimOwnership();
  }

  /**
   * @dev Transfer tokens from one address to another
   * @param _from address The address which you want to send tokens from
   * @param _to address The address which you want to transfer to
   * @param _value uint256 the amount of tokens to be transferred
   */
  function transferFrom(address _from, address _to, uint256 _value) public virtual override returns (bool) {
    transferFromAllArgs(_from, _to, _value, msg.sender);
    return true;
  }

  function transferFromAllArgs(address _from, address _to, uint256 _value, address spender) internal {
    require(_value <= allowances.allowanceOf(_from, spender));

    allowances.subAllowance(_from, spender, _value);
    transferAllArgs(_from, _to, _value);
  }

  /**
   * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
   *
   * 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
   * @param _spender The address which will spend the funds.
   * @param _value The amount of tokens to be spent.
   */
  function approve(address _spender, uint256 _value) public override returns (bool) {
    approveAllArgs(_spender, _value, msg.sender);
    return true;
  }

  function approveAllArgs(address _spender, uint256 _value, address _tokenHolder) internal {
    allowances.setAllowance(_tokenHolder, _spender, _value);
    emit Approval(_tokenHolder, _spender, _value);
  }

  /**
   * @dev Function to check the amount of tokens that an owner allowed to a spender.
   * @param _owner address The address which owns the funds.
   * @param _spender address The address which will spend the funds.
   * @return A uint256 specifying the amount of tokens still available for the spender.
   */
  function allowance(address _owner, address _spender) public view override returns (uint256) {
    return allowances.allowanceOf(_owner, _spender);
  }

  /**
   * @dev Increase the amount of tokens that an owner allowed to a spender.
   *
   * approve should be called when allowed[_spender] == 0. To increment
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param _spender The address which will spend the funds.
   * @param _addedValue The amount of tokens to increase the allowance by.
   */
  function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
    increaseApprovalAllArgs(_spender, _addedValue, msg.sender);
    return true;
  }

  function increaseApprovalAllArgs(address _spender, uint256 _addedValue, address tokenHolder) internal {
    allowances.addAllowance(tokenHolder, _spender, _addedValue);
    emit Approval(tokenHolder, _spender, allowances.allowanceOf(tokenHolder, _spender));
  }

  /**
   * @dev Decrease the amount of tokens that an owner allowed to a spender.
   *
   * approve should be called when allowed[_spender] == 0. To decrement
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param _spender The address which will spend the funds.
   * @param _subtractedValue The amount of tokens to decrease the allowance by.
   */
  function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
    decreaseApprovalAllArgs(_spender, _subtractedValue, msg.sender);
    return true;
  }

  function decreaseApprovalAllArgs(address _spender, uint256 _subtractedValue, address tokenHolder) internal {
    uint256 oldValue = allowances.allowanceOf(tokenHolder, _spender);
    if (_subtractedValue > oldValue) {
      allowances.setAllowance(tokenHolder, _spender, 0);
    } else {
      allowances.subAllowance(tokenHolder, _spender, _subtractedValue);
    }
    emit Approval(tokenHolder, _spender, allowances.allowanceOf(tokenHolder, _spender));
  }

}

File 5 of 13 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)

pragma solidity 0.8.16;

import "./ERC20Basic.sol";


/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
interface ERC20 is ERC20Basic {
  function allowance(address owner, address spender) external view returns (uint256);
  function transferFrom(address from, address to, uint256 value) external returns (bool);
  function approve(address spender, uint256 value) external returns (bool);
  event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 6 of 13 : AllowanceSheet.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import "./Claimable.sol";
import "./SafeMath.sol";

contract AllowanceSheet is Claimable {
    using SafeMath for uint256;

    mapping (address => mapping (address => uint256)) public allowanceOf;

    function addAllowance(address tokenHolder, address spender, uint256 value) public onlyOwner {
        allowanceOf[tokenHolder][spender] = allowanceOf[tokenHolder][spender].add(value);
    }

    function subAllowance(address tokenHolder, address spender, uint256 value) public onlyOwner {
        allowanceOf[tokenHolder][spender] = allowanceOf[tokenHolder][spender].sub(value);
    }

    function setAllowance(address tokenHolder, address spender, uint256 value) public onlyOwner {
        allowanceOf[tokenHolder][spender] = value;
    }
}

File 7 of 13 : BasicToken.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import "./ERC20Basic.sol";
import "./SafeMath.sol";
import "./BalanceSheet.sol";


// Version of OpenZeppelin's BasicToken whose balances mapping has been replaced
// with a separate BalanceSheet contract. Most useful in combination with e.g.
// HasNoContracts because then it can relinquish its balance sheet to a new
// version of the token, removing the need to copy over balances.
/**
 * @title Basic token
 * @dev Basic version of StandardToken, with no allowances.
 */
contract BasicToken is ERC20Basic, Claimable {
  using SafeMath for uint256;

  BalanceSheet public balances;

  uint256 totalSupply_;

  function setBalanceSheet(address sheet) external onlyOwner {
    balances = BalanceSheet(sheet);
    balances.claimOwnership();
  }

  /**
  * @dev total number of tokens in existence
  */
  function totalSupply() public view returns (uint256) {
    return totalSupply_;
  }

  /**
  * @dev transfer token for a specified address
  * @param _to The address to transfer to.
  * @param _value The amount to be transferred.
  */
  function transfer(address _to, uint256 _value) public virtual returns (bool) {
    transferAllArgs(msg.sender, _to, _value);
    return true;
  }

  function transferAllArgs(address _from, address _to, uint256 _value) internal {
    require(_to != address(0));
    require(_from != address(0));
    require(_value <= balances.balanceOf(_from));

    // SafeMath.sub will throw if there is not enough balance.
    balances.subBalance(_from, _value);
    balances.addBalance(_to, _value);
    emit Transfer(_from, _to, _value);
  }

  /**
  * @dev Gets the balance of the specified address.
  * @param _owner The address to query the the balance of.
  */
  function balanceOf(address _owner) public view virtual returns (uint256 balance) {
    return balances.balanceOf(_owner);
  }
}

File 8 of 13 : ERC20Basic.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/179
 */
interface ERC20Basic {
  function totalSupply() external view returns (uint256);
  function balanceOf(address who) external view returns (uint256);
  function transfer(address to, uint256 value) external returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}

File 9 of 13 : BalanceSheet.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import "./Claimable.sol";
import "./SafeMath.sol";

contract BalanceSheet is Claimable {
    using SafeMath for uint256;

    mapping (address => uint256) public balanceOf;

    function addBalance(address addr, uint256 value) public onlyOwner {
        balanceOf[addr] = balanceOf[addr].add(value);
    }

    function subBalance(address addr, uint256 value) public onlyOwner {
        balanceOf[addr] = balanceOf[addr].sub(value);
    }

    function setBalance(address addr, uint256 value) public onlyOwner {
        balanceOf[addr] = value;
    }
}

File 10 of 13 : SafeMath.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    if (a == 0) {
      return 0;
    }
    uint256 c = a * b;
    assert(c / a == b);
    return c;
  }

  /**
  * @dev Integer division of two numbers, truncating the quotient.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return c;
  }

  /**
  * @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

File 11 of 13 : Claimable.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import "./Ownable.sol";


/**
 * @title Claimable
 * @dev Extension for the Ownable contract, where the ownership needs to be claimed.
 * This allows the new owner to accept the transfer.
 */
contract Claimable is Ownable {
  address public pendingOwner;

  /**
   * @dev Modifier throws if called by any account other than the pendingOwner.
   */
  modifier onlyPendingOwner() {
    require(msg.sender == pendingOwner);
    _;
  }

  /**
   * @dev Allows the current owner to set the pendingOwner address.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) onlyOwner override public {
    pendingOwner = newOwner;
  }

  /**
   * @dev Allows the pendingOwner address to finalize the transfer.
   */
  function claimOwnership() onlyPendingOwner public {
    emit OwnershipTransferred(_owner, pendingOwner);
    _owner = pendingOwner;
    pendingOwner = address(0);
  }
}

File 12 of 13 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity 0.8.16;

import "./Context.sol";
/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address public _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 13 of 13 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity 0.8.16;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"_enabled","type":"bool"}],"name":"LockingPeriodEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_lockTimeInDays","type":"uint256"}],"name":"LockingPeriodUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"VerifiedAddressAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"VerifiedAddressRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"original","type":"address"},{"indexed":true,"internalType":"address","name":"replacement","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"VerifiedAddressSuperseded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bytes32","name":"oldHash","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"VerifiedAddressUpdated","type":"event"},{"inputs":[],"name":"_owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"addVerified","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowances","outputs":[{"internalType":"contract AllowanceSheet","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balances","outputs":[{"internalType":"contract BalanceSheet","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"original","type":"address"},{"internalType":"address","name":"replacement","type":"address"}],"name":"cancelAndReissue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_value","type":"bool"}],"name":"enableLockingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getCurrentFor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"hasHash","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"holderAt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"holderCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isHolder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isSuperseded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isVerified","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockingPeriodEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"removeVerified","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sheet","type":"address"}],"name":"setAllowanceSheet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sheet","type":"address"}],"name":"setBalanceSheet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockTimeInDays","type":"uint256"}],"name":"setLockingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"updateVerified","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260006007553480156200001657600080fd5b50620000376200002b620000fe60201b60201c565b6200010660201b60201c565b6040518060400160405280600a81526020017f457175697479436f696e00000000000000000000000000000000000000000000815250600590816200007d919062000444565b506040518060400160405280600481526020017f455154590000000000000000000000000000000000000000000000000000000081525060069081620000c4919062000444565b506001600c60006101000a81548160ff0219169083151502179055506301e1338042620000f291906200055a565b600d8190555062000595565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200024c57607f821691505b60208210810362000262576200026162000204565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620002cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200028d565b620002d886836200028d565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620003256200031f6200031984620002f0565b620002fa565b620002f0565b9050919050565b6000819050919050565b620003418362000304565b6200035962000350826200032c565b8484546200029a565b825550505050565b600090565b6200037062000361565b6200037d81848462000336565b505050565b5b81811015620003a5576200039960008262000366565b60018101905062000383565b5050565b601f821115620003f457620003be8162000268565b620003c9846200027d565b81016020851015620003d9578190505b620003f1620003e8856200027d565b83018262000382565b50505b505050565b600082821c905092915050565b60006200041960001984600802620003f9565b1980831691505092915050565b600062000434838362000406565b9150826002028217905092915050565b6200044f82620001ca565b67ffffffffffffffff8111156200046b576200046a620001d5565b5b62000477825462000233565b62000484828285620003a9565b600060209050601f831160018114620004bc5760008415620004a7578287015190505b620004b3858262000426565b86555062000523565b601f198416620004cc8662000268565b60005b82811015620004f657848901518255600182019150602085019450602081019050620004cf565b8683101562000516578489015162000512601f89168262000406565b8355505b6001600288020188555050505b505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006200056782620002f0565b91506200057483620002f0565b92508282019050808211156200058f576200058e6200052b565b5b92915050565b6141f080620005a56000396000f3fe608060405234801561001057600080fd5b50600436106102275760003560e01c80636618846311610130578063b85ec9fa116100b8578063dd62ed3e1161007c578063dd62ed3e1461068e578063e30c3978146106be578063edc1e4f9146106dc578063f2fde38b146106f8578063f3221c7f1461071457610227565b8063b85ec9fa146105b2578063b9209e33146105ce578063cc397ed3146105fe578063d4d7b19a1461062e578063d73dd6231461065e57610227565b80637bb98a68116100ff5780637bb98a681461050a5780638da5cb5b1461052857806395d89b4114610546578063a9059cbb14610564578063b2bdfa7b1461059457610227565b8063661884631461048457806370a08231146104b4578063715018a6146104e457806379f64720146104ee57610227565b8063354b7b1d116101b357806347089f621161018257806347089f62146104065780634e71e0c81461042257806354f78dad1461042c578063550066d5146104485780635db7fa411461046657610227565b8063354b7b1d146103805780633ed10b921461039c57806340c10f19146103ba5780634487b392146103ea57610227565b80631aab9a9f116101fa5780631aab9a9f146102c857806323b872dd146102e657806326b321d1146103165780632da7293e14610332578063313ce5671461036257610227565b806306fdde031461022c578063095ea7b31461024a57806318160ddd1461027a578063197bc33614610298575b600080fd5b610234610744565b60405161024191906137ad565b60405180910390f35b610264600480360381019061025f9190613868565b6107d2565b60405161027191906138c3565b60405180910390f35b6102826107e9565b60405161028f91906138ed565b60405180910390f35b6102b260048036038101906102ad9190613908565b6107f3565b6040516102bf9190613944565b60405180910390f35b6102d06108c8565b6040516102dd91906138ed565b60405180910390f35b61030060048036038101906102fb919061395f565b6108d5565b60405161030d91906138c3565b60405180910390f35b610330600480360381019061032b9190613908565b610a1d565b005b61034c600480360381019061034791906139b2565b610aef565b60405161035991906138c3565b60405180910390f35b61036a610c04565b60405161037791906138ed565b60405180910390f35b61039a60048036038101906103959190613a15565b610c0a565b005b6103a4610e17565b6040516103b19190613ab4565b60405180910390f35b6103d460048036038101906103cf9190613868565b610e3d565b6040516103e191906138c3565b60405180910390f35b61040460048036038101906103ff91906139b2565b610f5c565b005b610420600480360381019061041b9190613a15565b61116e565b005b61042a6113fd565b005b610446600480360381019061044191906139b2565b611599565b005b6104506116db565b60405161045d91906138ed565b60405180910390f35b61046e6116e1565b60405161047b91906138c3565b60405180910390f35b61049e60048036038101906104999190613868565b6116f4565b6040516104ab91906138c3565b60405180910390f35b6104ce60048036038101906104c991906139b2565b61170b565b6040516104db91906138ed565b60405180910390f35b6104ec6117b0565b005b61050860048036038101906105039190613acf565b611838565b005b610512611eac565b60405161051f9190613b30565b60405180910390f35b610530611ed2565b60405161053d9190613944565b60405180910390f35b61054e611efb565b60405161055b91906137ad565b60405180910390f35b61057e60048036038101906105799190613868565b611f89565b60405161058b91906138c3565b60405180910390f35b61059c6120cf565b6040516105a99190613944565b60405180910390f35b6105cc60048036038101906105c79190613b77565b6120f3565b005b6105e860048036038101906105e391906139b2565b6121ca565b6040516105f591906138c3565b60405180910390f35b610618600480360381019061061391906139b2565b612219565b6040516106259190613944565b60405180910390f35b610648600480360381019061064391906139b2565b6122a7565b60405161065591906138c3565b60405180910390f35b61067860048036038101906106739190613868565b6122f3565b60405161068591906138c3565b60405180910390f35b6106a860048036038101906106a39190613acf565b61230a565b6040516106b591906138ed565b60405180910390f35b6106c66123b2565b6040516106d39190613944565b60405180910390f35b6106f660048036038101906106f191906139b2565b6123d8565b005b610712600480360381019061070d91906139b2565b61251a565b005b61072e60048036038101906107299190613a15565b6125da565b60405161073b91906138c3565b60405180910390f35b6005805461075190613bd3565b80601f016020809104026020016040519081016040528092919081815260200182805461077d90613bd3565b80156107ca5780601f1061079f576101008083540402835291602001916107ca565b820191906000526020600020905b8154815290600101906020018083116107ad57829003601f168201915b505050505081565b60006107df838333612663565b6001905092915050565b6000600354905090565b60006107fd61275e565b73ffffffffffffffffffffffffffffffffffffffff1661081b611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614610871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161086890613c50565b60405180910390fd5b600b80549050821061088257600080fd5b600b828154811061089657610895613c70565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600b80549050905090565b6000600c60009054906101000a900460ff1615806108f4575042600d54105b806109315750610902611ed2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610970576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096790613d11565b60405180910390fd5b826000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054036109f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ec90613d7d565b60405180910390fd5b6109fe84612766565b610a08858461285d565b610a13858585612b35565b9150509392505050565b610a2561275e565b73ffffffffffffffffffffffffffffffffffffffff16610a43611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614610a99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9090613c50565b60405180910390fd5b60006201518082610aaa9190613dcc565b90508042610ab89190613e26565b600d81905550817f10e4464ec1508bc74373bc20969bfc3c86fb9f7b2fce089585495bf47bfce4bc60405160405180910390a25050565b6000610af961275e565b73ffffffffffffffffffffffffffffffffffffffff16610b17611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614610b6d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6490613c50565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60075481565b610c1261275e565b73ffffffffffffffffffffffffffffffffffffffff16610c30611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614610c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7d90613c50565b60405180910390fd5b816000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403610d0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0290613d7d565b60405180910390fd5b6000801b8203610d1a57600080fd5b6000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050828114610e115782600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f63ec12603f028c6f74dc3c59a67d645d431250142b56676015d25475ee3fc3d38386604051610e08929190613e69565b60405180910390a35b50505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000610e4761275e565b73ffffffffffffffffffffffffffffffffffffffff16610e65611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614610ebb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb290613c50565b60405180910390fd5b826000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403610f40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3790613d7d565b60405180910390fd5b610f4984612766565b610f538484612b4e565b91505092915050565b610f6461275e565b73ffffffffffffffffffffffffffffffffffffffff16610f82611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614610fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fcf90613c50565b60405180910390fd5b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016110359190613944565b602060405180830381865afa158015611052573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110769190613ea7565b1461108057600080fd5b6000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541461116b576000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8071c01a493142de896a206c19ca180d32e91d6486fcf11ea299f569f5d922b560405160405180910390a35b50565b61117661275e565b73ffffffffffffffffffffffffffffffffffffffff16611194611ed2565b73ffffffffffffffffffffffffffffffffffffffff16146111ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e190613c50565b60405180910390fd5b81600073ffffffffffffffffffffffffffffffffffffffff16600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146112b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b090613f20565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112f257600080fd5b6000801b820361130157600080fd5b6000801b600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541461134f57600080fd5b81600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb4f9d1d687d745820ae7c948518d6eef182cfbf5ef20b5b6a33769059592e7c8846040516113f09190613f40565b60405180910390a3505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461145757600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6115a161275e565b73ffffffffffffffffffffffffffffffffffffffff166115bf611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614611615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160c90613c50565b60405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634e71e0c86040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156116c057600080fd5b505af11580156116d4573d6000803e3d6000fd5b5050505050565b600d5481565b600c60009054906101000a900460ff1681565b6000611701838333612d2d565b6001905092915050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016117689190613944565b602060405180830381865afa158015611785573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a99190613ea7565b9050919050565b6117b861275e565b73ffffffffffffffffffffffffffffffffffffffff166117d6611ed2565b73ffffffffffffffffffffffffffffffffffffffff161461182c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182390613c50565b60405180910390fd5b6118366000613008565b565b61184061275e565b73ffffffffffffffffffffffffffffffffffffffff1661185e611ed2565b73ffffffffffffffffffffffffffffffffffffffff16146118b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ab90613c50565b60405180910390fd5b816000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403611937576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192e90613fa7565b60405180910390fd5b816000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146119ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b190614013565b60405180910390fd5b826000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403611a3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3690613d7d565b60405180910390fd5b6000801b600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555083600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006001600a60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611b529190614033565b905084600b8281548110611b6957611b68613c70565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600a60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e30443bc86600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a082318a6040518263ffffffff1660e01b8152600401611d139190613944565b602060405180830381865afa158015611d30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d549190613ea7565b6040518363ffffffff1660e01b8152600401611d71929190614067565b600060405180830381600087803b158015611d8b57600080fd5b505af1158015611d9f573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e30443bc8760006040518363ffffffff1660e01b8152600401611e019291906140cb565b600060405180830381600087803b158015611e1b57600080fd5b505af1158015611e2f573d6000803e3d6000fd5b505050503373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fb64971100522354f3d25283cb14e2eefcb0dd26a757482ccfe42479d0a68685760405160405180910390a4505050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60068054611f0890613bd3565b80601f0160208091040260200160405190810160405280929190818152602001828054611f3490613bd3565b8015611f815780601f10611f5657610100808354040283529160200191611f81565b820191906000526020600020905b815481529060010190602001808311611f6457829003601f168201915b505050505081565b6000600c60009054906101000a900460ff161580611fa8575042600d54105b80611fe55750611fb6611ed2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612024576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201b90613d11565b60405180910390fd5b826000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054036120a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a090613d7d565b60405180910390fd5b6120b284612766565b6120bc338461285d565b6120c684846130cc565b91505092915050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6120fb61275e565b73ffffffffffffffffffffffffffffffffffffffff16612119611ed2565b73ffffffffffffffffffffffffffffffffffffffff161461216f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161216690613c50565b60405180910390fd5b80600c60006101000a81548160ff021916908315150217905550600c60009054906101000a900460ff1615157fe039d903d34cc70b8016e3c231cc2dd1171f775eb4530f765ccf2efb9acb799860405160405180910390a250565b60008060001b600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414159050919050565b600061222361275e565b73ffffffffffffffffffffffffffffffffffffffff16612241611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614612297576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228e90613c50565b60405180910390fd5b6122a0826130e3565b9050919050565b600080600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414159050919050565b6000612300838333613197565b6001905092915050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631a46ec8284846040518363ffffffff1660e01b81526004016123699291906140f4565b602060405180830381865afa158015612386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123aa9190613ea7565b905092915050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6123e061275e565b73ffffffffffffffffffffffffffffffffffffffff166123fe611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614612454576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244b90613c50565b60405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634e71e0c86040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156124ff57600080fd5b505af1158015612513573d6000803e3d6000fd5b5050505050565b61252261275e565b73ffffffffffffffffffffffffffffffffffffffff16612540611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614612596576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161258d90613c50565b60405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612618576000905061265d565b81600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541490505b92915050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663da46098c8285856040518463ffffffff1660e01b81526004016126c29392919061411d565b600060405180830381600087803b1580156126dc57600080fd5b505af11580156126f0573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161275191906138ed565b60405180910390a3505050565b600033905090565b6000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540361285a57600b819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600b80549050600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b50565b600081600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b81526004016128bb9190613944565b602060405180830381865afa1580156128d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fc9190613ea7565b6129069190614033565b905060008111156129175750612b31565b60006001600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129659190614033565b905060006001600b8054905061297b9190614033565b90506000600b828154811061299357612992613c70565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905080600b84815481106129d5576129d4613c70565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600b805480612ab257612ab1614154565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905590556000600a60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050505b5050565b6000612b438484843361332f565b600190509392505050565b6000612b5861275e565b73ffffffffffffffffffffffffffffffffffffffff16612b76611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614612bcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bc390613c50565b60405180910390fd5b81600354612bda9190613e26565b600381905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166321e5383a84846040518363ffffffff1660e01b8152600401612c3d929190614067565b600060405180830381600087803b158015612c5757600080fd5b505af1158015612c6b573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688583604051612cb591906138ed565b60405180910390a28273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612d1b91906138ed565b60405180910390a36001905092915050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631a46ec8283866040518363ffffffff1660e01b8152600401612d8c9291906140f4565b602060405180830381865afa158015612da9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dcd9190613ea7565b905080831115612e6e57600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663da46098c838660006040518463ffffffff1660e01b8152600401612e3793929190614183565b600060405180830381600087803b158015612e5157600080fd5b505af1158015612e65573d6000803e3d6000fd5b50505050612f00565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166397d88cd28386866040518463ffffffff1660e01b8152600401612ecd9392919061411d565b600060405180830381600087803b158015612ee757600080fd5b505af1158015612efb573d6000803e3d6000fd5b505050505b8373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631a46ec8286896040518363ffffffff1660e01b8152600401612fac9291906140f4565b602060405180830381865afa158015612fc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fed9190613ea7565b604051612ffa91906138ed565b60405180910390a350505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006130d933848461347b565b6001905092915050565b600080600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036131855782915050613192565b61318e816130e3565b9150505b919050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635fd72d168285856040518463ffffffff1660e01b81526004016131f69392919061411d565b600060405180830381600087803b15801561321057600080fd5b505af1158015613224573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631a46ec8285886040518363ffffffff1660e01b81526004016132d49291906140f4565b602060405180830381865afa1580156132f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133159190613ea7565b60405161332291906138ed565b60405180910390a3505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631a46ec8285836040518363ffffffff1660e01b815260040161338c9291906140f4565b602060405180830381865afa1580156133a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133cd9190613ea7565b8211156133d957600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166397d88cd28583856040518463ffffffff1660e01b81526004016134389392919061411d565b600060405180830381600087803b15801561345257600080fd5b505af1158015613466573d6000803e3d6000fd5b5050505061347584848461347b565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036134b457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036134ed57600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b81526004016135489190613944565b602060405180830381865afa158015613565573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135899190613ea7565b81111561359557600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cf8eeb7e84836040518363ffffffff1660e01b81526004016135f2929190614067565b600060405180830381600087803b15801561360c57600080fd5b505af1158015613620573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166321e5383a83836040518363ffffffff1660e01b8152600401613681929190614067565b600060405180830381600087803b15801561369b57600080fd5b505af11580156136af573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161371091906138ed565b60405180910390a3505050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561375757808201518184015260208101905061373c565b60008484015250505050565b6000601f19601f8301169050919050565b600061377f8261371d565b6137898185613728565b9350613799818560208601613739565b6137a281613763565b840191505092915050565b600060208201905081810360008301526137c78184613774565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006137ff826137d4565b9050919050565b61380f816137f4565b811461381a57600080fd5b50565b60008135905061382c81613806565b92915050565b6000819050919050565b61384581613832565b811461385057600080fd5b50565b6000813590506138628161383c565b92915050565b6000806040838503121561387f5761387e6137cf565b5b600061388d8582860161381d565b925050602061389e85828601613853565b9150509250929050565b60008115159050919050565b6138bd816138a8565b82525050565b60006020820190506138d860008301846138b4565b92915050565b6138e781613832565b82525050565b600060208201905061390260008301846138de565b92915050565b60006020828403121561391e5761391d6137cf565b5b600061392c84828501613853565b91505092915050565b61393e816137f4565b82525050565b60006020820190506139596000830184613935565b92915050565b600080600060608486031215613978576139776137cf565b5b60006139868682870161381d565b93505060206139978682870161381d565b92505060406139a886828701613853565b9150509250925092565b6000602082840312156139c8576139c76137cf565b5b60006139d68482850161381d565b91505092915050565b6000819050919050565b6139f2816139df565b81146139fd57600080fd5b50565b600081359050613a0f816139e9565b92915050565b60008060408385031215613a2c57613a2b6137cf565b5b6000613a3a8582860161381d565b9250506020613a4b85828601613a00565b9150509250929050565b6000819050919050565b6000613a7a613a75613a70846137d4565b613a55565b6137d4565b9050919050565b6000613a8c82613a5f565b9050919050565b6000613a9e82613a81565b9050919050565b613aae81613a93565b82525050565b6000602082019050613ac96000830184613aa5565b92915050565b60008060408385031215613ae657613ae56137cf565b5b6000613af48582860161381d565b9250506020613b058582860161381d565b9150509250929050565b6000613b1a82613a81565b9050919050565b613b2a81613b0f565b82525050565b6000602082019050613b456000830184613b21565b92915050565b613b54816138a8565b8114613b5f57600080fd5b50565b600081359050613b7181613b4b565b92915050565b600060208284031215613b8d57613b8c6137cf565b5b6000613b9b84828501613b62565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613beb57607f821691505b602082108103613bfe57613bfd613ba4565b5b50919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613c3a602083613728565b9150613c4582613c04565b602082019050919050565b60006020820190508181036000830152613c6981613c2d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f63616e6e6f74207472616e7366657220746f6b656e7320647572696e67206c6f60008201527f636b696e6720706572696f64206f66203132206d6f6e74687300000000000000602082015250565b6000613cfb603983613728565b9150613d0682613c9f565b604082019050919050565b60006020820190508181036000830152613d2a81613cee565b9050919050565b7f61646472657373206e6f74207665726966696564000000000000000000000000600082015250565b6000613d67601483613728565b9150613d7282613d31565b602082019050919050565b60006020820190508181036000830152613d9681613d5a565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613dd782613832565b9150613de283613832565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613e1b57613e1a613d9d565b5b828202905092915050565b6000613e3182613832565b9150613e3c83613832565b9250828201905080821115613e5457613e53613d9d565b5b92915050565b613e63816139df565b82525050565b6000604082019050613e7e6000830185613e5a565b613e8b6020830184613e5a565b9392505050565b600081519050613ea18161383c565b92915050565b600060208284031215613ebd57613ebc6137cf565b5b6000613ecb84828501613e92565b91505092915050565b7f616464726573732069732063616e63656c656400000000000000000000000000600082015250565b6000613f0a601383613728565b9150613f1582613ed4565b602082019050919050565b60006020820190508181036000830152613f3981613efd565b9050919050565b6000602082019050613f556000830184613e5a565b92915050565b7f61646472657373206973206e6f74206120736861726564686f6c646572000000600082015250565b6000613f91601d83613728565b9150613f9c82613f5b565b602082019050919050565b60006020820190508181036000830152613fc081613f84565b9050919050565b7f616464726573732069732061207368617265686f6c6465720000000000000000600082015250565b6000613ffd601883613728565b915061400882613fc7565b602082019050919050565b6000602082019050818103600083015261402c81613ff0565b9050919050565b600061403e82613832565b915061404983613832565b925082820390508181111561406157614060613d9d565b5b92915050565b600060408201905061407c6000830185613935565b61408960208301846138de565b9392505050565b6000819050919050565b60006140b56140b06140ab84614090565b613a55565b613832565b9050919050565b6140c58161409a565b82525050565b60006040820190506140e06000830185613935565b6140ed60208301846140bc565b9392505050565b60006040820190506141096000830185613935565b6141166020830184613935565b9392505050565b60006060820190506141326000830186613935565b61413f6020830185613935565b61414c60408301846138de565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006060820190506141986000830186613935565b6141a56020830185613935565b6141b260408301846140bc565b94935050505056fea2646970667358221220f125139179ee9e72eef769c73a82ae061915cdd7e0b1864f35139edb3157c36364736f6c63430008100033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102275760003560e01c80636618846311610130578063b85ec9fa116100b8578063dd62ed3e1161007c578063dd62ed3e1461068e578063e30c3978146106be578063edc1e4f9146106dc578063f2fde38b146106f8578063f3221c7f1461071457610227565b8063b85ec9fa146105b2578063b9209e33146105ce578063cc397ed3146105fe578063d4d7b19a1461062e578063d73dd6231461065e57610227565b80637bb98a68116100ff5780637bb98a681461050a5780638da5cb5b1461052857806395d89b4114610546578063a9059cbb14610564578063b2bdfa7b1461059457610227565b8063661884631461048457806370a08231146104b4578063715018a6146104e457806379f64720146104ee57610227565b8063354b7b1d116101b357806347089f621161018257806347089f62146104065780634e71e0c81461042257806354f78dad1461042c578063550066d5146104485780635db7fa411461046657610227565b8063354b7b1d146103805780633ed10b921461039c57806340c10f19146103ba5780634487b392146103ea57610227565b80631aab9a9f116101fa5780631aab9a9f146102c857806323b872dd146102e657806326b321d1146103165780632da7293e14610332578063313ce5671461036257610227565b806306fdde031461022c578063095ea7b31461024a57806318160ddd1461027a578063197bc33614610298575b600080fd5b610234610744565b60405161024191906137ad565b60405180910390f35b610264600480360381019061025f9190613868565b6107d2565b60405161027191906138c3565b60405180910390f35b6102826107e9565b60405161028f91906138ed565b60405180910390f35b6102b260048036038101906102ad9190613908565b6107f3565b6040516102bf9190613944565b60405180910390f35b6102d06108c8565b6040516102dd91906138ed565b60405180910390f35b61030060048036038101906102fb919061395f565b6108d5565b60405161030d91906138c3565b60405180910390f35b610330600480360381019061032b9190613908565b610a1d565b005b61034c600480360381019061034791906139b2565b610aef565b60405161035991906138c3565b60405180910390f35b61036a610c04565b60405161037791906138ed565b60405180910390f35b61039a60048036038101906103959190613a15565b610c0a565b005b6103a4610e17565b6040516103b19190613ab4565b60405180910390f35b6103d460048036038101906103cf9190613868565b610e3d565b6040516103e191906138c3565b60405180910390f35b61040460048036038101906103ff91906139b2565b610f5c565b005b610420600480360381019061041b9190613a15565b61116e565b005b61042a6113fd565b005b610446600480360381019061044191906139b2565b611599565b005b6104506116db565b60405161045d91906138ed565b60405180910390f35b61046e6116e1565b60405161047b91906138c3565b60405180910390f35b61049e60048036038101906104999190613868565b6116f4565b6040516104ab91906138c3565b60405180910390f35b6104ce60048036038101906104c991906139b2565b61170b565b6040516104db91906138ed565b60405180910390f35b6104ec6117b0565b005b61050860048036038101906105039190613acf565b611838565b005b610512611eac565b60405161051f9190613b30565b60405180910390f35b610530611ed2565b60405161053d9190613944565b60405180910390f35b61054e611efb565b60405161055b91906137ad565b60405180910390f35b61057e60048036038101906105799190613868565b611f89565b60405161058b91906138c3565b60405180910390f35b61059c6120cf565b6040516105a99190613944565b60405180910390f35b6105cc60048036038101906105c79190613b77565b6120f3565b005b6105e860048036038101906105e391906139b2565b6121ca565b6040516105f591906138c3565b60405180910390f35b610618600480360381019061061391906139b2565b612219565b6040516106259190613944565b60405180910390f35b610648600480360381019061064391906139b2565b6122a7565b60405161065591906138c3565b60405180910390f35b61067860048036038101906106739190613868565b6122f3565b60405161068591906138c3565b60405180910390f35b6106a860048036038101906106a39190613acf565b61230a565b6040516106b591906138ed565b60405180910390f35b6106c66123b2565b6040516106d39190613944565b60405180910390f35b6106f660048036038101906106f191906139b2565b6123d8565b005b610712600480360381019061070d91906139b2565b61251a565b005b61072e60048036038101906107299190613a15565b6125da565b60405161073b91906138c3565b60405180910390f35b6005805461075190613bd3565b80601f016020809104026020016040519081016040528092919081815260200182805461077d90613bd3565b80156107ca5780601f1061079f576101008083540402835291602001916107ca565b820191906000526020600020905b8154815290600101906020018083116107ad57829003601f168201915b505050505081565b60006107df838333612663565b6001905092915050565b6000600354905090565b60006107fd61275e565b73ffffffffffffffffffffffffffffffffffffffff1661081b611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614610871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161086890613c50565b60405180910390fd5b600b80549050821061088257600080fd5b600b828154811061089657610895613c70565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600b80549050905090565b6000600c60009054906101000a900460ff1615806108f4575042600d54105b806109315750610902611ed2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610970576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096790613d11565b60405180910390fd5b826000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054036109f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ec90613d7d565b60405180910390fd5b6109fe84612766565b610a08858461285d565b610a13858585612b35565b9150509392505050565b610a2561275e565b73ffffffffffffffffffffffffffffffffffffffff16610a43611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614610a99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9090613c50565b60405180910390fd5b60006201518082610aaa9190613dcc565b90508042610ab89190613e26565b600d81905550817f10e4464ec1508bc74373bc20969bfc3c86fb9f7b2fce089585495bf47bfce4bc60405160405180910390a25050565b6000610af961275e565b73ffffffffffffffffffffffffffffffffffffffff16610b17611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614610b6d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6490613c50565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60075481565b610c1261275e565b73ffffffffffffffffffffffffffffffffffffffff16610c30611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614610c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7d90613c50565b60405180910390fd5b816000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403610d0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0290613d7d565b60405180910390fd5b6000801b8203610d1a57600080fd5b6000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050828114610e115782600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f63ec12603f028c6f74dc3c59a67d645d431250142b56676015d25475ee3fc3d38386604051610e08929190613e69565b60405180910390a35b50505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000610e4761275e565b73ffffffffffffffffffffffffffffffffffffffff16610e65611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614610ebb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb290613c50565b60405180910390fd5b826000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403610f40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3790613d7d565b60405180910390fd5b610f4984612766565b610f538484612b4e565b91505092915050565b610f6461275e565b73ffffffffffffffffffffffffffffffffffffffff16610f82611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614610fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fcf90613c50565b60405180910390fd5b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016110359190613944565b602060405180830381865afa158015611052573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110769190613ea7565b1461108057600080fd5b6000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541461116b576000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8071c01a493142de896a206c19ca180d32e91d6486fcf11ea299f569f5d922b560405160405180910390a35b50565b61117661275e565b73ffffffffffffffffffffffffffffffffffffffff16611194611ed2565b73ffffffffffffffffffffffffffffffffffffffff16146111ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e190613c50565b60405180910390fd5b81600073ffffffffffffffffffffffffffffffffffffffff16600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146112b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b090613f20565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112f257600080fd5b6000801b820361130157600080fd5b6000801b600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541461134f57600080fd5b81600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb4f9d1d687d745820ae7c948518d6eef182cfbf5ef20b5b6a33769059592e7c8846040516113f09190613f40565b60405180910390a3505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461145757600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6115a161275e565b73ffffffffffffffffffffffffffffffffffffffff166115bf611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614611615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160c90613c50565b60405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634e71e0c86040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156116c057600080fd5b505af11580156116d4573d6000803e3d6000fd5b5050505050565b600d5481565b600c60009054906101000a900460ff1681565b6000611701838333612d2d565b6001905092915050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016117689190613944565b602060405180830381865afa158015611785573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a99190613ea7565b9050919050565b6117b861275e565b73ffffffffffffffffffffffffffffffffffffffff166117d6611ed2565b73ffffffffffffffffffffffffffffffffffffffff161461182c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182390613c50565b60405180910390fd5b6118366000613008565b565b61184061275e565b73ffffffffffffffffffffffffffffffffffffffff1661185e611ed2565b73ffffffffffffffffffffffffffffffffffffffff16146118b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ab90613c50565b60405180910390fd5b816000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403611937576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192e90613fa7565b60405180910390fd5b816000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146119ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b190614013565b60405180910390fd5b826000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403611a3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3690613d7d565b60405180910390fd5b6000801b600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555083600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006001600a60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611b529190614033565b905084600b8281548110611b6957611b68613c70565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600a60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e30443bc86600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a082318a6040518263ffffffff1660e01b8152600401611d139190613944565b602060405180830381865afa158015611d30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d549190613ea7565b6040518363ffffffff1660e01b8152600401611d71929190614067565b600060405180830381600087803b158015611d8b57600080fd5b505af1158015611d9f573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e30443bc8760006040518363ffffffff1660e01b8152600401611e019291906140cb565b600060405180830381600087803b158015611e1b57600080fd5b505af1158015611e2f573d6000803e3d6000fd5b505050503373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fb64971100522354f3d25283cb14e2eefcb0dd26a757482ccfe42479d0a68685760405160405180910390a4505050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60068054611f0890613bd3565b80601f0160208091040260200160405190810160405280929190818152602001828054611f3490613bd3565b8015611f815780601f10611f5657610100808354040283529160200191611f81565b820191906000526020600020905b815481529060010190602001808311611f6457829003601f168201915b505050505081565b6000600c60009054906101000a900460ff161580611fa8575042600d54105b80611fe55750611fb6611ed2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612024576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201b90613d11565b60405180910390fd5b826000801b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054036120a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a090613d7d565b60405180910390fd5b6120b284612766565b6120bc338461285d565b6120c684846130cc565b91505092915050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6120fb61275e565b73ffffffffffffffffffffffffffffffffffffffff16612119611ed2565b73ffffffffffffffffffffffffffffffffffffffff161461216f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161216690613c50565b60405180910390fd5b80600c60006101000a81548160ff021916908315150217905550600c60009054906101000a900460ff1615157fe039d903d34cc70b8016e3c231cc2dd1171f775eb4530f765ccf2efb9acb799860405160405180910390a250565b60008060001b600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414159050919050565b600061222361275e565b73ffffffffffffffffffffffffffffffffffffffff16612241611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614612297576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228e90613c50565b60405180910390fd5b6122a0826130e3565b9050919050565b600080600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414159050919050565b6000612300838333613197565b6001905092915050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631a46ec8284846040518363ffffffff1660e01b81526004016123699291906140f4565b602060405180830381865afa158015612386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123aa9190613ea7565b905092915050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6123e061275e565b73ffffffffffffffffffffffffffffffffffffffff166123fe611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614612454576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244b90613c50565b60405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634e71e0c86040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156124ff57600080fd5b505af1158015612513573d6000803e3d6000fd5b5050505050565b61252261275e565b73ffffffffffffffffffffffffffffffffffffffff16612540611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614612596576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161258d90613c50565b60405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612618576000905061265d565b81600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541490505b92915050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663da46098c8285856040518463ffffffff1660e01b81526004016126c29392919061411d565b600060405180830381600087803b1580156126dc57600080fd5b505af11580156126f0573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161275191906138ed565b60405180910390a3505050565b600033905090565b6000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540361285a57600b819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600b80549050600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b50565b600081600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b81526004016128bb9190613944565b602060405180830381865afa1580156128d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fc9190613ea7565b6129069190614033565b905060008111156129175750612b31565b60006001600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129659190614033565b905060006001600b8054905061297b9190614033565b90506000600b828154811061299357612992613c70565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905080600b84815481106129d5576129d4613c70565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600b805480612ab257612ab1614154565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905590556000600a60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050505b5050565b6000612b438484843361332f565b600190509392505050565b6000612b5861275e565b73ffffffffffffffffffffffffffffffffffffffff16612b76611ed2565b73ffffffffffffffffffffffffffffffffffffffff1614612bcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bc390613c50565b60405180910390fd5b81600354612bda9190613e26565b600381905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166321e5383a84846040518363ffffffff1660e01b8152600401612c3d929190614067565b600060405180830381600087803b158015612c5757600080fd5b505af1158015612c6b573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688583604051612cb591906138ed565b60405180910390a28273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612d1b91906138ed565b60405180910390a36001905092915050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631a46ec8283866040518363ffffffff1660e01b8152600401612d8c9291906140f4565b602060405180830381865afa158015612da9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dcd9190613ea7565b905080831115612e6e57600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663da46098c838660006040518463ffffffff1660e01b8152600401612e3793929190614183565b600060405180830381600087803b158015612e5157600080fd5b505af1158015612e65573d6000803e3d6000fd5b50505050612f00565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166397d88cd28386866040518463ffffffff1660e01b8152600401612ecd9392919061411d565b600060405180830381600087803b158015612ee757600080fd5b505af1158015612efb573d6000803e3d6000fd5b505050505b8373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631a46ec8286896040518363ffffffff1660e01b8152600401612fac9291906140f4565b602060405180830381865afa158015612fc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fed9190613ea7565b604051612ffa91906138ed565b60405180910390a350505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006130d933848461347b565b6001905092915050565b600080600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036131855782915050613192565b61318e816130e3565b9150505b919050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635fd72d168285856040518463ffffffff1660e01b81526004016131f69392919061411d565b600060405180830381600087803b15801561321057600080fd5b505af1158015613224573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631a46ec8285886040518363ffffffff1660e01b81526004016132d49291906140f4565b602060405180830381865afa1580156132f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133159190613ea7565b60405161332291906138ed565b60405180910390a3505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631a46ec8285836040518363ffffffff1660e01b815260040161338c9291906140f4565b602060405180830381865afa1580156133a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133cd9190613ea7565b8211156133d957600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166397d88cd28583856040518463ffffffff1660e01b81526004016134389392919061411d565b600060405180830381600087803b15801561345257600080fd5b505af1158015613466573d6000803e3d6000fd5b5050505061347584848461347b565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036134b457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036134ed57600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b81526004016135489190613944565b602060405180830381865afa158015613565573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135899190613ea7565b81111561359557600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cf8eeb7e84836040518363ffffffff1660e01b81526004016135f2929190614067565b600060405180830381600087803b15801561360c57600080fd5b505af1158015613620573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166321e5383a83836040518363ffffffff1660e01b8152600401613681929190614067565b600060405180830381600087803b15801561369b57600080fd5b505af11580156136af573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161371091906138ed565b60405180910390a3505050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561375757808201518184015260208101905061373c565b60008484015250505050565b6000601f19601f8301169050919050565b600061377f8261371d565b6137898185613728565b9350613799818560208601613739565b6137a281613763565b840191505092915050565b600060208201905081810360008301526137c78184613774565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006137ff826137d4565b9050919050565b61380f816137f4565b811461381a57600080fd5b50565b60008135905061382c81613806565b92915050565b6000819050919050565b61384581613832565b811461385057600080fd5b50565b6000813590506138628161383c565b92915050565b6000806040838503121561387f5761387e6137cf565b5b600061388d8582860161381d565b925050602061389e85828601613853565b9150509250929050565b60008115159050919050565b6138bd816138a8565b82525050565b60006020820190506138d860008301846138b4565b92915050565b6138e781613832565b82525050565b600060208201905061390260008301846138de565b92915050565b60006020828403121561391e5761391d6137cf565b5b600061392c84828501613853565b91505092915050565b61393e816137f4565b82525050565b60006020820190506139596000830184613935565b92915050565b600080600060608486031215613978576139776137cf565b5b60006139868682870161381d565b93505060206139978682870161381d565b92505060406139a886828701613853565b9150509250925092565b6000602082840312156139c8576139c76137cf565b5b60006139d68482850161381d565b91505092915050565b6000819050919050565b6139f2816139df565b81146139fd57600080fd5b50565b600081359050613a0f816139e9565b92915050565b60008060408385031215613a2c57613a2b6137cf565b5b6000613a3a8582860161381d565b9250506020613a4b85828601613a00565b9150509250929050565b6000819050919050565b6000613a7a613a75613a70846137d4565b613a55565b6137d4565b9050919050565b6000613a8c82613a5f565b9050919050565b6000613a9e82613a81565b9050919050565b613aae81613a93565b82525050565b6000602082019050613ac96000830184613aa5565b92915050565b60008060408385031215613ae657613ae56137cf565b5b6000613af48582860161381d565b9250506020613b058582860161381d565b9150509250929050565b6000613b1a82613a81565b9050919050565b613b2a81613b0f565b82525050565b6000602082019050613b456000830184613b21565b92915050565b613b54816138a8565b8114613b5f57600080fd5b50565b600081359050613b7181613b4b565b92915050565b600060208284031215613b8d57613b8c6137cf565b5b6000613b9b84828501613b62565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613beb57607f821691505b602082108103613bfe57613bfd613ba4565b5b50919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613c3a602083613728565b9150613c4582613c04565b602082019050919050565b60006020820190508181036000830152613c6981613c2d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f63616e6e6f74207472616e7366657220746f6b656e7320647572696e67206c6f60008201527f636b696e6720706572696f64206f66203132206d6f6e74687300000000000000602082015250565b6000613cfb603983613728565b9150613d0682613c9f565b604082019050919050565b60006020820190508181036000830152613d2a81613cee565b9050919050565b7f61646472657373206e6f74207665726966696564000000000000000000000000600082015250565b6000613d67601483613728565b9150613d7282613d31565b602082019050919050565b60006020820190508181036000830152613d9681613d5a565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613dd782613832565b9150613de283613832565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613e1b57613e1a613d9d565b5b828202905092915050565b6000613e3182613832565b9150613e3c83613832565b9250828201905080821115613e5457613e53613d9d565b5b92915050565b613e63816139df565b82525050565b6000604082019050613e7e6000830185613e5a565b613e8b6020830184613e5a565b9392505050565b600081519050613ea18161383c565b92915050565b600060208284031215613ebd57613ebc6137cf565b5b6000613ecb84828501613e92565b91505092915050565b7f616464726573732069732063616e63656c656400000000000000000000000000600082015250565b6000613f0a601383613728565b9150613f1582613ed4565b602082019050919050565b60006020820190508181036000830152613f3981613efd565b9050919050565b6000602082019050613f556000830184613e5a565b92915050565b7f61646472657373206973206e6f74206120736861726564686f6c646572000000600082015250565b6000613f91601d83613728565b9150613f9c82613f5b565b602082019050919050565b60006020820190508181036000830152613fc081613f84565b9050919050565b7f616464726573732069732061207368617265686f6c6465720000000000000000600082015250565b6000613ffd601883613728565b915061400882613fc7565b602082019050919050565b6000602082019050818103600083015261402c81613ff0565b9050919050565b600061403e82613832565b915061404983613832565b925082820390508181111561406157614060613d9d565b5b92915050565b600060408201905061407c6000830185613935565b61408960208301846138de565b9392505050565b6000819050919050565b60006140b56140b06140ab84614090565b613a55565b613832565b9050919050565b6140c58161409a565b82525050565b60006040820190506140e06000830185613935565b6140ed60208301846140bc565b9392505050565b60006040820190506141096000830185613935565b6141166020830184613935565b9392505050565b60006060820190506141326000830186613935565b61413f6020830185613935565b61414c60408301846138de565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006060820190506141986000830186613935565b6141a56020830185613935565b6141b260408301846140bc565b94935050505056fea2646970667358221220f125139179ee9e72eef769c73a82ae061915cdd7e0b1864f35139edb3157c36364736f6c63430008100033

Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.