ETH Price: $3,345.09 (+2.14%)
Gas: 6 Gwei

Contract

0x85ABDfa7865261b236cBdcD1594153CbBDc904B4
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Transactions Sent

Latest: N/A First: N/A

Funded By

N/A

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Destroy146547492022-04-25 16:06:01825 days ago1650902761IN
0x85ABDfa7...bBDc904B4
0 ETH0.00364276125.63859704
Set Yield Reserv...146410942022-04-23 12:35:33828 days ago1650717333IN
0x85ABDfa7...bBDc904B4
0 ETH0.0011053732.52925178
0x61010060146410312022-04-23 12:21:16828 days ago1650716476IN
 Create: Vault
0 ETH0.0659659522.95314418

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
146547492022-04-25 16:06:01825 days ago1650902761
0x85ABDfa7...bBDc904B4
0 ETH
Loading...
Loading
Contract Self Destruct called at Txn Hash 0x8411c70f5ac10c8c82b3110e6fa166a9e83f10df2576da85f7f90aa4dc41179a


Contract Source Code Verified (Exact Match)

Contract Name:
Vault

Compiler Version
v0.8.3+commit.8d00100c

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-04-23
*/

// SPDX-License-Identifier: MIT
pragma solidity 0.8.3;

/**
 * @title Represents an ownable resource.
 */
contract Ownable {
    address internal _owner;

    event OwnershipTransferred(address previousOwner, address newOwner);

    /**
     * Constructor
     * @param addr The owner of the smart contract
     */
    constructor (address addr) {
        require(addr != address(0), "non-zero address required");
        require(addr != address(1), "ecrecover address not allowed");
        _owner = addr;
        emit OwnershipTransferred(address(0), addr);
    }

    /**
     * @notice This modifier indicates that the function can only be called by the owner.
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(msg.sender), "Only owner requirement");
        _;
    }

    /**
     * @notice Transfers ownership to the address specified.
     * @param addr Specifies the address of the new owner.
     * @dev Throws if called by any account other than the owner.
     */
    function transferOwnership (address addr) public onlyOwner {
        require(addr != address(0), "non-zero address required");
        emit OwnershipTransferred(_owner, addr);
        _owner = addr;
    }

    /**
     * @notice Destroys the smart contract.
     * @param addr The payable address of the recipient.
     */
    function destroy(address payable addr) public virtual onlyOwner {
        require(addr != address(0), "non-zero address required");
        require(addr != address(1), "ecrecover address not allowed");
        selfdestruct(addr);
    }

    /**
     * @notice Gets the address of the owner.
     * @return the address of the owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @notice Indicates if the address specified is the owner of the resource.
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner(address addr) public view returns (bool) {
        return addr == _owner;
    }
}

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
interface IERC20 {
    /**
    * 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);

    /**
     * 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.
     * @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);

    /**
     * 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);

    /**
     * Returns the total number of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    function decimals() external view returns (uint8);
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);

    /**
    * Gets the balance of the address specified.
    * @param addr The address to query the balance of.
    * @return An uint256 representing the amount owned by the passed address.
    */
    function balanceOf(address addr) external view returns (uint256);

    /**
     * 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);

    /**
     * This event is triggered when a given amount of tokens is sent to an address.
     * @param from The address of the sender
     * @param to The address of the receiver
     * @param value The amount transferred
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * This event is triggered when a given address is approved to spend a specific amount of tokens
     * on behalf of the sender.
     * @param owner The owner of the token
     * @param spender The spender
     * @param value The amount to transfer
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

/**
 * @title Represents an ERC-20
 */
contract ERC20 is IERC20 {
    // Basic ERC-20 data
    string private _name;
    string private _symbol;
    uint8 private _decimals;
    uint256 internal _totalSupply;

    // The balance of each owner
    mapping(address => uint256) internal _balances;

    // The allowance set by each owner
    mapping(address => mapping(address => uint256)) private _allowances;

    /**
     * @notice Constructor
     * @param tokenName The name of the token
     * @param tokenSymbol The symbol of the token
     * @param tokenDecimals The decimals of the token
     * @param initialSupply The initial supply
     */
    constructor (string memory tokenName, string memory tokenSymbol, uint8 tokenDecimals, uint256 initialSupply) {
        _name = tokenName;
        _symbol = tokenSymbol;
        _decimals = tokenDecimals;
        _totalSupply = initialSupply;
    }

    /**
    * @notice Transfers a given amount tokens to the address specified.
    * @param from The address of the sender.
    * @param to The address to transfer to.
    * @param value The amount to be transferred.
    * @return Returns true in case of success.
    */
    function executeErc20Transfer (address from, address to, uint256 value) private returns (bool) {
        // Checks
        require(to != address(0), "non-zero address required");
        require(from != address(0), "non-zero sender required");
        require(value > 0, "Amount cannot be zero");
        require(_balances[from] >= value, "Amount exceeds sender balance");

        // State changes
        _balances[from] = _balances[from] - value;
        _balances[to] = _balances[to] + value;

        // Emit the event per ERC-20
        emit Transfer(from, to, value);

        return true;
    }

    /**
     * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
     * @dev 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 ownerAddr The address of the owner.
     * @param spender The address which will spend the funds.
     * @param value The amount of tokens to be spent.
     * @return Returns true in case of success.
     */
    function approveSpender(address ownerAddr, address spender, uint256 value) private returns (bool) {
        require(spender != address(0), "non-zero spender required");
        require(ownerAddr != address(0), "non-zero owner required");

        // State changes
        _allowances[ownerAddr][spender] = value;

        // Emit the event
        emit Approval(ownerAddr, spender, value);

        return true;
    }

    /**
    * @notice Transfers a given amount tokens to the address specified.
    * @param to The address to transfer to.
    * @param value The amount to be transferred.
    * @return Returns true in case of success.
    */
    function transfer(address to, uint256 value) public override returns (bool) {
        require (executeErc20Transfer(msg.sender, to, value), "Failed to execute ERC20 transfer");
        return true;
    }

    /**
     * @notice Transfer tokens from one address to another.
     * @dev 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.
     * @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
     * @return Returns true in case of success.
     */
    function transferFrom(address from, address to, uint256 value) public override returns (bool) {
        require (executeErc20Transfer(from, to, value), "Failed to execute transferFrom");

        uint256 currentAllowance = _allowances[from][msg.sender];
        require(currentAllowance >= value, "Amount exceeds allowance");

        require(approveSpender(from, msg.sender, currentAllowance - value), "ERC20: Approval failed");

        return true;
    }

    /**
     * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
     * @dev 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.
     * @return Returns true in case of success.
     */
    function approve(address spender, uint256 value) public override returns (bool) {
        require(approveSpender(msg.sender, spender, value), "ERC20: Approval failed");
        return true;
    }

    /**
     * Gets the total supply of tokens
     */
    function totalSupply() public view override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @notice Gets the name of the token.
     */
    function name() public view override returns (string memory) {
        return _name;
    }

    /**
     * @notice Gets the symbol of the token.
     */
    function symbol() public view override returns (string memory) {
        return _symbol;
    }

    /**
     * @notice Gets the decimals of the token.
     */
    function decimals() public view override returns (uint8) {
        return _decimals;
    }

    /**
    * Gets the balance of the address specified.
    * @param addr The address to query the balance of.
    * @return An uint256 representing the amount owned by the passed address.
    */
    function balanceOf(address addr) public view override returns (uint256) {
        return _balances[addr];
    }

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

/**
 * @notice Represents an ERC20 that can be minted and/or burnt by multiple parties.
 */
contract Mintable is ERC20, Ownable {
    /**
     * @notice The maximum circulating supply of tokens
     */
    uint256 public maxSupply;

    // Keeps track of the authorized minters
    mapping (address => bool) internal _authorizedMinters;

    // Keeps track of the authorized burners
    mapping (address => bool) internal _authorizedBurners;

    // ---------------------------------------
    // Events
    // ---------------------------------------
    /**
     * This event is triggered whenever an address is added as a valid minter.
     * @param addr The address that became a valid minter
     */
    event OnMinterGranted(address addr);

    /**
     * This event is triggered when a minter is revoked.
     * @param addr The address that was revoked
     */
    event OnMinterRevoked(address addr);

    /**
     * This event is triggered whenever an address is added as a valid burner.
     * @param addr The address that became a valid burner
     */
    event OnBurnerGranted(address addr);

    /**
     * This event is triggered when a burner is revoked.
     * @param addr The address that was revoked
     */
    event OnBurnerRevoked(address addr);

    /**
     * This event is triggered when the maximum limit for minting tokens is updated.
     * @param prevValue The previous limit
     * @param newValue The new limit
     */
    event OnMaxSupplyChanged(uint256 prevValue, uint256 newValue);

    // ---------------------------------------
    // Constructor
    // ---------------------------------------
    /**
     * @notice Constructor
     * @param newOwner The contract owner
     * @param tokenName The name of the token
     * @param tokenSymbol The symbol of the token
     * @param tokenDecimals The decimals of the token
     * @param initialSupply The initial supply
     */
    constructor (address newOwner, string memory tokenName, string memory tokenSymbol, uint8 tokenDecimals, uint256 initialSupply)
    ERC20(tokenName, tokenSymbol, tokenDecimals, initialSupply)
    Ownable(newOwner) { // solhint-disable-line no-empty-blocks
    }

    /**
     * @notice Throws if the sender is not a valid minter
     */
    modifier onlyMinter() {
        require(_authorizedMinters[msg.sender], "Unauthorized minter");
        _;
    }

    /**
     * @notice Throws if the sender is not a valid burner
     */
    modifier onlyBurner() {
        require(_authorizedBurners[msg.sender], "Unauthorized burner");
        _;
    }

    /**
     * @notice Grants the right to issue new tokens to the address specified.
     * @dev This function can be called by the owner only.
     * @param addr The destination address
     */
    function grantMinter (address addr) public onlyOwner {
        require(!_authorizedMinters[addr], "Address authorized already");
        _authorizedMinters[addr] = true;
        emit OnMinterGranted(addr);
    }

    /**
     * @notice Revokes the right to issue new tokens from the address specified.
     * @dev This function can be called by the owner only.
     * @param addr The destination address
     */
    function revokeMinter (address addr) public onlyOwner {
        require(_authorizedMinters[addr], "Address was never authorized");
        _authorizedMinters[addr] = false;
        emit OnMinterRevoked(addr);
    }

    /**
     * @notice Grants the right to burn tokens to the address specified.
     * @dev This function can be called by the owner only.
     * @param addr The destination address
     */
    function grantBurner (address addr) public onlyOwner {
        require(!_authorizedBurners[addr], "Address authorized already");
        _authorizedBurners[addr] = true;
        emit OnBurnerGranted(addr);
    }

    /**
     * @notice Revokes the right to burn tokens from the address specified.
     * @dev This function can be called by the owner only.
     * @param addr The destination address
     */
    function revokeBurner (address addr) public onlyOwner {
        require(_authorizedBurners[addr], "Address was never authorized");
        _authorizedBurners[addr] = false;
        emit OnBurnerRevoked(addr);
    }

    /**
     * @notice Updates the maximum limit for minting tokens.
     * @param newValue The new limit
     */
    function changeMaxSupply (uint256 newValue) public onlyOwner {
        require(newValue == 0 || newValue > _totalSupply, "Invalid max supply");
        emit OnMaxSupplyChanged(maxSupply, newValue);
        maxSupply = newValue;
    }

    /**
     * @notice Issues a given number of tokens to the address specified.
     * @dev This function throws if the sender is not a whitelisted minter.
     * @param addr The destination address
     * @param amount The number of tokens
     */
    function mint (address addr, uint256 amount) public onlyMinter {
        require(addr != address(0) && addr != address(this), "Invalid address");
        require(amount > 0, "Invalid amount");
        require(canMint(amount), "Max token supply exceeded");

        _totalSupply += amount;
        _balances[addr] += amount;
        emit Transfer(address(0), addr, amount);
    }

    /**
     * @notice Burns a given number of tokens from the address specified.
     * @dev This function throws if the sender is not a whitelisted minter. In this context, minters and burners have the same privileges.
     * @param addr The destination address
     * @param amount The number of tokens
     */
    function burn (address addr, uint256 amount) public onlyBurner {
        require(addr != address(0) && addr != address(this), "Invalid address");
        require(amount > 0, "Invalid amount");
        require(_totalSupply > 0, "No token supply");

        uint256 accountBalance = _balances[addr];
        require(accountBalance >= amount, "Burn amount exceeds balance");

        _balances[addr] = accountBalance - amount;
        _totalSupply -= amount;
        emit Transfer(addr, address(0), amount);
    }

    /**
     * @notice Indicates if we can issue/mint the number of tokens specified.
     * @param amount The number of tokens to issue/mint
     */
    function canMint (uint256 amount) public view returns (bool) {
        return (maxSupply == 0) || (_totalSupply + amount <= maxSupply);
    }
}

/**
 * @title Represents a controllable resource.
 */
contract Controllable is Ownable {
    // The address of the controller
    address internal _controllerAddress;

    /**
     * @notice Constructor
     * @param ownerAddr The owner of the smart contract
     * @param controllerAddr The address of the controller
     */
    constructor (address ownerAddr, address controllerAddr) Ownable (ownerAddr) {
        require(controllerAddr != address(0), "Controller address required");
        require(controllerAddr != ownerAddr, "Owner cannot be the Controller");
        _controllerAddress = controllerAddr;
    }

    /**
     * @notice Throws if the sender is not the controller
     */
    modifier onlyController() {
        require(msg.sender == _controllerAddress, "Unauthorized controller");
        _;
    }

    /**
     * @notice Makes sure the sender is either the owner of the contract or the controller
     */
    modifier onlyOwnerOrController() {
        require(msg.sender == _controllerAddress || msg.sender == _owner, "Only owner or controller");
        _;
    }

    /**
     * @notice Sets the controller
     * @dev This function can be called by the owner only
     * @param controllerAddr The address of the controller
     */
    function setController (address controllerAddr) public onlyOwner {
        // Checks
        require(controllerAddr != address(0), "Controller address required");
        require(controllerAddr != _owner, "Owner cannot be the Controller");
        require(controllerAddr != _controllerAddress, "Controller already set");

        // State changes
        _controllerAddress = controllerAddr;
    }

    /**
     * @notice Gets the address of the controller
     * @return Returns an address
     */
    function getControllerAddress () public view returns (address) {
        return _controllerAddress;
    }
}


/**
 * @title Represents a receipt token. The token is fully compliant with the ERC20 interface.
 * @dev The token can be minted or burnt by whitelisted addresses only. Only the owner is allowed to enable/disable addresses.
 */
contract ReceiptToken is Mintable {
    /**
     * @notice Constructor.
     * @param newOwner The owner of the smart contract.
     */
    constructor (address newOwner, uint256 initialMaxSupply) Mintable(newOwner, "Fractal Protocol Vault Token", "USDF", 6, 0) {
        maxSupply = initialMaxSupply;
    }
}

/**
 * @notice This library provides stateless, general purpose functions.
 */
library Utils {
    /**
     * @notice Indicates if the address specified represents a smart contract.
     * @dev Notice that this method returns TRUE if the address is a contract under construction
     * @param addr The address to evaluate
     * @return Returns true if the address represents a smart contract
     */
    function isContract (address addr) internal view returns (bool) {
        bytes32 eoaHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;

        bytes32 codeHash;

        // solhint-disable-next-line no-inline-assembly
        assembly { codeHash := extcodehash(addr) }

        return (codeHash != eoaHash && codeHash != 0x0);
    }
}


library DateUtils {
    // The number of seconds per day
    uint256 internal constant SECONDS_PER_DAY = 24 * 60 * 60;

    // The number of seconds per hour
    uint256 internal constant SECONDS_PER_HOUR = 60 * 60;

    // The number of seconds per minute
    uint256 internal constant SECONDS_PER_MINUTE = 60;

    // The offset from 01/01/1970
    int256 internal constant OFFSET19700101 = 2440588;

    /**
     * @notice Gets the year of the timestamp specified.
     * @param timestamp The timestamp
     * @return year The year
     */
    function getYear (uint256 timestamp) internal pure returns (uint256 year) {
        (year,,) = _daysToDate(timestamp / SECONDS_PER_DAY);
    }

    /**
     * @notice Gets the timestamp of the date specified.
     * @param year The year
     * @param month The month
     * @param day The day
     * @param hour The hour
     * @param minute The minute
     * @param second The seconds
     * @return timestamp The timestamp
     */
    function timestampFromDateTime(uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second) internal pure returns (uint256 timestamp) {
        timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + hour * SECONDS_PER_HOUR + minute * SECONDS_PER_MINUTE + second;
    }

    /**
     * @notice Gets the number of days elapsed between the two timestamps specified.
     * @param fromTimestamp The source date
     * @param toTimestamp The target date
     * @return Returns the difference, in days
     */
    function diffDays (uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256) {
        require(fromTimestamp <= toTimestamp, "Invalid order for timestamps");
        return (toTimestamp - fromTimestamp) / SECONDS_PER_DAY;
    }

    /**
     * @notice Calculate year/month/day from the number of days since 1970/01/01 using the date conversion algorithm from http://aa.usno.navy.mil/faq/docs/JD_Formula.php and adding the offset 2440588 so that 1970/01/01 is day 0
     * @dev Taken from https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary/blob/master/contracts/BokkyPooBahsDateTimeLibrary.sol
     * @param _days The year
     * @return year The year
     * @return month The month
     * @return day The day
     */
    function _daysToDate (uint256 _days) internal pure returns (uint256 year, uint256 month, uint256 day) {
        int256 __days = int256(_days);

        int256 x = __days + 68569 + OFFSET19700101;
        int256 n = 4 * x / 146097;
        x = x - (146097 * n + 3) / 4;
        int256 _year = 4000 * (x + 1) / 1461001;
        x = x - 1461 * _year / 4 + 31;
        int256 _month = 80 * x / 2447;
        int256 _day = x - 2447 * _month / 80;
        x = _month / 11;
        _month = _month + 2 - 12 * x;
        _year = 100 * (n - 49) + _year + x;

        year = uint256(_year);
        month = uint256(_month);
        day = uint256(_day);
    }

    /**
     * @notice Calculates the number of days from 1970/01/01 to year/month/day using the date conversion algorithm from http://aa.usno.navy.mil/faq/docs/JD_Formula.php and subtracting the offset 2440588 so that 1970/01/01 is day 0
     * @dev Taken from https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary/blob/master/contracts/BokkyPooBahsDateTimeLibrary.sol
     * @param year The year
     * @param month The month
     * @param day The day
     * @return _days Returns the number of days
     */
    function _daysFromDate (uint256 year, uint256 month, uint256 day) internal pure returns (uint256 _days) {
        require(year >= 1970, "Error");
        int _year = int(year);
        int _month = int(month);
        int _day = int(day);

        int __days = _day
          - 32075
          + 1461 * (_year + 4800 + (_month - 14) / 12) / 4
          + 367 * (_month - 2 - (_month - 14) / 12 * 12) / 12
          - 3 * ((_year + 4900 + (_month - 14) / 12) / 100) / 4
          - OFFSET19700101;

        _days = uint256(__days);
    }
}

interface IDeployable {
    function deployCapital (uint256 deploymentAmount, bytes32 foreignNetwork) external;
    function claim (uint256 dailyInterestAmount) external;
}

/**
 * @title Represents a vault.
 */
contract Vault is Controllable {
    // The decimal multiplier of the receipt token
    uint256 private constant USDF_DECIMAL_MULTIPLIER = uint256(10) ** uint256(6);

    // Represents a record
    struct Record {
        uint8 apr;
        uint256 tokenPrice;
        uint256 totalDeposited;
        uint256 dailyInterest;
    }

    /**
     * @notice The timestamp that defines the start of the current year
     * @dev This is the unix epoch of January 1st of the current block's timestamp.
     */
    uint256 public startOfYearTimestamp;

    /**
     * @notice The current period. It is the zero-based day of the year, ranging from [0..364]
     * @dev Day zero represents January 1st (first day of the year) whereas day 364 represents December 31st (last day of the day)
     */
    uint256 public currentPeriod;

    /**
     * @notice The minimum amount you can deposit in the vault.
     */
    uint256 public minDepositAmount;

    /**
     * @notice The flat fee to apply to vault withdrawals.
     */
    uint256 public flatFeePercent;

    // The decimals multiplier of the underlying ERC20
    uint256 immutable private _decimalsMultiplier;

    // The decimals multiplier of the receipt token
    uint256 immutable private _decimalsMultiplierOfReceiptToken;

    /**
     * @notice The percentage of capital that needs to be invested. It ranges from [1..99]
     * @dev The investment percent is set to 90% by default
     */
    uint8 public investmentPercent = 90;

    // The reentrancy guard for deposits
    uint8 private _reentrancyMutexForDeposits;

    // The reentrancy guard for withdrawals
    uint8 private _reentrancyMutexForWithdrawals;

    /**
     * @notice The address of the yield reserve
     */
    address public yieldReserveAddress;

    /**
     * @notice The address that collects the applicable fees
     */
    address public feesAddress;

    /**
     * @notice The interface of the underlying token
     */
    IERC20 public immutable tokenInterface;

    // The receipt token. This is immutable so it cannot be altered after deployment.
    ReceiptToken private immutable _receiptToken;

    // The snapshots history
    mapping (uint256 => Record) private _records;

    // ---------------------------------------
    // Events
    // ---------------------------------------
    /**
     * @notice This event is fired when the vault receives a deposit.
     * @param tokenAddress Specifies the token address
     * @param fromAddress Specifies the address of the sender
     * @param depositAmount Specifies the deposit amount in USDC or the ERC20 handled by this contract
     * @param receiptTokensAmount Specifies the amount of receipt tokens issued to the user
     */
    event OnVaultDeposit (address tokenAddress, address fromAddress, uint256 depositAmount, uint256 receiptTokensAmount);

    /**
     * @notice This event is fired when a user withdraws funds from the vault.
     * @param tokenAddress Specifies the token address
     * @param toAddress Specifies the address of the recipient
     * @param erc20Amount Specifies the amount in USDC or the ERC20 handled by this contract
     * @param receiptTokensAmount Specifies the amount of receipt tokens withdrawn by the user
     * @param fee Specifies the withdrawal fee
     */
    event OnVaultWithdrawal (address tokenAddress, address toAddress, uint256 erc20Amount, uint256 receiptTokensAmount, uint256 fee);

    // ---------------------------------------
    // Constructor
    // ---------------------------------------
    constructor (
        address ownerAddr, 
        address controllerAddr, 
        ReceiptToken receiptTokenInterface, 
        IERC20 eip20Interface, 
        uint8 initialApr, 
        uint256 initialTokenPrice, 
        uint256 initialMinDepositAmount,
        uint256 flatFeePerc,
        address feesAddr) 
    Controllable (ownerAddr, controllerAddr) {
        // Checks
        require(initialMinDepositAmount > 0, "Invalid min deposit amount");
        require(feesAddr != address(0), "Invalid address for fees");

        // State changes
        tokenInterface = eip20Interface;
        _receiptToken = receiptTokenInterface;
        minDepositAmount = initialMinDepositAmount;
        _decimalsMultiplier = uint256(10) ** uint256(eip20Interface.decimals());
        _decimalsMultiplierOfReceiptToken = uint256(10) ** uint256(receiptTokenInterface.decimals());

        uint256 currentTimestamp = block.timestamp; // solhint-disable-line not-rely-on-time

        // Get the current year
        uint256 currentYear = DateUtils.getYear(currentTimestamp);

        // Set the timestamp of January 1st of the current year (the year starts at this unix epoch)
        startOfYearTimestamp = DateUtils.timestampFromDateTime(currentYear, 1, 1, 0, 0, 0);

        // Create the first record
        currentPeriod = DateUtils.diffDays(startOfYearTimestamp, currentTimestamp);
        
        _records[currentPeriod] = Record(initialApr, initialTokenPrice, 0, 0);

        flatFeePercent = flatFeePerc;
        feesAddress = feesAddr;
    }

    // ---------------------------------------
    // Modifiers
    // ---------------------------------------
    /**
     * @notice Throws if there is a deposit in progress
     */
    modifier ifNotReentrantDeposit() {
        require(_reentrancyMutexForDeposits == 0, "Reentrant deposit rejected");
        _;
    }

    /**
     * @notice Throws if there is a withdrawal in progress
     */
    modifier ifNotReentrantWithdrawal() {
        require(_reentrancyMutexForWithdrawals == 0, "Reentrant withdrawal rejected");
        _;
    }

    // ---------------------------------------
    // Functions
    // ---------------------------------------
    /**
     * @notice Sets the address of the bridge
     * @dev This function can be called by the owner or the controller.
     * @param addr The address of the bridge
     */
    function setYieldReserveAddress (address addr) public onlyOwnerOrController {
        require(addr != address(0) && addr != address(this), "Invalid address");
        require(Utils.isContract(addr), "The address must be a contract");

        yieldReserveAddress = addr;
    }

    /**
     * @notice Sets the minimum amount for deposits.
     * @dev This function can be called by the owner or the controller.
     * @param minAmount The minimum deposit amount
     */
    function setMinDepositAmount (uint256 minAmount) public onlyOwnerOrController {
        // Checks
        require(minAmount > 0, "Invalid minimum deposit amount");

        // State changes
        minDepositAmount = minAmount;
    }

    /**
     * @notice Sets a new flat fee for withdrawals.
     * @dev The new fee is allowed to be zero (aka: no fees).
     * @param newFeeWithMultiplier The new fee, which is expressed per decimals precision of the underlying token (say USDC for example)
     */
    function setFlatWithdrawalFee (uint256 newFeeWithMultiplier) public onlyOwnerOrController {
        // Example for USDC (6 decimal places):
        // Say the fee is: 0.03%
        // Thus the fee amount is: 0.03 * _decimalsMultiplier = 30000 = 0.03 * (10 to the power of 6)
        flatFeePercent = newFeeWithMultiplier;
    }

    /**
     * @notice Sets the address for collecting fees.
     * @param addr The address
     */
    function setFeeAddress (address addr) public onlyOwnerOrController {
        require(addr != address(0) && addr != feesAddress, "Invalid address for fees");
        feesAddress = addr;
    }

    /**
     * @notice Deposits funds in the vault. The caller gets the respective amount of receipt tokens in exchange for their deposit.
     * @dev The number of receipt tokens is calculated based on the current token price.
     * @param depositAmount Specifies the deposit amount
     */
    function deposit (uint256 depositAmount) public ifNotReentrantDeposit {
        // Make sure the deposit amount falls within the expected range
        require(depositAmount >= minDepositAmount, "Minimum deposit amount not met");

        // Wake up the reentrancy guard
        _reentrancyMutexForDeposits = 1;

        // Refresh the current timelime, if needed
        compute();

        // The transaction sender. Presumably it is also the legitimate depositor. Otherwise it is a relayer.
        address senderAddr = msg.sender;

        // Make sure the sender can cover the deposit (aka: has enough USDC/ERC20 on their wallet)
        require(tokenInterface.balanceOf(senderAddr) >= depositAmount, "Insufficient funds");

        // Make sure the user approved this contract to spend the amount specified
        require(tokenInterface.allowance(senderAddr, address(this)) >= depositAmount, "Insufficient allowance");

        // Determine how many tokens can be issued/minted to the destination address
        uint256 numberOfReceiptTokens = depositAmount * _decimalsMultiplierOfReceiptToken / _records[currentPeriod].tokenPrice;

        // Make sure we can issue the number of tokens specified, per limits
        require(_receiptToken.canMint(numberOfReceiptTokens), "Token supply limit exceeded");

        _records[currentPeriod].totalDeposited += depositAmount;

        // Get the current balance of this contract in USDC (or whatever the ERC20 is, which defined at deployment time)
        uint256 balanceBeforeTransfer = tokenInterface.balanceOf(address(this));

        // Make sure the ERC20 transfer succeeded
        require(tokenInterface.transferFrom(senderAddr, address(this), depositAmount), "Token transfer failed");

        // The new balance of this contract, after the transfer
        uint256 newBalance = tokenInterface.balanceOf(address(this));

        // At the very least, the new balance should be the previous balance + the deposit.
        require(newBalance >= balanceBeforeTransfer + depositAmount, "Balance verification failed");

        // Issue/mint the respective number of tokens. Users get a receipt token in exchange for their deposit in USDC/ERC20.
        _receiptToken.mint(senderAddr, numberOfReceiptTokens);

        // Emit a new "deposit" event
        emit OnVaultDeposit(address(tokenInterface), senderAddr, depositAmount, numberOfReceiptTokens);

        // Reset the reentrancy guard
        _reentrancyMutexForDeposits = 0;
    }

    /**
     * @notice Withdraws a specific amount of tokens from the Vault.
     * @param receiptTokenAmount The number of tokens to withdraw from the vault
     */
    function withdraw (uint256 receiptTokenAmount) public ifNotReentrantWithdrawal {
        // Checks
        require(receiptTokenAmount > 0, "Invalid withdrawal amount");

        // Wake up the reentrancy guard
        _reentrancyMutexForWithdrawals = 1;

        address senderAddr = msg.sender;

        // Refresh the current timelime, if needed
        compute();

        // Make sure the sender has enough receipt tokens to burn
        require(_receiptToken.balanceOf(senderAddr) >= receiptTokenAmount, "Insufficient balance of tokens");

        // The amount of USDC you get in exchange, at the current token price
        uint256 withdrawalAmount = toErc20Amount(receiptTokenAmount);
        require(withdrawalAmount <= _records[currentPeriod].totalDeposited, "Invalid withdrawal amount");

        uint256 maxWithdrawalAmount = getMaxWithdrawalAmount();
        require(withdrawalAmount <= maxWithdrawalAmount, "Max withdrawal amount exceeded");

        uint256 currentBalance = tokenInterface.balanceOf(address(this));
        require(currentBalance > withdrawalAmount, "Insufficient funds in the buffer");

        // Notice that the fee is applied in the underlying currency instead of receipt tokens.
        // The amount applicable to the fee
        uint256 feeAmount = (flatFeePercent > 0) ? withdrawalAmount * flatFeePercent / uint256(100) / _decimalsMultiplier : 0;
        require(feeAmount < withdrawalAmount, "Invalid fee");

        // The amount to send to the destination address (recipient), after applying the fee
        uint256 withdrawalAmountAfterFees = withdrawalAmount - feeAmount;

        // Update the record per amount withdrawn, with no applicable fees.
        // A common mistake would be update the metric below with fees included. DONT DO THAT.
        _records[currentPeriod].totalDeposited -= withdrawalAmount;

        // Burn the number of receipt tokens specified
        _receiptToken.burn(senderAddr, receiptTokenAmount);

        // Transfer the respective amount of underlying tokens to the sender (after applying the fee)
        require(tokenInterface.transfer(senderAddr, withdrawalAmountAfterFees), "Token transfer failed");

        if (feeAmount > 0) {
            // Transfer the applicable fee, if any
            require(tokenInterface.transfer(feesAddress, feeAmount), "Fee transfer failed");
        }

        // Emit a new "withdrawal" event
        emit OnVaultWithdrawal(address(tokenInterface), senderAddr, withdrawalAmount, receiptTokenAmount, feeAmount);

        // Reset the reentrancy guard
        _reentrancyMutexForWithdrawals = 0; // solhint-disable-line reentrancy
    }

    /**
     * @notice Runs an emergency withdrawal. Sends the whole balance to the address specified.
     * @dev This function can be called by the owner only.
     * @param destinationAddr The destination address
     */
    function emergencyWithdraw (address destinationAddr) public onlyOwner ifNotReentrantWithdrawal {
        require(destinationAddr != address(0) && destinationAddr != address(this), "Invalid address");

        // Wake up the reentrancy guard
        _reentrancyMutexForWithdrawals = 1;

        uint256 currentBalance = tokenInterface.balanceOf(address(this));
        require(currentBalance > 0, "The vault has no funds");

        // Transfer all funds to the address specified
        require(tokenInterface.transfer(destinationAddr, currentBalance), "Token transfer failed");

        // Reset the reentrancy guard
        _reentrancyMutexForWithdrawals = 0; // solhint-disable-line reentrancy
    }

    /**
     * @notice Updates the APR
     * @param newApr The new APR
     */
    function changeApr (uint8 newApr) public onlyOwner {
        require(newApr > 0, "Invalid APR");

        compute();
        _records[currentPeriod].apr = newApr;
    }

    /**
     * @notice Sets the token price, arbitrarily.
     * @param newTokenPrice The new price of the receipt token
     */
    function setTokenPrice (uint256 newTokenPrice) public onlyOwner {
        require(newTokenPrice > 0, "Invalid token price");

        compute();
        _records[currentPeriod].tokenPrice = newTokenPrice;
    }

    /**
     * @notice Sets the investment percent.
     * @param newPercent The new investment percent
     */
    function setInvestmentPercent (uint8 newPercent) public onlyOwnerOrController {
        require(newPercent > 0 && newPercent < 100, "Invalid investment percent");
        investmentPercent = newPercent;
    }

    /**
     * @notice Computes the metrics (token price, daily interest) for the current day of year
     */
    function compute () public {
        uint256 currentTimestamp = block.timestamp; // solhint-disable-line not-rely-on-time

        uint256 newPeriod = DateUtils.diffDays(startOfYearTimestamp, currentTimestamp);
        if (newPeriod <= currentPeriod) return;

        uint256 x = 0;

        for (uint256 i = currentPeriod + 1; i <= newPeriod; i++) {
            x++;
            _records[i].apr = _records[i - 1].apr;
            _records[i].totalDeposited = _records[i - 1].totalDeposited;

            uint256 diff = uint256(_records[i - 1].apr) * USDF_DECIMAL_MULTIPLIER * uint256(100) / uint256(365);
            _records[i].tokenPrice = _records[i - 1].tokenPrice + (diff / uint256(10000));
            _records[i].dailyInterest = _records[i - 1].totalDeposited * uint256(_records[i - 1].apr) / uint256(365) / uint256(100);
            if (x >= 30) break;
        }

        currentPeriod += x;
    }

    /**
     * @notice Moves the deployable capital from the vault to the yield reserve
     */
    function lockCapital () public onlyOwnerOrController {
        compute();

        // Get the maximum amount of capital that can be deployed at this point in time
        uint256 maxDeployableAmount = getDeployableCapital();
        require(maxDeployableAmount > 0, "Invalid deployable capital");

        require(tokenInterface.transfer(yieldReserveAddress, maxDeployableAmount), "Transfer failed");
    }

    /**
     * @notice Claims the daily interest promised per APR.
     */
    function claimDailyInterest () public onlyOwnerOrController {
        compute();

        // Get the daily interest that need to be claimed at this point in time
        uint256 dailyInterestAmount = getDailyInterest();

        uint256 balanceBefore = tokenInterface.balanceOf(address(this));

        IDeployable(yieldReserveAddress).claim(dailyInterestAmount);

        uint256 balanceAfter = tokenInterface.balanceOf(address(this));

        require(balanceAfter >= balanceBefore + dailyInterestAmount, "Balance verification failed");
    }

    /**
     * @notice Gets the period of the current unix epoch.
     * @dev The period is the zero-based day of the current year. It is the number of days that elapsed since January 1st of the current year.
     * @return Returns a number between [0..364]
     */
    function getPeriodOfCurrentEpoch () public view returns (uint256) {
        return DateUtils.diffDays(startOfYearTimestamp, block.timestamp); // solhint-disable-line not-rely-on-time
    }

    function getSnapshot (uint256 i) public view returns (uint8 apr, uint256 tokenPrice, uint256 totalDeposited, uint256 dailyInterest) {
        apr = _records[i].apr;
        tokenPrice = _records[i].tokenPrice;
        totalDeposited = _records[i].totalDeposited;
        dailyInterest = _records[i].dailyInterest;
    }

    /**
     * @notice Gets the total amount deposited in the vault
     * @return The total amount deposited
     */
    function getTotalDeposited () public view returns (uint256) {
        return _records[currentPeriod].totalDeposited;
    }

    /**
     * @notice Gets the daily interest
     * @return The daily interest
     */
    function getDailyInterest () public view returns (uint256) {
        return _records[currentPeriod].dailyInterest;
    }

    /**
     * @notice Gets the current token price
     * @return The price of the token
     */
    function getTokenPrice () public view returns (uint256) {
        return _records[currentPeriod].tokenPrice;
    }

    /**
     * @notice Gets the maximum amount of USDC/ERC20 you can withdraw from the vault
     * @return The maximum withdrawal amount
     */
    function getMaxWithdrawalAmount () public view returns (uint256) {
        return _records[currentPeriod].totalDeposited * (uint256(100) - uint256(investmentPercent)) / uint256(100);
    }

    /**
     * @notice Gets the amount of capital that can be deployed.
     * @return The amount of deployable capital
     */
    function getDeployableCapital () public view returns (uint256) {
        return tokenInterface.balanceOf(address(this)) * uint256(investmentPercent) / uint256(100);
    }

    /**
     * @notice Returns the amount of USDC you would get by burning the number of receipt tokens specified, at the current price.
     * @return The amount of USDC you get in exchange, at the current token price
     */
    function toErc20Amount (uint256 receiptTokenAmount) public view returns (uint256) {
        return receiptTokenAmount * _records[currentPeriod].tokenPrice / _decimalsMultiplierOfReceiptToken;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"ownerAddr","type":"address"},{"internalType":"address","name":"controllerAddr","type":"address"},{"internalType":"contract ReceiptToken","name":"receiptTokenInterface","type":"address"},{"internalType":"contract IERC20","name":"eip20Interface","type":"address"},{"internalType":"uint8","name":"initialApr","type":"uint8"},{"internalType":"uint256","name":"initialTokenPrice","type":"uint256"},{"internalType":"uint256","name":"initialMinDepositAmount","type":"uint256"},{"internalType":"uint256","name":"flatFeePerc","type":"uint256"},{"internalType":"address","name":"feesAddr","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"depositAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"receiptTokensAmount","type":"uint256"}],"name":"OnVaultDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"receiptTokensAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"OnVaultWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"uint8","name":"newApr","type":"uint8"}],"name":"changeApr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimDailyInterest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"compute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"depositAmount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"addr","type":"address"}],"name":"destroy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"destinationAddr","type":"address"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feesAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flatFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getControllerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDailyInterest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDeployableCapital","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxWithdrawalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPeriodOfCurrentEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"}],"name":"getSnapshot","outputs":[{"internalType":"uint8","name":"apr","type":"uint8"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"uint256","name":"totalDeposited","type":"uint256"},{"internalType":"uint256","name":"dailyInterest","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"investmentPercent","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockCapital","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minDepositAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"controllerAddr","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFeeWithMultiplier","type":"uint256"}],"name":"setFlatWithdrawalFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"newPercent","type":"uint8"}],"name":"setInvestmentPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minAmount","type":"uint256"}],"name":"setMinDepositAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newTokenPrice","type":"uint256"}],"name":"setTokenPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setYieldReserveAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startOfYearTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"receiptTokenAmount","type":"uint256"}],"name":"toErc20Amount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenInterface","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"receiptTokenAmount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"yieldReserveAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

6101006040526006805460ff1916605a1790553480156200001f57600080fd5b5060405162003bb338038062003bb3833981016040819052620000429162000961565b8888816001600160a01b038116620000a15760405162461bcd60e51b815260206004820152601960248201527f6e6f6e2d7a65726f20616464726573732072657175697265640000000000000060448201526064015b60405180910390fd5b6001600160a01b03811660011415620000fd5760405162461bcd60e51b815260206004820152601d60248201527f65637265636f7665722061646472657373206e6f7420616c6c6f776564000000604482015260640162000098565b600080546001600160a01b0319166001600160a01b03831690811782556040805192835260208301919091527f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0910160405180910390a1506001600160a01b038116620001ad5760405162461bcd60e51b815260206004820152601b60248201527f436f6e74726f6c6c657220616464726573732072657175697265640000000000604482015260640162000098565b816001600160a01b0316816001600160a01b03161415620002115760405162461bcd60e51b815260206004820152601e60248201527f4f776e65722063616e6e6f742062652074686520436f6e74726f6c6c65720000604482015260640162000098565b600180546001600160a01b0319166001600160a01b03929092169190911790555082620002815760405162461bcd60e51b815260206004820152601a60248201527f496e76616c6964206d696e206465706f73697420616d6f756e74000000000000604482015260640162000098565b6001600160a01b038116620002d95760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964206164647265737320666f7220666565730000000000000000604482015260640162000098565b6001600160601b0319606087811b821660c05288901b1660e05260048381556040805163313ce56760e01b815290516001600160a01b0389169263313ce56792808201926020929091829003018186803b1580156200033757600080fd5b505afa1580156200034c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000372919062000a0f565b620003829060ff16600a62000b26565b60808181525050866001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015620003c357600080fd5b505afa158015620003d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003fe919062000a0f565b6200040e9060ff16600a62000b26565b60a0524260006200042b82620004fd602090811b6200252317901c565b90506200044b8160018060008060006200052160201b620025431760201c565b6002819055506200046a600254836200058b60201b6200259f1760201c565b60038181556040805160808101825260ff9a8b16815260208082019a8b526000828401818152606084018281529682526008909252929092209051815460ff19169b169a909a178a55975160018a015596516002890155519690950195909555600591909155600780546001600160a01b0319166001600160a01b039092169190911790555062000d6395505050505050565b60006200051862000512620151808462000ac2565b62000602565b50909392505050565b60008162000531603c8562000c9d565b6200053f610e108762000c9d565b62015180620005508b8b8b620007ae565b6200055c919062000c9d565b62000568919062000a73565b62000574919062000a73565b62000580919062000a73565b979650505050505050565b600081831115620005df5760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f7264657220666f722074696d657374616d707300000000604482015260640162000098565b62015180620005ef848462000d04565b620005fb919062000ac2565b9392505050565b60008080838162253d8c6200061b8362010bd962000a2c565b62000627919062000a2c565b9050600062023ab16200063c83600462000c0e565b62000648919062000a8e565b905060046200065b8262023ab162000c0e565b6200066890600362000a2c565b62000674919062000a8e565b62000680908362000cbf565b9150600062164b096200069584600162000a2c565b620006a390610fa062000c0e565b620006af919062000a8e565b90506004620006c1826105b562000c0e565b620006cd919062000a8e565b620006d9908462000cbf565b620006e690601f62000a2c565b9250600061098f620006fa85605062000c0e565b62000706919062000a8e565b9050600060506200071a8361098f62000c0e565b62000726919062000a8e565b62000732908662000cbf565b905062000741600b8362000a8e565b94506200075085600c62000c0e565b6200075d83600262000a2c565b62000769919062000cbf565b915084836200077a60318762000cbf565b6200078790606462000c0e565b62000793919062000a2c565b6200079f919062000a2c565b9a919950975095505050505050565b60006107b2841015620007ec5760405162461bcd60e51b815260206004820152600560248201526422b93937b960d91b604482015260640162000098565b838383600062253d8c60046064600c62000808600e8862000cbf565b62000814919062000a8e565b620008228861132462000a2c565b6200082e919062000a2c565b6200083a919062000a8e565b6200084790600362000c0e565b62000853919062000a8e565b600c8062000863600e8862000cbf565b6200086f919062000a8e565b6200087c90600c62000c0e565b6200088960028862000cbf565b62000895919062000cbf565b620008a39061016f62000c0e565b620008af919062000a8e565b6004600c620008c0600e8962000cbf565b620008cc919062000a8e565b620008da896112c062000a2c565b620008e6919062000a2c565b620008f4906105b562000c0e565b62000900919062000a8e565b6200090e617d4b8762000cbf565b6200091a919062000a2c565b62000926919062000a2c565b62000932919062000cbf565b6200093e919062000cbf565b98975050505050505050565b805160ff811681146200095c57600080fd5b919050565b60008060008060008060008060006101208a8c03121562000980578485fd5b89516200098d8162000d4a565b60208b0151909950620009a08162000d4a565b60408b0151909850620009b38162000d4a565b60608b0151909750620009c68162000d4a565b9550620009d660808b016200094a565b945060a08a0151935060c08a0151925060e08a015191506101008a0151620009fe8162000d4a565b809150509295985092959850929598565b60006020828403121562000a21578081fd5b620005fb826200094a565b600080821280156001600160ff1b038490038513161562000a515762000a5162000d1e565b600160ff1b839003841281161562000a6d5762000a6d62000d1e565b50500190565b6000821982111562000a895762000a8962000d1e565b500190565b60008262000aa05762000aa062000d34565b600160ff1b82146000198414161562000abd5762000abd62000d1e565b500590565b60008262000ad45762000ad462000d34565b500490565b80825b600180861162000aed575062000b1d565b81870482111562000b025762000b0262000d1e565b8086161562000b1057918102915b9490941c93800262000adc565b94509492505050565b6000620005fb600019848460008262000b4257506001620005fb565b8162000b5157506000620005fb565b816001811462000b6a576002811462000b755762000ba9565b6001915050620005fb565b60ff84111562000b895762000b8962000d1e565b6001841b91508482111562000ba25762000ba262000d1e565b50620005fb565b5060208310610133831016604e8410600b841016171562000be1575081810a8381111562000bdb5762000bdb62000d1e565b620005fb565b62000bf0848484600162000ad9565b80860482111562000c055762000c0562000d1e565b02949350505050565b60006001600160ff1b038184138284138082168684048611161562000c375762000c3762000d1e565b600160ff1b8487128281168783058912161562000c585762000c5862000d1e565b85871292508782058712848416161562000c765762000c7662000d1e565b8785058712818416161562000c8f5762000c8f62000d1e565b505050929093029392505050565b600081600019048311821515161562000cba5762000cba62000d1e565b500290565b60008083128015600160ff1b85018412161562000ce05762000ce062000d1e565b6001600160ff1b038401831381161562000cfe5762000cfe62000d1e565b50500390565b60008282101562000d195762000d1962000d1e565b500390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6001600160a01b038116811462000d6057600080fd5b50565b60805160a05160c05160601c60e05160601c612d8462000e2f60003960008181610bea01528181610f6001528181611d8801526120fd0152600081816104e701528181610621015281816109b901528181610d9601528181610fe0015281816110a901528181611177015281816115170152818161160201528181611b7701528181611c6301528181611e9701528181611f4801528181611ffa0152818161216501528181612264015261235b01526000818161133b0152611d4001526000610e7d0152612d846000f3fe608060405234801561001057600080fd5b50600436106102105760003560e01c80636a61e5fc116101255780639ce7f670116100ad578063bced91171161007c578063bced9117146104b6578063c57380a2146104be578063f2fde38b146104cf578063f343d683146104e2578063f36932b71461050957610210565b80639ce7f6701461046e578063b508195014610476578063b68ef55914610489578063b6b55f25146104a357610210565b80638da5cb5b116100f45780638da5cb5b14610411578063919cfa211461042257806391dd75e71461043557806392eefe9b146104485780639c256eef1461045b57610210565b80636a61e5fc1461037a5780636ff1c9bc1461038d57806376f10ad0146103a05780638705fcd4146103fe57610210565b80632e1a7d4d116101a85780634378f0ec116101775780634378f0ec146103185780634b94f50e146103315780635798ef311461034b57806357e0bf941461035e578063645006ca1461037157610210565b80632e1a7d4d146102c25780632f54bf6e146102d55780633a621d371461030757806342c9b1d91461030f57610210565b80631a43c338116101e45780631a43c3381461026d578063292bbd32146102755780632a40eb72146102a75780632a80cda3146102af57610210565b8062f55d9d146102155780630301310b1461022a578063060406181461024e57806308b4a99414610265575b600080fd5b610228610223366004612928565b610512565b005b6006546102379060ff1681565b60405160ff90911681526020015b60405180910390f35b61025760035481565b604051908152602001610245565b6102576105fd565b6102286106bc565b60065461028f90630100000090046001600160a01b031681565b6040516001600160a01b039091168152602001610245565b6102286108e5565b6102286102bd366004612964565b610a76565b6102286102d0366004612964565b610b0a565b6102f76102e3366004612928565b6000546001600160a01b0390811691161490565b6040519015158152602001610245565b6102576111f7565b61025760025481565b6003805460009081526008602052604090200154610257565b600354600090815260086020526040902060010154610257565b610228610359366004612928565b611205565b61025761036c366004612964565b611324565b61025760045481565b610228610388366004612964565b611375565b61022861039b366004612928565b611404565b6103da6103ae366004612964565b600090815260086020526040902080546001820154600283015460039093015460ff9092169390929190565b6040805160ff90951685526020850193909352918301526060820152608001610245565b61022861040c366004612928565b6116aa565b6000546001600160a01b031661028f565b610228610430366004612964565b61177d565b60075461028f906001600160a01b031681565b610228610456366004612928565b6117c1565b610228610469366004612994565b611918565b6102576119cf565b610228610484366004612994565b611a04565b600354600090815260086020526040902060020154610257565b6102286104b1366004612964565b611a9c565b6102286121de565b6001546001600160a01b031661028f565b6102286104dd366004612928565b61243e565b61028f7f000000000000000000000000000000000000000000000000000000000000000081565b61025760055481565b6000546001600160a01b031633146105455760405162461bcd60e51b815260040161053c906129e4565b60405180910390fd5b6001600160a01b0381166105975760405162461bcd60e51b81526020600482015260196024820152781b9bdb8b5e995c9bc81859191c995cdcc81c995c5d5a5c9959603a1b604482015260640161053c565b6001600160a01b038116600114156105f15760405162461bcd60e51b815260206004820152601d60248201527f65637265636f7665722061646472657373206e6f7420616c6c6f776564000000604482015260640161053c565b806001600160a01b0316ff5b6006546040516370a0823160e01b815230600482015260009160649160ff909116907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561066b57600080fd5b505afa15801561067f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a3919061297c565b6106ad9190612c7d565b6106b79190612ad2565b905090565b600042905060006106cf6002548361259f565b905060035481116106e15750506108e3565b60008060035460016106f39190612a8c565b90505b8281116108c7578161070781612cf2565b925060089050600061071a600184612cdb565b81526020808201929092526040908101600090812054848252600893849052918120805460ff191660ff90931692909217909155610759600184612cdb565b8152602001908152602001600020600201546008600083815260200190815260200160002060020181905550600061016d60646006600a61079a9190612b2c565b600860006107a9600188612cdb565b81526020810191909152604001600020546107c7919060ff16612c7d565b6107d19190612c7d565b6107db9190612ad2565b90506107e961271082612ad2565b600860006107f8600186612cdb565b8152602001908152602001600020600101546108149190612a8c565b6000838152600860208190526040822060019081019390935560649261016d929061083f9087612cdb565b8152602081019190915260400160009081205460ff1690600890610864600188612cdb565b8152602001908152602001600020600201546108809190612c7d565b61088a9190612ad2565b6108949190612ad2565b600083815260086020526040902060030155601e83106108b457506108c7565b50806108bf81612cf2565b9150506106f6565b5080600360008282546108da9190612a8c565b90915550505050505b565b6001546001600160a01b031633148061090857506000546001600160a01b031633145b6109245760405162461bcd60e51b815260040161053c90612a14565b61092c6106bc565b60006109366105fd565b9050600081116109885760405162461bcd60e51b815260206004820152601a60248201527f496e76616c6964206465706c6f7961626c65206361706974616c000000000000604482015260640161053c565b60065460405163a9059cbb60e01b815263010000009091046001600160a01b039081166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b1580156109fd57600080fd5b505af1158015610a11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a359190612944565b610a735760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b604482015260640161053c565b50565b6001546001600160a01b0316331480610a9957506000546001600160a01b031633145b610ab55760405162461bcd60e51b815260040161053c90612a14565b60008111610b055760405162461bcd60e51b815260206004820152601e60248201527f496e76616c6964206d696e696d756d206465706f73697420616d6f756e740000604482015260640161053c565b600455565b60065462010000900460ff1615610b635760405162461bcd60e51b815260206004820152601d60248201527f5265656e7472616e74207769746864726177616c2072656a6563746564000000604482015260640161053c565b60008111610baf5760405162461bcd60e51b8152602060048201526019602482015278125b9d985b1a59081dda5d1a191c985dd85b08185b5bdd5b9d603a1b604482015260640161053c565b6006805462ff000019166201000017905533610bc96106bc565b6040516370a0823160e01b81526001600160a01b03828116600483015283917f0000000000000000000000000000000000000000000000000000000000000000909116906370a082319060240160206040518083038186803b158015610c2e57600080fd5b505afa158015610c42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c66919061297c565b1015610cb45760405162461bcd60e51b815260206004820152601e60248201527f496e73756666696369656e742062616c616e6365206f6620746f6b656e730000604482015260640161053c565b6000610cbf83611324565b600354600090815260086020526040902060020154909150811115610d225760405162461bcd60e51b8152602060048201526019602482015278125b9d985b1a59081dda5d1a191c985dd85b08185b5bdd5b9d603a1b604482015260640161053c565b6000610d2c6119cf565b905080821115610d7e5760405162461bcd60e51b815260206004820152601e60248201527f4d6178207769746864726177616c20616d6f756e742065786365656465640000604482015260640161053c565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015610de057600080fd5b505afa158015610df4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e18919061297c565b9050828111610e695760405162461bcd60e51b815260206004820181905260248201527f496e73756666696369656e742066756e647320696e2074686520627566666572604482015260640161053c565b60008060055411610e7b576000610ec0565b7f0000000000000000000000000000000000000000000000000000000000000000606460055486610eac9190612c7d565b610eb69190612ad2565b610ec09190612ad2565b9050838110610eff5760405162461bcd60e51b815260206004820152600b60248201526a496e76616c69642066656560a81b604482015260640161053c565b6000610f0b8286612cdb565b9050846008600060035481526020019081526020016000206002016000828254610f359190612cdb565b9091555050604051632770a7eb60e21b81526001600160a01b038781166004830152602482018990527f00000000000000000000000000000000000000000000000000000000000000001690639dc29fac90604401600060405180830381600087803b158015610fa457600080fd5b505af1158015610fb8573d6000803e3d6000fd5b505060405163a9059cbb60e01b81526001600160a01b038981166004830152602482018590527f000000000000000000000000000000000000000000000000000000000000000016925063a9059cbb9150604401602060405180830381600087803b15801561102657600080fd5b505af115801561103a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105e9190612944565b61107a5760405162461bcd60e51b815260040161053c906129b5565b81156111695760075460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018490527f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb90604401602060405180830381600087803b1580156110ef57600080fd5b505af1158015611103573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111279190612944565b6111695760405162461bcd60e51b8152602060048201526013602482015272119959481d1c985b9cd9995c8819985a5b1959606a1b604482015260640161053c565b604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682528816602082015290810186905260608101889052608081018390527f297b983b359127be0bb37e151a4fec683bc9012dd4d0ac96db47cfc17019c1e49060a00160405180910390a150506006805462ff0000191690555050505050565b60006106b76002544261259f565b6001546001600160a01b031633148061122857506000546001600160a01b031633145b6112445760405162461bcd60e51b815260040161053c90612a14565b6001600160a01b0381161580159061126557506001600160a01b0381163014155b6112a35760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640161053c565b6112ac81612610565b6112f85760405162461bcd60e51b815260206004820152601e60248201527f5468652061646472657373206d757374206265206120636f6e74726163740000604482015260640161053c565b600680546001600160a01b039092166301000000026301000000600160b81b0319909216919091179055565b6003546000908152600860205260408120600101547f0000000000000000000000000000000000000000000000000000000000000000906113659084612c7d565b61136f9190612ad2565b92915050565b6000546001600160a01b0316331461139f5760405162461bcd60e51b815260040161053c906129e4565b600081116113e55760405162461bcd60e51b8152602060048201526013602482015272496e76616c696420746f6b656e20707269636560681b604482015260640161053c565b6113ed6106bc565b600354600090815260086020526040902060010155565b6000546001600160a01b0316331461142e5760405162461bcd60e51b815260040161053c906129e4565b60065462010000900460ff16156114875760405162461bcd60e51b815260206004820152601d60248201527f5265656e7472616e74207769746864726177616c2072656a6563746564000000604482015260640161053c565b6001600160a01b038116158015906114a857506001600160a01b0381163014155b6114e65760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640161053c565b6006805462ff00001916620100001790556040516370a0823160e01b81523060048201526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b15801561155957600080fd5b505afa15801561156d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611591919061297c565b9050600081116115dc5760405162461bcd60e51b8152602060048201526016602482015275546865207661756c7420686173206e6f2066756e647360501b604482015260640161053c565b60405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b15801561164657600080fd5b505af115801561165a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167e9190612944565b61169a5760405162461bcd60e51b815260040161053c906129b5565b50506006805462ff000019169055565b6001546001600160a01b03163314806116cd57506000546001600160a01b031633145b6116e95760405162461bcd60e51b815260040161053c90612a14565b6001600160a01b0381161580159061170f57506007546001600160a01b03828116911614155b61175b5760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964206164647265737320666f7220666565730000000000000000604482015260640161053c565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314806117a057506000546001600160a01b031633145b6117bc5760405162461bcd60e51b815260040161053c90612a14565b600555565b6000546001600160a01b031633146117eb5760405162461bcd60e51b815260040161053c906129e4565b6001600160a01b0381166118415760405162461bcd60e51b815260206004820152601b60248201527f436f6e74726f6c6c657220616464726573732072657175697265640000000000604482015260640161053c565b6000546001600160a01b038281169116141561189f5760405162461bcd60e51b815260206004820152601e60248201527f4f776e65722063616e6e6f742062652074686520436f6e74726f6c6c65720000604482015260640161053c565b6001546001600160a01b03828116911614156118f65760405162461bcd60e51b815260206004820152601660248201527510dbdb9d1c9bdb1b195c88185b1c9958591e481cd95d60521b604482015260640161053c565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633148061193b57506000546001600160a01b031633145b6119575760405162461bcd60e51b815260040161053c90612a14565b60008160ff1611801561196d575060648160ff16105b6119b95760405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420696e766573746d656e742070657263656e74000000000000604482015260640161053c565b6006805460ff191660ff92909216919091179055565b6006546000906064906119e59060ff1682612cdb565b6003546000908152600860205260409020600201546106ad9190612c7d565b6000546001600160a01b03163314611a2e5760405162461bcd60e51b815260040161053c906129e4565b60008160ff1611611a6f5760405162461bcd60e51b815260206004820152600b60248201526a24b73b30b634b21020a82960a91b604482015260640161053c565b611a776106bc565b6003546000908152600860205260409020805460ff191660ff92909216919091179055565b600654610100900460ff1615611af45760405162461bcd60e51b815260206004820152601a60248201527f5265656e7472616e74206465706f7369742072656a6563746564000000000000604482015260640161053c565b600454811015611b465760405162461bcd60e51b815260206004820152601e60248201527f4d696e696d756d206465706f73697420616d6f756e74206e6f74206d65740000604482015260640161053c565b6006805461ff001916610100179055611b5d6106bc565b6040516370a0823160e01b815233600482018190529082907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015611bc157600080fd5b505afa158015611bd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf9919061297c565b1015611c3c5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b604482015260640161053c565b604051636eb1769f60e11b81526001600160a01b03828116600483015230602483015283917f00000000000000000000000000000000000000000000000000000000000000009091169063dd62ed3e9060440160206040518083038186803b158015611ca757600080fd5b505afa158015611cbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cdf919061297c565b1015611d265760405162461bcd60e51b8152602060048201526016602482015275496e73756666696369656e7420616c6c6f77616e636560501b604482015260640161053c565b600354600090815260086020526040812060010154611d657f000000000000000000000000000000000000000000000000000000000000000085612c7d565b611d6f9190612ad2565b604051635dd871a360e01b8152600481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635dd871a39060240160206040518083038186803b158015611dd257600080fd5b505afa158015611de6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0a9190612944565b611e565760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e20737570706c79206c696d69742065786365656465640000000000604482015260640161053c565b60035460009081526008602052604081206002018054859290611e7a908490612a8c565b90915550506040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015611ee157600080fd5b505afa158015611ef5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f19919061297c565b6040516323b872dd60e01b81526001600160a01b038581166004830152306024830152604482018790529192507f0000000000000000000000000000000000000000000000000000000000000000909116906323b872dd90606401602060405180830381600087803b158015611f8e57600080fd5b505af1158015611fa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc69190612944565b611fe25760405162461bcd60e51b815260040161053c906129b5565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561204457600080fd5b505afa158015612058573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207c919061297c565b90506120888583612a8c565b8110156120d75760405162461bcd60e51b815260206004820152601b60248201527f42616c616e636520766572696669636174696f6e206661696c65640000000000604482015260640161053c565b6040516340c10f1960e01b81526001600160a01b038581166004830152602482018590527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b15801561214157600080fd5b505af1158015612155573d6000803e3d6000fd5b5050604080516001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116825288166020820152908101889052606081018690527f6c6941772efad791f0e8f0ff7e3e76b52034604c1427fc1bbda4dbd3d2570fc69250608001905060405180910390a150506006805461ff0019169055505050565b6001546001600160a01b031633148061220157506000546001600160a01b031633145b61221d5760405162461bcd60e51b815260040161053c90612a14565b6122256106bc565b6000612241600380546000908152600860205260409020015490565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b1580156122a657600080fd5b505afa1580156122ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122de919061297c565b60065460405163379607f560e01b815260048101859052919250630100000090046001600160a01b03169063379607f590602401600060405180830381600087803b15801561232c57600080fd5b505af1158015612340573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691506370a082319060240160206040518083038186803b1580156123a657600080fd5b505afa1580156123ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123de919061297c565b90506123ea8383612a8c565b8110156124395760405162461bcd60e51b815260206004820152601b60248201527f42616c616e636520766572696669636174696f6e206661696c65640000000000604482015260640161053c565b505050565b6000546001600160a01b031633146124685760405162461bcd60e51b815260040161053c906129e4565b6001600160a01b0381166124ba5760405162461bcd60e51b81526020600482015260196024820152781b9bdb8b5e995c9bc81859191c995cdcc81c995c5d5a5c9959603a1b604482015260640161053c565b600054604080516001600160a01b03928316815291831660208301527f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0910160405180910390a1600080546001600160a01b0319166001600160a01b0392909216919091179055565b600061253a6125356201518084612ad2565b61264c565b50909392505050565b600081612551603c85612c7d565b61255d610e1087612c7d565b6201518061256c8b8b8b6127c0565b6125769190612c7d565b6125809190612a8c565b61258a9190612a8c565b6125949190612a8c565b979650505050505050565b6000818311156125f15760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f7264657220666f722074696d657374616d707300000000604482015260640161053c565b620151806125ff8484612cdb565b6126099190612ad2565b9392505050565b60007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470823f80821480159061264457508015155b949350505050565b60008080838162253d8c6126638362010bd9612a4b565b61266d9190612a4b565b9050600062023ab1612680836004612bfa565b61268a9190612aa4565b9050600461269b8262023ab1612bfa565b6126a6906003612a4b565b6126b09190612aa4565b6126ba9083612c9c565b9150600062164b096126cd846001612a4b565b6126d990610fa0612bfa565b6126e39190612aa4565b905060046126f3826105b5612bfa565b6126fd9190612aa4565b6127079084612c9c565b61271290601f612a4b565b9250600061098f612724856050612bfa565b61272e9190612aa4565b9050600060506127408361098f612bfa565b61274a9190612aa4565b6127549086612c9c565b9050612761600b83612aa4565b945061276e85600c612bfa565b612779836002612a4b565b6127839190612c9c565b91508483612792603187612c9c565b61279d906064612bfa565b6127a79190612a4b565b6127b19190612a4b565b9a919950975095505050505050565b60006107b28410156127fc5760405162461bcd60e51b815260206004820152600560248201526422b93937b960d91b604482015260640161053c565b838383600062253d8c60046064600c612816600e88612c9c565b6128209190612aa4565b61282c88611324612a4b565b6128369190612a4b565b6128409190612aa4565b61284b906003612bfa565b6128559190612aa4565b600c80612863600e88612c9c565b61286d9190612aa4565b61287890600c612bfa565b612883600288612c9c565b61288d9190612c9c565b6128999061016f612bfa565b6128a39190612aa4565b6004600c6128b2600e89612c9c565b6128bc9190612aa4565b6128c8896112c0612a4b565b6128d29190612a4b565b6128de906105b5612bfa565b6128e89190612aa4565b6128f4617d4b87612c9c565b6128fe9190612a4b565b6129089190612a4b565b6129129190612c9c565b61291c9190612c9c565b98975050505050505050565b600060208284031215612939578081fd5b813561260981612d39565b600060208284031215612955578081fd5b81518015158114612609578182fd5b600060208284031215612975578081fd5b5035919050565b60006020828403121561298d578081fd5b5051919050565b6000602082840312156129a5578081fd5b813560ff81168114612609578182fd5b602080825260159082015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b60208082526016908201527513db9b1e481bdddb995c881c995c5d5a5c995b595b9d60521b604082015260600190565b60208082526018908201527f4f6e6c79206f776e6572206f7220636f6e74726f6c6c65720000000000000000604082015260600190565b600080821280156001600160ff1b0384900385131615612a6d57612a6d612d0d565b600160ff1b8390038412811615612a8657612a86612d0d565b50500190565b60008219821115612a9f57612a9f612d0d565b500190565b600082612ab357612ab3612d23565b600160ff1b821460001984141615612acd57612acd612d0d565b500590565b600082612ae157612ae1612d23565b500490565b80825b6001808611612af85750612b23565b818704821115612b0a57612b0a612d0d565b80861615612b1757918102915b9490941c938002612ae9565b94509492505050565b60006126096000198484600082612b4557506001612609565b81612b5257506000612609565b8160018114612b685760028114612b7257612b9f565b6001915050612609565b60ff841115612b8357612b83612d0d565b6001841b915084821115612b9957612b99612d0d565b50612609565b5060208310610133831016604e8410600b8410161715612bd2575081810a83811115612bcd57612bcd612d0d565b612609565b612bdf8484846001612ae6565b808604821115612bf157612bf1612d0d565b02949350505050565b60006001600160ff1b0381841382841380821686840486111615612c2057612c20612d0d565b600160ff1b84871282811687830589121615612c3e57612c3e612d0d565b858712925087820587128484161615612c5957612c59612d0d565b87850587128184161615612c6f57612c6f612d0d565b505050929093029392505050565b6000816000190483118215151615612c9757612c97612d0d565b500290565b60008083128015600160ff1b850184121615612cba57612cba612d0d565b6001600160ff1b0384018313811615612cd557612cd5612d0d565b50500390565b600082821015612ced57612ced612d0d565b500390565b6000600019821415612d0657612d06612d0d565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6001600160a01b0381168114610a7357600080fdfea26469706673582212205de610586edd274fe0701d42d27c270fb8ea456b7cff4102d1c88b74c07e0be364736f6c63430008030033000000000000000000000000c692d583567cda0fde14cd3d6136c2623202ed68000000000000000000000000ca8d52bd76a0b09a2df5ccf49ab4fcab7611bbcc00000000000000000000000051acb1ea45c1ec2512ae4202b9076c13016dc8aa000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000c692d583567cda0fde14cd3d6136c2623202ed68

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102105760003560e01c80636a61e5fc116101255780639ce7f670116100ad578063bced91171161007c578063bced9117146104b6578063c57380a2146104be578063f2fde38b146104cf578063f343d683146104e2578063f36932b71461050957610210565b80639ce7f6701461046e578063b508195014610476578063b68ef55914610489578063b6b55f25146104a357610210565b80638da5cb5b116100f45780638da5cb5b14610411578063919cfa211461042257806391dd75e71461043557806392eefe9b146104485780639c256eef1461045b57610210565b80636a61e5fc1461037a5780636ff1c9bc1461038d57806376f10ad0146103a05780638705fcd4146103fe57610210565b80632e1a7d4d116101a85780634378f0ec116101775780634378f0ec146103185780634b94f50e146103315780635798ef311461034b57806357e0bf941461035e578063645006ca1461037157610210565b80632e1a7d4d146102c25780632f54bf6e146102d55780633a621d371461030757806342c9b1d91461030f57610210565b80631a43c338116101e45780631a43c3381461026d578063292bbd32146102755780632a40eb72146102a75780632a80cda3146102af57610210565b8062f55d9d146102155780630301310b1461022a578063060406181461024e57806308b4a99414610265575b600080fd5b610228610223366004612928565b610512565b005b6006546102379060ff1681565b60405160ff90911681526020015b60405180910390f35b61025760035481565b604051908152602001610245565b6102576105fd565b6102286106bc565b60065461028f90630100000090046001600160a01b031681565b6040516001600160a01b039091168152602001610245565b6102286108e5565b6102286102bd366004612964565b610a76565b6102286102d0366004612964565b610b0a565b6102f76102e3366004612928565b6000546001600160a01b0390811691161490565b6040519015158152602001610245565b6102576111f7565b61025760025481565b6003805460009081526008602052604090200154610257565b600354600090815260086020526040902060010154610257565b610228610359366004612928565b611205565b61025761036c366004612964565b611324565b61025760045481565b610228610388366004612964565b611375565b61022861039b366004612928565b611404565b6103da6103ae366004612964565b600090815260086020526040902080546001820154600283015460039093015460ff9092169390929190565b6040805160ff90951685526020850193909352918301526060820152608001610245565b61022861040c366004612928565b6116aa565b6000546001600160a01b031661028f565b610228610430366004612964565b61177d565b60075461028f906001600160a01b031681565b610228610456366004612928565b6117c1565b610228610469366004612994565b611918565b6102576119cf565b610228610484366004612994565b611a04565b600354600090815260086020526040902060020154610257565b6102286104b1366004612964565b611a9c565b6102286121de565b6001546001600160a01b031661028f565b6102286104dd366004612928565b61243e565b61028f7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b61025760055481565b6000546001600160a01b031633146105455760405162461bcd60e51b815260040161053c906129e4565b60405180910390fd5b6001600160a01b0381166105975760405162461bcd60e51b81526020600482015260196024820152781b9bdb8b5e995c9bc81859191c995cdcc81c995c5d5a5c9959603a1b604482015260640161053c565b6001600160a01b038116600114156105f15760405162461bcd60e51b815260206004820152601d60248201527f65637265636f7665722061646472657373206e6f7420616c6c6f776564000000604482015260640161053c565b806001600160a01b0316ff5b6006546040516370a0823160e01b815230600482015260009160649160ff909116907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316906370a082319060240160206040518083038186803b15801561066b57600080fd5b505afa15801561067f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a3919061297c565b6106ad9190612c7d565b6106b79190612ad2565b905090565b600042905060006106cf6002548361259f565b905060035481116106e15750506108e3565b60008060035460016106f39190612a8c565b90505b8281116108c7578161070781612cf2565b925060089050600061071a600184612cdb565b81526020808201929092526040908101600090812054848252600893849052918120805460ff191660ff90931692909217909155610759600184612cdb565b8152602001908152602001600020600201546008600083815260200190815260200160002060020181905550600061016d60646006600a61079a9190612b2c565b600860006107a9600188612cdb565b81526020810191909152604001600020546107c7919060ff16612c7d565b6107d19190612c7d565b6107db9190612ad2565b90506107e961271082612ad2565b600860006107f8600186612cdb565b8152602001908152602001600020600101546108149190612a8c565b6000838152600860208190526040822060019081019390935560649261016d929061083f9087612cdb565b8152602081019190915260400160009081205460ff1690600890610864600188612cdb565b8152602001908152602001600020600201546108809190612c7d565b61088a9190612ad2565b6108949190612ad2565b600083815260086020526040902060030155601e83106108b457506108c7565b50806108bf81612cf2565b9150506106f6565b5080600360008282546108da9190612a8c565b90915550505050505b565b6001546001600160a01b031633148061090857506000546001600160a01b031633145b6109245760405162461bcd60e51b815260040161053c90612a14565b61092c6106bc565b60006109366105fd565b9050600081116109885760405162461bcd60e51b815260206004820152601a60248201527f496e76616c6964206465706c6f7961626c65206361706974616c000000000000604482015260640161053c565b60065460405163a9059cbb60e01b815263010000009091046001600160a01b039081166004830152602482018390527f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48169063a9059cbb90604401602060405180830381600087803b1580156109fd57600080fd5b505af1158015610a11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a359190612944565b610a735760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b604482015260640161053c565b50565b6001546001600160a01b0316331480610a9957506000546001600160a01b031633145b610ab55760405162461bcd60e51b815260040161053c90612a14565b60008111610b055760405162461bcd60e51b815260206004820152601e60248201527f496e76616c6964206d696e696d756d206465706f73697420616d6f756e740000604482015260640161053c565b600455565b60065462010000900460ff1615610b635760405162461bcd60e51b815260206004820152601d60248201527f5265656e7472616e74207769746864726177616c2072656a6563746564000000604482015260640161053c565b60008111610baf5760405162461bcd60e51b8152602060048201526019602482015278125b9d985b1a59081dda5d1a191c985dd85b08185b5bdd5b9d603a1b604482015260640161053c565b6006805462ff000019166201000017905533610bc96106bc565b6040516370a0823160e01b81526001600160a01b03828116600483015283917f00000000000000000000000051acb1ea45c1ec2512ae4202b9076c13016dc8aa909116906370a082319060240160206040518083038186803b158015610c2e57600080fd5b505afa158015610c42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c66919061297c565b1015610cb45760405162461bcd60e51b815260206004820152601e60248201527f496e73756666696369656e742062616c616e6365206f6620746f6b656e730000604482015260640161053c565b6000610cbf83611324565b600354600090815260086020526040902060020154909150811115610d225760405162461bcd60e51b8152602060048201526019602482015278125b9d985b1a59081dda5d1a191c985dd85b08185b5bdd5b9d603a1b604482015260640161053c565b6000610d2c6119cf565b905080821115610d7e5760405162461bcd60e51b815260206004820152601e60248201527f4d6178207769746864726177616c20616d6f756e742065786365656465640000604482015260640161053c565b6040516370a0823160e01b81523060048201526000907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316906370a082319060240160206040518083038186803b158015610de057600080fd5b505afa158015610df4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e18919061297c565b9050828111610e695760405162461bcd60e51b815260206004820181905260248201527f496e73756666696369656e742066756e647320696e2074686520627566666572604482015260640161053c565b60008060055411610e7b576000610ec0565b7f00000000000000000000000000000000000000000000000000000000000f4240606460055486610eac9190612c7d565b610eb69190612ad2565b610ec09190612ad2565b9050838110610eff5760405162461bcd60e51b815260206004820152600b60248201526a496e76616c69642066656560a81b604482015260640161053c565b6000610f0b8286612cdb565b9050846008600060035481526020019081526020016000206002016000828254610f359190612cdb565b9091555050604051632770a7eb60e21b81526001600160a01b038781166004830152602482018990527f00000000000000000000000051acb1ea45c1ec2512ae4202b9076c13016dc8aa1690639dc29fac90604401600060405180830381600087803b158015610fa457600080fd5b505af1158015610fb8573d6000803e3d6000fd5b505060405163a9059cbb60e01b81526001600160a01b038981166004830152602482018590527f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816925063a9059cbb9150604401602060405180830381600087803b15801561102657600080fd5b505af115801561103a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105e9190612944565b61107a5760405162461bcd60e51b815260040161053c906129b5565b81156111695760075460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018490527f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489091169063a9059cbb90604401602060405180830381600087803b1580156110ef57600080fd5b505af1158015611103573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111279190612944565b6111695760405162461bcd60e51b8152602060048201526013602482015272119959481d1c985b9cd9995c8819985a5b1959606a1b604482015260640161053c565b604080516001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48811682528816602082015290810186905260608101889052608081018390527f297b983b359127be0bb37e151a4fec683bc9012dd4d0ac96db47cfc17019c1e49060a00160405180910390a150506006805462ff0000191690555050505050565b60006106b76002544261259f565b6001546001600160a01b031633148061122857506000546001600160a01b031633145b6112445760405162461bcd60e51b815260040161053c90612a14565b6001600160a01b0381161580159061126557506001600160a01b0381163014155b6112a35760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640161053c565b6112ac81612610565b6112f85760405162461bcd60e51b815260206004820152601e60248201527f5468652061646472657373206d757374206265206120636f6e74726163740000604482015260640161053c565b600680546001600160a01b039092166301000000026301000000600160b81b0319909216919091179055565b6003546000908152600860205260408120600101547f00000000000000000000000000000000000000000000000000000000000f4240906113659084612c7d565b61136f9190612ad2565b92915050565b6000546001600160a01b0316331461139f5760405162461bcd60e51b815260040161053c906129e4565b600081116113e55760405162461bcd60e51b8152602060048201526013602482015272496e76616c696420746f6b656e20707269636560681b604482015260640161053c565b6113ed6106bc565b600354600090815260086020526040902060010155565b6000546001600160a01b0316331461142e5760405162461bcd60e51b815260040161053c906129e4565b60065462010000900460ff16156114875760405162461bcd60e51b815260206004820152601d60248201527f5265656e7472616e74207769746864726177616c2072656a6563746564000000604482015260640161053c565b6001600160a01b038116158015906114a857506001600160a01b0381163014155b6114e65760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640161053c565b6006805462ff00001916620100001790556040516370a0823160e01b81523060048201526000906001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816906370a082319060240160206040518083038186803b15801561155957600080fd5b505afa15801561156d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611591919061297c565b9050600081116115dc5760405162461bcd60e51b8152602060048201526016602482015275546865207661756c7420686173206e6f2066756e647360501b604482015260640161053c565b60405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390527f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48169063a9059cbb90604401602060405180830381600087803b15801561164657600080fd5b505af115801561165a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167e9190612944565b61169a5760405162461bcd60e51b815260040161053c906129b5565b50506006805462ff000019169055565b6001546001600160a01b03163314806116cd57506000546001600160a01b031633145b6116e95760405162461bcd60e51b815260040161053c90612a14565b6001600160a01b0381161580159061170f57506007546001600160a01b03828116911614155b61175b5760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964206164647265737320666f7220666565730000000000000000604482015260640161053c565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314806117a057506000546001600160a01b031633145b6117bc5760405162461bcd60e51b815260040161053c90612a14565b600555565b6000546001600160a01b031633146117eb5760405162461bcd60e51b815260040161053c906129e4565b6001600160a01b0381166118415760405162461bcd60e51b815260206004820152601b60248201527f436f6e74726f6c6c657220616464726573732072657175697265640000000000604482015260640161053c565b6000546001600160a01b038281169116141561189f5760405162461bcd60e51b815260206004820152601e60248201527f4f776e65722063616e6e6f742062652074686520436f6e74726f6c6c65720000604482015260640161053c565b6001546001600160a01b03828116911614156118f65760405162461bcd60e51b815260206004820152601660248201527510dbdb9d1c9bdb1b195c88185b1c9958591e481cd95d60521b604482015260640161053c565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633148061193b57506000546001600160a01b031633145b6119575760405162461bcd60e51b815260040161053c90612a14565b60008160ff1611801561196d575060648160ff16105b6119b95760405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420696e766573746d656e742070657263656e74000000000000604482015260640161053c565b6006805460ff191660ff92909216919091179055565b6006546000906064906119e59060ff1682612cdb565b6003546000908152600860205260409020600201546106ad9190612c7d565b6000546001600160a01b03163314611a2e5760405162461bcd60e51b815260040161053c906129e4565b60008160ff1611611a6f5760405162461bcd60e51b815260206004820152600b60248201526a24b73b30b634b21020a82960a91b604482015260640161053c565b611a776106bc565b6003546000908152600860205260409020805460ff191660ff92909216919091179055565b600654610100900460ff1615611af45760405162461bcd60e51b815260206004820152601a60248201527f5265656e7472616e74206465706f7369742072656a6563746564000000000000604482015260640161053c565b600454811015611b465760405162461bcd60e51b815260206004820152601e60248201527f4d696e696d756d206465706f73697420616d6f756e74206e6f74206d65740000604482015260640161053c565b6006805461ff001916610100179055611b5d6106bc565b6040516370a0823160e01b815233600482018190529082907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316906370a082319060240160206040518083038186803b158015611bc157600080fd5b505afa158015611bd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf9919061297c565b1015611c3c5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b604482015260640161053c565b604051636eb1769f60e11b81526001600160a01b03828116600483015230602483015283917f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489091169063dd62ed3e9060440160206040518083038186803b158015611ca757600080fd5b505afa158015611cbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cdf919061297c565b1015611d265760405162461bcd60e51b8152602060048201526016602482015275496e73756666696369656e7420616c6c6f77616e636560501b604482015260640161053c565b600354600090815260086020526040812060010154611d657f00000000000000000000000000000000000000000000000000000000000f424085612c7d565b611d6f9190612ad2565b604051635dd871a360e01b8152600481018290529091507f00000000000000000000000051acb1ea45c1ec2512ae4202b9076c13016dc8aa6001600160a01b031690635dd871a39060240160206040518083038186803b158015611dd257600080fd5b505afa158015611de6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0a9190612944565b611e565760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e20737570706c79206c696d69742065786365656465640000000000604482015260640161053c565b60035460009081526008602052604081206002018054859290611e7a908490612a8c565b90915550506040516370a0823160e01b81523060048201526000907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316906370a082319060240160206040518083038186803b158015611ee157600080fd5b505afa158015611ef5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f19919061297c565b6040516323b872dd60e01b81526001600160a01b038581166004830152306024830152604482018790529192507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48909116906323b872dd90606401602060405180830381600087803b158015611f8e57600080fd5b505af1158015611fa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc69190612944565b611fe25760405162461bcd60e51b815260040161053c906129b5565b6040516370a0823160e01b81523060048201526000907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316906370a082319060240160206040518083038186803b15801561204457600080fd5b505afa158015612058573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207c919061297c565b90506120888583612a8c565b8110156120d75760405162461bcd60e51b815260206004820152601b60248201527f42616c616e636520766572696669636174696f6e206661696c65640000000000604482015260640161053c565b6040516340c10f1960e01b81526001600160a01b038581166004830152602482018590527f00000000000000000000000051acb1ea45c1ec2512ae4202b9076c13016dc8aa16906340c10f1990604401600060405180830381600087803b15801561214157600080fd5b505af1158015612155573d6000803e3d6000fd5b5050604080516001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488116825288166020820152908101889052606081018690527f6c6941772efad791f0e8f0ff7e3e76b52034604c1427fc1bbda4dbd3d2570fc69250608001905060405180910390a150506006805461ff0019169055505050565b6001546001600160a01b031633148061220157506000546001600160a01b031633145b61221d5760405162461bcd60e51b815260040161053c90612a14565b6122256106bc565b6000612241600380546000908152600860205260409020015490565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816906370a082319060240160206040518083038186803b1580156122a657600080fd5b505afa1580156122ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122de919061297c565b60065460405163379607f560e01b815260048101859052919250630100000090046001600160a01b03169063379607f590602401600060405180830381600087803b15801561232c57600080fd5b505af1158015612340573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b031691506370a082319060240160206040518083038186803b1580156123a657600080fd5b505afa1580156123ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123de919061297c565b90506123ea8383612a8c565b8110156124395760405162461bcd60e51b815260206004820152601b60248201527f42616c616e636520766572696669636174696f6e206661696c65640000000000604482015260640161053c565b505050565b6000546001600160a01b031633146124685760405162461bcd60e51b815260040161053c906129e4565b6001600160a01b0381166124ba5760405162461bcd60e51b81526020600482015260196024820152781b9bdb8b5e995c9bc81859191c995cdcc81c995c5d5a5c9959603a1b604482015260640161053c565b600054604080516001600160a01b03928316815291831660208301527f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0910160405180910390a1600080546001600160a01b0319166001600160a01b0392909216919091179055565b600061253a6125356201518084612ad2565b61264c565b50909392505050565b600081612551603c85612c7d565b61255d610e1087612c7d565b6201518061256c8b8b8b6127c0565b6125769190612c7d565b6125809190612a8c565b61258a9190612a8c565b6125949190612a8c565b979650505050505050565b6000818311156125f15760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f7264657220666f722074696d657374616d707300000000604482015260640161053c565b620151806125ff8484612cdb565b6126099190612ad2565b9392505050565b60007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470823f80821480159061264457508015155b949350505050565b60008080838162253d8c6126638362010bd9612a4b565b61266d9190612a4b565b9050600062023ab1612680836004612bfa565b61268a9190612aa4565b9050600461269b8262023ab1612bfa565b6126a6906003612a4b565b6126b09190612aa4565b6126ba9083612c9c565b9150600062164b096126cd846001612a4b565b6126d990610fa0612bfa565b6126e39190612aa4565b905060046126f3826105b5612bfa565b6126fd9190612aa4565b6127079084612c9c565b61271290601f612a4b565b9250600061098f612724856050612bfa565b61272e9190612aa4565b9050600060506127408361098f612bfa565b61274a9190612aa4565b6127549086612c9c565b9050612761600b83612aa4565b945061276e85600c612bfa565b612779836002612a4b565b6127839190612c9c565b91508483612792603187612c9c565b61279d906064612bfa565b6127a79190612a4b565b6127b19190612a4b565b9a919950975095505050505050565b60006107b28410156127fc5760405162461bcd60e51b815260206004820152600560248201526422b93937b960d91b604482015260640161053c565b838383600062253d8c60046064600c612816600e88612c9c565b6128209190612aa4565b61282c88611324612a4b565b6128369190612a4b565b6128409190612aa4565b61284b906003612bfa565b6128559190612aa4565b600c80612863600e88612c9c565b61286d9190612aa4565b61287890600c612bfa565b612883600288612c9c565b61288d9190612c9c565b6128999061016f612bfa565b6128a39190612aa4565b6004600c6128b2600e89612c9c565b6128bc9190612aa4565b6128c8896112c0612a4b565b6128d29190612a4b565b6128de906105b5612bfa565b6128e89190612aa4565b6128f4617d4b87612c9c565b6128fe9190612a4b565b6129089190612a4b565b6129129190612c9c565b61291c9190612c9c565b98975050505050505050565b600060208284031215612939578081fd5b813561260981612d39565b600060208284031215612955578081fd5b81518015158114612609578182fd5b600060208284031215612975578081fd5b5035919050565b60006020828403121561298d578081fd5b5051919050565b6000602082840312156129a5578081fd5b813560ff81168114612609578182fd5b602080825260159082015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b60208082526016908201527513db9b1e481bdddb995c881c995c5d5a5c995b595b9d60521b604082015260600190565b60208082526018908201527f4f6e6c79206f776e6572206f7220636f6e74726f6c6c65720000000000000000604082015260600190565b600080821280156001600160ff1b0384900385131615612a6d57612a6d612d0d565b600160ff1b8390038412811615612a8657612a86612d0d565b50500190565b60008219821115612a9f57612a9f612d0d565b500190565b600082612ab357612ab3612d23565b600160ff1b821460001984141615612acd57612acd612d0d565b500590565b600082612ae157612ae1612d23565b500490565b80825b6001808611612af85750612b23565b818704821115612b0a57612b0a612d0d565b80861615612b1757918102915b9490941c938002612ae9565b94509492505050565b60006126096000198484600082612b4557506001612609565b81612b5257506000612609565b8160018114612b685760028114612b7257612b9f565b6001915050612609565b60ff841115612b8357612b83612d0d565b6001841b915084821115612b9957612b99612d0d565b50612609565b5060208310610133831016604e8410600b8410161715612bd2575081810a83811115612bcd57612bcd612d0d565b612609565b612bdf8484846001612ae6565b808604821115612bf157612bf1612d0d565b02949350505050565b60006001600160ff1b0381841382841380821686840486111615612c2057612c20612d0d565b600160ff1b84871282811687830589121615612c3e57612c3e612d0d565b858712925087820587128484161615612c5957612c59612d0d565b87850587128184161615612c6f57612c6f612d0d565b505050929093029392505050565b6000816000190483118215151615612c9757612c97612d0d565b500290565b60008083128015600160ff1b850184121615612cba57612cba612d0d565b6001600160ff1b0384018313811615612cd557612cd5612d0d565b50500390565b600082821015612ced57612ced612d0d565b500390565b6000600019821415612d0657612d06612d0d565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6001600160a01b0381168114610a7357600080fdfea26469706673582212205de610586edd274fe0701d42d27c270fb8ea456b7cff4102d1c88b74c07e0be364736f6c63430008030033

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

000000000000000000000000c692d583567cda0fde14cd3d6136c2623202ed68000000000000000000000000ca8d52bd76a0b09a2df5ccf49ab4fcab7611bbcc00000000000000000000000051acb1ea45c1ec2512ae4202b9076c13016dc8aa000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000c692d583567cda0fde14cd3d6136c2623202ed68

-----Decoded View---------------
Arg [0] : ownerAddr (address): 0xc692d583567cdA0fDE14Cd3D6136c2623202Ed68
Arg [1] : controllerAddr (address): 0xCA8D52bd76a0b09a2DF5CcF49AB4FCab7611BBcc
Arg [2] : receiptTokenInterface (address): 0x51acB1ea45c1EC2512ae4202B9076C13016dc8aA
Arg [3] : eip20Interface (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [4] : initialApr (uint8): 15
Arg [5] : initialTokenPrice (uint256): 1000000
Arg [6] : initialMinDepositAmount (uint256): 1000000
Arg [7] : flatFeePerc (uint256): 1000000
Arg [8] : feesAddr (address): 0xc692d583567cdA0fDE14Cd3D6136c2623202Ed68

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 000000000000000000000000c692d583567cda0fde14cd3d6136c2623202ed68
Arg [1] : 000000000000000000000000ca8d52bd76a0b09a2df5ccf49ab4fcab7611bbcc
Arg [2] : 00000000000000000000000051acb1ea45c1ec2512ae4202b9076c13016dc8aa
Arg [3] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [4] : 000000000000000000000000000000000000000000000000000000000000000f
Arg [5] : 00000000000000000000000000000000000000000000000000000000000f4240
Arg [6] : 00000000000000000000000000000000000000000000000000000000000f4240
Arg [7] : 00000000000000000000000000000000000000000000000000000000000f4240
Arg [8] : 000000000000000000000000c692d583567cda0fde14cd3d6136c2623202ed68


Deployed Bytecode Sourcemap

26368:20182:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1427:239;;;;;;:::i;:::-;;:::i;:::-;;27859:35;;;;;;;;;;;;16089:4:1;16077:17;;;16059:36;;16047:2;16032:18;27859:35:0;;;;;;;;27181:28;;;;;;;;;15881:25:1;;;15869:2;15854:18;27181:28:0;15836:76:1;45937:172:0;;;:::i;41855:926::-;;;:::i;28160:34::-;;;;;;;;-1:-1:-1;;;;;28160:34:0;;;;;;-1:-1:-1;;;;;1700:32:1;;;1682:51;;1670:2;1655:18;28160:34:0;1637:102:1;42888:414:0;;;:::i;32944:239::-;;;;;;:::i;:::-;;:::i;37123:2702::-;;;;;;:::i;:::-;;:::i;2034:98::-;;;;;;:::i;:::-;2086:4;2118:6;-1:-1:-1;;;;;2118:6:0;;;2110:14;;;;2034:98;;;;3853:14:1;;3846:22;3828:41;;3816:2;3801:18;2034:98:0;3783:92:1;44224:190:0;;;:::i;26891:35::-;;;;;;45101:122;45187:13;;;45151:7;45178:23;;;:8;:23;;;;;:37;;45101:122;;45333:116;45416:13;;45380:7;45407:23;;;:8;:23;;;;;:34;;;45333:116;;32458:281;;;;;;:::i;:::-;;:::i;46348:199::-;;;;;;:::i;:::-;;:::i;27301:31::-;;;;;;41184:215;;;;;;:::i;:::-;;:::i;40062:716::-;;;;;;:::i;:::-;;:::i;44422:324::-;;;;;;:::i;:::-;44476:9;44571:11;;;:8;:11;;;;;:15;;;44610:22;;;44660:26;;;;44713:25;;;;;44571:15;;;;;44610:22;;44660:26;44713:25;44422:324;;;;;16363:4:1;16351:17;;;16333:36;;16400:2;16385:18;;16378:34;;;;16428:18;;;16421:34;16486:2;16471:18;;16464:34;16320:3;16305:19;44422:324:0;16287:217:1;33907:193:0;;;;;;:::i;:::-;;:::i;1781:79::-;1819:7;1846:6;-1:-1:-1;;;;;1846:6:0;1781:79;;33463:332;;;;;;:::i;:::-;;:::i;28283:26::-;;;;;-1:-1:-1;;;;;28283:26:0;;;20088:405;;;;;;:::i;:::-;;:::i;41523:211::-;;;;;;:::i;:::-;;:::i;45607:190::-;;;:::i;40870:173::-;;;;;;:::i;:::-;;:::i;44876:124::-;44963:13;;44927:7;44954:23;;;:8;:23;;;;;:38;;;44876:124;;34406:2539;;;;;;:::i;:::-;;:::i;43388:557::-;;;:::i;20605:107::-;20686:18;;-1:-1:-1;;;;;20686:18:0;20605:107;;1090:208;;;;;;:::i;:::-;;:::i;28390:38::-;;;;;27419:29;;;;;;1427:239;2086:4;2118:6;-1:-1:-1;;;;;2118:6:0;817:10;2110:14;801:54;;;;-1:-1:-1;;;801:54:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;1510:18:0;::::1;1502:56;;;::::0;-1:-1:-1;;;1502:56:0;;12425:2:1;1502:56:0::1;::::0;::::1;12407:21:1::0;12464:2;12444:18;;;12437:30;-1:-1:-1;;;12483:18:1;;;12476:55;12548:18;;1502:56:0::1;12397:175:1::0;1502:56:0::1;-1:-1:-1::0;;;;;1577:18:0;::::1;1593:1;1577:18;;1569:60;;;::::0;-1:-1:-1;;;1569:60:0;;6765:2:1;1569:60:0::1;::::0;::::1;6747:21:1::0;6804:2;6784:18;;;6777:30;6843:31;6823:18;;;6816:59;6892:18;;1569:60:0::1;6737:179:1::0;1569:60:0::1;1653:4;-1:-1:-1::0;;;;;1640:18:0::1;;45937:172:::0;46068:17;;46018:39;;-1:-1:-1;;;46018:39:0;;46051:4;46018:39;;;1682:51:1;45991:7:0;;46097:3;;46068:17;;;;;46018:14;-1:-1:-1;;;;;46018:24:0;;;;1655:18:1;;46018:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:68;;;;:::i;:::-;:83;;;;:::i;:::-;46011:90;;45937:172;:::o;41855:926::-;41893:24;41920:15;41893:42;;41989:17;42009:58;42028:20;;42050:16;42009:18;:58::i;:::-;41989:78;;42095:13;;42082:9;:26;42078:39;;42110:7;;;;42078:39;42129:9;42160;42172:13;;42188:1;42172:17;;;;:::i;:::-;42160:29;;42155:588;42196:9;42191:1;:14;42155:588;;42227:3;;;;:::i;:::-;;-1:-1:-1;42263:8:0;;-1:-1:-1;42263:15:0;42272:5;42276:1;42272;:5;:::i;:::-;42263:15;;;;;;;;;;;;;;-1:-1:-1;42263:15:0;;;:19;42245:11;;;:8;:11;;;;;;;:37;;-1:-1:-1;;42245:37:0;42263:19;;;;42245:37;;;;;;;42335:5;42263:19;42254:1;42335:5;:::i;:::-;42326:15;;;;;;;;;;;:30;;;42297:8;:11;42306:1;42297:11;;;;;;;;;;;:26;;:59;;;;42373:12;42468:3;42453;26532:1;26517:2;26509:25;;;;:::i;:::-;42396:8;:15;42405:5;42409:1;42405;:5;:::i;:::-;42396:15;;;;;;;;;;;-1:-1:-1;42396:15:0;:19;42388:54;;;42396:19;;42388:54;:::i;:::-;:69;;;;:::i;:::-;:84;;;;:::i;:::-;42373:99;-1:-1:-1;42542:21:0;42557:5;42373:99;42542:21;:::i;:::-;42512:8;:15;42521:5;42525:1;42521;:5;:::i;:::-;42512:15;;;;;;;;;;;:26;;;:52;;;;:::i;:::-;42487:11;;;;:8;:11;;;;;;;:22;;;;:77;;;;42694:3;;42679;;42487:11;42657:5;;42496:1;42657:5;:::i;:::-;42648:15;;;;;;;;;;;-1:-1:-1;42648:15:0;;;:19;;;;42607:8;;42616:5;42648:19;42616:1;:5;:::i;:::-;42607:15;;;;;;;;;;;:30;;;:61;;;;:::i;:::-;:76;;;;:::i;:::-;:91;;;;:::i;:::-;42579:11;;;;:8;:11;;;;;:25;;:119;42722:2;42717:7;;42713:18;;42726:5;;;42713:18;-1:-1:-1;42207:3:0;;;;:::i;:::-;;;;42155:588;;;;42772:1;42755:13;;:18;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;41855:926:0;:::o;42888:414::-;19816:18;;-1:-1:-1;;;;;19816:18:0;19802:10;:32;;:56;;-1:-1:-1;19852:6:0;;-1:-1:-1;;;;;19852:6:0;19838:10;:20;19802:56;19794:93;;;;-1:-1:-1;;;19794:93:0;;;;;;;:::i;:::-;42952:9:::1;:7;:9::i;:::-;43063:27;43093:22;:20;:22::i;:::-;43063:52;;43156:1;43134:19;:23;43126:62;;;::::0;-1:-1:-1;;;43126:62:0;;13490:2:1;43126:62:0::1;::::0;::::1;13472:21:1::0;13529:2;13509:18;;;13502:30;13568:28;13548:18;;;13541:56;13614:18;;43126:62:0::1;13462:176:1::0;43126:62:0::1;43233:19;::::0;43209:65:::1;::::0;-1:-1:-1;;;43209:65:0;;43233:19;;;::::1;-1:-1:-1::0;;;;;43233:19:0;;::::1;43209:65;::::0;::::1;3583:51:1::0;3650:18;;;3643:34;;;43209:14:0::1;:23;::::0;::::1;::::0;3556:18:1;;43209:65:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43201:93;;;::::0;-1:-1:-1;;;43201:93:0;;5002:2:1;43201:93:0::1;::::0;::::1;4984:21:1::0;5041:2;5021:18;;;5014:30;-1:-1:-1;;;5060:18:1;;;5053:45;5115:18;;43201:93:0::1;4974:165:1::0;43201:93:0::1;19898:1;42888:414::o:0;32944:239::-;19816:18;;-1:-1:-1;;;;;19816:18:0;19802:10;:32;;:56;;-1:-1:-1;19852:6:0;;-1:-1:-1;;;;;19852:6:0;19838:10;:20;19802:56;19794:93;;;;-1:-1:-1;;;19794:93:0;;;;;;;:::i;:::-;33072:1:::1;33060:9;:13;33052:56;;;::::0;-1:-1:-1;;;33052:56:0;;8177:2:1;33052:56:0::1;::::0;::::1;8159:21:1::0;8216:2;8196:18;;;8189:30;8255:32;8235:18;;;8228:60;8305:18;;33052:56:0::1;8149:180:1::0;33052:56:0::1;33147:16;:28:::0;32944:239::o;37123:2702::-;32063:30;;;;;;;:35;32055:77;;;;-1:-1:-1;;;32055:77:0;;9603:2:1;32055:77:0;;;9585:21:1;9642:2;9622:18;;;9615:30;9681:31;9661:18;;;9654:59;9730:18;;32055:77:0;9575:179:1;32055:77:0;37261:1:::1;37240:18;:22;37232:60;;;::::0;-1:-1:-1;;;37232:60:0;;4304:2:1;37232:60:0::1;::::0;::::1;4286:21:1::0;4343:2;4323:18;;;4316:30;-1:-1:-1;;;4362:18:1;;;4355:55;4427:18;;37232:60:0::1;4276:175:1::0;37232:60:0::1;37346:30;:34:::0;;-1:-1:-1;;37346:34:0::1;::::0;::::1;::::0;;37414:10:::1;37489:9;:7;:9::i;:::-;37586:35;::::0;-1:-1:-1;;;37586:35:0;;-1:-1:-1;;;;;1700:32:1;;;37586:35:0::1;::::0;::::1;1682:51:1::0;37625:18:0;;37586:13:::1;:23:::0;;::::1;::::0;::::1;::::0;1655:18:1;;37586:35:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:57;;37578:100;;;::::0;-1:-1:-1;;;37578:100:0;;9244:2:1;37578:100:0::1;::::0;::::1;9226:21:1::0;9283:2;9263:18;;;9256:30;9322:32;9302:18;;;9295:60;9372:18;;37578:100:0::1;9216:180:1::0;37578:100:0::1;37770:24;37797:33;37811:18;37797:13;:33::i;:::-;37878:13;::::0;37869:23:::1;::::0;;;:8:::1;:23;::::0;;;;:38:::1;;::::0;37770:60;;-1:-1:-1;37849:58:0;::::1;;37841:96;;;::::0;-1:-1:-1;;;37841:96:0;;4304:2:1;37841:96:0::1;::::0;::::1;4286:21:1::0;4343:2;4323:18;;;4316:30;-1:-1:-1;;;4362:18:1;;;4355:55;4427:18;;37841:96:0::1;4276:175:1::0;37841:96:0::1;37950:27;37980:24;:22;:24::i;:::-;37950:54;;38043:19;38023:16;:39;;38015:82;;;::::0;-1:-1:-1;;;38015:82:0;;13845:2:1;38015:82:0::1;::::0;::::1;13827:21:1::0;13884:2;13864:18;;;13857:30;13923:32;13903:18;;;13896:60;13973:18;;38015:82:0::1;13817:180:1::0;38015:82:0::1;38135:39;::::0;-1:-1:-1;;;38135:39:0;;38168:4:::1;38135:39;::::0;::::1;1682:51:1::0;38110:22:0::1;::::0;38135:14:::1;-1:-1:-1::0;;;;;38135:24:0::1;::::0;::::1;::::0;1655:18:1;;38135:39:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38110:64;;38210:16;38193:14;:33;38185:78;;;::::0;-1:-1:-1;;;38185:78:0;;8883:2:1;38185:78:0::1;::::0;::::1;8865:21:1::0;;;8902:18;;;8895:30;8961:34;8941:18;;;8934:62;9013:18;;38185:78:0::1;8855:182:1::0;38185:78:0::1;38418:17;38456:1:::0;38439:14:::1;;:18;38438:97;;38534:1;38438:97;;;38512:19;38505:3;38480:14;;38461:16;:33;;;;:::i;:::-;:48;;;;:::i;:::-;:70;;;;:::i;:::-;38418:117;;38566:16;38554:9;:28;38546:52;;;::::0;-1:-1:-1;;;38546:52:0;;10667:2:1;38546:52:0::1;::::0;::::1;10649:21:1::0;10706:2;10686:18;;;10679:30;-1:-1:-1;;;10725:18:1;;;10718:41;10776:18;;38546:52:0::1;10639:161:1::0;38546:52:0::1;38705:33;38741:28;38760:9:::0;38741:16;:28:::1;:::i;:::-;38705:64;;38997:16;38955:8;:23;38964:13;;38955:23;;;;;;;;;;;:38;;;:58;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;39082:50:0::1;::::0;-1:-1:-1;;;39082:50:0;;-1:-1:-1;;;;;3601:32:1;;;39082:50:0::1;::::0;::::1;3583:51:1::0;3650:18;;;3643:34;;;39082:13:0::1;:18;::::0;::::1;::::0;3556::1;;39082:50:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;39256:62:0::1;::::0;-1:-1:-1;;;39256:62:0;;-1:-1:-1;;;;;3601:32:1;;;39256:62:0::1;::::0;::::1;3583:51:1::0;3650:18;;;3643:34;;;39256:14:0::1;:23;::::0;-1:-1:-1;39256:23:0::1;::::0;-1:-1:-1;3556:18:1;;39256:62:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39248:96;;;;-1:-1:-1::0;;;39248:96:0::1;;;;;;;:::i;:::-;39361:13:::0;;39357:177:::1;;39475:11;::::0;39451:47:::1;::::0;-1:-1:-1;;;39451:47:0;;-1:-1:-1;;;;;39475:11:0;;::::1;39451:47;::::0;::::1;3583:51:1::0;3650:18;;;3643:34;;;39451:14:0::1;:23:::0;;::::1;::::0;::::1;::::0;3556:18:1;;39451:47:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39443:79;;;::::0;-1:-1:-1;;;39443:79:0;;7123:2:1;39443:79:0::1;::::0;::::1;7105:21:1::0;7162:2;7142:18;;;7135:30;-1:-1:-1;;;7181:18:1;;;7174:49;7240:18;;39443:79:0::1;7095:169:1::0;39443:79:0::1;39593:103;::::0;;-1:-1:-1;;;;;39619:14:0::1;3200:15:1::0;;3182:34;;3252:15;;3247:2;3232:18;;3225:43;3284:18;;;3277:34;;;3342:2;3327:18;;3320:34;;;3385:3;3370:19;;3363:35;;;39593:103:0::1;::::0;3131:3:1;3116:19;39593:103:0::1;;;;;;;-1:-1:-1::0;;39748:30:0::1;:34:::0;;-1:-1:-1;;39748:34:0::1;::::0;;-1:-1:-1;;;;;37123:2702:0:o;44224:190::-;44281:7;44308:57;44327:20;;44349:15;44308:18;:57::i;32458:281::-;19816:18;;-1:-1:-1;;;;;19816:18:0;19802:10;:32;;:56;;-1:-1:-1;19852:6:0;;-1:-1:-1;;;;;19852:6:0;19838:10;:20;19802:56;19794:93;;;;-1:-1:-1;;;19794:93:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;32553:18:0;::::1;::::0;;::::1;::::0;:43:::1;;-1:-1:-1::0;;;;;;32575:21:0;::::1;32591:4;32575:21;;32553:43;32545:71;;;::::0;-1:-1:-1;;;32545:71:0;;4658:2:1;32545:71:0::1;::::0;::::1;4640:21:1::0;4697:2;4677:18;;;4670:30;-1:-1:-1;;;4716:18:1;;;4709:45;4771:18;;32545:71:0::1;4630:165:1::0;32545:71:0::1;32635:22;32652:4;32635:16;:22::i;:::-;32627:65;;;::::0;-1:-1:-1;;;32627:65:0;;11007:2:1;32627:65:0::1;::::0;::::1;10989:21:1::0;11046:2;11026:18;;;11019:30;11085:32;11065:18;;;11058:60;11135:18;;32627:65:0::1;10979:180:1::0;32627:65:0::1;32705:19;:26:::0;;-1:-1:-1;;;;;32705:26:0;;::::1;::::0;::::1;-1:-1:-1::0;;;;;;32705:26:0;;::::1;::::0;;;::::1;::::0;;32458:281::o;46348:199::-;46478:13;;46421:7;46469:23;;;:8;:23;;;;;:34;;;46506:33;;46448:55;;:18;:55;:::i;:::-;:91;;;;:::i;:::-;46441:98;46348:199;-1:-1:-1;;46348:199:0:o;41184:215::-;2086:4;2118:6;-1:-1:-1;;;;;2118:6:0;817:10;2110:14;801:54;;;;-1:-1:-1;;;801:54:0;;;;;;;:::i;:::-;41283:1:::1;41267:13;:17;41259:49;;;::::0;-1:-1:-1;;;41259:49:0;;14204:2:1;41259:49:0::1;::::0;::::1;14186:21:1::0;14243:2;14223:18;;;14216:30;-1:-1:-1;;;14262:18:1;;;14255:49;14321:18;;41259:49:0::1;14176:169:1::0;41259:49:0::1;41321:9;:7;:9::i;:::-;41350:13;::::0;41341:23:::1;::::0;;;:8:::1;:23;::::0;;;;:34:::1;;:50:::0;41184:215::o;40062:716::-;2086:4;2118:6;-1:-1:-1;;;;;2118:6:0;817:10;2110:14;801:54;;;;-1:-1:-1;;;801:54:0;;;;;;;:::i;:::-;32063:30:::1;::::0;;;::::1;;;:35:::0;32055:77:::1;;;::::0;-1:-1:-1;;;32055:77:0;;9603:2:1;32055:77:0::1;::::0;::::1;9585:21:1::0;9642:2;9622:18;;;9615:30;9681:31;9661:18;;;9654:59;9730:18;;32055:77:0::1;9575:179:1::0;32055:77:0::1;-1:-1:-1::0;;;;;40176:29:0;::::2;::::0;;::::2;::::0;:65:::2;;-1:-1:-1::0;;;;;;40209:32:0;::::2;40236:4;40209:32;;40176:65;40168:93;;;::::0;-1:-1:-1;;;40168:93:0;;4658:2:1;40168:93:0::2;::::0;::::2;4640:21:1::0;4697:2;4677:18;;;4670:30;-1:-1:-1;;;4716:18:1;;;4709:45;4771:18;;40168:93:0::2;4630:165:1::0;40168:93:0::2;40315:30;:34:::0;;-1:-1:-1;;40315:34:0::2;::::0;::::2;::::0;;40387:39:::2;::::0;-1:-1:-1;;;40387:39:0;;40420:4:::2;40387:39;::::0;::::2;1682:51:1::0;-1:-1:-1;;;;;;;40387:14:0::2;:24;::::0;::::2;::::0;1655:18:1;;40387:39:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40362:64;;40462:1;40445:14;:18;40437:53;;;::::0;-1:-1:-1;;;40437:53:0;;7826:2:1;40437:53:0::2;::::0;::::2;7808:21:1::0;7865:2;7845:18;;;7838:30;-1:-1:-1;;;7884:18:1;;;7877:52;7946:18;;40437:53:0::2;7798:172:1::0;40437:53:0::2;40567:56;::::0;-1:-1:-1;;;40567:56:0;;-1:-1:-1;;;;;3601:32:1;;;40567:56:0::2;::::0;::::2;3583:51:1::0;3650:18;;;3643:34;;;40567:14:0::2;:23;::::0;::::2;::::0;3556:18:1;;40567:56:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40559:90;;;;-1:-1:-1::0;;;40559:90:0::2;;;;;;;:::i;:::-;-1:-1:-1::0;;40701:30:0::2;:34:::0;;-1:-1:-1;;40701:34:0::2;::::0;;40062:716::o;33907:193::-;19816:18;;-1:-1:-1;;;;;19816:18:0;19802:10;:32;;:56;;-1:-1:-1;19852:6:0;;-1:-1:-1;;;;;19852:6:0;19838:10;:20;19802:56;19794:93;;;;-1:-1:-1;;;19794:93:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;33993:18:0;::::1;::::0;;::::1;::::0;:41:::1;;-1:-1:-1::0;34023:11:0::1;::::0;-1:-1:-1;;;;;34015:19:0;;::::1;34023:11:::0;::::1;34015:19;;33993:41;33985:78;;;::::0;-1:-1:-1;;;33985:78:0;;5697:2:1;33985:78:0::1;::::0;::::1;5679:21:1::0;5736:2;5716:18;;;5709:30;5775:26;5755:18;;;5748:54;5819:18;;33985:78:0::1;5669:174:1::0;33985:78:0::1;34074:11;:18:::0;;-1:-1:-1;;;;;;34074:18:0::1;-1:-1:-1::0;;;;;34074:18:0;;;::::1;::::0;;;::::1;::::0;;33907:193::o;33463:332::-;19816:18;;-1:-1:-1;;;;;19816:18:0;19802:10;:32;;:56;;-1:-1:-1;19852:6:0;;-1:-1:-1;;;;;19852:6:0;19838:10;:20;19802:56;19794:93;;;;-1:-1:-1;;;19794:93:0;;;;;;;:::i;:::-;33750:14:::1;:37:::0;33463:332::o;20088:405::-;2086:4;2118:6;-1:-1:-1;;;;;2118:6:0;817:10;2110:14;801:54;;;;-1:-1:-1;;;801:54:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;20191:28:0;::::1;20183:68;;;::::0;-1:-1:-1;;;20183:68:0;;6050:2:1;20183:68:0::1;::::0;::::1;6032:21:1::0;6089:2;6069:18;;;6062:30;6128:29;6108:18;;;6101:57;6175:18;;20183:68:0::1;6022:177:1::0;20183:68:0::1;20288:6;::::0;-1:-1:-1;;;;;20270:24:0;;::::1;20288:6:::0;::::1;20270:24;;20262:67;;;::::0;-1:-1:-1;;;20262:67:0;;14885:2:1;20262:67:0::1;::::0;::::1;14867:21:1::0;14924:2;14904:18;;;14897:30;14963:32;14943:18;;;14936:60;15013:18;;20262:67:0::1;14857:180:1::0;20262:67:0::1;20366:18;::::0;-1:-1:-1;;;;;20348:36:0;;::::1;20366:18:::0;::::1;20348:36;;20340:71;;;::::0;-1:-1:-1;;;20340:71:0;;12074:2:1;20340:71:0::1;::::0;::::1;12056:21:1::0;12113:2;12093:18;;;12086:30;-1:-1:-1;;;12132:18:1;;;12125:52;12194:18;;20340:71:0::1;12046:172:1::0;20340:71:0::1;20450:18;:35:::0;;-1:-1:-1;;;;;;20450:35:0::1;-1:-1:-1::0;;;;;20450:35:0;;;::::1;::::0;;;::::1;::::0;;20088:405::o;41523:211::-;19816:18;;-1:-1:-1;;;;;19816:18:0;19802:10;:32;;:56;;-1:-1:-1;19852:6:0;;-1:-1:-1;;;;;19852:6:0;19838:10;:20;19802:56;19794:93;;;;-1:-1:-1;;;19794:93:0;;;;;;;:::i;:::-;41633:1:::1;41620:10;:14;;;:34;;;;;41651:3;41638:10;:16;;;41620:34;41612:73;;;::::0;-1:-1:-1;;;41612:73:0;;12779:2:1;41612:73:0::1;::::0;::::1;12761:21:1::0;12818:2;12798:18;;;12791:30;12857:28;12837:18;;;12830:56;12903:18;;41612:73:0::1;12751:176:1::0;41612:73:0::1;41696:17;:30:::0;;-1:-1:-1;;41696:30:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;41523:211::o;45607:190::-;45755:17;;45663:7;;45785:3;;45732:41;;45755:17;;45785:3;45732:41;:::i;:::-;45699:13;;45690:23;;;;:8;:23;;;;;:38;;;:84;;;;:::i;40870:173::-;2086:4;2118:6;-1:-1:-1;;;;;2118:6:0;817:10;2110:14;801:54;;;;-1:-1:-1;;;801:54:0;;;;;;;:::i;:::-;40949:1:::1;40940:6;:10;;;40932:34;;;::::0;-1:-1:-1;;;40932:34:0;;15597:2:1;40932:34:0::1;::::0;::::1;15579:21:1::0;15636:2;15616:18;;;15609:30;-1:-1:-1;;;15655:18:1;;;15648:41;15706:18;;40932:34:0::1;15569:161:1::0;40932:34:0::1;40979:9;:7;:9::i;:::-;41008:13;::::0;40999:23:::1;::::0;;;:8:::1;:23;::::0;;;;:36;;-1:-1:-1;;40999:36:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;40870:173::o;34406:2539::-;31839:27;;;;;;;:32;31831:71;;;;-1:-1:-1;;;31831:71:0;;7471:2:1;31831:71:0;;;7453:21:1;7510:2;7490:18;;;7483:30;7549:28;7529:18;;;7522:56;7595:18;;31831:71:0;7443:176:1;31831:71:0;34585:16:::1;;34568:13;:33;;34560:76;;;::::0;-1:-1:-1;;;34560:76:0;;6406:2:1;34560:76:0::1;::::0;::::1;6388:21:1::0;6445:2;6425:18;;;6418:30;6484:32;6464:18;;;6457:60;6534:18;;34560:76:0::1;6378:180:1::0;34560:76:0::1;34690:27;:31:::0;;-1:-1:-1;;34690:31:0::1;;;::::0;;34786:9:::1;:7;:9::i;:::-;35071:36;::::0;-1:-1:-1;;;35071:36:0;;34940:10:::1;35071:36;::::0;::::1;1682:51:1::0;;;34940:10:0;35111:13;;35071:14:::1;-1:-1:-1::0;;;;;35071:24:0::1;::::0;::::1;::::0;1655:18:1;;35071:36:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;35063:84;;;::::0;-1:-1:-1;;;35063:84:0;;8536:2:1;35063:84:0::1;::::0;::::1;8518:21:1::0;8575:2;8555:18;;;8548:30;-1:-1:-1;;;8594:18:1;;;8587:48;8652:18;;35063:84:0::1;8508:168:1::0;35063:84:0::1;35252:51;::::0;-1:-1:-1;;;35252:51:0;;-1:-1:-1;;;;;1974:15:1;;;35252:51:0::1;::::0;::::1;1956:34:1::0;35297:4:0::1;2006:18:1::0;;;1999:43;35307:13:0;;35252:14:::1;:24:::0;;::::1;::::0;::::1;::::0;1891:18:1;;35252:51:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:68;;35244:103;;;::::0;-1:-1:-1;;;35244:103:0;;5346:2:1;35244:103:0::1;::::0;::::1;5328:21:1::0;5385:2;5365:18;;;5358:30;-1:-1:-1;;;5404:18:1;;;5397:52;5466:18;;35244:103:0::1;5318:172:1::0;35244:103:0::1;35539:13;::::0;35446:29:::1;35530:23:::0;;;:8:::1;:23;::::0;;;;:34:::1;;::::0;35478:49:::1;35494:33;35478:13:::0;:49:::1;:::i;:::-;:86;;;;:::i;:::-;35663:44;::::0;-1:-1:-1;;;35663:44:0;;::::1;::::0;::::1;15881:25:1::0;;;35446:118:0;;-1:-1:-1;35663:13:0::1;-1:-1:-1::0;;;;;35663:21:0::1;::::0;::::1;::::0;15854:18:1;;35663:44:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35655:84;;;::::0;-1:-1:-1;;;35655:84:0;;13134:2:1;35655:84:0::1;::::0;::::1;13116:21:1::0;13173:2;13153:18;;;13146:30;13212:29;13192:18;;;13185:57;13259:18;;35655:84:0::1;13106:177:1::0;35655:84:0::1;35761:13;::::0;35752:23:::1;::::0;;;:8:::1;:23;::::0;;;;:38:::1;;:55:::0;;35794:13;;35752:23;:55:::1;::::0;35794:13;;35752:55:::1;:::i;:::-;::::0;;;-1:-1:-1;;35974:39:0::1;::::0;-1:-1:-1;;;35974:39:0;;36007:4:::1;35974:39;::::0;::::1;1682:51:1::0;35942:29:0::1;::::0;35974:14:::1;-1:-1:-1::0;;;;;35974:24:0::1;::::0;::::1;::::0;1655:18:1;;35974:39:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36085:69;::::0;-1:-1:-1;;;36085:69:0;;-1:-1:-1;;;;;2311:15:1;;;36085:69:0::1;::::0;::::1;2293:34:1::0;36133:4:0::1;2343:18:1::0;;;2336:43;2395:18;;;2388:34;;;35942:71:0;;-1:-1:-1;36085:14:0::1;:27:::0;;::::1;::::0;::::1;::::0;2228:18:1;;36085:69:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36077:103;;;;-1:-1:-1::0;;;36077:103:0::1;;;;;;;:::i;:::-;36279:39;::::0;-1:-1:-1;;;36279:39:0;;36312:4:::1;36279:39;::::0;::::1;1682:51:1::0;36258:18:0::1;::::0;36279:14:::1;-1:-1:-1::0;;;;;36279:24:0::1;::::0;::::1;::::0;1655:18:1;;36279:39:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36258:60:::0;-1:-1:-1;36446:37:0::1;36470:13:::0;36446:21;:37:::1;:::i;:::-;36432:10;:51;;36424:91;;;::::0;-1:-1:-1;;;36424:91:0;;10311:2:1;36424:91:0::1;::::0;::::1;10293:21:1::0;10350:2;10330:18;;;10323:30;10389:29;10369:18;;;10362:57;10436:18;;36424:91:0::1;10283:177:1::0;36424:91:0::1;36655:53;::::0;-1:-1:-1;;;36655:53:0;;-1:-1:-1;;;;;3601:32:1;;;36655:53:0::1;::::0;::::1;3583:51:1::0;3650:18;;;3643:34;;;36655:13:0::1;:18;::::0;::::1;::::0;3556::1;;36655:53:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;36765:89:0::1;::::0;;-1:-1:-1;;;;;36788:14:0::1;2720:15:1::0;;2702:34;;2772:15;;2767:2;2752:18;;2745:43;2804:18;;;2797:34;;;2862:2;2847:18;;2840:34;;;36765:89:0::1;::::0;-1:-1:-1;2651:3:1;2636:19;;-1:-1:-1;36765:89:0::1;;;;;;;-1:-1:-1::0;;36906:27:0::1;:31:::0;;-1:-1:-1;;36906:31:0::1;::::0;;-1:-1:-1;;;34406:2539:0:o;43388:557::-;19816:18;;-1:-1:-1;;;;;19816:18:0;19802:10;:32;;:56;;-1:-1:-1;19852:6:0;;-1:-1:-1;;;;;19852:6:0;19838:10;:20;19802:56;19794:93;;;;-1:-1:-1;;;19794:93:0;;;;;;;:::i;:::-;43459:9:::1;:7;:9::i;:::-;43562:27;43592:18;45187:13:::0;;;45151:7;45178:23;;;:8;:23;;;;;:37;;45101:122;;43592:18:::1;43647:39;::::0;-1:-1:-1;;;43647:39:0;;43680:4:::1;43647:39;::::0;::::1;1682:51:1::0;43562:48:0;;-1:-1:-1;43623:21:0::1;::::0;-1:-1:-1;;;;;43647:14:0::1;:24;::::0;::::1;::::0;1655:18:1;;43647:39:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43711:19;::::0;43699:59:::1;::::0;-1:-1:-1;;;43699:59:0;;::::1;::::0;::::1;15881:25:1::0;;;43623:63:0;;-1:-1:-1;43711:19:0;;::::1;-1:-1:-1::0;;;;;43711:19:0::1;::::0;43699:38:::1;::::0;15854:18:1;;43699:59:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;43794:39:0::1;::::0;-1:-1:-1;;;43794:39:0;;43827:4:::1;43794:39;::::0;::::1;1682:51:1::0;43771:20:0::1;::::0;-1:-1:-1;43794:14:0::1;-1:-1:-1::0;;;;;43794:24:0::1;::::0;-1:-1:-1;43794:24:0::1;::::0;1655:18:1;;43794:39:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43771:62:::0;-1:-1:-1;43870:35:0::1;43886:19:::0;43870:13;:35:::1;:::i;:::-;43854:12;:51;;43846:91;;;::::0;-1:-1:-1;;;43846:91:0;;10311:2:1;43846:91:0::1;::::0;::::1;10293:21:1::0;10350:2;10330:18;;;10323:30;10389:29;10369:18;;;10362:57;10436:18;;43846:91:0::1;10283:177:1::0;43846:91:0::1;19898:1;;;43388:557::o:0;1090:208::-;2086:4;2118:6;-1:-1:-1;;;;;2118:6:0;817:10;2110:14;801:54;;;;-1:-1:-1;;;801:54:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;1168:18:0;::::1;1160:56;;;::::0;-1:-1:-1;;;1160:56:0;;12425:2:1;1160:56:0::1;::::0;::::1;12407:21:1::0;12464:2;12444:18;;;12437:30;-1:-1:-1;;;12483:18:1;;;12476:55;12548:18;;1160:56:0::1;12397:175:1::0;1160:56:0::1;1253:6;::::0;1232:34:::1;::::0;;-1:-1:-1;;;;;1253:6:0;;::::1;1956:34:1::0;;2026:15;;;2021:2;2006:18;;1999:43;1232:34:0::1;::::0;1891:18:1;1232:34:0::1;;;;;;;1277:6;:13:::0;;-1:-1:-1;;;;;;1277:13:0::1;-1:-1:-1::0;;;;;1277:13:0;;;::::1;::::0;;;::::1;::::0;;1090:208::o;22630:144::-;22690:12;22726:40;22738:27;22172:12;22738:9;:27;:::i;:::-;22726:11;:40::i;:::-;-1:-1:-1;22715:51:0;;22630:144;-1:-1:-1;;;22630:144:0:o;23081:306::-;23223:17;23373:6;23343:27;22381:2;23343:6;:27;:::i;:::-;23317:23;22277:7;23317:4;:23;:::i;:::-;22172:12;23265:31;23279:4;23285:5;23292:3;23265:13;:31::i;:::-;:49;;;;:::i;:::-;:75;;;;:::i;:::-;:105;;;;:::i;:::-;:114;;;;:::i;:::-;23253:126;23081:306;-1:-1:-1;;;;;;;23081:306:0:o;23635:248::-;23721:7;23766:11;23749:13;:28;;23741:69;;;;-1:-1:-1;;;23741:69:0;;11366:2:1;23741:69:0;;;11348:21:1;11405:2;11385:18;;;11378:30;11444;11424:18;;;11417:58;11492:18;;23741:69:0;11338:178:1;23741:69:0;22172:12;23829:27;23843:13;23829:11;:27;:::i;:::-;23828:47;;;;:::i;:::-;23821:54;23635:248;-1:-1:-1;;;23635:248:0:o;21689:367::-;21747:4;21782:66;21970:17;;22009:19;;;;;;:38;;-1:-1:-1;22032:15:0;;;22009:38;22001:47;21689:367;-1:-1:-1;;;;21689:367:0:o;24395:665::-;24455:12;;;24531:5;24455:12;22469:7;24561:14;24531:5;24570;24561:14;:::i;:::-;:31;;;;:::i;:::-;24550:42;-1:-1:-1;24603:8:0;24622:6;24614:5;24550:42;24614:1;:5;:::i;:::-;:14;;;;:::i;:::-;24603:25;-1:-1:-1;24666:1:0;24648:10;24603:25;24648:6;:10;:::i;:::-;:14;;24661:1;24648:14;:::i;:::-;24647:20;;;;:::i;:::-;24643:24;;:1;:24;:::i;:::-;24639:28;-1:-1:-1;24678:12:0;24710:7;24701:5;24639:28;24705:1;24701:5;:::i;:::-;24693:14;;:4;:14;:::i;:::-;:24;;;;:::i;:::-;24678:39;-1:-1:-1;24751:1:0;24736:12;24678:39;24736:4;:12;:::i;:::-;:16;;;;:::i;:::-;24732:20;;:1;:20;:::i;:::-;:25;;24755:2;24732:25;:::i;:::-;24728:29;-1:-1:-1;24768:13:0;24793:4;24784:6;24728:29;24784:2;:6;:::i;:::-;:13;;;;:::i;:::-;24768:29;-1:-1:-1;24808:11:0;24842:2;24826:13;24768:29;24826:4;:13;:::i;:::-;:18;;;;:::i;:::-;24822:22;;:1;:22;:::i;:::-;24808:36;-1:-1:-1;24859:11:0;24868:2;24859:6;:11;:::i;:::-;24855:15;-1:-1:-1;24903:6:0;24855:15;24903:2;:6;:::i;:::-;24890:10;:6;24899:1;24890:10;:::i;:::-;:19;;;;:::i;:::-;24881:28;-1:-1:-1;24953:1:0;24945:5;24935:6;24939:2;24935:1;:6;:::i;:::-;24928:14;;:3;:14;:::i;:::-;:22;;;;:::i;:::-;:26;;;;:::i;:::-;24920:34;25015:6;;-1:-1:-1;25047:4:0;-1:-1:-1;24395:665:0;-1:-1:-1;;;;;;24395:665:0:o;25591:550::-;25680:13;25722:4;25714;:12;;25706:30;;;;-1:-1:-1;;;25706:30:0;;14552:2:1;25706:30:0;;;14534:21:1;14591:1;14571:18;;;14564:29;-1:-1:-1;;;14609:18:1;;;14602:35;14654:18;;25706:30:0;14524:154:1;25706:30:0;25763:4;25796:5;25828:3;25747:9;22469:7;26068:1;26061:3;26055:2;26040:11;26049:2;25796:5;26040:11;:::i;:::-;26039:18;;;;:::i;:::-;26024:12;:5;26032:4;26024:12;:::i;:::-;:33;;;;:::i;:::-;26023:41;;;;:::i;:::-;26018:47;;:1;:47;:::i;:::-;:51;;;;:::i;:::-;26002:2;;25976:11;25985:2;25976:6;:11;:::i;:::-;25975:18;;;;:::i;:::-;:23;;25996:2;25975:23;:::i;:::-;25962:10;25971:1;25962:6;:10;:::i;:::-;:36;;;;:::i;:::-;25955:44;;:3;:44;:::i;:::-;:49;;;;:::i;:::-;25940:1;25934:2;25919:11;25928:2;25919:6;:11;:::i;:::-;25918:18;;;;:::i;:::-;25903:12;:5;25911:4;25903:12;:::i;:::-;:33;;;;:::i;:::-;25895:42;;:4;:42;:::i;:::-;:46;;;;:::i;:::-;25858:23;25876:5;25858:4;:23;:::i;:::-;:83;;;;:::i;:::-;:146;;;;:::i;:::-;:211;;;;:::i;:::-;:239;;;;:::i;:::-;25845:252;25591:550;-1:-1:-1;;;;;;;;25591:550:0:o;14:257:1:-;;126:2;114:9;105:7;101:23;97:32;94:2;;;147:6;139;132:22;94:2;191:9;178:23;210:31;235:5;210:31;:::i;546:297::-;;666:2;654:9;645:7;641:23;637:32;634:2;;;687:6;679;672:22;634:2;724:9;718:16;777:5;770:13;763:21;756:5;753:32;743:2;;804:6;796;789:22;848:190;;960:2;948:9;939:7;935:23;931:32;928:2;;;981:6;973;966:22;928:2;-1:-1:-1;1009:23:1;;918:120;-1:-1:-1;918:120:1:o;1043:194::-;;1166:2;1154:9;1145:7;1141:23;1137:32;1134:2;;;1187:6;1179;1172:22;1134:2;-1:-1:-1;1215:16:1;;1124:113;-1:-1:-1;1124:113:1:o;1242:289::-;;1352:2;1340:9;1331:7;1327:23;1323:32;1320:2;;;1373:6;1365;1358:22;1320:2;1417:9;1404:23;1467:4;1460:5;1456:16;1449:5;1446:27;1436:2;;1492:6;1484;1477:22;9759:345;9961:2;9943:21;;;10000:2;9980:18;;;9973:30;-1:-1:-1;;;10034:2:1;10019:18;;10012:51;10095:2;10080:18;;9933:171::o;11521:346::-;11723:2;11705:21;;;11762:2;11742:18;;;11735:30;-1:-1:-1;;;11796:2:1;11781:18;;11774:52;11858:2;11843:18;;11695:172::o;15042:348::-;15244:2;15226:21;;;15283:2;15263:18;;;15256:30;15322:26;15317:2;15302:18;;15295:54;15381:2;15366:18;;15216:174::o;16509:267::-;;16576:11;;;16603:10;;-1:-1:-1;;;;;16622:27:1;;;16615:35;;16599:52;16596:2;;;16654:18;;:::i;:::-;-1:-1:-1;;;16701:19:1;;;16694:27;;16686:36;;16683:2;;;16725:18;;:::i;:::-;-1:-1:-1;;16761:9:1;;16556:220::o;16781:128::-;;16852:1;16848:6;16845:1;16842:13;16839:2;;;16858:18;;:::i;:::-;-1:-1:-1;16894:9:1;;16829:80::o;16914:193::-;;16979:1;16969:2;;16984:18;;:::i;:::-;-1:-1:-1;;;17020:18:1;;-1:-1:-1;;17040:13:1;;17016:38;17013:2;;;17057:18;;:::i;:::-;-1:-1:-1;17091:10:1;;16959:148::o;17112:120::-;;17178:1;17168:2;;17183:18;;:::i;:::-;-1:-1:-1;17217:9:1;;17158:74::o;17237:453::-;17333:6;17356:5;17370:314;17419:1;17456:2;17446:8;17443:16;17433:2;;17463:5;;;17433:2;17504:4;17499:3;17495:14;17489:4;17486:24;17483:2;;;17513:18;;:::i;:::-;17563:2;17553:8;17549:17;17546:2;;;17578:16;;;;17546:2;17657:17;;;;;17617:15;;17370:314;;;17314:376;;;;;;;:::o;17695:139::-;;17784:44;-1:-1:-1;;17811:8:1;17805:4;17839:922;17923:8;17913:2;;-1:-1:-1;17964:1:1;17978:5;;17913:2;18012:4;18002:2;;-1:-1:-1;18049:1:1;18063:5;;18002:2;18094:4;18112:1;18107:59;;;;18180:1;18175:183;;;;18087:271;;18107:59;18137:1;18128:10;;18151:5;;;18175:183;18212:3;18202:8;18199:17;18196:2;;;18219:18;;:::i;:::-;18275:1;18265:8;18261:16;18252:25;;18303:3;18296:5;18293:14;18290:2;;;18310:18;;:::i;:::-;18343:5;;;18087:271;;18442:2;18432:8;18429:16;18423:3;18417:4;18414:13;18410:36;18404:2;18394:8;18391:16;18386:2;18380:4;18377:12;18373:35;18370:77;18367:2;;;-1:-1:-1;18479:19:1;;;18514:14;;;18511:2;;;18531:18;;:::i;:::-;18564:5;;18367:2;18611:42;18649:3;18639:8;18633:4;18630:1;18611:42;:::i;:::-;18686:6;18681:3;18677:16;18668:7;18665:29;18662:2;;;18697:18;;:::i;:::-;18735:20;;17903:858;-1:-1:-1;;;;17903:858:1:o;18766:577::-;;-1:-1:-1;;;;;18875:15:1;;;18909;;;18940:11;;;18959:10;;;18953:17;;18936:35;18933:2;;;18974:18;;:::i;:::-;-1:-1:-1;;;19043:15:1;;;19074:11;;;19094;;;19087:19;;19070:37;19067:2;;;19110:18;;:::i;:::-;19156:7;19153:1;19149:15;19139:25;;19209:1;19205:2;19200:11;19197:1;19193:19;19188:2;19184;19180:11;19176:37;19173:2;;;19216:18;;:::i;:::-;19281:1;19277:2;19272:11;19269:1;19265:19;19260:2;19256;19252:11;19248:37;19245:2;;;19288:18;;:::i;:::-;-1:-1:-1;;;19328:9:1;;;;;18817:526;-1:-1:-1;;;18817:526:1:o;19348:168::-;;19454:1;19450;19446:6;19442:14;19439:1;19436:21;19431:1;19424:9;19417:17;19413:45;19410:2;;;19461:18;;:::i;:::-;-1:-1:-1;19501:9:1;;19400:116::o;19521:270::-;;19589:12;;;19617:10;;-1:-1:-1;;;19636:19:1;;19629:27;;19613:44;19610:2;;;19660:18;;:::i;:::-;-1:-1:-1;;;;;19707:27:1;;19700:35;;19692:44;;19689:2;;;19739:18;;:::i;:::-;-1:-1:-1;;19776:9:1;;19569:222::o;19796:125::-;;19864:1;19861;19858:8;19855:2;;;19869:18;;:::i;:::-;-1:-1:-1;19906:9:1;;19845:76::o;19926:135::-;;-1:-1:-1;;19986:17:1;;19983:2;;;20006:18;;:::i;:::-;-1:-1:-1;20053:1:1;20042:13;;19973:88::o;20066:127::-;20127:10;20122:3;20118:20;20115:1;20108:31;20158:4;20155:1;20148:15;20182:4;20179:1;20172:15;20198:127;20259:10;20254:3;20250:20;20247:1;20240:31;20290:4;20287:1;20280:15;20314:4;20311:1;20304:15;20330:131;-1:-1:-1;;;;;20405:31:1;;20395:42;;20385:2;;20451:1;20448;20441:12

Swarm Source

ipfs://5de610586edd274fe0701d42d27c270fb8ea456b7cff4102d1c88b74c07e0be3

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.