Token CACHE Gold

 

Overview [ERC-20]

Price
$58.22 @ 0.030676 Eth (-0.34%)
Fully Diluted Market Cap
Max Total Supply:
100,771.01 CGT

Holders:
238 ( 0.420%)

Transfers:
-

 
Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

OVERVIEW

CACHE Gold tokens each represent one gram of pure gold stored in vaults around the world. CACHE Gold tokens are redeemable for delivery of physical gold or can be sold for fiat currency.

Market

Volume (24H):$7,391.11
Market Capitalization:$4,597,604.00
Circulating Supply:78,923.00 CGT
Market Data Source: Coinmarketcap

# Exchange Pair Price  24H Volume % Volume
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CacheGold

Compiler Version
v0.5.16+commit.9c3226ce

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-02-17
*/

pragma solidity 0.5.16;

// File: openzeppelin-solidity/contracts/ownership/Ownable.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.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be aplied to your functions to restrict their use to
 * the owner.
 */
contract Ownable {
    address private _owner;
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
    }
    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }
    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(), "Ownable: caller is not the owner");
        _;
    }
    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _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 onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }
    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }
    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}
// File: openzeppelin-solidity/contracts/token/ERC20/IERC20.sol
/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see `ERC20Detailed`.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);
    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);
    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a `Transfer` event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);
    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through `transferFrom`. This is
     * zero by default.
     *
     * This value changes when `approve` or `transferFrom` are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);
    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * > Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an `Approval` event.
     */
    function approve(address spender, uint256 amount) external returns (bool);
    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a `Transfer` event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);
    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to `approve`. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}
// File: openzeppelin-solidity/contracts/math/SafeMath.sol
/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }
    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        uint256 c = a - b;
        return c;
    }
    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }
    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, "SafeMath: division by zero");
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold
        return c;
    }
    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}
// File: contracts/LockedGoldOracle.sol
// Simple contract regulating the total supply of gold locked at any
// given time so that the Cache contract can't over mint tokens
contract LockedGoldOracle is Ownable {
  using SafeMath for uint256;
  uint256 private _lockedGold;
  address private _cacheContract;
  event LockEvent(uint256 amount);
  event UnlockEvent(uint256 amount);
  function setCacheContract(address cacheContract) external onlyOwner {
    _cacheContract = cacheContract;
  }
  function lockAmount(uint256 amountGrams) external onlyOwner {
    _lockedGold = _lockedGold.add(amountGrams);
    emit LockEvent(amountGrams);
  }
  // Can only unlock amount of gold if it would leave the
  // total amount of locked gold greater than or equal to the
  // number of tokens in circulation
  function unlockAmount(uint256 amountGrams) external onlyOwner {
    _lockedGold = _lockedGold.sub(amountGrams);
    require(_lockedGold >= CacheGold(_cacheContract).totalCirculation());
    emit UnlockEvent(amountGrams);
  }
  function lockedGold() external view returns(uint256) {
    return _lockedGold;
  }
  function cacheContract() external view returns(address) {
    return _cacheContract;
  }
}
// File: contracts/CacheGold.sol
/// @title The CacheGold Token Contract
/// @author Cache Pte Ltd
contract CacheGold is IERC20, Ownable {
  using SafeMath for uint256;
  // ERC20 Detailed Info
  /* solhint-disable */
  string public constant name = "CACHE Gold";
  string public constant symbol = "CGT";
  uint8 public constant decimals = 8;
  /* solhint-enable */
  // 10^8 shortcut
  uint256 private constant TOKEN = 10 ** uint256(decimals);
  // Seconds in a day
  uint256 private constant DAY = 86400;
  // Days in a year
  uint256 private constant YEAR = 365;
  // The maximum transfer fee is 10 basis points
  uint256 private constant MAX_TRANSFER_FEE_BASIS_POINTS = 10;
  // Basis points means divide by 10,000 to get decimal
  uint256 private constant BASIS_POINTS_MULTIPLIER = 10000;
  // The storage fee of 0.25%
  uint256 private constant STORAGE_FEE_DENOMINATOR = 40000000000;
  // The inactive fee of 0.50%
  uint256 private constant INACTIVE_FEE_DENOMINATOR = 20000000000;
  // The minimum balance that would accrue a storage fee after 1 day
  uint256 private constant MIN_BALANCE_FOR_FEES = 146000;
  // Initial basis points for transfer fee
  uint256 private _transferFeeBasisPoints = 10;
  // Cap on total number of tokens that can ever be produced
  uint256 public constant SUPPLY_CAP = 8133525786 * TOKEN;
  // How many days need to pass before late fees can be collected (3 years)
  uint256 public constant INACTIVE_THRESHOLD_DAYS = 1095;
  // Token balance of each address
  mapping (address => uint256) private _balances;
  // Allowed transfer from address
  mapping (address => mapping (address => uint256)) private _allowances;
  // Last time storage fee was paid
  mapping (address => uint256) private _timeStorageFeePaid;
  // Last time the address produced a transaction on this contract
  mapping (address => uint256) private _timeLastActivity;
  // Amount of inactive fees already paid
  mapping (address => uint256) private _inactiveFeePaid;
  // If address doesn't have any activity for INACTIVE_THRESHOLD_DAYS
  // we can start deducting chunks off the address so that
  // full balance can be recouped after 200 years. This is likely
  // to happen if the user loses their private key.
  mapping (address => uint256) private _inactiveFeePerYear;
  // Addresses not subject to transfer fees
  mapping (address => bool) private _transferFeeExempt;
  // Address is not subject to storage fees
  mapping (address => bool) private _storageFeeExempt;
  // Save grace period on storage fees for an address
  mapping (address => uint256) private _storageFeeGracePeriod;
  // Current total number of tokens created
  uint256 private _totalSupply;
  // Address where storage and transfer fees are collected
  address private _feeAddress;
  // The address for the "backed treasury". When a bar is locked into the
  // vault for tokens to be minted, they are created in the backed_treasury
  // and can then be sold from this address.
  address private _backedTreasury;
  // The address for the "unbacked treasury". The unbacked treasury is a
  // storing address for excess tokens that are not locked in the vault
  // and therefore do not correspond to any real world value. If new bars are
  // locked in the vault, tokens will first be moved from the unbacked
  // treasury to the backed treasury before minting new tokens.
  //
  // This address only accepts transfers from the _backedTreasury or _redeemAddress
  // the general public should not be able to manipulate this balance.
  address private _unbackedTreasury;
  // The address for the LockedGoldOracle that determines the maximum number of
  // tokens that can be in circulation at any given time
  address private _oracle;
  // A fee-exempt address that can be used to collect gold tokens in exchange
  // for redemption of physical gold
  address private _redeemAddress;
  // An address that can force addresses with overdue storage or inactive fee to pay.
  // This is separate from the contract owner, because the owner will change
  // to a multisig address after deploy, and we want to be able to write
  // a script that can sign "force-pay" transactions with a single private key
  address private _feeEnforcer;
  // Grace period before storage fees kick in
  uint256 private _storageFeeGracePeriodDays = 0;
  // When gold bars are locked, we add tokens to circulation either
  // through moving them from the unbacked treasury or minting new ones,
  // or some combination of both
  event AddBackedGold(uint256 amount);
  // Before gold bars can be unlocked (removed from circulation), they must
  // be moved to the unbacked treasury, we emit an event when this happens
  // to signal a change in the circulating supply
  event RemoveGold(uint256 amount);
  // When an account has no activity for INACTIVE_THRESHOLD_DAYS
  // it will be flagged as inactive
  event AccountInactive(address indexed account, uint256 feePerYear);
  // If an previoulsy dormant account is reactivated
  event AccountReActive(address indexed account);
  /**
   * @dev Contructor for the CacheGold token sets internal addresses
   * @param unbackedTreasury The address of the unbacked treasury
   * @param backedTreasury The address of the backed treasury
   * @param feeAddress The address where fees are collected
   * @param redeemAddress The address where tokens are send to redeem physical gold
   * @param oracle The address of the LockedGoldOracle
   */
  constructor(address unbackedTreasury,
              address backedTreasury,
              address feeAddress,
              address redeemAddress,
              address oracle) public {
    _unbackedTreasury = unbackedTreasury;
    _backedTreasury = backedTreasury;
    _feeAddress = feeAddress;
    _redeemAddress = redeemAddress;
    _feeEnforcer = owner();
    _oracle = oracle;
    setFeeExempt(_feeAddress);
    setFeeExempt(_redeemAddress);
    setFeeExempt(_backedTreasury);
    setFeeExempt(_unbackedTreasury);
    setFeeExempt(owner());
  }
  /**
   * @dev Throws if called by any account other than THE ENFORCER
   */
  modifier onlyEnforcer() {
    require(msg.sender == _feeEnforcer);
    _;
  }
  /**
  * @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) external returns (bool) {
    // Update activity for the sender
    _updateActivity(msg.sender);
    // Can opportunistically mark an account inactive if someone
    // sends money to it
    if (_shouldMarkInactive(to)) {
      _setInactive(to);
    }
    _transfer(msg.sender, to, value);
    return true;
  }
  /**
  * @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) external returns (bool) {
    _updateActivity(msg.sender);
    _approve(msg.sender, spender, value);
    return true;
  }
  /**
  * @dev Transfer tokens from one address to another.
  * Note that while this function emits an Approval event, this is not required as per the specification,
  * and other compliant implementations may not emit the event.
  * Also note that even though balance requirements are not explicitly checked,
  * any transfer attempt over the approved amount will automatically fail due to
  * SafeMath revert when trying to subtract approval to a negative balance
  * @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) external returns (bool) {
    _updateActivity(msg.sender);
    _transfer(from, to, value);
    _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));
    return true;
  }
  /**
  * @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
  * Emits an Approval event.
  * @param spender The address which will spend the funds.
  * @param addedValue The amount of tokens to increase the allowance by.
  */
  function increaseAllowance(address spender, uint256 addedValue) external returns (bool) {
    _updateActivity(msg.sender);
    _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));
    return true;
  }
  /**
  * @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
  * Emits an Approval event.
  * @param spender The address which will spend the funds.
  * @param subtractedValue The amount of tokens to decrease the allowance by.
  */
  function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool) {
    _updateActivity(msg.sender);
    _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));
    return true;
  }
  /**
  * @dev Function to add a certain amount of backed tokens. This will first
  * take any tokens from the _unbackedTreasury address and move them to the
  * _backedTreasury. Any remaining tokens will actually be minted.
  * This operation will fail if there is not a sufficient supply of locked gold
  * as determined by the LockedGoldOracle
  *
  * @param value The amount of tokens to add to the backed treasury
  * @return A boolean that indicates if the operation was successful.
  */
  function addBackedTokens(uint256 value) external onlyOwner returns (bool)
  {
    uint256 unbackedBalance = _balances[_unbackedTreasury];
    // Use oracle to check if there is actually enough gold
    // in custody to validate this operation
    uint256 lockedGrams =  LockedGoldOracle(_oracle).lockedGold();
    // Should reject mint if it would make the total supply
    // exceed the amount actually locked in vault
    require(lockedGrams >= totalCirculation().add(value),
            "Insufficent grams locked in LockedGoldOracle to complete operation");
    // If we have sufficient balance, just move from the unbacked to backed
    // treasury address
    if (value <= unbackedBalance) {
      _transfer(_unbackedTreasury, _backedTreasury, value);
    } else {
      if (unbackedBalance > 0) {
        // There is no sufficient balance, so we have to both transfer and mint new tokens
        // Transfer the remaining unbacked treasury balance to backed treasury
        _transfer(_unbackedTreasury, _backedTreasury, unbackedBalance);
      }
      // And mint the remaining to the backed treasury
      _mint(value.sub(unbackedBalance));
    }
    emit AddBackedGold(value);
    return true;
  }
  /**
  * @dev Manually pay storage fees on senders address. Exchanges may want to
  * periodically call this function to pay owed storage fees. This is a
  * cheaper option than 'send to self', which would also trigger paying
  * storage fees
  *
  * @return A boolean that indicates if the operation was successful.
  */
  function payStorageFee() external returns (bool) {
    _updateActivity(msg.sender);
    _payStorageFee(msg.sender);
    return true;
  }
  function setAccountInactive(address account) external onlyEnforcer returns (bool) {
    require(_shouldMarkInactive(account), "Account not eligible to be marked inactive");
    _setInactive(account);
  }
  /**
  * @dev Contract allows the forcible collection of storage fees on an address
  * if it is has been more than than 365 days since the last time storage fees
  * were paid on this address.
  *
  * Alternatively inactive fees may also be collected periodically on a prorated
  * basis if the account is currently marked as inactive.
  *
  * @param account The address to pay storage fees on
  * @return A boolean that indicates if the operation was successful.
  */
  function forcePayFees(address account) external onlyEnforcer returns(bool) {
    require(account != address(0));
    require(_balances[account] > 0,
            "Account has no balance, cannot force paying fees");
    // If account is inactive, pay inactive fees
    if (isInactive(account)) {
      uint256 paid = _payInactiveFee(account);
      require(paid > 0);
    } else if (_shouldMarkInactive(account)) {
      // If it meets inactive threshold, but hasn't been set yet, set it.
      // This will also trigger automatic payment of owed storage fees
      // before starting inactive fees
      _setInactive(account);
    } else {
      // Otherwise just force paying owed storage fees, which can only
      // be called if they are more than 365 days overdue
      require(daysSincePaidStorageFee(account) >= YEAR,
              "Account has paid storage fees more recently than 365 days");
      uint256 paid = _payStorageFee(account);
      require(paid > 0, "No appreciable storage fees due, will refund gas");
    }
  }
  /**
  * @dev Set the address that can force collecting fees from users
  * @param enforcer The address to force collecting fees
  * @return An bool representing successfully changing enforcer address
  */
  function setFeeEnforcer(address enforcer) external onlyOwner returns(bool) {
    require(enforcer != address(0));
    _feeEnforcer = enforcer;
    setFeeExempt(_feeEnforcer);
    return true;
  }
  /**
  * @dev Set the address to collect fees
  * @param newFeeAddress The address to collect storage and transfer fees
  * @return An bool representing successfully changing fee address
  */
  function setFeeAddress(address newFeeAddress) external onlyOwner returns(bool) {
    require(newFeeAddress != address(0));
    require(newFeeAddress != _unbackedTreasury,
            "Cannot set fee address to unbacked treasury");
    _feeAddress = newFeeAddress;
    setFeeExempt(_feeAddress);
    return true;
  }
  /**
  * @dev Set the address to deposit tokens when redeeming for physical locked bars.
  * @param newRedeemAddress The address to redeem tokens for bars
  * @return An bool representing successfully changing redeem address
  */
  function setRedeemAddress(address newRedeemAddress) external onlyOwner returns(bool) {
    require(newRedeemAddress != address(0));
    require(newRedeemAddress != _unbackedTreasury,
            "Cannot set redeem address to unbacked treasury");
    _redeemAddress = newRedeemAddress;
    setFeeExempt(_redeemAddress);
    return true;
  }
  /**
  * @dev Set the address of backed treasury
  * @param newBackedAddress The address of backed treasury
  * @return An bool representing successfully changing backed address
  */
  function setBackedAddress(address newBackedAddress) external onlyOwner returns(bool) {
    require(newBackedAddress != address(0));
    require(newBackedAddress != _unbackedTreasury,
            "Cannot set backed address to unbacked treasury");
    _backedTreasury = newBackedAddress;
    setFeeExempt(_backedTreasury);
    return true;
  }
  /**
  * @dev Set the address to unbacked treasury
  * @param newUnbackedAddress The address of unbacked treasury
  * @return An bool representing successfully changing unbacked address
  */
  function setUnbackedAddress(address newUnbackedAddress) external onlyOwner returns(bool) {
    require(newUnbackedAddress != address(0));
    require(newUnbackedAddress != _backedTreasury,
            "Cannot set unbacked treasury to backed treasury");
    require(newUnbackedAddress != _feeAddress,
            "Cannot set unbacked treasury to fee address ");
    require(newUnbackedAddress != _redeemAddress,
            "Cannot set unbacked treasury to fee address ");
    _unbackedTreasury = newUnbackedAddress;
    setFeeExempt(_unbackedTreasury);
    return true;
  }
  /**
  * @dev Set the LockedGoldOracle address
  * @param oracleAddress The address for oracle
  * @return An bool representing successfully changing oracle address
  */
  function setOracleAddress(address oracleAddress) external onlyOwner returns(bool) {
    require(oracleAddress != address(0));
    _oracle = oracleAddress;
    return true;
  }
  /**
  * @dev Set the number of days before storage fees begin accruing.
  * @param daysGracePeriod The global setting for the grace period before storage
  * fees begin accruing. Note that calling this will not change the grace period
  * for addresses already actively inside a grace period
  */
  function setStorageFeeGracePeriodDays(uint256 daysGracePeriod) external onlyOwner {
    _storageFeeGracePeriodDays = daysGracePeriod;
  }
  /**
  * @dev Set this account as being exempt from transfer fees. This may be used
  * in special circumstance for cold storage addresses owed by Cache, exchanges, etc.
  * @param account The account to exempt from transfer fees
  */
  function setTransferFeeExempt(address account) external onlyOwner {
    _transferFeeExempt[account] = true;
  }
  /**
  * @dev Set this account as being exempt from storage fees. This may be used
  * in special circumstance for cold storage addresses owed by Cache, exchanges, etc.
  * @param account The account to exempt from storage fees
  */
  function setStorageFeeExempt(address account) external onlyOwner {
    _storageFeeExempt[account] = true;
  }
  /**
  * @dev Set account is no longer exempt from all fees
  * @param account The account to reactivate fees
  */
  function unsetFeeExempt(address account) external onlyOwner {
    _transferFeeExempt[account] = false;
    _storageFeeExempt[account] = false;
  }
  /**
  * @dev Set a new transfer fee in basis points, must be less than or equal to 10 basis points
  * @param fee The new transfer fee in basis points
  */
  function setTransferFeeBasisPoints(uint256 fee) external onlyOwner {
    require(fee <= MAX_TRANSFER_FEE_BASIS_POINTS,
            "Transfer fee basis points must be an integer between 0 and 10");
    _transferFeeBasisPoints = fee;
  }
  /**
  * @dev Gets the balance of the specified address deducting owed fees and
  * accounting for the maximum amount that could be sent including transfer fee
  * @param owner The address to query the balance of.
  * @return An uint256 representing the amount sendable by the passed address
  * including transaction and storage fees
  */
  function balanceOf(address owner) external view returns (uint256) {
    return calcSendAllBalance(owner);
  }
  /**
  * @dev Gets the balance of the specified address not deducting owed fees.
  * this returns the 'traditional' ERC-20 balance that represents the balance
  * currently stored in contract storage.
  * @param owner The address to query the balance of.
  * @return An uint256 representing the amount stored in passed address
  */
  function balanceOfNoFees(address owner) external view returns (uint256) {
    return _balances[owner];
  }
  /**
  * @dev Total number of tokens in existence. This includes tokens
  * in the unbacked treasury that are essentially unusable and not
  * in circulation
  * @return A uint256 representing the total number of minted tokens
  */
  function totalSupply() external view returns (uint256) {
    return _totalSupply;
  }
  /**
  * @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) external view returns (uint256) {
    return _allowances[owner][spender];
  }
  /**
  * @return address that can force paying overdue inactive fees
  */
  function feeEnforcer() external view returns(address) {
    return _feeEnforcer;
  }
  /**
   * @return address where fees are collected
   */
  function feeAddress() external view returns(address) {
    return _feeAddress;
  }
  /**
   * @return address for redeeming tokens for gold bars
   */
  function redeemAddress() external view returns(address) {
    return _redeemAddress;
  }
  /**
   * @return address for backed treasury
   */
  function backedTreasury() external view returns(address) {
    return _backedTreasury;
  }
  /**
  * @return address for unbacked treasury
  */
  function unbackedTreasury() external view returns(address) {
    return _unbackedTreasury;
  }
  /**
  * @return address for oracle contract
  */
  function oracleAddress() external view returns(address) {
    return _oracle;
  }
  /**
  * @return the current number of days and address is exempt
  * from storage fees upon receiving tokens
  */
  function storageFeeGracePeriodDays() external view returns(uint256) {
    return _storageFeeGracePeriodDays;
  }
  /**
  * @return the current transfer fee in basis points [0-10]
  */
  function transferFeeBasisPoints() external view returns(uint256) {
    return _transferFeeBasisPoints;
  }
  /**
  * @dev Simulate the transfer from one address to another see final balances and associated fees
  * @param from The address to transfer from.
  * @param to The address to transfer to.
  * @param value The amount to be transferred.
  * @return See _simulateTransfer function
  */
  function simulateTransfer(address from, address to, uint256 value) external view returns (uint256[5] memory) {
    return _simulateTransfer(from, to, value);
  }
  /**
  * @dev Set this account as being exempt from all fees. This may be used
  * in special circumstance for cold storage addresses owed by Cache, exchanges, etc.
  * @param account The account to exempt from storage and transfer fees
  */
  function setFeeExempt(address account) public onlyOwner {
    _transferFeeExempt[account] = true;
    _storageFeeExempt[account] = true;
  }
  /**
  * @dev Check if the address given is extempt from storage fees
  * @param account The address to check
  * @return A boolean if the address passed is exempt from storage fees
  */
  function isStorageFeeExempt(address account) public view returns(bool) {
    return _storageFeeExempt[account];
  }
  /**
  * @dev Check if the address given is extempt from transfer fees
  * @param account The address to check
  * @return A boolean if the address passed is exempt from transfer fees
  */
  function isTransferFeeExempt(address account) public view returns(bool) {
    return _transferFeeExempt[account];
  }
  /**
  * @dev Check if the address given is extempt from transfer fees
  * @param account The address to check
  * @return A boolean if the address passed is exempt from transfer fees
  */
  function isAllFeeExempt(address account) public view returns(bool) {
    return _transferFeeExempt[account] && _storageFeeExempt[account];
  }
  /**
  * @dev Check if the address is considered inactive for not having transacted with
  * the contract for INACTIVE_THRESHOLD_DAYS
  * @param account The address to check
  * @return A boolean if the address passed is considered inactive
  */
  function isInactive(address account) public view returns(bool) {
    return _inactiveFeePerYear[account] > 0;
  }
  /**
  * @dev Total number of tokens that are actually in circulation, which is
  * total tokens excluding the unbacked treasury
  * @return A uint256 representing the total number of tokens in circulation
  */
  function totalCirculation() public view returns (uint256) {
    return _totalSupply.sub(_balances[_unbackedTreasury]);
  }
  /**
  * @dev Get the number of days since the account last paid storage fees
  * @param account The address to check
  * @return A uint256 representing the number of days since storage fees where last paid
  */
  function daysSincePaidStorageFee(address account) public view returns(uint256) {
    if (isInactive(account) || _timeStorageFeePaid[account] == 0) {
      return 0;
    }
    return block.timestamp.sub(_timeStorageFeePaid[account]).div(DAY);
  }
  /**
  * @dev Get the days since the account last sent a transaction to the contract (activity)
  * @param account The address to check
  * @return A uint256 representing the number of days since the address last had activity
  * with the contract
  */
  function daysSinceActivity(address account) public view returns(uint256) {
    if (_timeLastActivity[account] == 0) {
      return 0;
    }
    return block.timestamp.sub(_timeLastActivity[account]).div(DAY);
  }
  /**
  * @dev Returns the total number of fees owed on a particular address
  * @param account The address to check
  * @return The total storage and inactive fees owed on the address
  */
  function calcOwedFees(address account) public view returns(uint256) {
    return calcStorageFee(account).add(calcInactiveFee(account));
  }
  /**
   * @dev Calculate the current storage fee owed for a given address
   * @param account The address to check
   * @return A uint256 representing current storage fees for the address
   */
  function calcStorageFee(address account) public view returns(uint256) {
    // If an account is in an inactive state those fees take over and
    // storage fees are effectively paused
    uint256 balance = _balances[account];
    if (isInactive(account) || isStorageFeeExempt(account) || balance == 0) {
      return 0;
    }
    uint256 daysSinceStoragePaid = daysSincePaidStorageFee(account);
    uint256 daysInactive = daysSinceActivity(account);
    uint256 gracePeriod = _storageFeeGracePeriod[account];
    // If there is a grace period, we can deduct it from the daysSinceStoragePaid
    if (gracePeriod > 0) {
      if (daysSinceStoragePaid > gracePeriod) {
        daysSinceStoragePaid = daysSinceStoragePaid.sub(gracePeriod);
      } else {
        daysSinceStoragePaid = 0;
      }
    }
    if (daysSinceStoragePaid == 0) {
      return 0;
    }
    // This is an edge case where the account has not yet been marked inactive, but
    // will be marked inactive whenever there is a transaction allowing it to be marked.
    // Therefore we know storage fees will only be valid up to a point, and inactive
    // fees will take over.
    if (daysInactive >= INACTIVE_THRESHOLD_DAYS) {
      // This should not be at risk of being negative, because its impossible to force paying
      // storage fees without also setting the account to inactive, so if we are here it means
      // the last time storage fees were paid was BEFORE the account became eligible to be inactive
      // and it's always the case that daysSinceStoragePaid > daysInactive.sub(INACTIVE_THRESHOLD_DAYS)
      daysSinceStoragePaid = daysSinceStoragePaid.sub(daysInactive.sub(INACTIVE_THRESHOLD_DAYS));
    }
    // The normal case with normal storage fees
    return storageFee(balance, daysSinceStoragePaid);
  }
  /**
   * @dev Calculate the current inactive fee for a given address
   * @param account The address to check
   * @return A uint256 representing current inactive fees for the address
   */
  function calcInactiveFee(address account) public view returns(uint256) {
    uint256 balance = _balances[account];
    uint256 daysInactive = daysSinceActivity(account);
    // if the account is marked inactive already, can use the snapshot balance
    if (isInactive(account)) {
      return _calcInactiveFee(balance,
                          daysInactive,
                          _inactiveFeePerYear[account],
                          _inactiveFeePaid[account]);
    } else if (_shouldMarkInactive(account)) {
      // Account has not yet been marked inactive in contract, but the inactive fees will still be due.
      // Just assume snapshotBalance will be current balance after fees
      uint256 snapshotBalance = balance.sub(calcStorageFee(account));
      return _calcInactiveFee(snapshotBalance,                          // current balance
                              daysInactive,                             // number of days inactive
                              _calcInactiveFeePerYear(snapshotBalance), // the inactive fee per year based on balance
                              0);                                       // fees paid already
    }
    return 0;
  }
  /**
   * @dev Calculate the amount that would clear the balance from the address
   * accounting for owed storage and transfer fees
   * accounting for storage and transfer fees
   * @param account The address to check
   * @return A uint256 representing total amount an address has available to send
   */
  function calcSendAllBalance(address account) public view returns (uint256) {
    require(account != address(0));
    // Internal addresses pay no fees, so they can send their entire balance
    uint256 balanceAfterStorage = _balances[account].sub(calcOwedFees(account));
    if (_transferFeeBasisPoints == 0 || isTransferFeeExempt(account)) {
      return balanceAfterStorage;
    }
    // Edge cases where remaining balance is 0.00000001, but is effectively 0
    if (balanceAfterStorage <= 1) {
      return 0;
    }
    // Calculate the send all amount including storage fee
    // Send All = Balance / 1.001
    // and round up 0.00000001
    uint256 divisor = TOKEN.add(_transferFeeBasisPoints.mul(BASIS_POINTS_MULTIPLIER));
    uint256 sendAllAmount = balanceAfterStorage.mul(TOKEN).div(divisor).add(1);
    // Calc transfer fee on send all amount
    uint256 transFee = sendAllAmount.mul(_transferFeeBasisPoints).div(BASIS_POINTS_MULTIPLIER);
    // Fix to include rounding errors
    if (sendAllAmount.add(transFee) > balanceAfterStorage) {
      return sendAllAmount.sub(1);
    }
    return sendAllAmount;
  }
  /*
   * @dev Calculate the transfer fee on an amount
   * @param value The value being sent
   * @return A uint256 representing the transfer fee on sending the value given
   */
  function calcTransferFee(address account, uint256 value) public view returns(uint256) {
    if (isTransferFeeExempt(account)) {
      return 0;
    }
    // Basis points -> decimal multiplier:
    // f(x) = x / 10,0000 (10 basis points is 0.001)
    // So transfer fee working with integers =
    // f(balance, basis) = (balance * TOKEN) / (10,000 * TOKEN / basis)
    return value.mul(_transferFeeBasisPoints).div(BASIS_POINTS_MULTIPLIER);
  }
  /*
   * @dev Calculate the storage fee for a given balance after a certain number of
   * days have passed since the last time fees were paid.
   * @param balance The current balance of the address
   * @param daysSinceStoragePaid The number days that have passed since fees where last paid
   * @return A uint256 representing the storage fee owed
   */
  function storageFee(uint256 balance, uint256 daysSinceStoragePaid) public pure returns(uint256) {
    uint256 fee = balance.mul(TOKEN).mul(daysSinceStoragePaid).div(YEAR).div(STORAGE_FEE_DENOMINATOR);
    if (fee > balance) {
      return balance;
    }
    return fee;
  }
  /**
   * @dev Approve an address to spend another addresses' tokens.
   * @param owner The address that owns the tokens.
   * @param spender The address that will spend the tokens.
   * @param value The number of tokens that can be spent.
   */
  function _approve(address owner, address spender, uint256 value) internal {
    require(spender != address(0));
    require(owner != address(0));
    _allowances[owner][spender] = value;
    emit Approval(owner, spender, value);
  }
  /**
  * @dev Transfer token for a specified addresses. Transfer is modified from a
  * standard ERC20 contract in that it must also process transfer and storage fees
  * for the token itself. Additionally there are certain internal addresses that
  * are not subject to fees.
  * @param from The address to transfer from.
  * @param to The address to transfer to.
  * @param value The amount to be transferred.
  */
  function _transfer(address from, address to, uint256 value) internal {
    _transferRestrictions(to, from);
    // If the account was previously inactive and initiated the transfer, the
    // inactive fees and storage fees have already been paid by the time we get here
    // via the _updateActivity() call
    uint256 storageFeeFrom = calcStorageFee(from);
    uint256 storageFeeTo = 0;
    uint256 allFeeFrom = storageFeeFrom;
    uint256 balanceFromBefore = _balances[from];
    uint256 balanceToBefore = _balances[to];
    // If not sending to self can pay storage and transfer fee
    if (from != to) {
      // Need transfer fee and storage fee for receiver if not sending to self
      allFeeFrom = allFeeFrom.add(calcTransferFee(from, value));
      storageFeeTo = calcStorageFee(to);
      _balances[from] = balanceFromBefore.sub(value).sub(allFeeFrom);
      _balances[to] = balanceToBefore.add(value).sub(storageFeeTo);
      _balances[_feeAddress] = _balances[_feeAddress].add(allFeeFrom).add(storageFeeTo);
    } else {
      // Only storage fee if sending to self
      _balances[from] = balanceFromBefore.sub(storageFeeFrom);
      _balances[_feeAddress] = _balances[_feeAddress].add(storageFeeFrom);
    }
    // Regular Transfer
    emit Transfer(from, to, value);
    // Fee transfer on `from` address
    if (allFeeFrom > 0) {
      emit Transfer(from, _feeAddress, allFeeFrom);
      if (storageFeeFrom > 0) {
        _timeStorageFeePaid[from] = block.timestamp;
        _endGracePeriod(from);
      }
    }
    // If first time receiving coins, set the grace period
    // and start the the activity clock and storage fee clock
    if (_timeStorageFeePaid[to] == 0) {
      // We may change the grace period in the future so we want to
      // preserve it per address so there is no retroactive deduction
      _storageFeeGracePeriod[to] = _storageFeeGracePeriodDays;
      _timeLastActivity[to] = block.timestamp;
      _timeStorageFeePaid[to] = block.timestamp;
    }
    // Fee transfer on `to` address
    if (storageFeeTo > 0) {
      emit Transfer(to, _feeAddress, storageFeeTo);
      _timeStorageFeePaid[to] = block.timestamp;
      _endGracePeriod(to);
    } else if (balanceToBefore < MIN_BALANCE_FOR_FEES) {
      // MIN_BALANCE_FOR_FEES is the minimum amount in which a storage fee
      // would be due after a sigle day, so if the balance is above that,
      // the storage fee would always be greater than 0.
      //
      // This avoids the following condition:
      // 1. User receives tokens
      // 2. Users sends all but a tiny amount to another address
      // 3. A year later, the user receives more tokens. Because
      // their previous balance was super small, there were no appreciable
      // storage fee, therefore the storage fee clock was not reset
      // 4. User now owes storage fees on entire balance, as if they
      // held tokens for 1 year, instead of resetting the clock to now.
      _timeStorageFeePaid[to] = block.timestamp;
    }
    // If transferring to unbacked treasury, tokens are being taken from
    // circulation, because gold is being 'unlocked' from the vault
    if (to == _unbackedTreasury) {
      emit RemoveGold(value);
    }
  }
  /**
  * @dev Function to mint tokens to backed treasury. In general this method
  * will not be called on it's own, but instead will be called from
  * addBackedTokens.
  * @param value The amount of tokens to mint to backed treasury
  * @return A boolean that indicates if the operation was successful.
  */
  function _mint(uint256 value) internal returns(bool) {
    // Can't break supply cap
    require(_totalSupply.add(value) <= SUPPLY_CAP, "Call would exceed supply cap");
    // Can only mint if the unbacked treasury balance is 0
    require(_balances[_unbackedTreasury] == 0, "The unbacked treasury balance is not 0");
    // Can only mint to the backed treasury
    _totalSupply = _totalSupply.add(value);
    _balances[_backedTreasury] = _balances[_backedTreasury].add(value);
    emit Transfer(address(0), _backedTreasury, value);
    return true;
  }
  /**
   * @dev Apply storage fee deduction
   * @param account The account to pay storage fees
   * @return A uint256 representing the storage fee paid
   */
  function _payStorageFee(address account) internal returns(uint256) {
    uint256 storeFee = calcStorageFee(account);
    if (storeFee == 0) {
      return 0;
    }
    // Reduce account balance and add to fee address
    _balances[account] = _balances[account].sub(storeFee);
    _balances[_feeAddress] = _balances[_feeAddress].add(storeFee);
    emit Transfer(account, _feeAddress, storeFee);
    _timeStorageFeePaid[account] = block.timestamp;
    _endGracePeriod(account);
    return storeFee;
  }
  /**
   * @dev Apply inactive fee deduction
   * @param account The account to pay inactive fees
   * @return A uint256 representing the inactive fee paid
   */
  function _payInactiveFee(address account) internal returns(uint256) {
    uint256 fee = _calcInactiveFee(
        _balances[account],
        daysSinceActivity(account),
        _inactiveFeePerYear[account],
        _inactiveFeePaid[account]);
    if (fee == 0) {
      return 0;
    }
    _balances[account] = _balances[account].sub(fee);
    _balances[_feeAddress] = _balances[_feeAddress].add(fee);
    _inactiveFeePaid[account] = _inactiveFeePaid[account].add(fee);
    emit Transfer(account, _feeAddress, fee);
    return fee;
  }
  function _shouldMarkInactive(address account) internal view returns(bool) {
    // Can only mark an account as inactive if
    //
    // 1. it's not fee exempt
    // 2. it has a balance
    // 3. it's been over INACTIVE_THRESHOLD_DAYS since last activity
    // 4. it's not already marked inactive
    // 5. the storage fees owed already consume entire balance
    if (account != address(0) &&
        _balances[account] > 0 &&
        daysSinceActivity(account) >= INACTIVE_THRESHOLD_DAYS &&
        !isInactive(account) &&
        !isAllFeeExempt(account) &&
        _balances[account].sub(calcStorageFee(account)) > 0) {
      return true;
    }
    return false;
  }
  /**
  * @dev Mark an account as inactive. The function will automatically deduct
  * owed storage fees and inactive fees in one go.
  *
  * @param account The account to mark inactive
  */
  function _setInactive(address account) internal {
    // First get owed storage fees
    uint256 storeFee = calcStorageFee(account);
    uint256 snapshotBalance = _balances[account].sub(storeFee);
    // all _setInactive calls are wrapped in _shouldMarkInactive, which
    // already checks this, so we shouldn't hit this condition
    assert(snapshotBalance > 0);
    // Set the account inactive on deducted balance
    _inactiveFeePerYear[account] = _calcInactiveFeePerYear(snapshotBalance);
    emit AccountInactive(account, _inactiveFeePerYear[account]);
    uint256 inactiveFees = _calcInactiveFee(snapshotBalance,
                                            daysSinceActivity(account),
                                            _inactiveFeePerYear[account],
                                            0);
    // Deduct owed storage and inactive fees
    uint256 fees = storeFee.add(inactiveFees);
    _balances[account] = _balances[account].sub(fees);
    _balances[_feeAddress] = _balances[_feeAddress].add(fees);
    _inactiveFeePaid[account] = _inactiveFeePaid[account].add(inactiveFees);
    emit Transfer(account, _feeAddress, fees);
    // Reset storage fee clock if storage fees paid
    if (storeFee > 0) {
      _timeStorageFeePaid[account] = block.timestamp;
      _endGracePeriod(account);
    }
  }
  /**
  * @dev Update the activity clock on an account thats originated a transaction.
  * If the account has previously been marked inactive or should have been
  * marked inactive, it will opportunistically collect those owed fees.
  *
  * @param account The account to update activity
  */
  function _updateActivity(address account) internal {
    // Cache has the ability to force collecting storage and inactivity fees,
    // but in the event an address was missed, can we still detect if the
    // account was inactive when they next transact
    //
    // Here we simply set the account as being inactive, collect the previous
    // storage and inactive fees that were owed, and then reactivate the account
    if (_shouldMarkInactive(account)) {
      // Call will pay existing storage fees before marking inactive
      _setInactive(account);
    }
    // Pay remaining fees and reset fee clocks
    if (isInactive(account)) {
      _payInactiveFee(account);
      _inactiveFeePerYear[account] = 0;
      _timeStorageFeePaid[account] = block.timestamp;
      emit AccountReActive(account);
    }
    // The normal case will just hit this and update
    // the activity clock for the account
    _timeLastActivity[account] = block.timestamp;
  }
  /**
   * @dev Turn off storage fee grace period for an address the first
   * time storage fees are paid (after grace period has ended)
   * @param account The account to turn off storage fee grace period
   */
  function _endGracePeriod(address account) internal {
    if (_storageFeeGracePeriod[account] > 0) {
      _storageFeeGracePeriod[account] = 0;
    }
  }
  /**
  * @dev Enforce the rules of which addresses can transfer to others
  * @param to The sending address
  * @param from The receiving address
  */
  function _transferRestrictions(address to, address from) internal view {
    require(from != address(0));
    require(to != address(0));
    require(to != address(this), "Cannot transfer tokens to the contract");
    // unbacked treasury can only transfer to backed treasury
    if (from == _unbackedTreasury) {
      require(to == _backedTreasury,
              "Unbacked treasury can only transfer to backed treasury");
    }
    // redeem address can only transfer to unbacked or backed treasury
    if (from == _redeemAddress) {
      require((to == _unbackedTreasury) || (to == _backedTreasury),
              "Redeem address can only transfer to treasury");
    }
    // Only the backed treasury  and redeem address
    // can transfer to unbacked treasury
    if (to == _unbackedTreasury) {
      require((from == _backedTreasury) || (from == _redeemAddress),
              "Unbacked treasury can only receive from redeem address and backed treasury");
    }
    // Only the unbacked treasury can transfer to the backed treasury
    if (to == _backedTreasury) {
      require((from == _unbackedTreasury) || (from == _redeemAddress),
              "Only unbacked treasury and redeem address can transfer to backed treasury");
    }
  }
  /**
   * @dev Simulate the transfer from one address to another see final balances and associated fees
   * @param from address The address which you want to send tokens from
   * @param to address The address which you want to transfer to
   * @return a uint256 array of 5 values representing the
   * [0] storage fees `from`
   * [1] storage fees `to`
   * [2] transfer fee `from`
   * [3] final `from` balance
   * [4] final `to` balance
   */
  function _simulateTransfer(address from, address to, uint256 value) internal view returns (uint256[5] memory) {
    uint256[5] memory ret;
    // Return value slots
    // 0 - fees `from`
    // 1 - fees `to`
    // 2 - transfer fee `from`
    // 3 - final `from` balance
    // 4 - final `to` balance
    ret[0] = calcOwedFees(from);
    ret[1] = 0;
    ret[2] = 0;
    // Don't double charge storage fee sending to self
    if (from != to) {
      ret[1] = calcOwedFees(to);
      ret[2] = calcTransferFee(from, value);
      ret[3] = _balances[from].sub(value).sub(ret[0]).sub(ret[2]);
      ret[4] = _balances[to].add(value).sub(ret[1]);
    } else {
      ret[3] = _balances[from].sub(ret[0]);
      ret[4] = ret[3];
    }
    return ret;
  }
  /**
  * @dev Calculate the amount of inactive fees due per year on the snapshot balance.
  * Should return 50 basis points or 1 token minimum.
  *
  * @param snapshotBalance The balance of the account when marked inactive
  * @return uint256 the inactive fees due each year
  */
  function _calcInactiveFeePerYear(uint256 snapshotBalance) internal pure returns(uint256) {
    uint256 inactiveFeePerYear = snapshotBalance.mul(TOKEN).div(INACTIVE_FEE_DENOMINATOR);
    if (inactiveFeePerYear < TOKEN) {
      return TOKEN;
    }
    return inactiveFeePerYear;
  }
  /**
  * @dev Calcuate inactive fees due on an account
  * @param balance The current account balance
  * @param daysInactive The number of days the account has been inactive
  * @param feePerYear The inactive fee per year based on snapshot balance
  * @param paidAlready The amount of inactive fees that have been paid already
  * @return uint256 for inactive fees due
  */
  function _calcInactiveFee(uint256 balance,
                        uint256 daysInactive,
                        uint256 feePerYear,
                        uint256 paidAlready) internal pure returns(uint256) {
    uint256 daysDue = daysInactive.sub(INACTIVE_THRESHOLD_DAYS);
    uint256 totalDue = feePerYear.mul(TOKEN).mul(daysDue).div(YEAR).div(TOKEN).sub(paidAlready);
    // The fee per year can be off by 0.00000001 so we can collect
    // the final dust after 200 years
    if (totalDue > balance || balance.sub(totalDue) <= 200) {
      return balance;
    }
    return totalDue;
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"unbackedTreasury","type":"address"},{"internalType":"address","name":"backedTreasury","type":"address"},{"internalType":"address","name":"feeAddress","type":"address"},{"internalType":"address","name":"redeemAddress","type":"address"},{"internalType":"address","name":"oracle","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"feePerYear","type":"uint256"}],"name":"AccountInactive","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AccountReActive","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AddBackedGold","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RemoveGold","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"},{"constant":true,"inputs":[],"name":"INACTIVE_THRESHOLD_DAYS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SUPPLY_CAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"addBackedTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"backedTreasury","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOfNoFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"calcInactiveFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"calcOwedFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"calcSendAllBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"calcStorageFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"calcTransferFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"daysSinceActivity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"daysSincePaidStorageFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"feeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"feeEnforcer","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"forcePayFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isAllFeeExempt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isInactive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isStorageFeeExempt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isTransferFeeExempt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oracleAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"payStorageFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"redeemAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"setAccountInactive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newBackedAddress","type":"address"}],"name":"setBackedAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newFeeAddress","type":"address"}],"name":"setFeeAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"enforcer","type":"address"}],"name":"setFeeEnforcer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"setFeeExempt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"oracleAddress","type":"address"}],"name":"setOracleAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newRedeemAddress","type":"address"}],"name":"setRedeemAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"setStorageFeeExempt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"daysGracePeriod","type":"uint256"}],"name":"setStorageFeeGracePeriodDays","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"setTransferFeeBasisPoints","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"setTransferFeeExempt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newUnbackedAddress","type":"address"}],"name":"setUnbackedAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"simulateTransfer","outputs":[{"internalType":"uint256[5]","name":"","type":"uint256[5]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"daysSinceStoragePaid","type":"uint256"}],"name":"storageFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"storageFeeGracePeriodDays","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalCirculation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"transferFeeBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"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"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"unbackedTreasury","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unsetFeeExempt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

6080604052600a60015560006012553480156200001b57600080fd5b506040516200366c3803806200366c833981810160405260a08110156200004157600080fd5b50805160208201516040808401516060850151608090950151600080546001600160a01b031916331780825593519596949592949391926001600160a01b0392909216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600e80546001600160a01b038088166001600160a01b031992831617909255600d8054878416908316179055600c80548684169083161790556010805492851692909116919091179055620001076001600160e01b03620001d316565b601180546001600160a01b03199081166001600160a01b0393841617909155600f8054909116838316179055600c54620001429116620001e2565b60105462000162906001600160a01b03166001600160e01b03620001e216565b600d5462000182906001600160a01b03166001600160e01b03620001e216565b600e54620001a2906001600160a01b03166001600160e01b03620001e216565b620001c8620001b96001600160e01b03620001d316565b6001600160e01b03620001e216565b505050505062000294565b6000546001600160a01b031690565b620001f56001600160e01b036200028316565b62000247576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b031660009081526008602090815260408083208054600160ff1991821681179092556009909352922080549091169091179055565b6000546001600160a01b0316331490565b6133c880620002a46000396000f3fe608060405234801561001057600080fd5b50600436106103785760003560e01c80636a5de0f3116101d357806395d89b4111610104578063dd62ed3e116100a2578063edd496fa1161007c578063edd496fa14610a48578063f2fde38b14610a6e578063fc2edf5a14610a94578063fd1c1ae014610a9c57610378565b8063dd62ed3e146109ce578063e3461119146109fc578063e8337a2714610a2257610378565b8063a89ae4ba116100de578063a89ae4ba14610957578063a9059cbb1461095f578063cbabd8d81461098b578063da403903146109b157610378565b806395d89b41146108fd578063a457c2d714610905578063a47913151461093157610378565b80637650e683116101715780638705fcd41161014b5780638705fcd4146108bf5780638da5cb5b146108e55780638f32d59b146108ed5780638f9e4cf2146108f557610378565b80637650e683146108745780637c37080e1461089a57806380a78ac7146108a257610378565b806370a08231116101ad57806370a0823114610818578063715018a61461083e57806372cc14fa14610846578063749796a51461084e57610378565b80636a5de0f3146107c25780636d9c8cd8146107e85780636f9423f6146107f057610378565b80632f648c1a116102ad5780634d1e090a1161024b578063549b472911610225578063549b4729146107485780635aa349211461076e5780635dcf8d2b146107945780635fcbc8961461079c57610378565b80634d1e090a146106d95780634fcf262c146106fc578063536f21201461072257610378565b8063395093511161028757806339509351146106535780633c6d47741461067f57806341275358146106ab5780634c69c00f146106b357610378565b80632f648c1a146105e9578063313ce5671461060f57806335dd44031461062d57610378565b80631a222ac71161031a57806329c25d39116102f457806329c25d39146105275780632a5332391461054d5780632ae96a80146105555780632ec3fc8e146105c357610378565b80631a222ac7146104a757806323b872dd146104cd578063265b51501461050357610378565b80630c7a971e116103565780630c7a971e146104575780630cfccc831461048f57806318160ddd14610497578063183767da1461049f57610378565b806306fdde031461037d578063095ea7b3146103fa57806309d6ec0a1461043a575b600080fd5b610385610ac2565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103bf5781810151838201526020016103a7565b50505050905090810190601f1680156103ec5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104266004803603604081101561041057600080fd5b506001600160a01b038135169060200135610ae8565b604080519115158252519081900360200190f35b6104266004803603602081101561045057600080fd5b5035610b08565b61047d6004803603602081101561046d57600080fd5b50356001600160a01b0316610cd0565b60408051918252519081900360200190f35b61047d610e04565b61047d610e10565b61047d610e16565b61047d600480360360208110156104bd57600080fd5b50356001600160a01b0316610e1c565b610426600480360360608110156104e357600080fd5b506001600160a01b03813581169160208101359091169060400135610edf565b61050b610f3f565b604080516001600160a01b039092168252519081900360200190f35b61047d6004803603602081101561053d57600080fd5b50356001600160a01b0316610f4e565b61047d610fa6565b61058b6004803603606081101561056b57600080fd5b506001600160a01b03813581169160208101359091169060400135610fac565b604051808260a080838360005b838110156105b0578181015183820152602001610598565b5050505090500191505060405180910390f35b610426600480360360208110156105d957600080fd5b50356001600160a01b0316610fc7565b610426600480360360208110156105ff57600080fd5b50356001600160a01b031661112d565b610617611209565b6040805160ff9092168252519081900360200190f35b61047d6004803603602081101561064357600080fd5b50356001600160a01b031661120e565b6104266004803603604081101561066957600080fd5b506001600160a01b03813516906020013561127a565b61047d6004803603604081101561069557600080fd5b506001600160a01b0381351690602001356112c0565b61050b6112fa565b610426600480360360208110156106c957600080fd5b50356001600160a01b0316611309565b61047d600480360360408110156106ef57600080fd5b508035906020013561138a565b61047d6004803603602081101561071257600080fd5b50356001600160a01b03166113d1565b6104266004803603602081101561073857600080fd5b50356001600160a01b03166113ec565b6104266004803603602081101561075e57600080fd5b50356001600160a01b0316611473565b61047d6004803603602081101561078457600080fd5b50356001600160a01b0316611491565b61047d6114a8565b610426600480360360208110156107b257600080fd5b50356001600160a01b03166114da565b610426600480360360208110156107d857600080fd5b50356001600160a01b03166114f7565b61050b61155e565b6108166004803603602081101561080657600080fd5b50356001600160a01b031661156d565b005b61047d6004803603602081101561082e57600080fd5b50356001600160a01b03166115d8565b6108166115e3565b61050b611674565b6108166004803603602081101561086457600080fd5b50356001600160a01b0316611683565b6104266004803603602081101561088a57600080fd5b50356001600160a01b0316611706565b61047d611874565b610816600480360360208110156108b857600080fd5b503561187a565b610426600480360360208110156108d557600080fd5b50356001600160a01b03166118c6565b61050b61199a565b6104266119a9565b6104266119ba565b6103856119d6565b6104266004803603604081101561091b57600080fd5b506001600160a01b0381351690602001356119f5565b6104266004803603602081101561094757600080fd5b50356001600160a01b0316611a3b565b61050b611a7d565b6104266004803603604081101561097557600080fd5b506001600160a01b038135169060200135611a8c565b610816600480360360208110156109a157600080fd5b50356001600160a01b0316611ab9565b610816600480360360208110156109c757600080fd5b5035611b36565b61047d600480360360408110156109e457600080fd5b506001600160a01b0381358116916020013516611bc2565b61042660048036036020811015610a1257600080fd5b50356001600160a01b0316611bed565b61042660048036036020811015610a3857600080fd5b50356001600160a01b0316611cc1565b61081660048036036020811015610a5e57600080fd5b50356001600160a01b0316611cdf565b61081660048036036020811015610a8457600080fd5b50356001600160a01b0316611d4a565b61050b611d9d565b61047d60048036036020811015610ab257600080fd5b50356001600160a01b0316611dac565b6040518060400160405280600a81526020016910d050d2114811dbdb1960b21b81525081565b6000610af333611e9a565b610afe338484611f34565b5060015b92915050565b6000610b126119a9565b610b51576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b600e546001600160a01b03908116600090815260026020908152604080832054600f5482516337bc67d560e21b815292519195169263def19f549260048082019391829003018186803b158015610ba757600080fd5b505afa158015610bbb573d6000803e3d6000fd5b505050506040513d6020811015610bd157600080fd5b50519050610bed84610be16114a8565b9063ffffffff611fbc16565b811015610c2b5760405162461bcd60e51b81526004018080602001828103825260428152602001806131476042913960600191505060405180910390fd5b818411610c5457600e54600d54610c4f916001600160a01b03908116911686612016565b610c91565b8115610c7757600e54600d54610c77916001600160a01b03908116911684612016565b610c8f610c8a858463ffffffff61236516565b6123c2565b505b6040805185815290517f09b6db8121b98e8afd720f8845773ef4340dfe3c6a1eadc5e068ff266357e8079181900360200190a16001925050505b919050565b60006001600160a01b038216610ce557600080fd5b6000610d18610cf384611491565b6001600160a01b0385166000908152600260205260409020549063ffffffff61236516565b905060015460001480610d2f5750610d2f83611473565b15610d3b579050610ccb565b60018111610d4d576000915050610ccb565b6000610d7a610d6961271060015461251e90919063ffffffff16565b6305f5e1009063ffffffff611fbc16565b90506000610da76001610be184610d9b876305f5e10063ffffffff61251e16565b9063ffffffff61257716565b90506000610dc6612710610d9b6001548561251e90919063ffffffff16565b905083610dd9838363ffffffff611fbc16565b1115610dfb57610df082600163ffffffff61236516565b945050505050610ccb565b50949350505050565b670b499bdc6499da0081565b600b5490565b60015490565b6001600160a01b03811660009081526002602052604081205481610e3f84610f4e565b9050610e4a846114da565b15610e8b576001600160a01b038416600090815260076020908152604080832054600690925290912054610e829184918491906125e1565b92505050610ccb565b610e948461264d565b15610ed5576000610eb4610ea786611dac565b849063ffffffff61236516565b9050610ecb8183610ec4846126e4565b60006125e1565b9350505050610ccb565b5060009392505050565b6000610eea33611e9a565b610ef5848484612016565b6001600160a01b038416600090815260036020908152604080832033808552925290912054610f35918691610f30908663ffffffff61236516565b611f34565b5060019392505050565b6010546001600160a01b031690565b6001600160a01b038116600090815260056020526040812054610f7357506000610ccb565b6001600160a01b038216600090815260056020526040902054610b02906201518090610d9b90429063ffffffff61236516565b60125490565b610fb4612f89565b610fbf84848461271f565b949350505050565b6011546000906001600160a01b03163314610fe157600080fd5b6001600160a01b038216610ff457600080fd5b6001600160a01b0382166000908152600260205260409020546110485760405162461bcd60e51b81526004018080602001828103825260308152602001806130ec6030913960400191505060405180910390fd5b611051826114da565b156110765760006110618361282f565b90506000811161107057600080fd5b50610ccb565b61107f8261264d565b156110925761108d82612981565b610ccb565b61016d61109e8361120e565b10156110db5760405162461bcd60e51b81526004018080602001828103825260398152602001806130446039913960400191505060405180910390fd5b60006110e683612b80565b9050600081116111275760405162461bcd60e51b81526004018080602001828103825260308152602001806131896030913960400191505060405180910390fd5b50919050565b60006111376119a9565b611176576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b6001600160a01b03821661118957600080fd5b600e546001600160a01b03838116911614156111d65760405162461bcd60e51b815260040180806020018281038252602e8152602001806131b9602e913960400191505060405180910390fd5b600d80546001600160a01b0319166001600160a01b0384811691909117918290556112019116611683565b506001919050565b600881565b6000611219826114da565b8061123a57506001600160a01b038216600090815260046020526040902054155b1561124757506000610ccb565b6001600160a01b038216600090815260046020526040902054610b02906201518090610d9b90429063ffffffff61236516565b600061128533611e9a565b3360008181526003602090815260408083206001600160a01b0388168452909152902054610afe91908590610f30908663ffffffff611fbc16565b60006112cb83611473565b156112d857506000610b02565b6112f3612710610d9b6001548561251e90919063ffffffff16565b9392505050565b600c546001600160a01b031690565b60006113136119a9565b611352576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b6001600160a01b03821661136557600080fd5b50600f80546001600160a01b0383166001600160a01b03199091161790556001919050565b6000806113be6409502f9000610d9b61016d81876113b28a6305f5e10063ffffffff61251e16565b9063ffffffff61251e16565b9050838111156112f35783915050610b02565b6001600160a01b031660009081526002602052604090205490565b60006113f66119a9565b611435576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b6001600160a01b03821661144857600080fd5b601180546001600160a01b0319166001600160a01b0384811691909117918290556112019116611683565b6001600160a01b031660009081526008602052604090205460ff1690565b6000610b0261149f83610e1c565b610be184611dac565b600e546001600160a01b0316600090815260026020526040812054600b546114d59163ffffffff61236516565b905090565b6001600160a01b0316600090815260076020526040902054151590565b6011546000906001600160a01b0316331461151157600080fd5b61151a8261264d565b6115555760405162461bcd60e51b815260040180806020018281038252602a81526020018061332d602a913960400191505060405180910390fd5b610ccb82612981565b600d546001600160a01b031690565b6115756119a9565b6115b4576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b6001600160a01b03166000908152600860205260409020805460ff19166001179055565b6000610b0282610cd0565b6115eb6119a9565b61162a576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600e546001600160a01b031690565b61168b6119a9565b6116ca576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b6001600160a01b031660009081526008602090815260408083208054600160ff1991821681179092556009909352922080549091169091179055565b60006117106119a9565b61174f576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b6001600160a01b03821661176257600080fd5b600d546001600160a01b03838116911614156117af5760405162461bcd60e51b815260040180806020018281038252602f8152602001806132fe602f913960400191505060405180910390fd5b600c546001600160a01b03838116911614156117fc5760405162461bcd60e51b815260040180806020018281038252602c815260200180612fa8602c913960400191505060405180910390fd5b6010546001600160a01b03838116911614156118495760405162461bcd60e51b815260040180806020018281038252602c815260200180612fa8602c913960400191505060405180910390fd5b600e80546001600160a01b0319166001600160a01b0384811691909117918290556112019116611683565b61044781565b6118826119a9565b6118c1576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b601255565b60006118d06119a9565b61190f576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b6001600160a01b03821661192257600080fd5b600e546001600160a01b038381169116141561196f5760405162461bcd60e51b815260040180806020018281038252602b81526020018061311c602b913960400191505060405180910390fd5b600c80546001600160a01b0319166001600160a01b0384811691909117918290556112019116611683565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b60006119c533611e9a565b6119ce33612b80565b506001905090565b6040518060400160405280600381526020016210d1d560ea1b81525081565b6000611a0033611e9a565b3360008181526003602090815260408083206001600160a01b0388168452909152902054610afe91908590610f30908663ffffffff61236516565b6001600160a01b03811660009081526008602052604081205460ff168015610b025750506001600160a01b031660009081526009602052604090205460ff1690565b600f546001600160a01b031690565b6000611a9733611e9a565b611aa08361264d565b15611aae57611aae83612981565b610afe338484612016565b611ac16119a9565b611b00576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b6001600160a01b03166000908152600860209081526040808320805460ff19908116909155600990925290912080549091169055565b611b3e6119a9565b611b7d576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b600a811115611bbd5760405162461bcd60e51b815260040180806020018281038252603d815260200180613357603d913960400191505060405180910390fd5b600155565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b6000611bf76119a9565b611c36576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b6001600160a01b038216611c4957600080fd5b600e546001600160a01b0383811691161415611c965760405162461bcd60e51b815260040180806020018281038252602e81526020018061323e602e913960400191505060405180910390fd5b601080546001600160a01b0319166001600160a01b0384811691909117918290556112019116611683565b6001600160a01b031660009081526009602052604090205460ff1690565b611ce76119a9565b611d26576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b6001600160a01b03166000908152600960205260409020805460ff19166001179055565b611d526119a9565b611d91576040805162461bcd60e51b8152602060048201819052602482015260008051602061326c833981519152604482015290519081900360640190fd5b611d9a81612c6f565b50565b6011546001600160a01b031690565b6001600160a01b038116600090815260026020526040812054611dce836114da565b80611ddd5750611ddd83611cc1565b80611de6575080155b15611df5576000915050610ccb565b6000611e008461120e565b90506000611e0d85610f4e565b6001600160a01b0386166000908152600a60205260409020549091508015611e535780831115611e4e57611e47838263ffffffff61236516565b9250611e53565b600092505b82611e65576000945050505050610ccb565b6104478210611e8657611e83610ea78361044763ffffffff61236516565b92505b611e90848461138a565b9695505050505050565b611ea38161264d565b15611eb157611eb181612981565b611eba816114da565b15611f1857611ec88161282f565b506001600160a01b03811660008181526007602090815260408083208390556004909152808220429055517f96cc51e6ab9b6970cc6fc055179c755849347faa4f703098b52724f2a76ad9569190a25b6001600160a01b03166000908152600560205260409020429055565b6001600160a01b038216611f4757600080fd5b6001600160a01b038316611f5a57600080fd5b6001600160a01b03808416600081815260036020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6000828201838110156112f3576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6120208284612d0f565b600061202b84611dac565b6001600160a01b03808616600081815260026020526040808220549388168083529082205494955090938593929091146121315761207961206c89886112c0565b849063ffffffff611fbc16565b925061208487611dac565b93506120a68361209a848963ffffffff61236516565b9063ffffffff61236516565b6001600160a01b0389166000908152600260205260409020556120d38461209a838963ffffffff611fbc16565b6001600160a01b0380891660009081526002602052604080822093909355600c5490911681522054612111908590610be1908663ffffffff611fbc16565b600c546001600160a01b0316600090815260026020526040902055612195565b612141828663ffffffff61236516565b6001600160a01b03808a1660009081526002602052604080822093909355600c5490911681522054612179908663ffffffff611fbc16565b600c546001600160a01b03166000908152600260205260409020555b866001600160a01b0316886001600160a01b03166000805160206132de833981519152886040518082815260200191505060405180910390a3821561223257600c546040805185815290516001600160a01b03928316928b16916000805160206132de833981519152919081900360200190a38415612232576001600160a01b038816600090815260046020526040902042905561223288612f51565b6001600160a01b038716600090815260046020526040902054612287576012546001600160a01b0388166000908152600a60209081526040808320939093556005815282822042908190556004909152919020555b83156122ea57600c546040805186815290516001600160a01b03928316928a16916000805160206132de833981519152919081900360200190a36001600160a01b03871660009081526004602052604090204290556122e587612f51565b612311565b62023a50811015612311576001600160a01b03871660009081526004602052604090204290555b600e546001600160a01b038881169116141561235b576040805187815290517f19b4cf73e928f35f5b561a793ad1648ee8ffd717737f5a605419936c8c5a22369181900360200190a15b5050505050505050565b6000828211156123bc576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600b54600090670b499bdc6499da00906123e2908463ffffffff611fbc16565b1115612435576040805162461bcd60e51b815260206004820152601c60248201527f43616c6c20776f756c642065786365656420737570706c792063617000000000604482015290519081900360640190fd5b600e546001600160a01b03166000908152600260205260409020541561248c5760405162461bcd60e51b815260040180806020018281038252602681526020018061328c6026913960400191505060405180910390fd5b600b5461249f908363ffffffff611fbc16565b600b55600d546001600160a01b03166000908152600260205260409020546124cd908363ffffffff611fbc16565b600d80546001600160a01b0390811660009081526002602090815260408083209590955592548451878152945192169390926000805160206132de83398151915292918290030190a3506001919050565b60008261252d57506000610b02565b8282028284828161253a57fe5b04146112f35760405162461bcd60e51b815260040180806020018281038252602181526020018061321d6021913960400191505060405180910390fd5b60008082116125cd576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b60008284816125d857fe5b04949350505050565b6000806125f68561044763ffffffff61236516565b9050600061261e8461209a6305f5e100610d9b61016d81886113b28d8663ffffffff61251e16565b90508681118061263e575060c861263b888363ffffffff61236516565b11155b15611e90578692505050610fbf565b60006001600160a01b0382161580159061267e57506001600160a01b03821660009081526002602052604090205415155b8015612694575061044761269183610f4e565b10155b80156126a657506126a4826114da565b155b80156126b857506126b682611a3b565b155b80156126cf575060006126cd610cf384611dac565b115b156126dc57506001610ccb565b506000919050565b6000806127046404a817c800610d9b856305f5e10063ffffffff61251e16565b90506305f5e100811015610b0257506305f5e1009050610ccb565b612727612f89565b61272f612f89565b61273885611491565b815260006020820181905260408201526001600160a01b03848116908616146127f15761276484611491565b602082015261277385846112c0565b604080830182905282516001600160a01b0388166000908152600260205291909120546127ad929161209a9182908863ffffffff61236516565b60608201526020808201516001600160a01b038616600090815260029092526040909120546127e7919061209a908663ffffffff611fbc16565b6080820152610fbf565b80516001600160a01b03861660009081526002602052604090205461281b9163ffffffff61236516565b606082018190526080820152949350505050565b6001600160a01b03811660009081526002602052604081205481906128819061285785610f4e565b6001600160a01b0386166000908152600760209081526040808320546006909252909120546125e1565b905080612892576000915050610ccb565b6001600160a01b0383166000908152600260205260409020546128bb908263ffffffff61236516565b6001600160a01b0380851660009081526002602052604080822093909355600c54909116815220546128f3908263ffffffff611fbc16565b600c546001600160a01b03908116600090815260026020908152604080832094909455918616815260069091522054612932908263ffffffff611fbc16565b6001600160a01b0380851660008181526006602090815260409182902094909455600c548151868152915193169391926000805160206132de833981519152929181900390910190a392915050565b600061298c82611dac565b6001600160a01b038316600090815260026020526040812054919250906129b9908363ffffffff61236516565b9050600081116129c557fe5b6129ce816126e4565b6001600160a01b0384166000818152600760209081526040918290208490558151938452905191927f481010afe95c4aad3901e4d3948ca845e8772b11b72f77bf2dd74a9940e21a21929081900390910190a26000612a4f82612a3086610f4e565b6001600160a01b038716600090815260076020526040812054906125e1565b90506000612a63848363ffffffff611fbc16565b6001600160a01b038616600090815260026020526040902054909150612a8f908263ffffffff61236516565b6001600160a01b0380871660009081526002602052604080822093909355600c5490911681522054612ac7908263ffffffff611fbc16565b600c546001600160a01b03908116600090815260026020908152604080832094909455918816815260069091522054612b06908363ffffffff611fbc16565b6001600160a01b0380871660008181526006602090815260409182902094909455600c548151868152915193169391926000805160206132de833981519152929181900390910190a38315612b79576001600160a01b0385166000908152600460205260409020429055612b7985612f51565b5050505050565b600080612b8c83611dac565b905080612b9d576000915050610ccb565b6001600160a01b038316600090815260026020526040902054612bc6908263ffffffff61236516565b6001600160a01b0380851660009081526002602052604080822093909355600c5490911681522054612bfe908263ffffffff611fbc16565b600c80546001600160a01b039081166000908152600260209081526040918290209490945591548251858152925190821693918716926000805160206132de83398151915292908290030190a36001600160a01b0383166000908152600460205260409020429055610b0283612f51565b6001600160a01b038116612cb45760405162461bcd60e51b815260040180806020018281038252602681526020018061301e6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116612d2257600080fd5b6001600160a01b038216612d3557600080fd5b6001600160a01b038216301415612d7d5760405162461bcd60e51b815260040180806020018281038252602681526020018061307d6026913960400191505060405180910390fd5b600e546001600160a01b0382811691161415612ddf57600d546001600160a01b03838116911614612ddf5760405162461bcd60e51b81526004018080602001828103825260368152602001806131e76036913960400191505060405180910390fd5b6010546001600160a01b0382811691161415612e5957600e546001600160a01b0383811691161480612e1e5750600d546001600160a01b038381169116145b612e595760405162461bcd60e51b815260040180806020018281038252602c8152602001806132b2602c913960400191505060405180910390fd5b600e546001600160a01b0383811691161415612ed357600d546001600160a01b0382811691161480612e9857506010546001600160a01b038281169116145b612ed35760405162461bcd60e51b815260040180806020018281038252604a815260200180612fd4604a913960600191505060405180910390fd5b600d546001600160a01b0383811691161415612f4d57600e546001600160a01b0382811691161480612f1257506010546001600160a01b038281169116145b612f4d5760405162461bcd60e51b81526004018080602001828103825260498152602001806130a36049913960600191505060405180910390fd5b5050565b6001600160a01b0381166000908152600a602052604090205415611d9a576001600160a01b03166000908152600a6020526040812055565b6040518060a00160405280600590602082028038833950919291505056fe43616e6e6f742073657420756e6261636b656420747265617375727920746f20666565206164647265737320556e6261636b65642074726561737572792063616e206f6e6c7920726563656976652066726f6d2072656465656d206164647265737320616e64206261636b65642074726561737572794f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734163636f756e742068617320706169642073746f726167652066656573206d6f726520726563656e746c79207468616e20333635206461797343616e6e6f74207472616e7366657220746f6b656e7320746f2074686520636f6e74726163744f6e6c7920756e6261636b656420747265617375727920616e642072656465656d20616464726573732063616e207472616e7366657220746f206261636b65642074726561737572794163636f756e7420686173206e6f2062616c616e63652c2063616e6e6f7420666f72636520706179696e67206665657343616e6e6f742073657420666565206164647265737320746f20756e6261636b6564207472656173757279496e737566666963656e74206772616d73206c6f636b656420696e204c6f636b6564476f6c644f7261636c6520746f20636f6d706c657465206f7065726174696f6e4e6f206170707265636961626c652073746f726167652066656573206475652c2077696c6c20726566756e642067617343616e6e6f7420736574206261636b6564206164647265737320746f20756e6261636b6564207472656173757279556e6261636b65642074726561737572792063616e206f6e6c79207472616e7366657220746f206261636b6564207472656173757279536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743616e6e6f74207365742072656465656d206164647265737320746f20756e6261636b65642074726561737572794f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657254686520756e6261636b65642074726561737572792062616c616e6365206973206e6f74203052656465656d20616464726573732063616e206f6e6c79207472616e7366657220746f207472656173757279ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef43616e6e6f742073657420756e6261636b656420747265617375727920746f206261636b65642074726561737572794163636f756e74206e6f7420656c696769626c6520746f206265206d61726b656420696e6163746976655472616e736665722066656520626173697320706f696e7473206d75737420626520616e20696e7465676572206265747765656e203020616e64203130a265627a7a72315820372aef8637f26d411673ba0df6d4802802fddde7cb63ea1edfab40abc640faaa64736f6c63430005100032000000000000000000000000d4033ea2ec53a26d6295f6f375d5c6afbe7886600000000000000000000000006522b05fe48d274f14559e0391be3675e6a1ac910000000000000000000000007ea9b52e9f8673f3e22b4eec2c4c7a7e2d1b6636000000000000000000000000c8bf2dbde1d69d174fd40581f5177f684fa26eda0000000000000000000000005b7820e62778c7317403d892f6501dd816f82730

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000d4033ea2ec53a26d6295f6f375d5c6afbe7886600000000000000000000000006522b05fe48d274f14559e0391be3675e6a1ac910000000000000000000000007ea9b52e9f8673f3e22b4eec2c4c7a7e2d1b6636000000000000000000000000c8bf2dbde1d69d174fd40581f5177f684fa26eda0000000000000000000000005b7820e62778c7317403d892f6501dd816f82730

-----Decoded View---------------
Arg [0] : unbackedTreasury (address): 0xd4033ea2ec53a26d6295f6f375d5c6afbe788660
Arg [1] : backedTreasury (address): 0x6522b05fe48d274f14559e0391be3675e6a1ac91
Arg [2] : feeAddress (address): 0x7ea9b52e9f8673f3e22b4eec2c4c7a7e2d1b6636
Arg [3] : redeemAddress (address): 0xc8bf2dbde1d69d174fd40581f5177f684fa26eda
Arg [4] : oracle (address): 0x5b7820e62778c7317403d892f6501dd816f82730

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000d4033ea2ec53a26d6295f6f375d5c6afbe788660
Arg [1] : 0000000000000000000000006522b05fe48d274f14559e0391be3675e6a1ac91
Arg [2] : 0000000000000000000000007ea9b52e9f8673f3e22b4eec2c4c7a7e2d1b6636
Arg [3] : 000000000000000000000000c8bf2dbde1d69d174fd40581f5177f684fa26eda
Arg [4] : 0000000000000000000000005b7820e62778c7317403d892f6501dd816f82730


Deployed ByteCode Sourcemap

10263:46590:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;10263:46590:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10388:42;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;10388:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17572:174;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;17572:174:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;20635:1231;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20635:1231:0;;:::i;39790:1142::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;39790:1142:0;-1:-1:-1;;;;;39790:1142:0;;:::i;:::-;;;;;;;;;;;;;;;;11460:55;;;:::i;30297:87::-;;;:::i;32079:108::-;;;:::i;38265:1205::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;38265:1205:0;-1:-1:-1;;;;;38265:1205:0;;:::i;18431:253::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;18431:253:0;;;;;;;;;;;;;;;;;:::i;31224:90::-;;;:::i;:::-;;;;-1:-1:-1;;;;;31224:90:0;;;;;;;;;;;;;;35471:217;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;35471:217:0;-1:-1:-1;;;;;35471:217:0;;:::i;31887:114::-;;;:::i;32485:163::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;32485:163:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;32485:163:0;;;;;;;;;;;;;;;;23037:1053;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23037:1053:0;-1:-1:-1;;;;;23037:1053:0;;:::i;25809:348::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25809:348:0;-1:-1:-1;;;;;25809:348:0;;:::i;10477:34::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;34957:250;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;34957:250:0;-1:-1:-1;;;;;34957:250:0;;:::i;19166:232::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;19166:232:0;;;;;;;;:::i;41121:453::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;41121:453:0;;;;;;;;:::i;31065:84::-;;;:::i;27122:179::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;27122:179:0;-1:-1:-1;;;;;27122:179:0;;:::i;41941:279::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;41941:279:0;;;;;;;:::i;29946:108::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;29946:108:0;-1:-1:-1;;;;;29946:108:0;;:::i;24306:200::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24306:200:0;-1:-1:-1;;;;;24306:200:0;;:::i;33556:119::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33556:119:0;-1:-1:-1;;;;;33556:119:0;;:::i;35887:141::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;35887:141:0;-1:-1:-1;;;;;35887:141:0;;:::i;34611:124::-;;;:::i;34275:115::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;34275:115:0;-1:-1:-1;;;;;34275:115:0;;:::i;22345:206::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22345:206:0;-1:-1:-1;;;;;22345:206:0;;:::i;31374:92::-;;;:::i;27994:113::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;27994:113:0;-1:-1:-1;;;;;27994:113:0;;:::i;:::-;;29491:111;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;29491:111:0;-1:-1:-1;;;;;29491:111:0;;:::i;1704:140::-;;;:::i;31526:96::-;;;:::i;32900:143::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;32900:143:0;-1:-1:-1;;;;;32900:143:0;;:::i;26358:584::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;26358:584:0;-1:-1:-1;;;;;26358:584:0;;:::i;11597:54::-;;;:::i;27610:139::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;27610:139:0;;:::i;24708:322::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24708:322:0;-1:-1:-1;;;;;24708:322:0;;:::i;899:79::-;;;:::i;1261:92::-;;;:::i;22201:140::-;;;:::i;10435:37::-;;;:::i;19885:242::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;19885:242:0;;;;;;;;:::i;33874:144::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33874:144:0;-1:-1:-1;;;;;33874:144:0;;:::i;31680:83::-;;;:::i;16590:365::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;16590:365:0;;;;;;;;:::i;28585:149::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28585:149:0;-1:-1:-1;;;;;28585:149:0;;:::i;28900:239::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28900:239:0;;:::i;30702:130::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;30702:130:0;;;;;;;;;;:::i;25270:346::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25270:346:0;-1:-1:-1;;;;;25270:346:0;;:::i;33240:117::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33240:117:0;-1:-1:-1;;;;;33240:117:0;;:::i;28350:111::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28350:111:0;-1:-1:-1;;;;;28350:111:0;;:::i;1997:109::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1997:109:0;-1:-1:-1;;;;;1997:109:0;;:::i;30914:86::-;;;:::i;36232:1832::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36232:1832:0;-1:-1:-1;;;;;36232:1832:0;;:::i;10388:42::-;;;;;;;;;;;;;;-1:-1:-1;;;10388:42:0;;;;:::o;17572:174::-;17639:4;17652:27;17668:10;17652:15;:27::i;:::-;17686:36;17695:10;17707:7;17716:5;17686:8;:36::i;:::-;-1:-1:-1;17736:4:0;17572:174;;;;;:::o;20635:1231::-;20703:4;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;20755:17;;-1:-1:-1;;;;;20755:17:0;;;20719:23;20745:28;;;:9;:28;;;;;;;;;20927:7;;20910:38;;-1:-1:-1;;;20910:38:0;;;;20745:28;;20927:7;;20910:36;;:38;;;;;;;;;;;20927:7;20910:38;;;5:2:-1;;;;30:1;27;20:12;5:2;20910:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;20910:38:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20910:38:0;;-1:-1:-1;21090:29:0;21113:5;21090:18;:16;:18::i;:::-;:22;:29;:22;:29;:::i;:::-;21075:11;:44;;21067:136;;;;-1:-1:-1;;;21067:136:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21325:15;21316:5;:24;21312:499;;21361:17;;21380:15;;21351:52;;-1:-1:-1;;;;;21361:17:0;;;;21380:15;21397:5;21351:9;:52::i;:::-;21312:499;;;21430:19;;21426:280;;21644:17;;21663:15;;21634:62;;-1:-1:-1;;;;;21644:17:0;;;;21663:15;21680;21634:9;:62::i;:::-;21770:33;21776:26;:5;21786:15;21776:26;:9;:26;:::i;:::-;21770:5;:33::i;:::-;;21312:499;21822:20;;;;;;;;;;;;;;;;;21856:4;21849:11;;;;1166:1;20635:1231;;;:::o;39790:1142::-;39856:7;-1:-1:-1;;;;;39880:21:0;;39872:30;;;;;;39987:27;40017:45;40040:21;40053:7;40040:12;:21::i;:::-;-1:-1:-1;;;;;40017:18:0;;;;;;:9;:18;;;;;;;:45;:22;:45;:::i;:::-;39987:75;;40073:23;;40100:1;40073:28;:60;;;;40105:28;40125:7;40105:19;:28::i;:::-;40069:109;;;40151:19;-1:-1:-1;40144:26:0;;40069:109;40290:1;40267:19;:24;40263:55;;40309:1;40302:8;;;;;40263:55;40451:15;40469:63;40479:52;10968:5;40479:23;;:27;;:52;;;;:::i;:::-;10593:23;;40469:63;:9;:63;:::i;:::-;40451:81;-1:-1:-1;40539:21:0;40563:50;40611:1;40563:43;40451:81;40563:30;:19;10593:23;40563:30;:23;:30;:::i;:::-;:34;:43;:34;:43;:::i;:50::-;40539:74;;40665:16;40684:71;10968:5;40684:42;40702:23;;40684:13;:17;;:42;;;;:::i;:71::-;40665:90;-1:-1:-1;40835:19:0;40805:27;:13;40665:90;40805:27;:17;:27;:::i;:::-;:49;40801:99;;;40872:20;:13;40890:1;40872:20;:17;:20;:::i;:::-;40865:27;;;;;;;;40801:99;-1:-1:-1;40913:13:0;39790:1142;-1:-1:-1;;;;39790:1142:0:o;11460:55::-;11497:18;11460:55;:::o;30297:87::-;30366:12;;30297:87;:::o;32079:108::-;32158:23;;32079:108;:::o;38265:1205::-;-1:-1:-1;;;;;38361:18:0;;38327:7;38361:18;;;:9;:18;;;;;;38327:7;38409:26;38371:7;38409:17;:26::i;:::-;38386:49;;38526:19;38537:7;38526:10;:19::i;:::-;38522:928;;;-1:-1:-1;;;;;38657:28:0;;;;;;:19;:28;;;;;;;;;38714:16;:25;;;;;;;38563:177;;38580:7;;38616:12;;38657:28;38563:16;:177::i;:::-;38556:184;;;;;;38522:928;38758:28;38778:7;38758:19;:28::i;:::-;38754:696;;;38975:23;39001:36;39013:23;39028:7;39013:14;:23::i;:::-;39001:7;;:36;:11;:36;:::i;:::-;38975:62;;39053:330;39070:15;39162:12;39262:40;39286:15;39262:23;:40::i;:::-;39381:1;39053:16;:330::i;:::-;39046:337;;;;;;;38754:696;-1:-1:-1;39463:1:0;;38265:1205;-1:-1:-1;;;38265:1205:0:o;18431:253::-;18512:4;18525:27;18541:10;18525:15;:27::i;:::-;18559:26;18569:4;18575:2;18579:5;18559:9;:26::i;:::-;-1:-1:-1;;;;;18619:17:0;;;;;;:11;:17;;;;;;;;18607:10;18619:29;;;;;;;;;18592:68;;18601:4;;18619:40;;18653:5;18619:40;:33;:40;:::i;:::-;18592:8;:68::i;:::-;-1:-1:-1;18674:4:0;18431:253;;;;;:::o;31224:90::-;31294:14;;-1:-1:-1;;;;;31294:14:0;31224:90;:::o;35471:217::-;-1:-1:-1;;;;;35555:26:0;;35535:7;35555:26;;;:17;:26;;;;;;35551:62;;-1:-1:-1;35604:1:0;35597:8;;35551:62;-1:-1:-1;;;;;35646:26:0;;;;;;:17;:26;;;;;;35626:56;;10675:5;;35626:47;;:15;;:47;:19;:47;:::i;31887:114::-;31969:26;;31887:114;:::o;32485:163::-;32575:17;;:::i;:::-;32608:34;32626:4;32632:2;32636:5;32608:17;:34::i;:::-;32601:41;32485:163;-1:-1:-1;;;;32485:163:0:o;23037:1053::-;16406:12;;23106:4;;-1:-1:-1;;;;;16406:12:0;16392:10;:26;16384:35;;;;;;-1:-1:-1;;;;;23127:21:0;;23119:30;;;;;;-1:-1:-1;;;;;23164:18:0;;23185:1;23164:18;;;:9;:18;;;;;;23156:96;;;;-1:-1:-1;;;23156:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23313:19;23324:7;23313:10;:19::i;:::-;23309:776;;;23343:12;23358:24;23374:7;23358:15;:24::i;:::-;23343:39;;23406:1;23399:4;:8;23391:17;;;;;;23309:776;;;;23426:28;23446:7;23426:19;:28::i;:::-;23422:663;;;23652:21;23665:7;23652:12;:21::i;:::-;23422:663;;;10738:3;23835:32;23859:7;23835:23;:32::i;:::-;:40;;23827:125;;;;-1:-1:-1;;;23827:125:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23961:12;23976:23;23991:7;23976:14;:23::i;:::-;23961:38;;24023:1;24016:4;:8;24008:69;;;;-1:-1:-1;;;24008:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23422:663;23037:1053;;;:::o;25809:348::-;25888:4;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;25909:30:0;;25901:39;;;;;;25975:17;;-1:-1:-1;;;;;25955:37:0;;;25975:17;;25955:37;;25947:109;;;;-1:-1:-1;;;25947:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26063:15;:34;;-1:-1:-1;;;;;;26063:34:0;-1:-1:-1;;;;;26063:34:0;;;;;;;;;;;26104:29;;26117:15;26104:12;:29::i;:::-;-1:-1:-1;26147:4:0;25809:348;;;:::o;10477:34::-;10510:1;10477:34;:::o;34957:250::-;35027:7;35047:19;35058:7;35047:10;:19::i;:::-;:56;;;-1:-1:-1;;;;;;35070:28:0;;;;;;:19;:28;;;;;;:33;35047:56;35043:87;;;-1:-1:-1;35121:1:0;35114:8;;35043:87;-1:-1:-1;;;;;35163:28:0;;;;;;:19;:28;;;;;;35143:58;;10675:5;;35143:49;;:15;;:49;:19;:49;:::i;19166:232::-;19248:4;19261:27;19277:10;19261:15;:27::i;:::-;19304:10;19325:23;;;;:11;:23;;;;;;;;-1:-1:-1;;;;;19325:32:0;;;;;;;;;;19295:79;;19304:10;19316:7;;19325:48;;19362:10;19325:48;:36;:48;:::i;41121:453::-;41198:7;41218:28;41238:7;41218:19;:28::i;:::-;41214:59;;;-1:-1:-1;41264:1:0;41257:8;;41214:59;41505:63;10968:5;41505:34;41515:23;;41505:5;:9;;:34;;;;:::i;:63::-;41498:70;41121:453;-1:-1:-1;;;41121:453:0:o;31065:84::-;31132:11;;-1:-1:-1;;;;;31132:11:0;31065:84;:::o;27122:179::-;27198:4;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;27219:27:0;;27211:36;;;;;;-1:-1:-1;27254:7:0;:23;;-1:-1:-1;;;;;27254:23:0;;-1:-1:-1;;;;;;27254:23:0;;;;;;;27122:179;;;:::o;41941:279::-;42028:7;;42058:83;11060:11;42058:54;10738:3;42058:54;42081:20;42058:18;:7;10593:23;42058:18;:11;:18;:::i;:::-;:22;:44;:22;:44;:::i;:83::-;42044:97;;42158:7;42152:3;:13;42148:50;;;42183:7;42176:14;;;;;29946:108;-1:-1:-1;;;;;30032:16:0;30009:7;30032:16;;;:9;:16;;;;;;;29946:108::o;24306:200::-;24375:4;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;24396:22:0;;24388:31;;;;;;24426:12;:23;;-1:-1:-1;;;;;;24426:23:0;-1:-1:-1;;;;;24426:23:0;;;;;;;;;;;24456:26;;24469:12;24456;:26::i;33556:119::-;-1:-1:-1;;;;;33642:27:0;33622:4;33642:27;;;:18;:27;;;;;;;;;33556:119::o;35887:141::-;35946:7;35969:53;35997:24;36013:7;35997:15;:24::i;:::-;35969:23;35984:7;35969:14;:23::i;34611:124::-;34710:17;;-1:-1:-1;;;;;34710:17:0;34660:7;34700:28;;;:9;:28;;;;;;34683:12;;:46;;;:16;:46;:::i;:::-;34676:53;;34611:124;:::o;34275:115::-;-1:-1:-1;;;;;34352:28:0;34332:4;34352:28;;;:19;:28;;;;;;:32;;;34275:115::o;22345:206::-;16406:12;;22421:4;;-1:-1:-1;;;;;16406:12:0;16392:10;:26;16384:35;;;;;;22442:28;22462:7;22442:19;:28::i;:::-;22434:83;;;;-1:-1:-1;;;22434:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22524:21;22537:7;22524:12;:21::i;31374:92::-;31445:15;;-1:-1:-1;;;;;31445:15:0;31374:92;:::o;27994:113::-;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;28067:27:0;;;;;:18;:27;;;;;:34;;-1:-1:-1;;28067:34:0;28097:4;28067:34;;;27994:113::o;29491:111::-;29548:7;29571:25;29590:5;29571:18;:25::i;1704:140::-;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;1803:1;1787:6;;1766:40;;-1:-1:-1;;;;;1787:6:0;;;;1766:40;;1803:1;;1766:40;1834:1;1817:19;;-1:-1:-1;;;;;;1817:19:0;;;1704:140::o;31526:96::-;31599:17;;-1:-1:-1;;;;;31599:17:0;31526:96;:::o;32900:143::-;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;32963:27:0;;;;;:18;:27;;;;;;;;:34;;32993:4;-1:-1:-1;;32963:34:0;;;;;;;;33004:17;:26;;;;;:33;;;;;;;;;;32900:143::o;26358:584::-;26441:4;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;26462:32:0;;26454:41;;;;;;26532:15;;-1:-1:-1;;;;;26510:37:0;;;26532:15;;26510:37;;26502:110;;;;-1:-1:-1;;;26502:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26649:11;;-1:-1:-1;;;;;26627:33:0;;;26649:11;;26627:33;;26619:103;;;;-1:-1:-1;;;26619:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26759:14;;-1:-1:-1;;;;;26737:36:0;;;26759:14;;26737:36;;26729:106;;;;-1:-1:-1;;;26729:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26842:17;:38;;-1:-1:-1;;;;;;26842:38:0;-1:-1:-1;;;;;26842:38:0;;;;;;;;;;;26887:31;;26900:17;26887:12;:31::i;11597:54::-;11647:4;11597:54;:::o;27610:139::-;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;27699:26;:44;27610:139::o;24708:322::-;24781:4;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;24802:27:0;;24794:36;;;;;;24862:17;;-1:-1:-1;;;;;24845:34:0;;;24862:17;;24845:34;;24837:103;;;;-1:-1:-1;;;24837:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24947:11;:27;;-1:-1:-1;;;;;;24947:27:0;-1:-1:-1;;;;;24947:27:0;;;;;;;;;;;24981:25;;24994:11;24981:12;:25::i;899:79::-;937:7;964:6;-1:-1:-1;;;;;964:6:0;899:79;:::o;1261:92::-;1301:4;1339:6;-1:-1:-1;;;;;1339:6:0;1325:10;:20;;1261:92::o;22201:140::-;22244:4;22257:27;22273:10;22257:15;:27::i;:::-;22291:26;22306:10;22291:14;:26::i;:::-;;22331:4;22324:11;;22201:140;:::o;10435:37::-;;;;;;;;;;;;;;-1:-1:-1;;;10435:37:0;;;;:::o;19885:242::-;19972:4;19985:27;20001:10;19985:15;:27::i;:::-;20028:10;20049:23;;;;:11;:23;;;;;;;;-1:-1:-1;;;;;20049:32:0;;;;;;;;;;20019:84;;20028:10;20040:7;;20049:53;;20086:15;20049:53;:36;:53;:::i;33874:144::-;-1:-1:-1;;;;;33955:27:0;;33935:4;33955:27;;;:18;:27;;;;;;;;:57;;;;-1:-1:-1;;;;;;;33986:26:0;;;;;:17;:26;;;;;;;;;33874:144::o;31680:83::-;31750:7;;-1:-1:-1;;;;;31750:7:0;31680:83;:::o;16590:365::-;16653:4;16705:27;16721:10;16705:15;:27::i;:::-;16835:23;16855:2;16835:19;:23::i;:::-;16831:62;;;16869:16;16882:2;16869:12;:16::i;:::-;16899:32;16909:10;16921:2;16925:5;16899:9;:32::i;28585:149::-;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;28652:27:0;28682:5;28652:27;;;:18;:27;;;;;;;;:35;;-1:-1:-1;;28652:35:0;;;;;;28694:17;:26;;;;;;:34;;;;;;;28585:149::o;28900:239::-;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;10853:2;28982:3;:36;;28974:123;;;;-1:-1:-1;;;28974:123:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29104:23;:29;28900:239::o;30702:130::-;-1:-1:-1;;;;;30799:18:0;;;30776:7;30799:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;30702:130::o;25270:346::-;25349:4;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;25370:30:0;;25362:39;;;;;;25436:17;;-1:-1:-1;;;;;25416:37:0;;;25436:17;;25416:37;;25408:109;;;;-1:-1:-1;;;25408:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25524:14;:33;;-1:-1:-1;;;;;;25524:33:0;-1:-1:-1;;;;;25524:33:0;;;;;;;;;;;25564:28;;25577:14;25564:12;:28::i;33240:117::-;-1:-1:-1;;;;;33325:26:0;33305:4;33325:26;;;:17;:26;;;;;;;;;33240:117::o;28350:111::-;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;28422:26:0;;;;;:17;:26;;;;;:33;;-1:-1:-1;;28422:33:0;28451:4;28422:33;;;28350:111::o;1997:109::-;1109:9;:7;:9::i;:::-;1101:54;;;;;-1:-1:-1;;;1101:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1101:54:0;;;;;;;;;;;;;;;2070:28;2089:8;2070:18;:28::i;:::-;1997:109;:::o;30914:86::-;30982:12;;-1:-1:-1;;;;;30982:12:0;30914:86;:::o;36232:1832::-;-1:-1:-1;;;;;36442:18:0;;36293:7;36442:18;;;:9;:18;;;;;;36471:19;36452:7;36471:10;:19::i;:::-;:50;;;;36494:27;36513:7;36494:18;:27::i;:::-;36471:66;;;-1:-1:-1;36525:12:0;;36471:66;36467:97;;;36555:1;36548:8;;;;;36467:97;36570:28;36601:32;36625:7;36601:23;:32::i;:::-;36570:63;;36640:20;36663:26;36681:7;36663:17;:26::i;:::-;-1:-1:-1;;;;;36718:31:0;;36696:19;36718:31;;;:22;:31;;;;;;36640:49;;-1:-1:-1;36843:15:0;;36839:209;;36896:11;36873:20;:34;36869:172;;;36943:37;:20;36968:11;36943:37;:24;:37;:::i;:::-;36920:60;;36869:172;;;37030:1;37007:24;;36869:172;37058:25;37054:56;;37101:1;37094:8;;;;;;;;37054:56;11647:4;37410:12;:39;37406:549;;37880:67;37905:41;:12;11647:4;37905:41;:16;:41;:::i;37880:67::-;37857:90;;37406:549;38017:41;38028:7;38037:20;38017:10;:41::i;:::-;38010:48;36232:1832;-1:-1:-1;;;;;;36232:1832:0:o;51259:983::-;51697:28;51717:7;51697:19;:28::i;:::-;51693:142;;;51806:21;51819:7;51806:12;:21::i;:::-;51893:19;51904:7;51893:10;:19::i;:::-;51889:200;;;51923:24;51939:7;51923:15;:24::i;:::-;-1:-1:-1;;;;;;51956:28:0;;51987:1;51956:28;;;:19;:28;;;;;;;;:32;;;51997:19;:28;;;;;;52028:15;51997:46;;52057:24;;;51987:1;52057:24;51889:200;-1:-1:-1;;;;;52192:26:0;;;;;:17;:26;;;;;52221:15;52192:44;;51259:983::o;42477:237::-;-1:-1:-1;;;;;42566:21:0;;42558:30;;;;;;-1:-1:-1;;;;;42603:19:0;;42595:28;;;;;;-1:-1:-1;;;;;42630:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:35;;;42677:31;;;;;;;;;;;;;;;;;42477:237;;;:::o;6170:179::-;6228:7;6260:5;;;6284:6;;;;6276:46;;;;;-1:-1:-1;;;6276:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;43145:3288;43221:31;43243:2;43247:4;43221:21;:31::i;:::-;43463:22;43488:20;43503:4;43488:14;:20::i;:::-;-1:-1:-1;;;;;43616:15:0;;;43515:20;43616:15;;;:9;:15;;;;;;;43664:13;;;;;;;;;;43463:45;;-1:-1:-1;43515:20:0;;43463:45;;43616:15;43664:13;;43752:10;43748:642;;43866:44;43881:28;43897:4;43903:5;43881:15;:28::i;:::-;43866:10;;:44;:14;:44;:::i;:::-;43853:57;;43934:18;43949:2;43934:14;:18::i;:::-;43919:33;-1:-1:-1;43979:44:0;44012:10;43979:28;:17;44001:5;43979:28;:21;:28;:::i;:::-;:32;:44;:32;:44;:::i;:::-;-1:-1:-1;;;;;43961:15:0;;;;;;:9;:15;;;;;:62;44048:44;44079:12;44048:26;:15;44068:5;44048:26;:19;:26;:::i;:44::-;-1:-1:-1;;;;;44032:13:0;;;;;;;:9;:13;;;;;;:60;;;;44136:11;;;;;44126:22;;;;:56;;44169:12;;44126:38;;44153:10;44126:38;:26;:38;:::i;:56::-;44111:11;;-1:-1:-1;;;;;44111:11:0;44101:22;;;;:9;:22;;;;;:81;43748:642;;;44269:37;:17;44291:14;44269:37;:21;:37;:::i;:::-;-1:-1:-1;;;;;44251:15:0;;;;;;;:9;:15;;;;;;:55;;;;44350:11;;;;;44340:22;;;;:42;;44367:14;44340:42;:26;:42;:::i;:::-;44325:11;;-1:-1:-1;;;;;44325:11:0;44315:22;;;;:9;:22;;;;;:67;43748:642;44441:2;-1:-1:-1;;;;;44426:25:0;44435:4;-1:-1:-1;;;;;44426:25:0;-1:-1:-1;;;;;;;;;;;44445:5:0;44426:25;;;;;;;;;;;;;;;;;;44501:14;;44497:209;;44546:11;;44531:39;;;;;;;;-1:-1:-1;;;;;44546:11:0;;;;44531:39;;;-1:-1:-1;;;;;;;;;;;44531:39:0;;;;;;;;;44583:18;;44579:120;;-1:-1:-1;;;;;44614:25:0;;;;;;:19;:25;;;;;44642:15;44614:43;;44668:21;44634:4;44668:15;:21::i;:::-;-1:-1:-1;;;;;44839:23:0;;;;;;:19;:23;;;;;;44835:344;;45047:26;;-1:-1:-1;;;;;45018:26:0;;;;;;:22;:26;;;;;;;;:55;;;;45082:17;:21;;;;;45106:15;45082:39;;;;45130:19;:23;;;;;;:41;44835:344;45226:16;;45222:989;;45271:11;;45258:39;;;;;;;;-1:-1:-1;;;;;45271:11:0;;;;45258:39;;;-1:-1:-1;;;;;;;;;;;45258:39:0;;;;;;;;;-1:-1:-1;;;;;45306:23:0;;;;;;:19;:23;;;;;45332:15;45306:41;;45356:19;45326:2;45356:15;:19::i;:::-;45222:989;;;11294:6;45393:15;:38;45389:822;;;-1:-1:-1;;;;;46162:23:0;;;;;;:19;:23;;;;;46188:15;46162:41;;45389:822;46370:17;;-1:-1:-1;;;;;46364:23:0;;;46370:17;;46364:23;46360:68;;;46403:17;;;;;;;;;;;;;;;;;46360:68;43145:3288;;;;;;;;:::o;6622:182::-;6680:7;6713:1;6708;:6;;6700:49;;;;;-1:-1:-1;;;6700:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6772:5:0;;;6622:182::o;46755:563::-;46854:12;;46802:4;;11497:18;;46854:23;;46871:5;46854:23;:16;:23;:::i;:::-;:37;;46846:78;;;;;-1:-1:-1;;;46846:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;47009:17;;-1:-1:-1;;;;;47009:17:0;46999:28;;;;:9;:28;;;;;;:33;46991:84;;;;-1:-1:-1;;;46991:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47142:12;;:23;;47159:5;47142:23;:16;:23;:::i;:::-;47127:12;:38;47211:15;;-1:-1:-1;;;;;47211:15:0;47201:26;;;;:9;:26;;;;;;:37;;47232:5;47201:37;:30;:37;:::i;:::-;47182:15;;;-1:-1:-1;;;;;47182:15:0;;;47172:26;;;;:9;:26;;;;;;;;:66;;;;47271:15;;47250:44;;;;;;;47271:15;;;47172:26;;-1:-1:-1;;;;;;;;;;;47250:44:0;;;;;;;;-1:-1:-1;47308:4:0;46755:563;;;:::o;7053:466::-;7111:7;7355:6;7351:47;;-1:-1:-1;7385:1:0;7378:8;;7351:47;7420:5;;;7424:1;7420;:5;:1;7444:5;;;;;:10;7436:56;;;;-1:-1:-1;;;7436:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7985:331;8043:7;8142:1;8138;:5;8130:44;;;;;-1:-1:-1;;;8130:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;8185:9;8201:1;8197;:5;;;;;;;7985:331;-1:-1:-1;;;;7985:331:0:o;56246:604::-;56449:7;;56483:41;:12;11647:4;56483:41;:16;:41;:::i;:::-;56465:59;-1:-1:-1;56531:16:0;56550:72;56610:11;56550:55;10593:23;56550:44;10738:3;56550:44;56465:59;56550:21;:10;10593:23;56550:21;:14;:21;:::i;:72::-;56531:91;;56751:7;56740:8;:18;:50;;;-1:-1:-1;56787:3:0;56762:21;:7;56774:8;56762:21;:11;:21;:::i;:::-;:28;;56740:50;56736:87;;;56808:7;56801:14;;;;;;48722:688;48790:4;-1:-1:-1;;;;;49100:21:0;;;;;;:56;;-1:-1:-1;;;;;;49134:18:0;;49155:1;49134:18;;;:9;:18;;;;;;:22;;49100:56;:122;;;;;11647:4;49169:26;49187:7;49169:17;:26::i;:::-;:53;;49100:122;:155;;;;;49236:19;49247:7;49236:10;:19::i;:::-;49235:20;49100:155;:192;;;;;49269:23;49284:7;49269:14;:23::i;:::-;49268:24;49100:192;:256;;;;;49355:1;49305:47;49328:23;49343:7;49328:14;:23::i;49305:47::-;:51;49100:256;49096:290;;;-1:-1:-1;49374:4:0;49367:11;;49096:290;-1:-1:-1;49399:5:0;48722:688;;;:::o;55572:286::-;55652:7;;55697:56;11160:11;55697:26;:15;10593:23;55697:26;:19;:26;:::i;:56::-;55668:85;-1:-1:-1;10593:23:0;55764:26;;55760:61;;;-1:-1:-1;10593:23:0;;-1:-1:-1;55801:12:0;;54511:769;54602:17;;:::i;:::-;54628:21;;:::i;:::-;54834:18;54847:4;54834:12;:18::i;:::-;54825:27;;54829:1;54825:6;54859;;:10;;;54876:6;;;:10;-1:-1:-1;;;;;54953:10:0;;;;;;;54949:309;;54983:16;54996:2;54983:12;:16::i;:::-;54974:6;;;:25;55017:28;55033:4;55039:5;55017:15;:28::i;:::-;55008:6;;;;:37;;;55094:6;;-1:-1:-1;;;;;55063:15:0;;55098:1;55063:15;;;55012:1;55008:6;55063:15;;;;;;:50;;55008:37;55063:38;;;;55083:5;55063:26;:19;:26;:::i;:50::-;55054:6;;;:59;:6;55160;;;;-1:-1:-1;;;;;55131:13:0;;;;;;:9;:13;;;;;;;;:36;;55160:6;55131:24;;55149:5;55131:24;:17;:24;:::i;:36::-;55122:6;;;:45;54949:309;;;55219:6;;-1:-1:-1;;;;;55199:15:0;;55223:1;55199:15;;;:9;55219:6;55199:15;;;;;:27;;;:19;:27;:::i;:::-;55190:6;;;:36;;;55235:6;;;:15;55190:3;55271;-1:-1:-1;;;;54511:769:0:o;48169:549::-;-1:-1:-1;;;;;48285:18:0;;48228:7;48285:18;;;:9;:18;;;;;;48228:7;;48258:158;;48314:26;48295:7;48314:17;:26::i;:::-;-1:-1:-1;;;;;48351:28:0;;;;;;:19;:28;;;;;;;;;48390:16;:25;;;;;;;48258:16;:158::i;:::-;48244:172;-1:-1:-1;48427:8:0;48423:39;;48453:1;48446:8;;;;;48423:39;-1:-1:-1;;;;;48489:18:0;;;;;;:9;:18;;;;;;:27;;48512:3;48489:27;:22;:27;:::i;:::-;-1:-1:-1;;;;;48468:18:0;;;;;;;:9;:18;;;;;;:48;;;;48558:11;;;;;48548:22;;;;:31;;48575:3;48548:31;:26;:31;:::i;:::-;48533:11;;-1:-1:-1;;;;;48533:11:0;;;48523:22;;;;:9;:22;;;;;;;;:56;;;;48614:25;;;;;:16;:25;;;;;:34;;48644:3;48614:34;:29;:34;:::i;:::-;-1:-1:-1;;;;;48586:25:0;;;;;;;:16;:25;;;;;;;;;:62;;;;48678:11;;48660:35;;;;;;;48678:11;;;48586:25;;-1:-1:-1;;;;;;;;;;;48660:35:0;;;;;;;;;;48709:3;48169:549;-1:-1:-1;;48169:549:0:o;49611:1344::-;49702:16;49721:23;49736:7;49721:14;:23::i;:::-;-1:-1:-1;;;;;49777:18:0;;49751:23;49777:18;;;:9;:18;;;;;;49702:42;;-1:-1:-1;49751:23:0;49777:32;;49702:42;49777:32;:22;:32;:::i;:::-;49751:58;;49978:1;49960:15;:19;49953:27;;;;50071:40;50095:15;50071:23;:40::i;:::-;-1:-1:-1;;;;;50040:28:0;;;;;;:19;:28;;;;;;;;;:71;;;50123:54;;;;;;;50040:28;;50123:54;;;;;;;;;;;50184:20;50207:229;50224:15;50286:26;50304:7;50286:17;:26::i;:::-;-1:-1:-1;;;;;50359:28:0;;;;;;:19;:28;;;;;;;50207:16;:229::i;:::-;50184:252;-1:-1:-1;50489:12:0;50504:26;:8;50184:252;50504:26;:12;:26;:::i;:::-;-1:-1:-1;;;;;50558:18:0;;;;;;:9;:18;;;;;;50489:41;;-1:-1:-1;50558:28:0;;50489:41;50558:28;:22;:28;:::i;:::-;-1:-1:-1;;;;;50537:18:0;;;;;;;:9;:18;;;;;;:49;;;;50628:11;;;;;50618:22;;;;:32;;50645:4;50618:32;:26;:32;:::i;:::-;50603:11;;-1:-1:-1;;;;;50603:11:0;;;50593:22;;;;:9;:22;;;;;;;;:57;;;;50685:25;;;;;:16;:25;;;;;:43;;50715:12;50685:43;:29;:43;:::i;:::-;-1:-1:-1;;;;;50657:25:0;;;;;;;:16;:25;;;;;;;;;:71;;;;50758:11;;50740:36;;;;;;;50758:11;;;50657:25;;-1:-1:-1;;;;;;;;;;;50740:36:0;;;;;;;;;;50840:12;;50836:114;;-1:-1:-1;;;;;50863:28:0;;;;;;:19;:28;;;;;50894:15;50863:46;;50918:24;50883:7;50918:15;:24::i;:::-;49611:1344;;;;;:::o;47486:512::-;47544:7;47560:16;47579:23;47594:7;47579:14;:23::i;:::-;47560:42;-1:-1:-1;47613:13:0;47609:44;;47644:1;47637:8;;;;;47609:44;-1:-1:-1;;;;;47734:18:0;;;;;;:9;:18;;;;;;:32;;47757:8;47734:32;:22;:32;:::i;:::-;-1:-1:-1;;;;;47713:18:0;;;;;;;:9;:18;;;;;;:53;;;;47808:11;;;;;47798:22;;;;:36;;47825:8;47798:36;:26;:36;:::i;:::-;47783:11;;;-1:-1:-1;;;;;47783:11:0;;;47773:22;;;;:9;:22;;;;;;;;;:61;;;;47864:11;;47846:40;;;;;;;47864:11;;;;47846:40;;;;-1:-1:-1;;;;;;;;;;;47846:40:0;;;;;;;;-1:-1:-1;;;;;47893:28:0;;;;;;:19;:28;;;;;47924:15;47893:46;;47946:24;47913:7;47946:15;:24::i;2210:229::-;-1:-1:-1;;;;;2284:22:0;;2276:73;;;;-1:-1:-1;;;2276:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2386:6;;;2365:38;;-1:-1:-1;;;;;2365:38:0;;;;2386:6;;;2365:38;;;2414:6;:17;;-1:-1:-1;;;;;;2414:17:0;-1:-1:-1;;;;;2414:17:0;;;;;;;;;;2210:229::o;52781:1266::-;-1:-1:-1;;;;;52867:18:0;;52859:27;;;;;;-1:-1:-1;;;;;52901:16:0;;52893:25;;;;;;-1:-1:-1;;;;;52933:19:0;;52947:4;52933:19;;52925:70;;;;-1:-1:-1;;;52925:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53077:17;;-1:-1:-1;;;;;53069:25:0;;;53077:17;;53069:25;53065:151;;;53119:15;;-1:-1:-1;;;;;53113:21:0;;;53119:15;;53113:21;53105:103;;;;-1:-1:-1;;;53105:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53306:14;;-1:-1:-1;;;;;53298:22:0;;;53306:14;;53298:22;53294:169;;;53346:17;;-1:-1:-1;;;;;53340:23:0;;;53346:17;;53340:23;;53339:52;;-1:-1:-1;53375:15:0;;-1:-1:-1;;;;;53369:21:0;;;53375:15;;53369:21;53339:52;53331:124;;;;-1:-1:-1;;;53331:124:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53574:17;;-1:-1:-1;;;;;53568:23:0;;;53574:17;;53568:23;53564:201;;;53619:15;;-1:-1:-1;;;;;53611:23:0;;;53619:15;;53611:23;;53610:53;;-1:-1:-1;53648:14:0;;-1:-1:-1;;;;;53640:22:0;;;53648:14;;53640:22;53610:53;53602:155;;;;-1:-1:-1;;;53602:155:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53852:15;;-1:-1:-1;;;;;53846:21:0;;;53852:15;;53846:21;53842:200;;;53895:17;;-1:-1:-1;;;;;53887:25:0;;;53895:17;;53887:25;;53886:55;;-1:-1:-1;53926:14:0;;-1:-1:-1;;;;;53918:22:0;;;53926:14;;53918:22;53886:55;53878:156;;;;-1:-1:-1;;;53878:156:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52781:1266;;:::o;52464:156::-;-1:-1:-1;;;;;52526:31:0;;52560:1;52526:31;;;:22;:31;;;;;;:35;52522:93;;-1:-1:-1;;;;;52572:31:0;52606:1;52572:31;;;:22;:31;;;;;:35;52464:156::o;10263:46590::-;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;10263:46590:0;;;-1:-1:-1;;10263:46590:0:o

Swarm Source

bzzr://372aef8637f26d411673ba0df6d4802802fddde7cb63ea1edfab40abc640faaa

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.