false
true
0

Contract Address Details

0xb1cFF81b9305166ff1EFc49A129ad2AfCd7BCf19

Contract Name
Vault
Creator
0xf827ac–48cabf at 0x518083–087e85
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
31 Transactions
Transfers
7,322 Transfers
Gas Used
929,648
Last Balance Update
26134159
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been partially verified via Sourcify. View contract in Sourcify repository
Contract name:
Vault




Optimization enabled
true
Compiler version
v0.7.5+commit.eb77ed08




Optimization runs
200
EVM Version
istanbul




Verified at
2026-03-28T02:09:37.459275Z

Constructor Arguments

000000000000000000000000b46f8cf42e504efe8bef895f848741daa55e9f1d000000000000000000000000c76fb75950536d98fa62ea968e1d6b45ffea2a550000000000000000000000001456688345527be1f37e9e627da0837d6f08c925000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

Arg [0] (address) : 0xb46f8cf42e504efe8bef895f848741daa55e9f1d
Arg [1] (address) : 0xc76fb75950536d98fa62ea968e1d6b45ffea2a55
Arg [2] (address) : 0x1456688345527be1f37e9e627da0837d6f08c925
Arg [3] (address) : 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

              

Vault.sol

// SPDX-License-Identifier: bsl-1.1

// File: contracts/helpers/SafeMath.sol

/*
  Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz).
*/
pragma solidity ^0.7.1;


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

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

    /**
    * @dev Integer division of two numbers, truncating the quotient.
    */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: division by zero");
        return a / b;
    }

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

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

// File: contracts/VaultParameters.sol

/*
  Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz).
*/
pragma solidity ^0.7.1;


/**
 * @title Auth
 * @author Unit Protocol: Ivan Zakharov (@34x4p08)
 * @dev Manages USDP's system access
 **/
contract Auth {

    // address of the the contract with vault parameters
    VaultParameters public vaultParameters;

    constructor(address _parameters) public {
        vaultParameters = VaultParameters(_parameters);
    }

    // ensures tx's sender is a manager
    modifier onlyManager() {
        require(vaultParameters.isManager(msg.sender), "Unit Protocol: AUTH_FAILED");
        _;
    }

    // ensures tx's sender is able to modify the Vault
    modifier hasVaultAccess() {
        require(vaultParameters.canModifyVault(msg.sender), "Unit Protocol: AUTH_FAILED");
        _;
    }

    // ensures tx's sender is the Vault
    modifier onlyVault() {
        require(msg.sender == vaultParameters.vault(), "Unit Protocol: AUTH_FAILED");
        _;
    }
}


/**
 * @title VaultParameters
 * @author Unit Protocol: Ivan Zakharov (@34x4p08)
 **/
contract VaultParameters is Auth {

    // map token to stability fee percentage; 3 decimals
    mapping(address => uint) public stabilityFee;

    // map token to liquidation fee percentage, 0 decimals
    mapping(address => uint) public liquidationFee;

    // map token to USDP mint limit
    mapping(address => uint) public tokenDebtLimit;

    // permissions to modify the Vault
    mapping(address => bool) public canModifyVault;

    // managers
    mapping(address => bool) public isManager;

    // enabled oracle types
    mapping(uint => mapping (address => bool)) public isOracleTypeEnabled;

    // address of the Vault
    address payable public vault;

    // The foundation address
    address public foundation;

    /**
     * The address for an Ethereum contract is deterministically computed from the address of its creator (sender)
     * and how many transactions the creator has sent (nonce). The sender and nonce are RLP encoded and then
     * hashed with Keccak-256.
     * Therefore, the Vault address can be pre-computed and passed as an argument before deployment.
    **/
    constructor(address payable _vault, address _foundation) public Auth(address(this)) {
        require(_vault != address(0), "Unit Protocol: ZERO_ADDRESS");
        require(_foundation != address(0), "Unit Protocol: ZERO_ADDRESS");

        isManager[msg.sender] = true;
        vault = _vault;
        foundation = _foundation;
    }

    /**
     * @notice Only manager is able to call this function
     * @dev Grants and revokes manager's status of any address
     * @param who The target address
     * @param permit The permission flag
     **/
    function setManager(address who, bool permit) external onlyManager {
        isManager[who] = permit;
    }

    /**
     * @notice Only manager is able to call this function
     * @dev Sets the foundation address
     * @param newFoundation The new foundation address
     **/
    function setFoundation(address newFoundation) external onlyManager {
        require(newFoundation != address(0), "Unit Protocol: ZERO_ADDRESS");
        foundation = newFoundation;
    }

    /**
     * @notice Only manager is able to call this function
     * @dev Sets ability to use token as the main collateral
     * @param asset The address of the main collateral token
     * @param stabilityFeeValue The percentage of the year stability fee (3 decimals)
     * @param liquidationFeeValue The liquidation fee percentage (0 decimals)
     * @param usdpLimit The USDP token issue limit
     * @param oracles The enables oracle types
     **/
    function setCollateral(
        address asset,
        uint stabilityFeeValue,
        uint liquidationFeeValue,
        uint usdpLimit,
        uint[] calldata oracles
    ) external onlyManager {
        setStabilityFee(asset, stabilityFeeValue);
        setLiquidationFee(asset, liquidationFeeValue);
        setTokenDebtLimit(asset, usdpLimit);
        for (uint i=0; i < oracles.length; i++) {
            setOracleType(oracles[i], asset, true);
        }
    }

    /**
     * @notice Only manager is able to call this function
     * @dev Sets a permission for an address to modify the Vault
     * @param who The target address
     * @param permit The permission flag
     **/
    function setVaultAccess(address who, bool permit) external onlyManager {
        canModifyVault[who] = permit;
    }

    /**
     * @notice Only manager is able to call this function
     * @dev Sets the percentage of the year stability fee for a particular collateral
     * @param asset The address of the main collateral token
     * @param newValue The stability fee percentage (3 decimals)
     **/
    function setStabilityFee(address asset, uint newValue) public onlyManager {
        stabilityFee[asset] = newValue;
    }

    /**
     * @notice Only manager is able to call this function
     * @dev Sets the percentage of the liquidation fee for a particular collateral
     * @param asset The address of the main collateral token
     * @param newValue The liquidation fee percentage (0 decimals)
     **/
    function setLiquidationFee(address asset, uint newValue) public onlyManager {
        require(newValue <= 100, "Unit Protocol: VALUE_OUT_OF_RANGE");
        liquidationFee[asset] = newValue;
    }

    /**
     * @notice Only manager is able to call this function
     * @dev Enables/disables oracle types
     * @param _type The type of the oracle
     * @param asset The address of the main collateral token
     * @param enabled The control flag
     **/
    function setOracleType(uint _type, address asset, bool enabled) public onlyManager {
        isOracleTypeEnabled[_type][asset] = enabled;
    }

    /**
     * @notice Only manager is able to call this function
     * @dev Sets USDP limit for a specific collateral
     * @param asset The address of the main collateral token
     * @param limit The limit number
     **/
    function setTokenDebtLimit(address asset, uint limit) public onlyManager {
        tokenDebtLimit[asset] = limit;
    }
}

// File: contracts/helpers/TransferHelper.sol

/*
  Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz).
*/
pragma solidity ^0.7.1;

// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
    function safeApprove(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED');
    }

    function safeTransfer(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED');
    }

    function safeTransferFrom(address token, address from, address to, uint value) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');
    }

    function safeTransferETH(address to, uint value) internal {
        (bool success,) = to.call{value:value}(new bytes(0));
        require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
    }
}

// File: contracts/USDP.sol

/*
  Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz).
*/
pragma solidity ^0.7.1;




/**
 * @title USDP token implementation
 * @author Unit Protocol: Ivan Zakharov (@34x4p08)
 * @dev ERC20 token
 **/
contract USDP is Auth {
    using SafeMath for uint;

    // name of the token
    string public constant name = "USDP Stablecoin";

    // symbol of the token
    string public constant symbol = "USDP";

    // version of the token
    string public constant version = "1";

    // number of decimals the token uses
    uint8 public constant decimals = 18;

    // total token supply
    uint public totalSupply;

    // balance information map
    mapping(address => uint) public balanceOf;

    // token allowance mapping
    mapping(address => mapping(address => uint)) public allowance;

    /**
     * @dev Trigger on any successful call to approve(address spender, uint amount)
    **/
    event Approval(address indexed owner, address indexed spender, uint value);

    /**
     * @dev Trigger when tokens are transferred, including zero value transfers
    **/
    event Transfer(address indexed from, address indexed to, uint value);

    /**
      * @param _parameters The address of system parameters contract
     **/
    constructor(address _parameters) public Auth(_parameters) {}

    /**
      * @notice Only Vault can mint USDP
      * @dev Mints 'amount' of tokens to address 'to', and MUST fire the
      * Transfer event
      * @param to The address of the recipient
      * @param amount The amount of token to be minted
     **/
    function mint(address to, uint amount) external onlyVault {
        require(to != address(0), "Unit Protocol: ZERO_ADDRESS");

        balanceOf[to] = balanceOf[to].add(amount);
        totalSupply = totalSupply.add(amount);

        emit Transfer(address(0), to, amount);
    }

    /**
      * @notice Only manager can burn tokens from manager's balance
      * @dev Burns 'amount' of tokens, and MUST fire the Transfer event
      * @param amount The amount of token to be burned
     **/
    function burn(uint amount) external onlyManager {
        _burn(msg.sender, amount);
    }

    /**
      * @notice Only Vault can burn tokens from any balance
      * @dev Burns 'amount' of tokens from 'from' address, and MUST fire the Transfer event
      * @param from The address of the balance owner
      * @param amount The amount of token to be burned
     **/
    function burn(address from, uint amount) external onlyVault {
        _burn(from, amount);
    }

    /**
      * @dev Transfers 'amount' of tokens to address 'to', and MUST fire the Transfer event. The
      * function SHOULD throw if the _from account balance does not have enough tokens to spend.
      * @param to The address of the recipient
      * @param amount The amount of token to be transferred
     **/
    function transfer(address to, uint amount) external returns (bool) {
        return transferFrom(msg.sender, to, amount);
    }

    /**
      * @dev Transfers 'amount' of tokens from address 'from' to address 'to', and MUST fire the
      * Transfer event
      * @param from The address of the sender
      * @param to The address of the recipient
      * @param amount The amount of token to be transferred
     **/
    function transferFrom(address from, address to, uint amount) public returns (bool) {
        require(to != address(0), "Unit Protocol: ZERO_ADDRESS");
        require(balanceOf[from] >= amount, "Unit Protocol: INSUFFICIENT_BALANCE");

        if (from != msg.sender) {
            require(allowance[from][msg.sender] >= amount, "Unit Protocol: INSUFFICIENT_ALLOWANCE");
            _approve(from, msg.sender, allowance[from][msg.sender].sub(amount));
        }
        balanceOf[from] = balanceOf[from].sub(amount);
        balanceOf[to] = balanceOf[to].add(amount);

        emit Transfer(from, to, amount);
        return true;
    }

    /**
      * @dev Allows 'spender' to withdraw from your account multiple times, up to the 'amount' amount. If
      * this function is called again it overwrites the current allowance with 'amount'.
      * @param spender The address of the account able to transfer the tokens
      * @param amount The amount of tokens to be approved for transfer
     **/
    function approve(address spender, uint amount) external returns (bool) {
        _approve(msg.sender, spender, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to `approve` that can be used as a mitigation for
     * problems described in `IERC20.approve`.
     *
     * Emits an `Approval` event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint addedValue) public virtual returns (bool) {
        _approve(msg.sender, spender, allowance[msg.sender][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to `approve` that can be used as a mitigation for
     * problems described in `IERC20.approve`.
     *
     * Emits an `Approval` event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint subtractedValue) public virtual returns (bool) {
        _approve(msg.sender, spender, allowance[msg.sender][spender].sub(subtractedValue));
        return true;
    }

    function _approve(address owner, address spender, uint amount) internal virtual {
        require(owner != address(0), "Unit Protocol: approve from the zero address");
        require(spender != address(0), "Unit Protocol: approve to the zero address");

        allowance[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    function _burn(address from, uint amount) internal virtual {
        balanceOf[from] = balanceOf[from].sub(amount);
        totalSupply = totalSupply.sub(amount);

        emit Transfer(from, address(0), amount);
    }
}

// File: contracts/helpers/IWETH.sol

/*
  Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz).
*/
pragma solidity ^0.7.1;


interface IWETH {
    function deposit() external payable;
    function transfer(address to, uint value) external returns (bool);
    function withdraw(uint) external;
}

// File: contracts/Vault.sol

/*
  Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz).
*/
pragma solidity ^0.7.1;







/**
 * @title Vault
 * @author Unit Protocol: Ivan Zakharov (@34x4p08)
 * @notice Vault is the core of Unit Protocol USDP Stablecoin system
 * @notice Vault stores and manages collateral funds of all positions and counts debts
 * @notice Only Vault can manage supply of USDP token
 * @notice Vault will not be changed/upgraded after initial deployment for the current stablecoin version
 **/
contract Vault is Auth {
    using SafeMath for uint;

    // COL token address
    address public immutable col;

    // WETH token address
    address payable public immutable weth;

    uint public constant DENOMINATOR_1E5 = 1e5;

    uint public constant DENOMINATOR_1E2 = 1e2;

    // USDP token address
    address public immutable usdp;

    // collaterals whitelist
    mapping(address => mapping(address => uint)) public collaterals;

    // COL token collaterals
    mapping(address => mapping(address => uint)) public colToken;

    // user debts
    mapping(address => mapping(address => uint)) public debts;

    // block number of liquidation trigger
    mapping(address => mapping(address => uint)) public liquidationBlock;

    // initial price of collateral
    mapping(address => mapping(address => uint)) public liquidationPrice;

    // debts of tokens
    mapping(address => uint) public tokenDebts;

    // stability fee pinned to each position
    mapping(address => mapping(address => uint)) public stabilityFee;

    // liquidation fee pinned to each position, 0 decimals
    mapping(address => mapping(address => uint)) public liquidationFee;

    // type of using oracle pinned for each position
    mapping(address => mapping(address => uint)) public oracleType;

    // timestamp of the last update
    mapping(address => mapping(address => uint)) public lastUpdate;

    modifier notLiquidating(address asset, address user) {
        require(liquidationBlock[asset][user] == 0, "Unit Protocol: LIQUIDATING_POSITION");
        _;
    }

    /**
     * @param _parameters The address of the system parameters
     * @param _col COL token address
     * @param _usdp USDP token address
     **/
    constructor(address _parameters, address _col, address _usdp, address payable _weth) public Auth(_parameters) {
        col = _col;
        usdp = _usdp;
        weth = _weth;
    }

    // only accept ETH via fallback from the WETH contract
    receive() external payable {
        require(msg.sender == weth, "Unit Protocol: RESTRICTED");
    }

    /**
     * @dev Updates parameters of the position to the current ones
     * @param asset The address of the main collateral token
     * @param user The owner of a position
     **/
    function update(address asset, address user) public hasVaultAccess notLiquidating(asset, user) {

        // calculate fee using stored stability fee
        uint debtWithFee = getTotalDebt(asset, user);
        tokenDebts[asset] = tokenDebts[asset].sub(debts[asset][user]).add(debtWithFee);
        debts[asset][user] = debtWithFee;

        stabilityFee[asset][user] = vaultParameters.stabilityFee(asset);
        liquidationFee[asset][user] = vaultParameters.liquidationFee(asset);
        lastUpdate[asset][user] = block.timestamp;
    }

    /**
     * @dev Creates new position for user
     * @param asset The address of the main collateral token
     * @param user The address of a position's owner
     * @param _oracleType The type of an oracle
     **/
    function spawn(address asset, address user, uint _oracleType) external hasVaultAccess notLiquidating(asset, user) {
        oracleType[asset][user] = _oracleType;
        delete liquidationBlock[asset][user];
    }

    /**
     * @dev Clears unused storage variables
     * @param asset The address of the main collateral token
     * @param user The address of a position's owner
     **/
    function destroy(address asset, address user) public hasVaultAccess notLiquidating(asset, user) {
        delete stabilityFee[asset][user];
        delete oracleType[asset][user];
        delete lastUpdate[asset][user];
        delete liquidationFee[asset][user];
    }

    /**
     * @notice Tokens must be pre-approved
     * @dev Adds main collateral to a position
     * @param asset The address of the main collateral token
     * @param user The address of a position's owner
     * @param amount The amount of tokens to deposit
     **/
    function depositMain(address asset, address user, uint amount) external hasVaultAccess notLiquidating(asset, user) {
        collaterals[asset][user] = collaterals[asset][user].add(amount);
        TransferHelper.safeTransferFrom(asset, user, address(this), amount);
    }

    /**
     * @dev Converts ETH to WETH and adds main collateral to a position
     * @param user The address of a position's owner
     **/
    function depositEth(address user) external payable notLiquidating(weth, user) {
        IWETH(weth).deposit{value: msg.value}();
        collaterals[weth][user] = collaterals[weth][user].add(msg.value);
    }

    /**
     * @dev Withdraws main collateral from a position
     * @param asset The address of the main collateral token
     * @param user The address of a position's owner
     * @param amount The amount of tokens to withdraw
     **/
    function withdrawMain(address asset, address user, uint amount) external hasVaultAccess notLiquidating(asset, user) {
        collaterals[asset][user] = collaterals[asset][user].sub(amount);
        TransferHelper.safeTransfer(asset, user, amount);
    }

    /**
     * @dev Withdraws WETH collateral from a position converting WETH to ETH
     * @param user The address of a position's owner
     * @param amount The amount of ETH to withdraw
     **/
    function withdrawEth(address payable user, uint amount) external hasVaultAccess notLiquidating(weth, user) {
        collaterals[weth][user] = collaterals[weth][user].sub(amount);
        IWETH(weth).withdraw(amount);
        TransferHelper.safeTransferETH(user, amount);
    }

    /**
     * @notice Tokens must be pre-approved
     * @dev Adds COL token to a position
     * @param asset The address of the main collateral token
     * @param user The address of a position's owner
     * @param amount The amount of tokens to deposit
     **/
    function depositCol(address asset, address user, uint amount) external hasVaultAccess notLiquidating(asset, user) {
        colToken[asset][user] = colToken[asset][user].add(amount);
        TransferHelper.safeTransferFrom(col, user, address(this), amount);
    }

    /**
     * @dev Withdraws COL token from a position
     * @param asset The address of the main collateral token
     * @param user The address of a position's owner
     * @param amount The amount of tokens to withdraw
     **/
    function withdrawCol(address asset, address user, uint amount) external hasVaultAccess notLiquidating(asset, user) {
        colToken[asset][user] = colToken[asset][user].sub(amount);
        TransferHelper.safeTransfer(col, user, amount);
    }

    /**
     * @dev Increases position's debt and mints USDP token
     * @param asset The address of the main collateral token
     * @param user The address of a position's owner
     * @param amount The amount of USDP to borrow
     **/
    function borrow(
        address asset,
        address user,
        uint amount
    )
    external
    hasVaultAccess
    notLiquidating(asset, user)
    returns(uint)
    {
        require(vaultParameters.isOracleTypeEnabled(oracleType[asset][user], asset), "Unit Protocol: WRONG_ORACLE_TYPE");
        update(asset, user);
        debts[asset][user] = debts[asset][user].add(amount);
        tokenDebts[asset] = tokenDebts[asset].add(amount);

        // check USDP limit for token
        require(tokenDebts[asset] <= vaultParameters.tokenDebtLimit(asset), "Unit Protocol: ASSET_DEBT_LIMIT");

        USDP(usdp).mint(user, amount);

        return debts[asset][user];
    }

    /**
     * @dev Decreases position's debt and burns USDP token
     * @param asset The address of the main collateral token
     * @param user The address of a position's owner
     * @param amount The amount of USDP to repay
     * @return updated debt of a position
     **/
    function repay(
        address asset,
        address user,
        uint amount
    )
    external
    hasVaultAccess
    notLiquidating(asset, user)
    returns(uint)
    {
        uint debt = debts[asset][user];
        debts[asset][user] = debt.sub(amount);
        tokenDebts[asset] = tokenDebts[asset].sub(amount);
        USDP(usdp).burn(user, amount);

        return debts[asset][user];
    }

    /**
     * @dev Transfers fee to foundation
     * @param asset The address of the fee asset
     * @param user The address to transfer funds from
     * @param amount The amount of asset to transfer
     **/
    function chargeFee(address asset, address user, uint amount) external hasVaultAccess notLiquidating(asset, user) {
        if (amount != 0) {
            TransferHelper.safeTransferFrom(asset, user, vaultParameters.foundation(), amount);
        }
    }

    /**
     * @dev Deletes position and transfers collateral to liquidation system
     * @param asset The address of the main collateral token
     * @param positionOwner The address of a position's owner
     * @param initialPrice The starting price of collateral in USDP
     **/
    function triggerLiquidation(
        address asset,
        address positionOwner,
        uint initialPrice
    )
    external
    hasVaultAccess
    notLiquidating(asset, positionOwner)
    {
        // reverts if oracle type is disabled
        require(vaultParameters.isOracleTypeEnabled(oracleType[asset][positionOwner], asset), "Unit Protocol: WRONG_ORACLE_TYPE");

        // fix the debt
        debts[asset][positionOwner] = getTotalDebt(asset, positionOwner);

        liquidationBlock[asset][positionOwner] = block.number;
        liquidationPrice[asset][positionOwner] = initialPrice;
    }

    /**
     * @dev Internal liquidation process
     * @param asset The address of the main collateral token
     * @param positionOwner The address of a position's owner
     * @param mainAssetToLiquidator The amount of main asset to send to a liquidator
     * @param colToLiquidator The amount of COL to send to a liquidator
     * @param mainAssetToPositionOwner The amount of main asset to send to a position owner
     * @param colToPositionOwner The amount of COL to send to a position owner
     * @param repayment The repayment in USDP
     * @param penalty The liquidation penalty in USDP
     * @param liquidator The address of a liquidator
     **/
    function liquidate(
        address asset,
        address positionOwner,
        uint mainAssetToLiquidator,
        uint colToLiquidator,
        uint mainAssetToPositionOwner,
        uint colToPositionOwner,
        uint repayment,
        uint penalty,
        address liquidator
    )
        external
        hasVaultAccess
    {
        require(liquidationBlock[asset][positionOwner] != 0, "Unit Protocol: NOT_TRIGGERED_LIQUIDATION");

        uint mainAssetInPosition = collaterals[asset][positionOwner];
        uint mainAssetToFoundation = mainAssetInPosition.sub(mainAssetToLiquidator).sub(mainAssetToPositionOwner);

        uint colInPosition = colToken[asset][positionOwner];
        uint colToFoundation = colInPosition.sub(colToLiquidator).sub(colToPositionOwner);

        delete liquidationPrice[asset][positionOwner];
        delete liquidationBlock[asset][positionOwner];
        delete debts[asset][positionOwner];
        delete collaterals[asset][positionOwner];
        delete colToken[asset][positionOwner];

        destroy(asset, positionOwner);

        // charge liquidation fee and burn USDP
        if (repayment > penalty) {
            if (penalty != 0) {
                TransferHelper.safeTransferFrom(usdp, liquidator, vaultParameters.foundation(), penalty);
            }
            USDP(usdp).burn(liquidator, repayment.sub(penalty));
        } else {
            if (repayment != 0) {
                TransferHelper.safeTransferFrom(usdp, liquidator, vaultParameters.foundation(), repayment);
            }
        }

        // send the part of collateral to a liquidator
        if (mainAssetToLiquidator != 0) {
            TransferHelper.safeTransfer(asset, liquidator, mainAssetToLiquidator);
        }

        if (colToLiquidator != 0) {
            TransferHelper.safeTransfer(col, liquidator, colToLiquidator);
        }

        // send the rest of collateral to a position owner
        if (mainAssetToPositionOwner != 0) {
            TransferHelper.safeTransfer(asset, positionOwner, mainAssetToPositionOwner);
        }

        if (colToPositionOwner != 0) {
            TransferHelper.safeTransfer(col, positionOwner, colToPositionOwner);
        }

        if (mainAssetToFoundation != 0) {
            TransferHelper.safeTransfer(asset, vaultParameters.foundation(), mainAssetToFoundation);
        }

        if (colToFoundation != 0) {
            TransferHelper.safeTransfer(col, vaultParameters.foundation(), colToFoundation);
        }
    }

    /**
     * @notice Only manager can call this function
     * @dev Changes broken oracle type to the correct one
     * @param asset The address of the main collateral token
     * @param user The address of a position's owner
     * @param newOracleType The new type of an oracle
     **/
    function changeOracleType(address asset, address user, uint newOracleType) external onlyManager {
        oracleType[asset][user] = newOracleType;
    }

    /**
     * @dev Calculates the total amount of position's debt based on elapsed time
     * @param asset The address of the main collateral token
     * @param user The address of a position's owner
     * @return user debt of a position plus accumulated fee
     **/
    function getTotalDebt(address asset, address user) public view returns (uint) {
        uint debt = debts[asset][user];
        if (liquidationBlock[asset][user] != 0) return debt;
        uint fee = calculateFee(asset, user, debt);
        return debt.add(fee);
    }

    /**
     * @dev Calculates the amount of fee based on elapsed time and repayment amount
     * @param asset The address of the main collateral token
     * @param user The address of a position's owner
     * @param amount The repayment amount
     * @return fee amount
     **/
    function calculateFee(address asset, address user, uint amount) public view returns (uint) {
        uint sFeePercent = stabilityFee[asset][user];
        uint timePast = block.timestamp.sub(lastUpdate[asset][user]);

        return amount.mul(sFeePercent).mul(timePast).div(365 days).div(DENOMINATOR_1E5);
    }
}
        

Compiler Settings

{"remappings":[],"optimizer":{"runs":200,"enabled":true},"metadata":{"bytecodeHash":"ipfs"},"libraries":{},"evmVersion":"istanbul","compilationTarget":{"Vault.sol":"Vault"}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_parameters","internalType":"address"},{"type":"address","name":"_col","internalType":"address"},{"type":"address","name":"_usdp","internalType":"address"},{"type":"address","name":"_weth","internalType":"address payable"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"DENOMINATOR_1E2","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"DENOMINATOR_1E5","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"borrow","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"calculateFee","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeOracleType","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"newOracleType","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"chargeFee","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"col","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"colToken","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"collaterals","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"debts","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"depositCol","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"depositEth","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"depositMain","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"destroy","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTotalDebt","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastUpdate","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"liquidate","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"positionOwner","internalType":"address"},{"type":"uint256","name":"mainAssetToLiquidator","internalType":"uint256"},{"type":"uint256","name":"colToLiquidator","internalType":"uint256"},{"type":"uint256","name":"mainAssetToPositionOwner","internalType":"uint256"},{"type":"uint256","name":"colToPositionOwner","internalType":"uint256"},{"type":"uint256","name":"repayment","internalType":"uint256"},{"type":"uint256","name":"penalty","internalType":"uint256"},{"type":"address","name":"liquidator","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"liquidationBlock","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"liquidationFee","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"liquidationPrice","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"oracleType","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"repay","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"spawn","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"_oracleType","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"stabilityFee","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"tokenDebts","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"triggerLiquidation","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"positionOwner","internalType":"address"},{"type":"uint256","name":"initialPrice","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"usdp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract VaultParameters"}],"name":"vaultParameters","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"weth","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawCol","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawEth","inputs":[{"type":"address","name":"user","internalType":"address payable"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawMain","inputs":[{"type":"address","name":"asset","internalType":"address"},{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"receive","stateMutability":"payable"}]
              

Contract Creation Code

Verify & Publish
0x60e060405234801561001057600080fd5b506040516134d93803806134d98339818101604052608081101561003357600080fd5b50805160208201516040830151606093840151600080546001600160a01b0319166001600160a01b0395861617815583861b6001600160601b031990811660805283871b811660c0529582901b90951660a052918316939183169216906133cc9061010d903980610e0252806111d5528061127d528061131b5280611bca528061207d5250806102025280610a9d5280610b2a5280610b7a5280611729528061230e5280612393528061240d52806124605250806113d5528061141752806114d052806122be528061263a5280612c2652506133cc6000f3fe6080604052600436106101f25760003560e01c806388ad7a611161010d578063c1a3b9a6116100a0578063d4b93dbe1161006f578063d4b93dbe146108a2578063d6446d43146108dd578063e51e119e14610918578063ee18359e14610953578063f190439e1461099657610276565b8063c1a3b9a61461079e578063c640752d146107e1578063c6d894f01461081c578063d3511d6f1461085f57610276565b8063aa9c2c16116100dc578063aa9c2c16146106ed578063aca345ee14610728578063ad9d4ba31461073d578063b4da092c1461076357610276565b806388ad7a61146106455780638d7cad8814610680578063971182c6146106c3578063a78695b0146106d857610276565b806340f626e31161018557806362b40f9f1161015457806362b40f9f1461056f578063742a326e146105aa57806374e6076c146105ed5780637ca87cb61461060257610276565b806340f626e31461049957806347ba94f9146104ae5780634ac1c33d146104f15780635224372c1461052c57610276565b806330c77c7e116101c157806330c77c7e1461037f5780633ba0af81146103ba5780633d1aa963146104255780633fc8cef31461046857610276565b80630fbac4e61461027b5780631b9a91a4146102c85780631ce4b4a7146103015780631da649cf1461033c57610276565b3661027657336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610274576040805162461bcd60e51b815260206004820152601960248201527f556e69742050726f746f636f6c3a205245535452494354454400000000000000604482015290519081900360640190fd5b005b600080fd5b34801561028757600080fd5b506102b66004803603604081101561029e57600080fd5b506001600160a01b03813581169160200135166109c9565b60408051918252519081900360200190f35b3480156102d457600080fd5b50610274600480360360408110156102eb57600080fd5b506001600160a01b0381351690602001356109e6565b34801561030d57600080fd5b506102b66004803603604081101561032457600080fd5b506001600160a01b0381358116916020013516610c1c565b34801561034857600080fd5b506102b66004803603606081101561035f57600080fd5b506001600160a01b03813581169160208101359091169060400135610c39565b34801561038b57600080fd5b506102b6600480360360408110156103a257600080fd5b506001600160a01b0381358116916020013516610e91565b3480156103c657600080fd5b5061027460048036036101208110156103de57600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359160c08201359160e0810135916101009091013516610eae565b34801561043157600080fd5b506102746004803603606081101561044857600080fd5b506001600160a01b0381358116916020810135909116906040013561157c565b34801561047457600080fd5b5061047d611727565b604080516001600160a01b039092168252519081900360200190f35b3480156104a557600080fd5b506102b661174b565b3480156104ba57600080fd5b50610274600480360360608110156104d157600080fd5b506001600160a01b03813581169160208101359091169060400135611750565b3480156104fd57600080fd5b506102b66004803603604081101561051457600080fd5b506001600160a01b0381358116916020013516611832565b34801561053857600080fd5b506102b66004803603606081101561054f57600080fd5b506001600160a01b0381358116916020810135909116906040013561184f565b34801561057b57600080fd5b506102746004803603604081101561059257600080fd5b506001600160a01b0381358116916020013516611c88565b3480156105b657600080fd5b50610274600480360360608110156105cd57600080fd5b506001600160a01b03813581169160208101359091169060400135611e11565b3480156105f957600080fd5b5061047d61207b565b34801561060e57600080fd5b506102b66004803603606081101561062557600080fd5b506001600160a01b0381358116916020810135909116906040013561209f565b34801561065157600080fd5b506102b66004803603604081101561066857600080fd5b506001600160a01b038135811691602001351661211c565b34801561068c57600080fd5b50610274600480360360608110156106a357600080fd5b506001600160a01b03813581169160208101359091169060400135612139565b3480156106cf57600080fd5b506102b66122b5565b3480156106e457600080fd5b5061047d6122bc565b3480156106f957600080fd5b506102b66004803603604081101561071057600080fd5b506001600160a01b03813581169160200135166122e0565b34801561073457600080fd5b5061047d6122fd565b6102746004803603602081101561075357600080fd5b50356001600160a01b031661230c565b34801561076f57600080fd5b506102b66004803603604081101561078657600080fd5b506001600160a01b03813581169160200135166124a7565b3480156107aa57600080fd5b50610274600480360360608110156107c157600080fd5b506001600160a01b038135811691602081013590911690604001356124c4565b3480156107ed57600080fd5b506102746004803603604081101561080457600080fd5b506001600160a01b0381358116916020013516612660565b34801561082857600080fd5b506102746004803603606081101561083f57600080fd5b506001600160a01b03813581169160208101359091169060400135612950565b34801561086b57600080fd5b506102746004803603606081101561088257600080fd5b506001600160a01b03813581169160208101359091169060400135612ab0565b3480156108ae57600080fd5b506102b6600480360360408110156108c557600080fd5b506001600160a01b0381358116916020013516612c4d565b3480156108e957600080fd5b506102b66004803603604081101561090057600080fd5b506001600160a01b0381358116916020013516612c6a565b34801561092457600080fd5b506102b66004803603604081101561093b57600080fd5b506001600160a01b0381358116916020013516612cd7565b34801561095f57600080fd5b506102746004803603606081101561097657600080fd5b506001600160a01b03813581169160208101359091169060400135612cf4565b3480156109a257600080fd5b506102b6600480360360208110156109b957600080fd5b50356001600160a01b0316612e71565b600560209081526000928352604080842090915290825290205481565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015610a3057600080fd5b505afa158015610a44573d6000803e3d6000fd5b505050506040513d6020811015610a5a57600080fd5b5051610a9b576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03818116600090815260046020908152604080832093871683529290522054839015610b205760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600090815260016020908152604080832093881683529290522054610b709084612e83565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166000818152600160209081526040808320948a168352939052828120939093558151632e1a7d4d60e01b81526004810187905291519092632e1a7d4d926024808201939182900301818387803b158015610bf457600080fd5b505af1158015610c08573d6000803e3d6000fd5b50505050610c168484612e95565b50505050565b600460209081526000928352604080842090915290825290205481565b600080546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015610c8457600080fd5b505afa158015610c98573d6000803e3d6000fd5b505050506040513d6020811015610cae57600080fd5b5051610cef576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b038085166000908152600460209081526040808320938716835292905220548490849015610d555760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b6001600160a01b03808716600090815260036020908152604080832093891683529290522054610d858186612e83565b6001600160a01b038089166000818152600360209081526040808320948c168352938152838220949094559081526006909252902054610dc59086612e83565b6001600160a01b03808916600090815260066020526040808220939093558251632770a7eb60e21b815289831660048201526024810189905292517f000000000000000000000000000000000000000000000000000000000000000090921692639dc29fac926044808301939282900301818387803b158015610e4757600080fd5b505af1158015610e5b573d6000803e3d6000fd5b5050506001600160a01b038089166000908152600360209081526040808320938b16835292905220549450505050509392505050565b600960209081526000928352604080842090915290825290205481565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015610ef857600080fd5b505afa158015610f0c573d6000803e3d6000fd5b505050506040513d6020811015610f2257600080fd5b5051610f63576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b03808a166000908152600460209081526040808320938c1683529290522054610fc45760405162461bcd60e51b81526004018080602001828103825260288152602001806132e56028913960400191505060405180910390fd5b6001600160a01b03808a166000908152600160209081526040808320938c168352929052908120549061100187610ffb848c612e83565b90612e83565b6001600160a01b03808d166000908152600260209081526040808320938f1683529290529081205491925061103a88610ffb848d612e83565b9050600560008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002060009055600460008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002060009055600360008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002060009055600160008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002060009055600260008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008d6001600160a01b03166001600160a01b03168152602001908152602001600020600090556111c28d8d611c88565b85871115611310578515611273576112737f00000000000000000000000000000000000000000000000000000000000000008660008054906101000a90046001600160a01b03166001600160a01b03166341fbb0506040518163ffffffff1660e01b815260040160206040518083038186803b15801561124157600080fd5b505afa158015611255573d6000803e3d6000fd5b505050506040513d602081101561126b57600080fd5b505189612f8d565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016639dc29fac866112ad8a8a612e83565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156112f357600080fd5b505af1158015611307573d6000803e3d6000fd5b505050506113b9565b86156113b9576113b97f00000000000000000000000000000000000000000000000000000000000000008660008054906101000a90046001600160a01b03166001600160a01b03166341fbb0506040518163ffffffff1660e01b815260040160206040518083038186803b15801561138757600080fd5b505afa15801561139b573d6000803e3d6000fd5b505050506040513d60208110156113b157600080fd5b50518a612f8d565b8a156113ca576113ca8d868d6130ea565b89156113fb576113fb7f0000000000000000000000000000000000000000000000000000000000000000868c6130ea565b881561140c5761140c8d8d8b6130ea565b871561143d5761143d7f00000000000000000000000000000000000000000000000000000000000000008d8a6130ea565b82156114c5576114c58d60008054906101000a90046001600160a01b03166001600160a01b03166341fbb0506040518163ffffffff1660e01b815260040160206040518083038186803b15801561149357600080fd5b505afa1580156114a7573d6000803e3d6000fd5b505050506040513d60208110156114bd57600080fd5b5051856130ea565b801561156d5761156d7f000000000000000000000000000000000000000000000000000000000000000060008054906101000a90046001600160a01b03166001600160a01b03166341fbb0506040518163ffffffff1660e01b815260040160206040518083038186803b15801561153b57600080fd5b505afa15801561154f573d6000803e3d6000fd5b505050506040513d602081101561156557600080fd5b5051836130ea565b50505050505050505050505050565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b1580156115c657600080fd5b505afa1580156115da573d6000803e3d6000fd5b505050506040513d60208110156115f057600080fd5b5051611631576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b0380841660009081526004602090815260408083209386168352929052205483908390156116975760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b821561172057611720858560008054906101000a90046001600160a01b03166001600160a01b03166341fbb0506040518163ffffffff1660e01b815260040160206040518083038186803b1580156116ee57600080fd5b505afa158015611702573d6000803e3d6000fd5b505050506040513d602081101561171857600080fd5b505186612f8d565b5050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b606481565b6000546040805163f3ae241560e01b815233600482015290516001600160a01b039092169163f3ae241591602480820192602092909190829003018186803b15801561179b57600080fd5b505afa1580156117af573d6000803e3d6000fd5b505050506040513d60208110156117c557600080fd5b5051611806576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b0392831660009081526009602090815260408083209490951682529290925291902055565b600360209081526000928352604080842090915290825290205481565b600080546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b15801561189a57600080fd5b505afa1580156118ae573d6000803e3d6000fd5b505050506040513d60208110156118c457600080fd5b5051611905576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b03808516600090815260046020908152604080832093871683529290522054849084901561196b5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b600080546001600160a01b038881168084526009602090815260408086208b8516875282529485902054855163fec0feb360e01b8152600481019190915260248101929092529351919092169263fec0feb39260448082019391829003018186803b1580156119d957600080fd5b505afa1580156119ed573d6000803e3d6000fd5b505050506040513d6020811015611a0357600080fd5b5051611a56576040805162461bcd60e51b815260206004820181905260248201527f556e69742050726f746f636f6c3a2057524f4e475f4f5241434c455f54595045604482015290519081900360640190fd5b611a608686612660565b6001600160a01b03808716600090815260036020908152604080832093891683529290522054611a90908561324d565b6001600160a01b038088166000818152600360209081526040808320948b168352938152838220949094559081526006909252902054611ad0908561324d565b6001600160a01b038088166000818152600660209081526040808320959095559054845163797191dd60e11b815260048101939093529351939092169263f2e323ba92602480840193919291829003018186803b158015611b3057600080fd5b505afa158015611b44573d6000803e3d6000fd5b505050506040513d6020811015611b5a57600080fd5b50516001600160a01b0387166000908152600660205260409020541115611bc8576040805162461bcd60e51b815260206004820152601f60248201527f556e69742050726f746f636f6c3a2041535345545f444542545f4c494d495400604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166340c10f1986866040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611c3f57600080fd5b505af1158015611c53573d6000803e3d6000fd5b5050506001600160a01b038088166000908152600360209081526040808320938a168352929052205493505050509392505050565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015611cd257600080fd5b505afa158015611ce6573d6000803e3d6000fd5b505050506040513d6020811015611cfc57600080fd5b5051611d3d576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b038083166000908152600460209081526040808320938516835292905220548290829015611da35760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b50506001600160a01b03918216600081815260076020908152604080832094909516808352938152848220829055828252600981528482208483528152848220829055828252600a815284822084835281528482208290559181526008825283812092815291905290812055565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015611e5b57600080fd5b505afa158015611e6f573d6000803e3d6000fd5b505050506040513d6020811015611e8557600080fd5b5051611ec6576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b038084166000908152600460209081526040808320938616835292905220548390839015611f2c5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b600080546001600160a01b038781168084526009602090815260408086208a8516875282529485902054855163fec0feb360e01b8152600481019190915260248101929092529351919092169263fec0feb39260448082019391829003018186803b158015611f9a57600080fd5b505afa158015611fae573d6000803e3d6000fd5b505050506040513d6020811015611fc457600080fd5b5051612017576040805162461bcd60e51b815260206004820181905260248201527f556e69742050726f746f636f6c3a2057524f4e475f4f5241434c455f54595045604482015290519081900360640190fd5b6120218585612c6a565b6001600160a01b039586166000818152600360209081526040808320989099168083529781528882209390935581815260048352878120878252835287812043905590815260058252868120958152949052505091902055565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001600160a01b03808416600081815260076020908152604080832094871680845294825280832054938352600a82528083209483529390529182205482906120e9904290612e83565b9050612112620186a061210c6301e1338081856121068a8961325a565b9061325a565b9061327f565b9695505050505050565b600a60209081526000928352604080842090915290825290205481565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b15801561218357600080fd5b505afa158015612197573d6000803e3d6000fd5b505050506040513d60208110156121ad57600080fd5b50516121ee576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b0380841660009081526004602090815260408083209386168352929052205483908390156122545760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b6001600160a01b038086166000908152600160209081526040808320938816835292905220546122849084612e83565b6001600160a01b038087166000908152600160209081526040808320938916835292905220556117208585856130ea565b620186a081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600860209081526000928352604080842090915290825290205481565b6000546001600160a01b031681565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b038181166000908152600460209081526040808320938616835292905220548290156123915760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156123ec57600080fd5b505af1158015612400573d6000803e3d6000fd5b5050506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600090815260016020908152604080832093891683529290522054612456925090503461324d565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600090815260016020908152604080832097909316825295909552909320929092555050565b600260209081526000928352604080842090915290825290205481565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b15801561250e57600080fd5b505afa158015612522573d6000803e3d6000fd5b505050506040513d602081101561253857600080fd5b5051612579576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b0380841660009081526004602090815260408083209386168352929052205483908390156125df5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b6001600160a01b0380861660009081526002602090815260408083209388168352929052205461260f9084612e83565b6001600160a01b038087166000908152600260209081526040808320938916835292905220556117207f000000000000000000000000000000000000000000000000000000000000000085856130ea565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b1580156126aa57600080fd5b505afa1580156126be573d6000803e3d6000fd5b505050506040513d60208110156126d457600080fd5b5051612715576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b03808316600090815260046020908152604080832093851683529290522054829082901561277b5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b60006127878585612c6a565b6001600160a01b038087166000818152600360209081526040808320948a168352938152838220549282526006905291909120549192506127d49183916127ce9190612e83565b9061324d565b6001600160a01b03808716600081815260066020908152604080832095909555600381528482208985168352815284822086905590548451634cbd12b960e11b815260048101939093529351939092169263997a257292602480840193919291829003018186803b15801561284857600080fd5b505afa15801561285c573d6000803e3d6000fd5b505050506040513d602081101561287257600080fd5b50516001600160a01b0380871660008181526007602090815260408083208a86168452825280832095909555905484516332008ebd60e21b815260048101939093529351939092169263c8023af492602480840193919291829003018186803b1580156128de57600080fd5b505afa1580156128f2573d6000803e3d6000fd5b505050506040513d602081101561290857600080fd5b50516001600160a01b0395861660008181526008602090815260408083209890991680835297815288822093909355908152600a825286812095815294905250505020429055565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b15801561299a57600080fd5b505afa1580156129ae573d6000803e3d6000fd5b505050506040513d60208110156129c457600080fd5b5051612a05576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b038084166000908152600460209081526040808320938616835292905220548390839015612a6b5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b50506001600160a01b03928316600081815260096020908152604080832095909616808352948152858220939093559081526004825283812092815291905290812055565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015612afa57600080fd5b505afa158015612b0e573d6000803e3d6000fd5b505050506040513d6020811015612b2457600080fd5b5051612b65576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b038084166000908152600460209081526040808320938616835292905220548390839015612bcb5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b6001600160a01b03808616600090815260026020908152604080832093881683529290522054612bfb908461324d565b6001600160a01b038087166000908152600260209081526040808320938916835292905220556117207f0000000000000000000000000000000000000000000000000000000000000000853086612f8d565b600760209081526000928352604080842090915290825290205481565b6001600160a01b03808316600081815260036020908152604080832094861680845294825280832054938352600482528083209483529390529182205415612cb3579050612cd1565b6000612cc085858461209f565b9050612ccc828261324d565b925050505b92915050565b600160209081526000928352604080842090915290825290205481565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015612d3e57600080fd5b505afa158015612d52573d6000803e3d6000fd5b505050506040513d6020811015612d6857600080fd5b5051612da9576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b038084166000908152600460209081526040808320938616835292905220548390839015612e0f5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b6001600160a01b03808616600090815260016020908152604080832093881683529290522054612e3f908461324d565b6001600160a01b0380871660009081526001602090815260408083209389168352929052205561172085853086612f8d565b60066020526000908152604090205481565b600082821115612e8f57fe5b50900390565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b60208310612ee15780518252601f199092019160209182019101612ec2565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612f43576040519150601f19603f3d011682016040523d82523d6000602084013e612f48565b606091505b5050905080612f885760405162461bcd60e51b81526004018080602001828103825260238152602001806133506023913960400191505060405180910390fd5b505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17815292518251600094606094938a169392918291908083835b602083106130125780518252601f199092019160209182019101612ff3565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613074576040519150601f19603f3d011682016040523d82523d6000602084013e613079565b606091505b50915091508180156130a75750805115806130a757508080602001905160208110156130a457600080fd5b50515b6130e25760405162461bcd60e51b81526004018080602001828103825260248152602001806133736024913960400191505060405180910390fd5b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b178152925182516000946060949389169392918291908083835b602083106131675780518252601f199092019160209182019101613148565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146131c9576040519150601f19603f3d011682016040523d82523d6000602084013e6131ce565b606091505b50915091508180156131fc5750805115806131fc57508080602001905160208110156131f957600080fd5b50515b611720576040805162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604482015290519081900360640190fd5b81810182811015612cd157fe5b60008261326957506000612cd1565b508181028183828161327757fe5b0414612cd157fe5b6000816132d3576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b8183816132dc57fe5b04939250505056fe556e69742050726f746f636f6c3a204e4f545f5452494747455245445f4c49515549444154494f4e556e69742050726f746f636f6c3a204c49515549444154494e475f504f534954494f4e556e69742050726f746f636f6c3a20415554485f4641494c45440000000000005472616e7366657248656c7065723a204554485f5452414e534645525f4641494c45445472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c4544a26469706673582212203a58836158d05a30b90a521015e863619f5c833e531b28dcb047b10a6694ecf464736f6c63430007050033000000000000000000000000b46f8cf42e504efe8bef895f848741daa55e9f1d000000000000000000000000c76fb75950536d98fa62ea968e1d6b45ffea2a550000000000000000000000001456688345527be1f37e9e627da0837d6f08c925000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

Deployed ByteCode

0x6080604052600436106101f25760003560e01c806388ad7a611161010d578063c1a3b9a6116100a0578063d4b93dbe1161006f578063d4b93dbe146108a2578063d6446d43146108dd578063e51e119e14610918578063ee18359e14610953578063f190439e1461099657610276565b8063c1a3b9a61461079e578063c640752d146107e1578063c6d894f01461081c578063d3511d6f1461085f57610276565b8063aa9c2c16116100dc578063aa9c2c16146106ed578063aca345ee14610728578063ad9d4ba31461073d578063b4da092c1461076357610276565b806388ad7a61146106455780638d7cad8814610680578063971182c6146106c3578063a78695b0146106d857610276565b806340f626e31161018557806362b40f9f1161015457806362b40f9f1461056f578063742a326e146105aa57806374e6076c146105ed5780637ca87cb61461060257610276565b806340f626e31461049957806347ba94f9146104ae5780634ac1c33d146104f15780635224372c1461052c57610276565b806330c77c7e116101c157806330c77c7e1461037f5780633ba0af81146103ba5780633d1aa963146104255780633fc8cef31461046857610276565b80630fbac4e61461027b5780631b9a91a4146102c85780631ce4b4a7146103015780631da649cf1461033c57610276565b3661027657336001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21614610274576040805162461bcd60e51b815260206004820152601960248201527f556e69742050726f746f636f6c3a205245535452494354454400000000000000604482015290519081900360640190fd5b005b600080fd5b34801561028757600080fd5b506102b66004803603604081101561029e57600080fd5b506001600160a01b03813581169160200135166109c9565b60408051918252519081900360200190f35b3480156102d457600080fd5b50610274600480360360408110156102eb57600080fd5b506001600160a01b0381351690602001356109e6565b34801561030d57600080fd5b506102b66004803603604081101561032457600080fd5b506001600160a01b0381358116916020013516610c1c565b34801561034857600080fd5b506102b66004803603606081101561035f57600080fd5b506001600160a01b03813581169160208101359091169060400135610c39565b34801561038b57600080fd5b506102b6600480360360408110156103a257600080fd5b506001600160a01b0381358116916020013516610e91565b3480156103c657600080fd5b5061027460048036036101208110156103de57600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359160c08201359160e0810135916101009091013516610eae565b34801561043157600080fd5b506102746004803603606081101561044857600080fd5b506001600160a01b0381358116916020810135909116906040013561157c565b34801561047457600080fd5b5061047d611727565b604080516001600160a01b039092168252519081900360200190f35b3480156104a557600080fd5b506102b661174b565b3480156104ba57600080fd5b50610274600480360360608110156104d157600080fd5b506001600160a01b03813581169160208101359091169060400135611750565b3480156104fd57600080fd5b506102b66004803603604081101561051457600080fd5b506001600160a01b0381358116916020013516611832565b34801561053857600080fd5b506102b66004803603606081101561054f57600080fd5b506001600160a01b0381358116916020810135909116906040013561184f565b34801561057b57600080fd5b506102746004803603604081101561059257600080fd5b506001600160a01b0381358116916020013516611c88565b3480156105b657600080fd5b50610274600480360360608110156105cd57600080fd5b506001600160a01b03813581169160208101359091169060400135611e11565b3480156105f957600080fd5b5061047d61207b565b34801561060e57600080fd5b506102b66004803603606081101561062557600080fd5b506001600160a01b0381358116916020810135909116906040013561209f565b34801561065157600080fd5b506102b66004803603604081101561066857600080fd5b506001600160a01b038135811691602001351661211c565b34801561068c57600080fd5b50610274600480360360608110156106a357600080fd5b506001600160a01b03813581169160208101359091169060400135612139565b3480156106cf57600080fd5b506102b66122b5565b3480156106e457600080fd5b5061047d6122bc565b3480156106f957600080fd5b506102b66004803603604081101561071057600080fd5b506001600160a01b03813581169160200135166122e0565b34801561073457600080fd5b5061047d6122fd565b6102746004803603602081101561075357600080fd5b50356001600160a01b031661230c565b34801561076f57600080fd5b506102b66004803603604081101561078657600080fd5b506001600160a01b03813581169160200135166124a7565b3480156107aa57600080fd5b50610274600480360360608110156107c157600080fd5b506001600160a01b038135811691602081013590911690604001356124c4565b3480156107ed57600080fd5b506102746004803603604081101561080457600080fd5b506001600160a01b0381358116916020013516612660565b34801561082857600080fd5b506102746004803603606081101561083f57600080fd5b506001600160a01b03813581169160208101359091169060400135612950565b34801561086b57600080fd5b506102746004803603606081101561088257600080fd5b506001600160a01b03813581169160208101359091169060400135612ab0565b3480156108ae57600080fd5b506102b6600480360360408110156108c557600080fd5b506001600160a01b0381358116916020013516612c4d565b3480156108e957600080fd5b506102b66004803603604081101561090057600080fd5b506001600160a01b0381358116916020013516612c6a565b34801561092457600080fd5b506102b66004803603604081101561093b57600080fd5b506001600160a01b0381358116916020013516612cd7565b34801561095f57600080fd5b506102746004803603606081101561097657600080fd5b506001600160a01b03813581169160208101359091169060400135612cf4565b3480156109a257600080fd5b506102b6600480360360208110156109b957600080fd5b50356001600160a01b0316612e71565b600560209081526000928352604080842090915290825290205481565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015610a3057600080fd5b505afa158015610a44573d6000803e3d6000fd5b505050506040513d6020811015610a5a57600080fd5b5051610a9b576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03818116600090815260046020908152604080832093871683529290522054839015610b205760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28116600090815260016020908152604080832093881683529290522054610b709084612e83565b6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281166000818152600160209081526040808320948a168352939052828120939093558151632e1a7d4d60e01b81526004810187905291519092632e1a7d4d926024808201939182900301818387803b158015610bf457600080fd5b505af1158015610c08573d6000803e3d6000fd5b50505050610c168484612e95565b50505050565b600460209081526000928352604080842090915290825290205481565b600080546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015610c8457600080fd5b505afa158015610c98573d6000803e3d6000fd5b505050506040513d6020811015610cae57600080fd5b5051610cef576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b038085166000908152600460209081526040808320938716835292905220548490849015610d555760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b6001600160a01b03808716600090815260036020908152604080832093891683529290522054610d858186612e83565b6001600160a01b038089166000818152600360209081526040808320948c168352938152838220949094559081526006909252902054610dc59086612e83565b6001600160a01b03808916600090815260066020526040808220939093558251632770a7eb60e21b815289831660048201526024810189905292517f0000000000000000000000001456688345527be1f37e9e627da0837d6f08c92590921692639dc29fac926044808301939282900301818387803b158015610e4757600080fd5b505af1158015610e5b573d6000803e3d6000fd5b5050506001600160a01b038089166000908152600360209081526040808320938b16835292905220549450505050509392505050565b600960209081526000928352604080842090915290825290205481565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015610ef857600080fd5b505afa158015610f0c573d6000803e3d6000fd5b505050506040513d6020811015610f2257600080fd5b5051610f63576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b03808a166000908152600460209081526040808320938c1683529290522054610fc45760405162461bcd60e51b81526004018080602001828103825260288152602001806132e56028913960400191505060405180910390fd5b6001600160a01b03808a166000908152600160209081526040808320938c168352929052908120549061100187610ffb848c612e83565b90612e83565b6001600160a01b03808d166000908152600260209081526040808320938f1683529290529081205491925061103a88610ffb848d612e83565b9050600560008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002060009055600460008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002060009055600360008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002060009055600160008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002060009055600260008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008d6001600160a01b03166001600160a01b03168152602001908152602001600020600090556111c28d8d611c88565b85871115611310578515611273576112737f0000000000000000000000001456688345527be1f37e9e627da0837d6f08c9258660008054906101000a90046001600160a01b03166001600160a01b03166341fbb0506040518163ffffffff1660e01b815260040160206040518083038186803b15801561124157600080fd5b505afa158015611255573d6000803e3d6000fd5b505050506040513d602081101561126b57600080fd5b505189612f8d565b6001600160a01b037f0000000000000000000000001456688345527be1f37e9e627da0837d6f08c92516639dc29fac866112ad8a8a612e83565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156112f357600080fd5b505af1158015611307573d6000803e3d6000fd5b505050506113b9565b86156113b9576113b97f0000000000000000000000001456688345527be1f37e9e627da0837d6f08c9258660008054906101000a90046001600160a01b03166001600160a01b03166341fbb0506040518163ffffffff1660e01b815260040160206040518083038186803b15801561138757600080fd5b505afa15801561139b573d6000803e3d6000fd5b505050506040513d60208110156113b157600080fd5b50518a612f8d565b8a156113ca576113ca8d868d6130ea565b89156113fb576113fb7f000000000000000000000000c76fb75950536d98fa62ea968e1d6b45ffea2a55868c6130ea565b881561140c5761140c8d8d8b6130ea565b871561143d5761143d7f000000000000000000000000c76fb75950536d98fa62ea968e1d6b45ffea2a558d8a6130ea565b82156114c5576114c58d60008054906101000a90046001600160a01b03166001600160a01b03166341fbb0506040518163ffffffff1660e01b815260040160206040518083038186803b15801561149357600080fd5b505afa1580156114a7573d6000803e3d6000fd5b505050506040513d60208110156114bd57600080fd5b5051856130ea565b801561156d5761156d7f000000000000000000000000c76fb75950536d98fa62ea968e1d6b45ffea2a5560008054906101000a90046001600160a01b03166001600160a01b03166341fbb0506040518163ffffffff1660e01b815260040160206040518083038186803b15801561153b57600080fd5b505afa15801561154f573d6000803e3d6000fd5b505050506040513d602081101561156557600080fd5b5051836130ea565b50505050505050505050505050565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b1580156115c657600080fd5b505afa1580156115da573d6000803e3d6000fd5b505050506040513d60208110156115f057600080fd5b5051611631576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b0380841660009081526004602090815260408083209386168352929052205483908390156116975760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b821561172057611720858560008054906101000a90046001600160a01b03166001600160a01b03166341fbb0506040518163ffffffff1660e01b815260040160206040518083038186803b1580156116ee57600080fd5b505afa158015611702573d6000803e3d6000fd5b505050506040513d602081101561171857600080fd5b505186612f8d565b5050505050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b606481565b6000546040805163f3ae241560e01b815233600482015290516001600160a01b039092169163f3ae241591602480820192602092909190829003018186803b15801561179b57600080fd5b505afa1580156117af573d6000803e3d6000fd5b505050506040513d60208110156117c557600080fd5b5051611806576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b0392831660009081526009602090815260408083209490951682529290925291902055565b600360209081526000928352604080842090915290825290205481565b600080546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b15801561189a57600080fd5b505afa1580156118ae573d6000803e3d6000fd5b505050506040513d60208110156118c457600080fd5b5051611905576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b03808516600090815260046020908152604080832093871683529290522054849084901561196b5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b600080546001600160a01b038881168084526009602090815260408086208b8516875282529485902054855163fec0feb360e01b8152600481019190915260248101929092529351919092169263fec0feb39260448082019391829003018186803b1580156119d957600080fd5b505afa1580156119ed573d6000803e3d6000fd5b505050506040513d6020811015611a0357600080fd5b5051611a56576040805162461bcd60e51b815260206004820181905260248201527f556e69742050726f746f636f6c3a2057524f4e475f4f5241434c455f54595045604482015290519081900360640190fd5b611a608686612660565b6001600160a01b03808716600090815260036020908152604080832093891683529290522054611a90908561324d565b6001600160a01b038088166000818152600360209081526040808320948b168352938152838220949094559081526006909252902054611ad0908561324d565b6001600160a01b038088166000818152600660209081526040808320959095559054845163797191dd60e11b815260048101939093529351939092169263f2e323ba92602480840193919291829003018186803b158015611b3057600080fd5b505afa158015611b44573d6000803e3d6000fd5b505050506040513d6020811015611b5a57600080fd5b50516001600160a01b0387166000908152600660205260409020541115611bc8576040805162461bcd60e51b815260206004820152601f60248201527f556e69742050726f746f636f6c3a2041535345545f444542545f4c494d495400604482015290519081900360640190fd5b7f0000000000000000000000001456688345527be1f37e9e627da0837d6f08c9256001600160a01b03166340c10f1986866040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611c3f57600080fd5b505af1158015611c53573d6000803e3d6000fd5b5050506001600160a01b038088166000908152600360209081526040808320938a168352929052205493505050509392505050565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015611cd257600080fd5b505afa158015611ce6573d6000803e3d6000fd5b505050506040513d6020811015611cfc57600080fd5b5051611d3d576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b038083166000908152600460209081526040808320938516835292905220548290829015611da35760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b50506001600160a01b03918216600081815260076020908152604080832094909516808352938152848220829055828252600981528482208483528152848220829055828252600a815284822084835281528482208290559181526008825283812092815291905290812055565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015611e5b57600080fd5b505afa158015611e6f573d6000803e3d6000fd5b505050506040513d6020811015611e8557600080fd5b5051611ec6576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b038084166000908152600460209081526040808320938616835292905220548390839015611f2c5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b600080546001600160a01b038781168084526009602090815260408086208a8516875282529485902054855163fec0feb360e01b8152600481019190915260248101929092529351919092169263fec0feb39260448082019391829003018186803b158015611f9a57600080fd5b505afa158015611fae573d6000803e3d6000fd5b505050506040513d6020811015611fc457600080fd5b5051612017576040805162461bcd60e51b815260206004820181905260248201527f556e69742050726f746f636f6c3a2057524f4e475f4f5241434c455f54595045604482015290519081900360640190fd5b6120218585612c6a565b6001600160a01b039586166000818152600360209081526040808320989099168083529781528882209390935581815260048352878120878252835287812043905590815260058252868120958152949052505091902055565b7f0000000000000000000000001456688345527be1f37e9e627da0837d6f08c92581565b6001600160a01b03808416600081815260076020908152604080832094871680845294825280832054938352600a82528083209483529390529182205482906120e9904290612e83565b9050612112620186a061210c6301e1338081856121068a8961325a565b9061325a565b9061327f565b9695505050505050565b600a60209081526000928352604080842090915290825290205481565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b15801561218357600080fd5b505afa158015612197573d6000803e3d6000fd5b505050506040513d60208110156121ad57600080fd5b50516121ee576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b0380841660009081526004602090815260408083209386168352929052205483908390156122545760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b6001600160a01b038086166000908152600160209081526040808320938816835292905220546122849084612e83565b6001600160a01b038087166000908152600160209081526040808320938916835292905220556117208585856130ea565b620186a081565b7f000000000000000000000000c76fb75950536d98fa62ea968e1d6b45ffea2a5581565b600860209081526000928352604080842090915290825290205481565b6000546001600160a01b031681565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b038181166000908152600460209081526040808320938616835292905220548290156123915760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156123ec57600080fd5b505af1158015612400573d6000803e3d6000fd5b5050506001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28116600090815260016020908152604080832093891683529290522054612456925090503461324d565b6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28116600090815260016020908152604080832097909316825295909552909320929092555050565b600260209081526000928352604080842090915290825290205481565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b15801561250e57600080fd5b505afa158015612522573d6000803e3d6000fd5b505050506040513d602081101561253857600080fd5b5051612579576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b0380841660009081526004602090815260408083209386168352929052205483908390156125df5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b6001600160a01b0380861660009081526002602090815260408083209388168352929052205461260f9084612e83565b6001600160a01b038087166000908152600260209081526040808320938916835292905220556117207f000000000000000000000000c76fb75950536d98fa62ea968e1d6b45ffea2a5585856130ea565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b1580156126aa57600080fd5b505afa1580156126be573d6000803e3d6000fd5b505050506040513d60208110156126d457600080fd5b5051612715576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b03808316600090815260046020908152604080832093851683529290522054829082901561277b5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b60006127878585612c6a565b6001600160a01b038087166000818152600360209081526040808320948a168352938152838220549282526006905291909120549192506127d49183916127ce9190612e83565b9061324d565b6001600160a01b03808716600081815260066020908152604080832095909555600381528482208985168352815284822086905590548451634cbd12b960e11b815260048101939093529351939092169263997a257292602480840193919291829003018186803b15801561284857600080fd5b505afa15801561285c573d6000803e3d6000fd5b505050506040513d602081101561287257600080fd5b50516001600160a01b0380871660008181526007602090815260408083208a86168452825280832095909555905484516332008ebd60e21b815260048101939093529351939092169263c8023af492602480840193919291829003018186803b1580156128de57600080fd5b505afa1580156128f2573d6000803e3d6000fd5b505050506040513d602081101561290857600080fd5b50516001600160a01b0395861660008181526008602090815260408083209890991680835297815288822093909355908152600a825286812095815294905250505020429055565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b15801561299a57600080fd5b505afa1580156129ae573d6000803e3d6000fd5b505050506040513d60208110156129c457600080fd5b5051612a05576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b038084166000908152600460209081526040808320938616835292905220548390839015612a6b5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b50506001600160a01b03928316600081815260096020908152604080832095909616808352948152858220939093559081526004825283812092815291905290812055565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015612afa57600080fd5b505afa158015612b0e573d6000803e3d6000fd5b505050506040513d6020811015612b2457600080fd5b5051612b65576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b038084166000908152600460209081526040808320938616835292905220548390839015612bcb5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b6001600160a01b03808616600090815260026020908152604080832093881683529290522054612bfb908461324d565b6001600160a01b038087166000908152600260209081526040808320938916835292905220556117207f000000000000000000000000c76fb75950536d98fa62ea968e1d6b45ffea2a55853086612f8d565b600760209081526000928352604080842090915290825290205481565b6001600160a01b03808316600081815260036020908152604080832094861680845294825280832054938352600482528083209483529390529182205415612cb3579050612cd1565b6000612cc085858461209f565b9050612ccc828261324d565b925050505b92915050565b600160209081526000928352604080842090915290825290205481565b6000546040805162db063b60e41b815233600482015290516001600160a01b0390921691630db063b091602480820192602092909190829003018186803b158015612d3e57600080fd5b505afa158015612d52573d6000803e3d6000fd5b505050506040513d6020811015612d6857600080fd5b5051612da9576040805162461bcd60e51b815260206004820152601a6024820152600080516020613330833981519152604482015290519081900360640190fd5b6001600160a01b038084166000908152600460209081526040808320938616835292905220548390839015612e0f5760405162461bcd60e51b815260040180806020018281038252602381526020018061330d6023913960400191505060405180910390fd5b6001600160a01b03808616600090815260016020908152604080832093881683529290522054612e3f908461324d565b6001600160a01b0380871660009081526001602090815260408083209389168352929052205561172085853086612f8d565b60066020526000908152604090205481565b600082821115612e8f57fe5b50900390565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b60208310612ee15780518252601f199092019160209182019101612ec2565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612f43576040519150601f19603f3d011682016040523d82523d6000602084013e612f48565b606091505b5050905080612f885760405162461bcd60e51b81526004018080602001828103825260238152602001806133506023913960400191505060405180910390fd5b505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17815292518251600094606094938a169392918291908083835b602083106130125780518252601f199092019160209182019101612ff3565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613074576040519150601f19603f3d011682016040523d82523d6000602084013e613079565b606091505b50915091508180156130a75750805115806130a757508080602001905160208110156130a457600080fd5b50515b6130e25760405162461bcd60e51b81526004018080602001828103825260248152602001806133736024913960400191505060405180910390fd5b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b178152925182516000946060949389169392918291908083835b602083106131675780518252601f199092019160209182019101613148565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146131c9576040519150601f19603f3d011682016040523d82523d6000602084013e6131ce565b606091505b50915091508180156131fc5750805115806131fc57508080602001905160208110156131f957600080fd5b50515b611720576040805162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604482015290519081900360640190fd5b81810182811015612cd157fe5b60008261326957506000612cd1565b508181028183828161327757fe5b0414612cd157fe5b6000816132d3576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b8183816132dc57fe5b04939250505056fe556e69742050726f746f636f6c3a204e4f545f5452494747455245445f4c49515549444154494f4e556e69742050726f746f636f6c3a204c49515549444154494e475f504f534954494f4e556e69742050726f746f636f6c3a20415554485f4641494c45440000000000005472616e7366657248656c7065723a204554485f5452414e534645525f4641494c45445472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c4544a26469706673582212203a58836158d05a30b90a521015e863619f5c833e531b28dcb047b10a6694ecf464736f6c63430007050033