ETH Price: $3,068.30 (-3.40%)
Gas: 5 Gwei

Contract

0x7e497Be7532CC4954D73c6dF93F016c53CC0C29a
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Set Governance113022672020-11-21 15:23:531262 days ago1605972233IN
0x7e497Be7...53CC0C29a
0 ETH0.0026527590
Set Theta113020102020-11-21 14:30:401262 days ago1605969040IN
0x7e497Be7...53CC0C29a
0 ETH0.0029739666
Set Theta113020082020-11-21 14:30:201262 days ago1605969020IN
0x7e497Be7...53CC0C29a
0 ETH0.0029739666
Activate113020072020-11-21 14:30:081262 days ago1605969008IN
0x7e497Be7...53CC0C29a
0 ETH0.0110295966
0x60e06040113019992020-11-21 14:29:101262 days ago1605968950IN
 Create: CoFiXControllerV2
0 ETH0.1388417566

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To Value
116942952021-01-20 19:33:341202 days ago1611171214
0x7e497Be7...53CC0C29a
0.01 ETH
116942952021-01-20 19:33:341202 days ago1611171214
0x7e497Be7...53CC0C29a
0.01 ETH
116875352021-01-19 19:04:011203 days ago1611083041
0x7e497Be7...53CC0C29a
0.01 ETH
116875352021-01-19 19:04:011203 days ago1611083041
0x7e497Be7...53CC0C29a
0.01 ETH
116866102021-01-19 15:40:031203 days ago1611070803
0x7e497Be7...53CC0C29a
0.01 ETH
116866102021-01-19 15:40:031203 days ago1611070803
0x7e497Be7...53CC0C29a
0.01 ETH
116861412021-01-19 13:58:041203 days ago1611064684
0x7e497Be7...53CC0C29a
0.01 ETH
116861412021-01-19 13:58:041203 days ago1611064684
0x7e497Be7...53CC0C29a
0.01 ETH
116855502021-01-19 11:47:281203 days ago1611056848
0x7e497Be7...53CC0C29a
0.01 ETH
116855502021-01-19 11:47:281203 days ago1611056848
0x7e497Be7...53CC0C29a
0.01 ETH
116855332021-01-19 11:43:421203 days ago1611056622
0x7e497Be7...53CC0C29a
0.01 ETH
116855332021-01-19 11:43:421203 days ago1611056622
0x7e497Be7...53CC0C29a
0.01 ETH
116845042021-01-19 7:58:041203 days ago1611043084
0x7e497Be7...53CC0C29a
0.01 ETH
116845042021-01-19 7:58:041203 days ago1611043084
0x7e497Be7...53CC0C29a
0.01 ETH
116844782021-01-19 7:51:291203 days ago1611042689
0x7e497Be7...53CC0C29a
0.01 ETH
116844782021-01-19 7:51:291203 days ago1611042689
0x7e497Be7...53CC0C29a
0.01 ETH
116844762021-01-19 7:51:121203 days ago1611042672
0x7e497Be7...53CC0C29a
0.01 ETH
116844762021-01-19 7:51:121203 days ago1611042672
0x7e497Be7...53CC0C29a
0.01 ETH
116844592021-01-19 7:45:481203 days ago1611042348
0x7e497Be7...53CC0C29a
0.01 ETH
116844592021-01-19 7:45:481203 days ago1611042348
0x7e497Be7...53CC0C29a
0.01 ETH
116842902021-01-19 7:08:391203 days ago1611040119
0x7e497Be7...53CC0C29a
0.01 ETH
116842902021-01-19 7:08:391203 days ago1611040119
0x7e497Be7...53CC0C29a
0.01 ETH
116842152021-01-19 6:51:591203 days ago1611039119
0x7e497Be7...53CC0C29a
0.01 ETH
116842152021-01-19 6:51:591203 days ago1611039119
0x7e497Be7...53CC0C29a
0.01 ETH
116840392021-01-19 6:09:521204 days ago1611036592
0x7e497Be7...53CC0C29a
0.01 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CoFiXControllerV2

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 6666 runs

Other Settings:
default evmVersion
File 1 of 11 : CoFiXControllerV2.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.6.12;

import "@openzeppelin/contracts/math/SafeMath.sol";
import "./lib/ABDKMath64x64.sol";
import "./interface/INest_3_OfferPrice.sol";
import "./interface/ICoFiXKTable.sol";
import "./lib/TransferHelper.sol";
import "./interface/ICoFiXController.sol";
import "./interface/INest_3_VoteFactory.sol";
import "./interface/ICoFiXPair.sol";
import "./interface/ICoFiXFactory.sol";

// Controller contract to call NEST Oracle for prices, managed by governance
// Governance role of this contract should be the `Timelock` contract, which is further managed by a multisig contract
contract CoFiXControllerV2 is ICoFiXController {  // ctrl-v2: change contract name to avoid truffle complaint

    using SafeMath for uint256;

    enum CoFiX_OP { QUERY, MINT, BURN, SWAP_WITH_EXACT, SWAP_FOR_EXACT } // operations in CoFiX

    uint256 constant public AONE = 1 ether;
    uint256 constant public K_BASE = 1E8;
    uint256 constant public NAVPS_BASE = 1E18; // NAVPS (Net Asset Value Per Share), need accuracy
    uint256 internal T = 600; // ctrl-v2: V1 (900) -> V2 (600)
    uint256 internal K_EXPECTED_VALUE = 0.005*1E8; // ctrl-v2: V1 (0.0025) -> V2 (0.005)
    // impact cost params
    uint256 constant internal C_BUYIN_ALPHA = 25700000000000; // α=2.570e-05*1e18
    uint256 constant internal C_BUYIN_BETA = 854200000000; // β=8.542e-07*1e18
    uint256 constant internal C_SELLOUT_ALPHA = 117100000000000; // α=-1.171e-04*1e18
    uint256 constant internal C_SELLOUT_BETA = 838600000000; // β=8.386e-07*1e18

    mapping(address => uint32[3]) internal KInfoMap; // gas saving, index [0] is k vlaue, index [1] is updatedAt, index [2] is theta
    mapping(address => bool) public callerAllowed;

    INest_3_VoteFactory public immutable voteFactory;

    // managed by governance
    address public governance;
    address public immutable nestToken;
    address public immutable factory;
    address public kTable;
    uint256 public timespan = 14;
    uint256 public kRefreshInterval = 5 minutes;
    uint256 public DESTRUCTION_AMOUNT = 0 ether; // from nest oracle
    int128 public MAX_K0 = 0xCCCCCCCCCCCCD00; // (0.05*2**64).toString(16)
    int128 public GAMMA = 0x8000000000000000; // (0.5*2**64).toString(16)

    modifier onlyGovernance() {
        require(msg.sender == governance, "CoFiXCtrl: !governance");
        _;
    }

    constructor(address _voteFactory, address _nest, address _factory, address _kTable) public {
        governance = msg.sender;
        voteFactory = INest_3_VoteFactory(address(_voteFactory));
        nestToken = _nest;
        factory = _factory;
        kTable = _kTable;

        // add previous pair as caller
        ICoFiXFactory cFactory = ICoFiXFactory(_factory);
        uint256 pairCnt = cFactory.allPairsLength();
        for (uint256 i = 0; i < pairCnt; i++) {
            address pair = cFactory.allPairs(i);
            callerAllowed[pair] = true;
        }
    }

    receive() external payable {}

    /* setters for protocol governance */
    function setGovernance(address _new) external onlyGovernance {
        governance = _new;
        emit NewGovernance(_new);
    }

    function setKTable(address _kTable) external onlyGovernance {
        kTable = _kTable;
        emit NewKTable(_kTable);
    }    

    function setTimespan(uint256 _timeSpan) external onlyGovernance {
        timespan = _timeSpan;
        emit NewTimespan(_timeSpan);
    }

    function setKRefreshInterval(uint256 _interval) external onlyGovernance {
        kRefreshInterval = _interval;
        emit NewKRefreshInterval(_interval);
    }

    function setOracleDestructionAmount(uint256 _amount) external onlyGovernance {
        DESTRUCTION_AMOUNT = _amount;
    }

    function setTLimit(uint256 _T) external onlyGovernance { // ctrl-v2: new setter for T
        T = _T;
    }

    function setK(address token, uint32 k) external onlyGovernance { // ctrl-v2: new setter for K, adjustable by governance
        K_EXPECTED_VALUE = uint256(k);
        emit NewK(token, k); // new event for setting K
    }

    function setTheta(address token, uint32 theta) external onlyGovernance {
        KInfoMap[token][2] = theta;
        emit NewTheta(token, theta);
    }

    // Activate on NEST Oracle, should not be called twice for the same nest oracle
    function activate() external onlyGovernance {
        // address token, address from, address to, uint value
        TransferHelper.safeTransferFrom(nestToken, msg.sender, address(this), DESTRUCTION_AMOUNT);
        address oracle = voteFactory.checkAddress("nest.v3.offerPrice");
        // address token, address to, uint value
        TransferHelper.safeApprove(nestToken, oracle, DESTRUCTION_AMOUNT);
        INest_3_OfferPrice(oracle).activation(); // nest.transferFrom will be called
        TransferHelper.safeApprove(nestToken, oracle, 0); // ensure safety
    }

    function addCaller(address caller) external override {
        require(msg.sender == factory || msg.sender == governance, "CoFiXCtrl: only factory or gov");
        callerAllowed[caller] = true;
    }

    // Calc variance of price and K in CoFiX is very expensive
    // We use expected value of K based on statistical calculations here to save gas
    // In the near future, NEST could provide the variance of price directly. We will adopt it then.
    // We can make use of `data` bytes in the future
    function queryOracle(address token, uint8 op, bytes memory data) external override payable returns (uint256 _k, uint256 _ethAmount, uint256 _erc20Amount, uint256 _blockNum, uint256 _theta) {
        require(callerAllowed[msg.sender], "CoFiXCtrl: caller not allowed");
        (_ethAmount, _erc20Amount, _blockNum) = getLatestPrice(token);
        CoFiX_OP cop = CoFiX_OP(op);
        uint256 impactCost;
        if (cop == CoFiX_OP.SWAP_WITH_EXACT) {
            impactCost = calcImpactCostFor_SWAP_WITH_EXACT(token, data, _ethAmount, _erc20Amount);
        } else if (cop == CoFiX_OP.SWAP_FOR_EXACT) {
            revert("disabled experimental feature!"); // ctrl-v2: disable swapForExact function
         } else if (cop == CoFiX_OP.BURN) {
            impactCost = calcImpactCostFor_BURN(token, data, _ethAmount, _erc20Amount);
        }
        _k = K_EXPECTED_VALUE.add(impactCost); // ctrl-v2: adjustable K + impactCost is the final K
        _theta = KInfoMap[token][2];
        return (_k, _ethAmount, _erc20Amount, _blockNum, _theta);
    }

    function calcImpactCostFor_BURN(address token, bytes memory data, uint256 ethAmount, uint256 erc20Amount) public view returns (uint256 impactCost) {
        // bytes memory data = abi.encode(msg.sender, outToken, to, liquidity);
        (, address outToken, , uint256 liquidity) = abi.decode(data, (address, address, address, uint256));
        // calc real vol by liquidity * np
        uint256 navps = ICoFiXPair(msg.sender).getNAVPerShare(ethAmount, erc20Amount); // pair call controller, msg.sender is pair
        uint256 vol = liquidity.mul(navps).div(NAVPS_BASE);
        if (outToken != token) {
            // buy in ETH, outToken is ETH
            return impactCostForBuyInETH(vol);
        }
        // sell out liquidity, outToken is token, take this as sell out ETH and get token
        return impactCostForSellOutETH(vol);
    }

    function calcImpactCostFor_SWAP_WITH_EXACT(address token, bytes memory data, uint256 ethAmount, uint256 erc20Amount) public pure returns (uint256 impactCost) {
        (, address outToken, , uint256 amountIn) = abi.decode(data, (address, address, address, uint256));
        if (outToken != token) {
            // buy in ETH, outToken is ETH, amountIn is token
            // convert to amountIn in ETH
            uint256 vol = uint256(amountIn).mul(ethAmount).div(erc20Amount);
            return impactCostForBuyInETH(vol);
        }
        // sell out ETH, amountIn is ETH
        return impactCostForSellOutETH(amountIn);
    }

    function calcImpactCostFor_SWAP_FOR_EXACT(address token, bytes memory data, uint256 ethAmount, uint256 erc20Amount) public pure returns (uint256 impactCost) {
        (, address outToken, uint256 amountOutExact,) = abi.decode(data, (address, address, uint256, address));
        if (outToken != token) {
            // buy in ETH, outToken is ETH, amountOutExact is ETH
            return impactCostForBuyInETH(amountOutExact);
        }
        // sell out ETH, amountIn is ETH, amountOutExact is token
        // convert to amountOutExact in ETH
        uint256 vol = uint256(amountOutExact).mul(ethAmount).div(erc20Amount);
        return impactCostForSellOutETH(vol);
    }

    // impact cost
    // - C = 0, if VOL < 500
    // - C = α + β * VOL, if VOL >= 500

    // α=2.570e-05,β=8.542e-07
    function impactCostForBuyInETH(uint256 vol) public pure returns (uint256 impactCost) {
        if (vol < 500 ether) {
            return 0;
        }
        // return C_BUYIN_ALPHA.add(C_BUYIN_BETA.mul(vol).div(1e18)).mul(1e8).div(1e18);
        return C_BUYIN_ALPHA.add(C_BUYIN_BETA.mul(vol).div(1e18)).div(1e10); // combine mul div
    }

    // α=-1.171e-04,β=8.386e-07
    function impactCostForSellOutETH(uint256 vol) public pure returns (uint256 impactCost) {
        if (vol < 500 ether) {
            return 0;
        }
        // return (C_SELLOUT_BETA.mul(vol).div(1e18)).sub(C_SELLOUT_ALPHA).mul(1e8).div(1e18);
        return (C_SELLOUT_BETA.mul(vol).div(1e18)).sub(C_SELLOUT_ALPHA).div(1e10); // combine mul div
    }

    function getKInfo(address token) external view returns (uint32 k, uint32 updatedAt, uint32 theta) {
        k = uint32(K_EXPECTED_VALUE); // ctrl-v2: load from storage instead of constant value
        updatedAt = uint32(block.timestamp);
        theta = KInfoMap[token][2];
    }

    function getLatestPrice(address token) internal returns (uint256 _ethAmount, uint256 _erc20Amount, uint256 _blockNum) {
        uint256 _balanceBefore = address(this).balance;
        address oracle = voteFactory.checkAddress("nest.v3.offerPrice");
        uint256[] memory _rawPriceList = INest_3_OfferPrice(oracle).updateAndCheckPriceList{value: msg.value}(token, 1);
        require(_rawPriceList.length == 3, "CoFiXCtrl: bad price len");
        // validate T
        uint256 _T = block.number.sub(_rawPriceList[2]).mul(timespan);
        require(_T < T, "CoFiXCtrl: oralce price outdated"); // ctrl-v2: adjustable T
        uint256 oracleFeeChange = msg.value.sub(_balanceBefore.sub(address(this).balance));
        if (oracleFeeChange > 0) TransferHelper.safeTransferETH(msg.sender, oracleFeeChange);
        return (_rawPriceList[0], _rawPriceList[1], _rawPriceList[2]);
        // return (K_EXPECTED_VALUE, _rawPriceList[0], _rawPriceList[1], _rawPriceList[2], KInfoMap[token][2]);
    }
    
    // ctrl-v2: remove unused code bellow according to PeckShield's advice
}

File 3 of 11 : ICoFiXController.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.6.12;

interface ICoFiXController {

    event NewK(address token, int128 K, int128 sigma, uint256 T, uint256 ethAmount, uint256 erc20Amount, uint256 blockNum, uint256 tIdx, uint256 sigmaIdx, int128 K0);
    event NewGovernance(address _new);
    event NewOracle(address _priceOracle);
    event NewKTable(address _kTable);
    event NewTimespan(uint256 _timeSpan);
    event NewKRefreshInterval(uint256 _interval);
    event NewKLimit(int128 maxK0);
    event NewGamma(int128 _gamma);
    event NewTheta(address token, uint32 theta);
    event NewK(address token, uint32 k);

    function addCaller(address caller) external;

    function queryOracle(address token, uint8 op, bytes memory data) external payable returns (uint256 k, uint256 ethAmount, uint256 erc20Amount, uint256 blockNum, uint256 theta);
}

File 4 of 11 : ICoFiXERC20.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.6.12;

interface ICoFiXERC20 {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    // function name() external pure returns (string memory);
    // function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
}

File 5 of 11 : ICoFiXFactory.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.6.12;

interface ICoFiXFactory {
    // All pairs: {ETH <-> ERC20 Token}
    event PairCreated(address indexed token, address pair, uint256);
    event NewGovernance(address _new);
    event NewController(address _new);
    event NewFeeReceiver(address _new);
    event NewFeeVaultForLP(address token, address feeVault);
    event NewVaultForLP(address _new);
    event NewVaultForTrader(address _new);
    event NewVaultForCNode(address _new);

    /// @dev Create a new token pair for trading
    /// @param  token the address of token to trade
    /// @return pair the address of new token pair
    function createPair(
        address token
        )
        external
        returns (address pair);

    function getPair(address token) external view returns (address pair);
    function allPairs(uint256) external view returns (address pair);
    function allPairsLength() external view returns (uint256);

    function getTradeMiningStatus(address token) external view returns (bool status);
    function setTradeMiningStatus(address token, bool status) external;
    function getFeeVaultForLP(address token) external view returns (address feeVault); // for LPs
    function setFeeVaultForLP(address token, address feeVault) external;

    function setGovernance(address _new) external;
    function setController(address _new) external;
    function setFeeReceiver(address _new) external;
    function setVaultForLP(address _new) external;
    function setVaultForTrader(address _new) external;
    function setVaultForCNode(address _new) external;
    function getController() external view returns (address controller);
    function getFeeReceiver() external view returns (address feeReceiver); // For CoFi Holders
    function getVaultForLP() external view returns (address vaultForLP);
    function getVaultForTrader() external view returns (address vaultForTrader);
    function getVaultForCNode() external view returns (address vaultForCNode);
}

File 6 of 11 : ICoFiXKTable.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.6.12;

interface ICoFiXKTable {
    function setK0(uint256 tIdx, uint256 sigmaIdx, int128 k0) external;
    function setK0InBatch(uint256[] memory tIdxs, uint256[] memory sigmaIdxs, int128[] memory k0s) external;
    function getK0(uint256 tIdx, uint256 sigmaIdx) external view returns (int128);
}

File 7 of 11 : ICoFiXPair.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.6.12;
import './ICoFiXERC20.sol';

interface ICoFiXPair is ICoFiXERC20 {

    struct OraclePrice {
        uint256 ethAmount;
        uint256 erc20Amount;
        uint256 blockNum;
        uint256 K;
        uint256 theta;
    }

    // All pairs: {ETH <-> ERC20 Token}
    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, address outToken, uint outAmount, address indexed to);
    event Swap(
        address indexed sender,
        uint amountIn,
        uint amountOut,
        address outToken,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1);

    function mint(address to) external payable returns (uint liquidity, uint oracleFeeChange);
    function burn(address outToken, address to) external payable returns (uint amountOut, uint oracleFeeChange);
    function swapWithExact(address outToken, address to) external payable returns (uint amountIn, uint amountOut, uint oracleFeeChange, uint256[4] memory tradeInfo);
    function swapForExact(address outToken, uint amountOutExact, address to) external payable returns (uint amountIn, uint amountOut, uint oracleFeeChange, uint256[4] memory tradeInfo);
    function skim(address to) external;
    function sync() external;

    function initialize(address, address, string memory, string memory) external;

    /// @dev get Net Asset Value Per Share
    /// @param  ethAmount ETH side of Oracle price {ETH <-> ERC20 Token}
    /// @param  erc20Amount Token side of Oracle price {ETH <-> ERC20 Token}
    /// @return navps The Net Asset Value Per Share (liquidity) represents
    function getNAVPerShare(uint256 ethAmount, uint256 erc20Amount) external view returns (uint256 navps);
}

File 8 of 11 : INest_3_OfferPrice.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.6.12;

interface INest_3_OfferPrice {
    function transfer(address to, uint value) external returns (bool);

    /**
    * @dev Update and check the latest price
    * @param tokenAddress Token address
    * @return ethAmount ETH amount
    * @return erc20Amount Erc20 amount
    * @return blockNum Price block
    */
    function updateAndCheckPriceNow(address tokenAddress) external payable returns(uint256 ethAmount, uint256 erc20Amount, uint256 blockNum);

    /**
    * @dev Update and check the effective price list
    * @param tokenAddress Token address
    * @param num Number of prices to check
    * @return uint256[] price list
    */
    function updateAndCheckPriceList(address tokenAddress, uint256 num) external payable returns (uint256[] memory);

    // Activate the price checking function
    function activation() external;

    // Check the minimum ETH cost of obtaining the price
    function checkPriceCostLeast(address tokenAddress) external view returns(uint256);

    // Check the maximum ETH cost of obtaining the price
    function checkPriceCostMost(address tokenAddress) external view returns(uint256);

    // Check the cost of a single price data
    function checkPriceCostSingle(address tokenAddress) external view returns(uint256);

    // Check whether the price-checking functions can be called
    function checkUseNestPrice(address target) external view returns (bool);

    // Check whether the address is in the blocklist
    function checkBlocklist(address add) external view returns(bool);

    // Check the amount of NEST to destroy to call prices
    function checkDestructionAmount() external view returns(uint256);

    // Check the waiting time to start calling prices
    function checkEffectTime() external view returns (uint256);
}

File 9 of 11 : INest_3_VoteFactory.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.6.12;

interface INest_3_VoteFactory {
    // 查询地址
	function checkAddress(string calldata name) external view returns (address contractAddress);
    // _offerPrice = Nest_3_OfferPrice(address(voteFactoryMap.checkAddress("nest.v3.offerPrice")));
}

File 10 of 11 : ABDKMath64x64.sol
// SPDX-License-Identifier: Copyright © 2019 by ABDK Consulting

/*
 * ABDK Math 64.64 Smart Contract Library.  Copyright © 2019 by ABDK Consulting.
 * Author: Mikhail Vladimirov <[email protected]>
 */
pragma solidity 0.6.12;

/**
 * Smart contract library of mathematical functions operating with signed
 * 64.64-bit fixed point numbers.  Signed 64.64-bit fixed point number is
 * basically a simple fraction whose numerator is signed 128-bit integer and
 * denominator is 2^64.  As long as denominator is always the same, there is no
 * need to store it, thus in Solidity signed 64.64-bit fixed point numbers are
 * represented by int128 type holding only the numerator.
 */
library ABDKMath64x64 {
  /**
   * @dev Minimum value signed 64.64-bit fixed point number may have. 
   */
  int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;

  /**
   * @dev Maximum value signed 64.64-bit fixed point number may have. 
   */
  int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

  /**
   * Convert signed 256-bit integer number into signed 64.64-bit fixed point
   * number.  Revert on overflow.
   *
   * @param x signed 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function fromInt (int256 x) internal pure returns (int128) {
    require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF);
    return int128 (x << 64);
  }

  /**
   * Convert signed 64.64 fixed point number into signed 64-bit integer number
   * rounding down.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64-bit integer number
   */
  function toInt (int128 x) internal pure returns (int64) {
    return int64 (x >> 64);
  }

  /**
   * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point
   * number.  Revert on overflow.
   *
   * @param x unsigned 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function fromUInt (uint256 x) internal pure returns (int128) {
    require (x <= 0x7FFFFFFFFFFFFFFF);
    return int128 (x << 64);
  }

  /**
   * Convert signed 64.64 fixed point number into unsigned 64-bit integer
   * number rounding down.  Revert on underflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return unsigned 64-bit integer number
   */
  function toUInt (int128 x) internal pure returns (uint64) {
    require (x >= 0);
    return uint64 (x >> 64);
  }

  /**
   * Convert signed 128.128 fixed point number into signed 64.64-bit fixed point
   * number rounding down.  Revert on overflow.
   *
   * @param x signed 128.128-bin fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function from128x128 (int256 x) internal pure returns (int128) {
    int256 result = x >> 64;
    require (result >= MIN_64x64 && result <= MAX_64x64);
    return int128 (result);
  }

  /**
   * Convert signed 64.64 fixed point number into signed 128.128 fixed point
   * number.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 128.128 fixed point number
   */
  function to128x128 (int128 x) internal pure returns (int256) {
    return int256 (x) << 64;
  }

  /**
   * Calculate x + y.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function add (int128 x, int128 y) internal pure returns (int128) {
    int256 result = int256(x) + y;
    require (result >= MIN_64x64 && result <= MAX_64x64);
    return int128 (result);
  }

  /**
   * Calculate x - y.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function sub (int128 x, int128 y) internal pure returns (int128) {
    int256 result = int256(x) - y;
    require (result >= MIN_64x64 && result <= MAX_64x64);
    return int128 (result);
  }

  /**
   * Calculate x * y rounding down.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function mul (int128 x, int128 y) internal pure returns (int128) {
    int256 result = int256(x) * y >> 64;
    require (result >= MIN_64x64 && result <= MAX_64x64);
    return int128 (result);
  }

  /**
   * Calculate x * y rounding towards zero, where x is signed 64.64 fixed point
   * number and y is signed 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64 fixed point number
   * @param y signed 256-bit integer number
   * @return signed 256-bit integer number
   */
  function muli (int128 x, int256 y) internal pure returns (int256) {
    if (x == MIN_64x64) {
      require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF &&
        y <= 0x1000000000000000000000000000000000000000000000000);
      return -y << 63;
    } else {
      bool negativeResult = false;
      if (x < 0) {
        x = -x;
        negativeResult = true;
      }
      if (y < 0) {
        y = -y; // We rely on overflow behavior here
        negativeResult = !negativeResult;
      }
      uint256 absoluteResult = mulu (x, uint256 (y));
      if (negativeResult) {
        require (absoluteResult <=
          0x8000000000000000000000000000000000000000000000000000000000000000);
        return -int256 (absoluteResult); // We rely on overflow behavior here
      } else {
        require (absoluteResult <=
          0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
        return int256 (absoluteResult);
      }
    }
  }

  /**
   * Calculate x * y rounding down, where x is signed 64.64 fixed point number
   * and y is unsigned 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64 fixed point number
   * @param y unsigned 256-bit integer number
   * @return unsigned 256-bit integer number
   */
  function mulu (int128 x, uint256 y) internal pure returns (uint256) {
    if (y == 0) return 0;

    require (x >= 0);

    uint256 lo = (uint256 (x) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;
    uint256 hi = uint256 (x) * (y >> 128);

    require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
    hi <<= 64;

    require (hi <=
      0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo);
    return hi + lo;
  }

  /**
   * Calculate x / y rounding towards zero.  Revert on overflow or when y is
   * zero.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function div (int128 x, int128 y) internal pure returns (int128) {
    require (y != 0);
    int256 result = (int256 (x) << 64) / y;
    require (result >= MIN_64x64 && result <= MAX_64x64);
    return int128 (result);
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are signed 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x signed 256-bit integer number
   * @param y signed 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function divi (int256 x, int256 y) internal pure returns (int128) {
    require (y != 0);

    bool negativeResult = false;
    if (x < 0) {
      x = -x; // We rely on overflow behavior here
      negativeResult = true;
    }
    if (y < 0) {
      y = -y; // We rely on overflow behavior here
      negativeResult = !negativeResult;
    }
    uint128 absoluteResult = divuu (uint256 (x), uint256 (y));
    if (negativeResult) {
      require (absoluteResult <= 0x80000000000000000000000000000000);
      return -int128 (absoluteResult); // We rely on overflow behavior here
    } else {
      require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
      return int128 (absoluteResult); // We rely on overflow behavior here
    }
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x unsigned 256-bit integer number
   * @param y unsigned 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function divu (uint256 x, uint256 y) internal pure returns (int128) {
    require (y != 0);
    uint128 result = divuu (x, y);
    require (result <= uint128 (MAX_64x64));
    return int128 (result);
  }

  /**
   * Calculate -x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function neg (int128 x) internal pure returns (int128) {
    require (x != MIN_64x64);
    return -x;
  }

  /**
   * Calculate |x|.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function abs (int128 x) internal pure returns (int128) {
    require (x != MIN_64x64);
    return x < 0 ? -x : x;
  }

  /**
   * Calculate 1 / x rounding towards zero.  Revert on overflow or when x is
   * zero.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function inv (int128 x) internal pure returns (int128) {
    require (x != 0);
    int256 result = int256 (0x100000000000000000000000000000000) / x;
    require (result >= MIN_64x64 && result <= MAX_64x64);
    return int128 (result);
  }

  /**
   * Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function avg (int128 x, int128 y) internal pure returns (int128) {
    return int128 ((int256 (x) + int256 (y)) >> 1);
  }

  /**
   * Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down.
   * Revert on overflow or in case x * y is negative.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function gavg (int128 x, int128 y) internal pure returns (int128) {
    int256 m = int256 (x) * int256 (y);
    require (m >= 0);
    require (m <
        0x4000000000000000000000000000000000000000000000000000000000000000);
    return int128 (sqrtu (uint256 (m), uint256 (x) + uint256 (y) >> 1));
  }

  /**
   * Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number
   * and y is unsigned 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y uint256 value
   * @return signed 64.64-bit fixed point number
   */
  function pow (int128 x, uint256 y) internal pure returns (int128) {
    uint256 absoluteResult;
    bool negativeResult = false;
    if (x >= 0) {
      absoluteResult = powu (uint256 (x) << 63, y);
    } else {
      // We rely on overflow behavior here
      absoluteResult = powu (uint256 (uint128 (-x)) << 63, y);
      negativeResult = y & 1 > 0;
    }

    absoluteResult >>= 63;

    if (negativeResult) {
      require (absoluteResult <= 0x80000000000000000000000000000000);
      return -int128 (absoluteResult); // We rely on overflow behavior here
    } else {
      require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
      return int128 (absoluteResult); // We rely on overflow behavior here
    }
  }

  /**
   * Calculate sqrt (x) rounding down.  Revert if x < 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function sqrt (int128 x) internal pure returns (int128) {
    require (x >= 0);
    return int128 (sqrtu (uint256 (x) << 64, 0x10000000000000000));
  }

  /**
   * Calculate binary logarithm of x.  Revert if x <= 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function log_2 (int128 x) internal pure returns (int128) {
    require (x > 0);

    int256 msb = 0;
    int256 xc = x;
    if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; }
    if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
    if (xc >= 0x10000) { xc >>= 16; msb += 16; }
    if (xc >= 0x100) { xc >>= 8; msb += 8; }
    if (xc >= 0x10) { xc >>= 4; msb += 4; }
    if (xc >= 0x4) { xc >>= 2; msb += 2; }
    if (xc >= 0x2) msb += 1;  // No need to shift xc anymore

    int256 result = msb - 64 << 64;
    uint256 ux = uint256 (x) << 127 - msb;
    for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) {
      ux *= ux;
      uint256 b = ux >> 255;
      ux >>= 127 + b;
      result += bit * int256 (b);
    }

    return int128 (result);
  }

  /**
   * Calculate natural logarithm of x.  Revert if x <= 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function ln (int128 x) internal pure returns (int128) {
    require (x > 0);

    return int128 (
        uint256 (log_2 (x)) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128);
  }

  /**
   * Calculate binary exponent of x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function exp_2 (int128 x) internal pure returns (int128) {
    require (x < 0x400000000000000000); // Overflow

    if (x < -0x400000000000000000) return 0; // Underflow

    uint256 result = 0x80000000000000000000000000000000;

    if (x & 0x8000000000000000 > 0)
      result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128;
    if (x & 0x4000000000000000 > 0)
      result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128;
    if (x & 0x2000000000000000 > 0)
      result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128;
    if (x & 0x1000000000000000 > 0)
      result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128;
    if (x & 0x800000000000000 > 0)
      result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128;
    if (x & 0x400000000000000 > 0)
      result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128;
    if (x & 0x200000000000000 > 0)
      result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128;
    if (x & 0x100000000000000 > 0)
      result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128;
    if (x & 0x80000000000000 > 0)
      result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128;
    if (x & 0x40000000000000 > 0)
      result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128;
    if (x & 0x20000000000000 > 0)
      result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128;
    if (x & 0x10000000000000 > 0)
      result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128;
    if (x & 0x8000000000000 > 0)
      result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128;
    if (x & 0x4000000000000 > 0)
      result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128;
    if (x & 0x2000000000000 > 0)
      result = result * 0x1000162E525EE054754457D5995292026 >> 128;
    if (x & 0x1000000000000 > 0)
      result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128;
    if (x & 0x800000000000 > 0)
      result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128;
    if (x & 0x400000000000 > 0)
      result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128;
    if (x & 0x200000000000 > 0)
      result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128;
    if (x & 0x100000000000 > 0)
      result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128;
    if (x & 0x80000000000 > 0)
      result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128;
    if (x & 0x40000000000 > 0)
      result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128;
    if (x & 0x20000000000 > 0)
      result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128;
    if (x & 0x10000000000 > 0)
      result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128;
    if (x & 0x8000000000 > 0)
      result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128;
    if (x & 0x4000000000 > 0)
      result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128;
    if (x & 0x2000000000 > 0)
      result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128;
    if (x & 0x1000000000 > 0)
      result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128;
    if (x & 0x800000000 > 0)
      result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128;
    if (x & 0x400000000 > 0)
      result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128;
    if (x & 0x200000000 > 0)
      result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128;
    if (x & 0x100000000 > 0)
      result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128;
    if (x & 0x80000000 > 0)
      result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128;
    if (x & 0x40000000 > 0)
      result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128;
    if (x & 0x20000000 > 0)
      result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128;
    if (x & 0x10000000 > 0)
      result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128;
    if (x & 0x8000000 > 0)
      result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128;
    if (x & 0x4000000 > 0)
      result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128;
    if (x & 0x2000000 > 0)
      result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128;
    if (x & 0x1000000 > 0)
      result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128;
    if (x & 0x800000 > 0)
      result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128;
    if (x & 0x400000 > 0)
      result = result * 0x100000000002C5C85FDF477B662B26945 >> 128;
    if (x & 0x200000 > 0)
      result = result * 0x10000000000162E42FEFA3AE53369388C >> 128;
    if (x & 0x100000 > 0)
      result = result * 0x100000000000B17217F7D1D351A389D40 >> 128;
    if (x & 0x80000 > 0)
      result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128;
    if (x & 0x40000 > 0)
      result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128;
    if (x & 0x20000 > 0)
      result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128;
    if (x & 0x10000 > 0)
      result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128;
    if (x & 0x8000 > 0)
      result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128;
    if (x & 0x4000 > 0)
      result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128;
    if (x & 0x2000 > 0)
      result = result * 0x1000000000000162E42FEFA39F02B772C >> 128;
    if (x & 0x1000 > 0)
      result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128;
    if (x & 0x800 > 0)
      result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128;
    if (x & 0x400 > 0)
      result = result * 0x100000000000002C5C85FDF473DEA871F >> 128;
    if (x & 0x200 > 0)
      result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128;
    if (x & 0x100 > 0)
      result = result * 0x100000000000000B17217F7D1CF79E949 >> 128;
    if (x & 0x80 > 0)
      result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128;
    if (x & 0x40 > 0)
      result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128;
    if (x & 0x20 > 0)
      result = result * 0x100000000000000162E42FEFA39EF366F >> 128;
    if (x & 0x10 > 0)
      result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128;
    if (x & 0x8 > 0)
      result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128;
    if (x & 0x4 > 0)
      result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128;
    if (x & 0x2 > 0)
      result = result * 0x1000000000000000162E42FEFA39EF358 >> 128;
    if (x & 0x1 > 0)
      result = result * 0x10000000000000000B17217F7D1CF79AB >> 128;

    result >>= 63 - (x >> 64);
    require (result <= uint256 (MAX_64x64));

    return int128 (result);
  }

  /**
   * Calculate natural exponent of x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function exp (int128 x) internal pure returns (int128) {
    require (x < 0x400000000000000000); // Overflow

    if (x < -0x400000000000000000) return 0; // Underflow

    return exp_2 (
        int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128));
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x unsigned 256-bit integer number
   * @param y unsigned 256-bit integer number
   * @return unsigned 64.64-bit fixed point number
   */
  function divuu (uint256 x, uint256 y) private pure returns (uint128) {
    require (y != 0);

    uint256 result;

    if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
      result = (x << 64) / y;
    else {
      uint256 msb = 192;
      uint256 xc = x >> 192;
      if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
      if (xc >= 0x10000) { xc >>= 16; msb += 16; }
      if (xc >= 0x100) { xc >>= 8; msb += 8; }
      if (xc >= 0x10) { xc >>= 4; msb += 4; }
      if (xc >= 0x4) { xc >>= 2; msb += 2; }
      if (xc >= 0x2) msb += 1;  // No need to shift xc anymore

      result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1);
      require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

      uint256 hi = result * (y >> 128);
      uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

      uint256 xh = x >> 192;
      uint256 xl = x << 64;

      if (xl < lo) xh -= 1;
      xl -= lo; // We rely on overflow behavior here
      lo = hi << 128;
      if (xl < lo) xh -= 1;
      xl -= lo; // We rely on overflow behavior here

      assert (xh == hi >> 128);

      result += xl / y;
    }

    require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
    return uint128 (result);
  }

  /**
   * Calculate x^y assuming 0^0 is 1, where x is unsigned 129.127 fixed point
   * number and y is unsigned 256-bit integer number.  Revert on overflow.
   *
   * @param x unsigned 129.127-bit fixed point number
   * @param y uint256 value
   * @return unsigned 129.127-bit fixed point number
   */
  function powu (uint256 x, uint256 y) private pure returns (uint256) {
    if (y == 0) return 0x80000000000000000000000000000000;
    else if (x == 0) return 0;
    else {
      int256 msb = 0;
      uint256 xc = x;
      if (xc >= 0x100000000000000000000000000000000) { xc >>= 128; msb += 128; }
      if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; }
      if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
      if (xc >= 0x10000) { xc >>= 16; msb += 16; }
      if (xc >= 0x100) { xc >>= 8; msb += 8; }
      if (xc >= 0x10) { xc >>= 4; msb += 4; }
      if (xc >= 0x4) { xc >>= 2; msb += 2; }
      if (xc >= 0x2) msb += 1;  // No need to shift xc anymore

      int256 xe = msb - 127;
      if (xe > 0) x >>= xe;
      else x <<= -xe;

      uint256 result = 0x80000000000000000000000000000000;
      int256 re = 0;

      while (y > 0) {
        if (y & 1 > 0) {
          result = result * x;
          y -= 1;
          re += xe;
          if (result >=
            0x8000000000000000000000000000000000000000000000000000000000000000) {
            result >>= 128;
            re += 1;
          } else result >>= 127;
          if (re < -127) return 0; // Underflow
          require (re < 128); // Overflow
        } else {
          x = x * x;
          y >>= 1;
          xe <<= 1;
          if (x >=
            0x8000000000000000000000000000000000000000000000000000000000000000) {
            x >>= 128;
            xe += 1;
          } else x >>= 127;
          if (xe < -127) return 0; // Underflow
          require (xe < 128); // Overflow
        }
      }

      if (re > 0) result <<= re;
      else if (re < 0) result >>= -re;

      return result;
    }
  }

  /**
   * Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer
   * number.
   *
   * @param x unsigned 256-bit integer number
   * @return unsigned 128-bit integer number
   */
  function sqrtu (uint256 x, uint256 r) private pure returns (uint128) {
    if (x == 0) return 0;
    else {
      require (r > 0);
      while (true) {
        uint256 rr = x / r;
        if (r == rr || r + 1 == rr) return uint128 (r);
        else if (r == rr + 1) return uint128 (rr);
        r = r + rr + 1 >> 1;
      }
    }
  }
}

File 11 of 11 : TransferHelper.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.6.12;

// 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 12 of 11 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

Settings
{
  "remappings": [],
  "optimizer": {
    "enabled": true,
    "runs": 6666
  },
  "evmVersion": "istanbul",
  "libraries": {
    "": {}
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_voteFactory","type":"address"},{"internalType":"address","name":"_nest","type":"address"},{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_kTable","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int128","name":"_gamma","type":"int128"}],"name":"NewGamma","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_new","type":"address"}],"name":"NewGovernance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"int128","name":"K","type":"int128"},{"indexed":false,"internalType":"int128","name":"sigma","type":"int128"},{"indexed":false,"internalType":"uint256","name":"T","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNum","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tIdx","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sigmaIdx","type":"uint256"},{"indexed":false,"internalType":"int128","name":"K0","type":"int128"}],"name":"NewK","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint32","name":"k","type":"uint32"}],"name":"NewK","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int128","name":"maxK0","type":"int128"}],"name":"NewKLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_interval","type":"uint256"}],"name":"NewKRefreshInterval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_kTable","type":"address"}],"name":"NewKTable","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_priceOracle","type":"address"}],"name":"NewOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint32","name":"theta","type":"uint32"}],"name":"NewTheta","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_timeSpan","type":"uint256"}],"name":"NewTimespan","type":"event"},{"inputs":[],"name":"AONE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DESTRUCTION_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GAMMA","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"K_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_K0","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NAVPS_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"addCaller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"}],"name":"calcImpactCostFor_BURN","outputs":[{"internalType":"uint256","name":"impactCost","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"}],"name":"calcImpactCostFor_SWAP_FOR_EXACT","outputs":[{"internalType":"uint256","name":"impactCost","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"}],"name":"calcImpactCostFor_SWAP_WITH_EXACT","outputs":[{"internalType":"uint256","name":"impactCost","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"callerAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getKInfo","outputs":[{"internalType":"uint32","name":"k","type":"uint32"},{"internalType":"uint32","name":"updatedAt","type":"uint32"},{"internalType":"uint32","name":"theta","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vol","type":"uint256"}],"name":"impactCostForBuyInETH","outputs":[{"internalType":"uint256","name":"impactCost","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"vol","type":"uint256"}],"name":"impactCostForSellOutETH","outputs":[{"internalType":"uint256","name":"impactCost","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"kRefreshInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kTable","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nestToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint8","name":"op","type":"uint8"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"queryOracle","outputs":[{"internalType":"uint256","name":"_k","type":"uint256"},{"internalType":"uint256","name":"_ethAmount","type":"uint256"},{"internalType":"uint256","name":"_erc20Amount","type":"uint256"},{"internalType":"uint256","name":"_blockNum","type":"uint256"},{"internalType":"uint256","name":"_theta","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_new","type":"address"}],"name":"setGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint32","name":"k","type":"uint32"}],"name":"setK","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_interval","type":"uint256"}],"name":"setKRefreshInterval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_kTable","type":"address"}],"name":"setKTable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setOracleDestructionAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_T","type":"uint256"}],"name":"setTLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint32","name":"theta","type":"uint32"}],"name":"setTheta","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timeSpan","type":"uint256"}],"name":"setTimespan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timespan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voteFactory","outputs":[{"internalType":"contract INest_3_VoteFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60e060405261025860009081556207a120600155600e60065561012c60075560085560098054600160bf1b6001600160801b0319909116670ccccccccccccd00176001600160801b03161790553480156200005957600080fd5b506040516200236e3803806200236e833981810160405260808110156200007f57600080fd5b508051602080830151604080850151606095860151600480546001600160a01b0319908116331782556001600160601b0319888a1b8116608052868a1b811660a0529884901b90981660c052600580546001600160a01b0380851691909a16179055835163574f2ba360e01b81529351969794969295919486946000949186169363574f2ba393828101939192829003018186803b1580156200012157600080fd5b505afa15801562000136573d6000803e3d6000fd5b505050506040513d60208110156200014d57600080fd5b5051905060005b8181101562000203576000836001600160a01b0316631e3dd18b836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015620001a457600080fd5b505afa158015620001b9573d6000803e3d6000fd5b505050506040513d6020811015620001d057600080fd5b50516001600160a01b03166000908152600360205260409020805460ff1916600190811790915591909101905062000154565b5050505050505060805160601c60a05160601c60c05160601c6121106200025e60003980610eee52806114c252508061099a5280610aa95280610b285280610b65525080610a2f52806113b85280611acb52506121106000f3fe6080604052600436106101dc5760003560e01c80638dba932911610102578063c13b476c11610095578063cf0c282911610064578063cf0c2829146108a3578063d342d977146108e2578063e2e016981461090c578063eba0df6e14610921576101e3565b8063c13b476c14610724578063c45a01551461076b578063c7d5308f14610780578063cdfadb34146107db576101e3565b8063a536b60a116100d1578063a536b60a146102b6578063a8369006146106c7578063ab033ea9146106dc578063be1900321461070f576101e3565b80638dba9329146104d75780638e85056d146105c05780638f2637fb146106885780639d5bfae21461069d576101e3565b80635aa6e6751161017a578063733ed80611610149578063733ed80614610426578063747293fb14610450578063823d309e1461048357806382963012146104ad576101e3565b80635aa6e675146103935780635b8ea798146103a85780635f69bd3d146103d257806363f0c3d9146103e7576101e3565b806337fc2beb116101b657806337fc2beb146102525780634e929741146102835780634f6ec2dd146102b6578063551359de146102cb576101e3565b80630f15f4c0146101e857806325e7fe38146101ff578063329861311461022b576101e3565b366101e357005b600080fd5b3480156101f457600080fd5b506101fd610936565b005b34801561020b57600080fd5b50610214610b52565b60408051600f9290920b8252519081900360200190f35b34801561023757600080fd5b50610240610b5b565b60408051918252519081900360200190f35b34801561025e57600080fd5b50610267610b63565b604080516001600160a01b039092168252519081900360200190f35b34801561028f57600080fd5b506101fd600480360360208110156102a657600080fd5b50356001600160a01b0316610b87565b3480156102c257600080fd5b50610240610c52565b3480156102d757600080fd5b50610240600480360360808110156102ee57600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561031957600080fd5b82018360208201111561032b57600080fd5b8035906020019184600183028401116401000000008311171561034d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505082359350505060200135610c5e565b34801561039f57600080fd5b50610267610cdd565b3480156103b457600080fd5b506101fd600480360360208110156103cb57600080fd5b5035610cec565b3480156103de57600080fd5b50610240610d50565b3480156103f357600080fd5b506101fd6004803603604081101561040a57600080fd5b5080356001600160a01b0316906020013563ffffffff16610d56565b34801561043257600080fd5b506101fd6004803603602081101561044957600080fd5b5035610e49565b34801561045c57600080fd5b506101fd6004803603602081101561047357600080fd5b50356001600160a01b0316610ee3565b34801561048f57600080fd5b506101fd600480360360208110156104a657600080fd5b5035610fb7565b3480156104b957600080fd5b50610240600480360360208110156104d057600080fd5b503561101b565b610595600480360360608110156104ed57600080fd5b6001600160a01b038235169160ff6020820135169181019060608101604082013564010000000081111561052057600080fd5b82018360208201111561053257600080fd5b8035906020019184600183028401116401000000008311171561055457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611070945050505050565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b3480156105cc57600080fd5b50610240600480360360808110156105e357600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561060e57600080fd5b82018360208201111561062057600080fd5b8035906020019184600183028401116401000000008311171561064257600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050823593505050602001356111f8565b34801561069457600080fd5b5061026761130d565b3480156106a957600080fd5b506101fd600480360360208110156106c057600080fd5b503561131c565b3480156106d357600080fd5b506102676113b6565b3480156106e857600080fd5b506101fd600480360360208110156106ff57600080fd5b50356001600160a01b03166113da565b34801561071b57600080fd5b506102406114a5565b34801561073057600080fd5b506107576004803603602081101561074757600080fd5b50356001600160a01b03166114ab565b604080519115158252519081900360200190f35b34801561077757600080fd5b506102676114c0565b34801561078c57600080fd5b506107b3600480360360208110156107a357600080fd5b50356001600160a01b03166114e4565b6040805163ffffffff9485168152928416602084015292168183015290519081900360600190f35b3480156107e757600080fd5b50610240600480360360808110156107fe57600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561082957600080fd5b82018360208201111561083b57600080fd5b8035906020019184600183028401116401000000008311171561085d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550508235935050506020013561151b565b3480156108af57600080fd5b506101fd600480360360408110156108c657600080fd5b5080356001600160a01b0316906020013563ffffffff16611592565b3480156108ee57600080fd5b506102406004803603602081101561090557600080fd5b5035611645565b34801561091857600080fd5b50610240611692565b34801561092d57600080fd5b50610214611698565b6004546001600160a01b03163314610995576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b6109c37f000000000000000000000000000000000000000000000000000000000000000033306008546116b5565b604080517f8fe77e86000000000000000000000000000000000000000000000000000000008152602060048201819052601260248301527f6e6573742e76332e6f6666657250726963650000000000000000000000000000604483015291516000926001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001692638fe77e869260648083019392829003018186803b158015610a7157600080fd5b505afa158015610a85573d6000803e3d6000fd5b505050506040513d6020811015610a9b57600080fd5b5051600854909150610ad0907f0000000000000000000000000000000000000000000000000000000000000000908390611840565b806001600160a01b0316633629c8de6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b0b57600080fd5b505af1158015610b1f573d6000803e3d6000fd5b50505050610b4f7f0000000000000000000000000000000000000000000000000000000000000000826000611840565b50565b600954600f0b81565b6305f5e10081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6004546001600160a01b03163314610be6576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b600580546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915560408051918252517fb8a7215c66d7533048ef6969ce3d23be990ce682c859f835e4bed6f6f33194bb9181900360200190a150565b670de0b6b3a764000081565b6000806000858060200190516080811015610c7857600080fd5b50602081015160609091015190925090506001600160a01b0380831690881614610cc7576000610cb285610cac84896119d8565b90611a3a565b9050610cbd81611645565b9350505050610cd5565b610cd08161101b565b925050505b949350505050565b6004546001600160a01b031681565b6004546001600160a01b03163314610d4b576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b600855565b60085481565b6004546001600160a01b03163314610db5576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b6001600160a01b03821660008181526002602090815260409182902080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff166801000000000000000063ffffffff87169081029190911790915582519384529083015280517fdf754dcc54212b1583a43e52dc93c9a33b0a5310fe26ccefbb832a384577e72d9281900390910190a15050565b6004546001600160a01b03163314610ea8576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b60068190556040805182815290517f9fe8f70a914cfc48197ae6ab66b8c3b2e611c7fa27ef9af879ad1fd494fd7b5b9181900360200190a150565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480610f2457506004546001600160a01b031633145b610f75576040805162461bcd60e51b815260206004820152601e60248201527f436f4669584374726c3a206f6e6c7920666163746f7279206f7220676f760000604482015290519081900360640190fd5b6001600160a01b0316600090815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6004546001600160a01b03163314611016576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b600055565b6000681b1ae4d6e2ef5000008210156110365750600061106b565b6110686402540be400610cac656a8077e73800611062670de0b6b3a76400008364c340748200896119d8565b90611a7c565b90505b919050565b33600090815260036020526040812054819081908190819060ff166110dc576040805162461bcd60e51b815260206004820152601d60248201527f436f4669584374726c3a2063616c6c6572206e6f7420616c6c6f776564000000604482015290519081900360640190fd5b6110e588611abe565b91955093509150600060ff881660048111156110fd57fe5b90506000600382600481111561110f57fe5b1415611128576111218a898888610c5e565b90506111ac565b600482600481111561113657fe5b1415611189576040805162461bcd60e51b815260206004820152601e60248201527f64697361626c6564206578706572696d656e74616c2066656174757265210000604482015290519081900360640190fd5b600282600481111561119757fe5b14156111ac576111a98a8988886111f8565b90505b6001546111b99082611e24565b6001600160a01b039a909a16600090815260026020526040902054999a959994985092965050506801000000000000000090910463ffffffff16925050565b600080600085806020019051608081101561121257600080fd5b50602080820151606090920151604080517f24334be8000000000000000000000000000000000000000000000000000000008152600481018a905260248101899052905193955090935060009233926324334be89260448082019391829003018186803b15801561128257600080fd5b505afa158015611296573d6000803e3d6000fd5b505050506040513d60208110156112ac57600080fd5b5051905060006112c8670de0b6b3a7640000610cac85856119d8565b9050886001600160a01b0316846001600160a01b0316146112f7576112ec81611645565b945050505050610cd5565b6113008161101b565b9998505050505050505050565b6005546001600160a01b031681565b6004546001600160a01b0316331461137b576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b60078190556040805182815290517f50305e979fe14d7795fbb7d2f90b6b2370220629d50fc15d87e78092a900b72c9181900360200190a150565b7f000000000000000000000000000000000000000000000000000000000000000081565b6004546001600160a01b03163314611439576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b600480546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915560408051918252517f4f386975ea1c2f7cf1845b08bee00626fbb624ecad16254d63d9bb9ba86526de9181900360200190a150565b60065481565b60036020526000908152604090205460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001546001600160a01b03919091166000908152600260205260409020549091429168010000000000000000900463ffffffff1690565b600080600085806020019051608081101561153557600080fd5b50602081015160409091015190925090506001600160a01b038083169088161461156b5761156281611645565b92505050610cd5565b600061157b85610cac84896119d8565b90506115868161101b565b98975050505050505050565b6004546001600160a01b031633146115f1576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b63ffffffff81166001819055604080516001600160a01b0385168152602081019290925280517f6b5a7bf27649aa058ceb45c028708f76f2b12277f096a828fd1db5b711e4188e9281900390910190a15050565b6000681b1ae4d6e2ef5000008210156116605750600061106b565b6110686402540be400610cac611685670de0b6b3a76400008264c6e2499e00886119d8565b65175fbf5ee80090611e24565b60075481565b6009547001000000000000000000000000000000009004600f0b81565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017815292518251600094606094938a169392918291908083835b602083106117685780518252601f199092019160209182019101611749565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146117ca576040519150601f19603f3d011682016040523d82523d6000602084013e6117cf565b606091505b50915091508180156117fd5750805115806117fd57508080602001905160208110156117fa57600080fd5b50515b6118385760405162461bcd60e51b81526004018080602001828103825260248152602001806120b76024913960400191505060405180910390fd5b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000178152925182516000946060949389169392918291908083835b602083106118eb5780518252601f1990920191602091820191016118cc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461194d576040519150601f19603f3d011682016040523d82523d6000602084013e611952565b606091505b5091509150818015611980575080511580611980575080806020019051602081101561197d57600080fd5b50515b6119d1576040805162461bcd60e51b815260206004820152601e60248201527f5472616e7366657248656c7065723a20415050524f56455f4641494c45440000604482015290519081900360640190fd5b5050505050565b6000826119e757506000611a34565b828202828482816119f457fe5b0414611a315760405162461bcd60e51b81526004018080602001828103825260218152602001806120736021913960400191505060405180910390fd5b90505b92915050565b6000611a3183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611e7e565b6000611a3183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611f20565b60008060008047905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638fe77e866040518163ffffffff1660e01b81526004018080602001828103825260128152602001807f6e6573742e76332e6f666665725072696365000000000000000000000000000081525060200191505060206040518083038186803b158015611b5e57600080fd5b505afa158015611b72573d6000803e3d6000fd5b505050506040513d6020811015611b8857600080fd5b5051604080517f08d0099e0000000000000000000000000000000000000000000000000000000081526001600160a01b038981166004830152600160248301529151929350606092918416916308d0099e913491604480830192600092919082900301818588803b158015611bfc57600080fd5b505af1158015611c10573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040526020811015611c3a57600080fd5b8101908080516040519392919084640100000000821115611c5a57600080fd5b908301906020820185811115611c6f57600080fd5b8251866020820283011164010000000082111715611c8c57600080fd5b82525081516020918201928201910280838360005b83811015611cb9578181015183820152602001611ca1565b5050505090500160405250505090508051600314611d1e576040805162461bcd60e51b815260206004820152601860248201527f436f4669584374726c3a20626164207072696365206c656e0000000000000000604482015290519081900360640190fd5b6000611d53600654611d4d84600281518110611d3657fe5b602002602001015143611a7c90919063ffffffff16565b906119d8565b90506000548110611dab576040805162461bcd60e51b815260206004820181905260248201527f436f4669584374726c3a206f72616c6365207072696365206f75746461746564604482015290519081900360640190fd5b6000611dc1611dba8647611a7c565b3490611a7c565b90508015611dd357611dd33382611f7a565b82600081518110611de057fe5b602002602001015183600181518110611df557fe5b602002602001015184600281518110611e0a57fe5b602002602001015197509750975050505050509193909250565b600082820183811015611a31576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008183611f0a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611ecf578181015183820152602001611eb7565b50505050905090810190601f168015611efc5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581611f1657fe5b0495945050505050565b60008184841115611f725760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611ecf578181015183820152602001611eb7565b505050900390565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b60208310611fc65780518252601f199092019160209182019101611fa7565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612028576040519150601f19603f3d011682016040523d82523d6000602084013e61202d565b606091505b505090508061206d5760405162461bcd60e51b81526004018080602001828103825260238152602001806120946023913960400191505060405180910390fd5b50505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775472616e7366657248656c7065723a204554485f5452414e534645525f4641494c45445472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c4544a264697066735822122081e864c7e9a87179a88dfb07064f4b38466a7ad525e45c2e7919b95fa6020f8164736f6c634300060c00330000000000000000000000006cd5698e8854fb6879d6b1c694223b389b465dea00000000000000000000000004abeda201850ac0124161f037efd70c74ddc74c00000000000000000000000066c64ecc3a6014733325a8f2ebee46b4ca3ed55000000000000000000000000075e360be6248bd46030c6818624a09403ef5ec21

Deployed Bytecode

0x6080604052600436106101dc5760003560e01c80638dba932911610102578063c13b476c11610095578063cf0c282911610064578063cf0c2829146108a3578063d342d977146108e2578063e2e016981461090c578063eba0df6e14610921576101e3565b8063c13b476c14610724578063c45a01551461076b578063c7d5308f14610780578063cdfadb34146107db576101e3565b8063a536b60a116100d1578063a536b60a146102b6578063a8369006146106c7578063ab033ea9146106dc578063be1900321461070f576101e3565b80638dba9329146104d75780638e85056d146105c05780638f2637fb146106885780639d5bfae21461069d576101e3565b80635aa6e6751161017a578063733ed80611610149578063733ed80614610426578063747293fb14610450578063823d309e1461048357806382963012146104ad576101e3565b80635aa6e675146103935780635b8ea798146103a85780635f69bd3d146103d257806363f0c3d9146103e7576101e3565b806337fc2beb116101b657806337fc2beb146102525780634e929741146102835780634f6ec2dd146102b6578063551359de146102cb576101e3565b80630f15f4c0146101e857806325e7fe38146101ff578063329861311461022b576101e3565b366101e357005b600080fd5b3480156101f457600080fd5b506101fd610936565b005b34801561020b57600080fd5b50610214610b52565b60408051600f9290920b8252519081900360200190f35b34801561023757600080fd5b50610240610b5b565b60408051918252519081900360200190f35b34801561025e57600080fd5b50610267610b63565b604080516001600160a01b039092168252519081900360200190f35b34801561028f57600080fd5b506101fd600480360360208110156102a657600080fd5b50356001600160a01b0316610b87565b3480156102c257600080fd5b50610240610c52565b3480156102d757600080fd5b50610240600480360360808110156102ee57600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561031957600080fd5b82018360208201111561032b57600080fd5b8035906020019184600183028401116401000000008311171561034d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505082359350505060200135610c5e565b34801561039f57600080fd5b50610267610cdd565b3480156103b457600080fd5b506101fd600480360360208110156103cb57600080fd5b5035610cec565b3480156103de57600080fd5b50610240610d50565b3480156103f357600080fd5b506101fd6004803603604081101561040a57600080fd5b5080356001600160a01b0316906020013563ffffffff16610d56565b34801561043257600080fd5b506101fd6004803603602081101561044957600080fd5b5035610e49565b34801561045c57600080fd5b506101fd6004803603602081101561047357600080fd5b50356001600160a01b0316610ee3565b34801561048f57600080fd5b506101fd600480360360208110156104a657600080fd5b5035610fb7565b3480156104b957600080fd5b50610240600480360360208110156104d057600080fd5b503561101b565b610595600480360360608110156104ed57600080fd5b6001600160a01b038235169160ff6020820135169181019060608101604082013564010000000081111561052057600080fd5b82018360208201111561053257600080fd5b8035906020019184600183028401116401000000008311171561055457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611070945050505050565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b3480156105cc57600080fd5b50610240600480360360808110156105e357600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561060e57600080fd5b82018360208201111561062057600080fd5b8035906020019184600183028401116401000000008311171561064257600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050823593505050602001356111f8565b34801561069457600080fd5b5061026761130d565b3480156106a957600080fd5b506101fd600480360360208110156106c057600080fd5b503561131c565b3480156106d357600080fd5b506102676113b6565b3480156106e857600080fd5b506101fd600480360360208110156106ff57600080fd5b50356001600160a01b03166113da565b34801561071b57600080fd5b506102406114a5565b34801561073057600080fd5b506107576004803603602081101561074757600080fd5b50356001600160a01b03166114ab565b604080519115158252519081900360200190f35b34801561077757600080fd5b506102676114c0565b34801561078c57600080fd5b506107b3600480360360208110156107a357600080fd5b50356001600160a01b03166114e4565b6040805163ffffffff9485168152928416602084015292168183015290519081900360600190f35b3480156107e757600080fd5b50610240600480360360808110156107fe57600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561082957600080fd5b82018360208201111561083b57600080fd5b8035906020019184600183028401116401000000008311171561085d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550508235935050506020013561151b565b3480156108af57600080fd5b506101fd600480360360408110156108c657600080fd5b5080356001600160a01b0316906020013563ffffffff16611592565b3480156108ee57600080fd5b506102406004803603602081101561090557600080fd5b5035611645565b34801561091857600080fd5b50610240611692565b34801561092d57600080fd5b50610214611698565b6004546001600160a01b03163314610995576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b6109c37f00000000000000000000000004abeda201850ac0124161f037efd70c74ddc74c33306008546116b5565b604080517f8fe77e86000000000000000000000000000000000000000000000000000000008152602060048201819052601260248301527f6e6573742e76332e6f6666657250726963650000000000000000000000000000604483015291516000926001600160a01b037f0000000000000000000000006cd5698e8854fb6879d6b1c694223b389b465dea1692638fe77e869260648083019392829003018186803b158015610a7157600080fd5b505afa158015610a85573d6000803e3d6000fd5b505050506040513d6020811015610a9b57600080fd5b5051600854909150610ad0907f00000000000000000000000004abeda201850ac0124161f037efd70c74ddc74c908390611840565b806001600160a01b0316633629c8de6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b0b57600080fd5b505af1158015610b1f573d6000803e3d6000fd5b50505050610b4f7f00000000000000000000000004abeda201850ac0124161f037efd70c74ddc74c826000611840565b50565b600954600f0b81565b6305f5e10081565b7f00000000000000000000000004abeda201850ac0124161f037efd70c74ddc74c81565b6004546001600160a01b03163314610be6576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b600580546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915560408051918252517fb8a7215c66d7533048ef6969ce3d23be990ce682c859f835e4bed6f6f33194bb9181900360200190a150565b670de0b6b3a764000081565b6000806000858060200190516080811015610c7857600080fd5b50602081015160609091015190925090506001600160a01b0380831690881614610cc7576000610cb285610cac84896119d8565b90611a3a565b9050610cbd81611645565b9350505050610cd5565b610cd08161101b565b925050505b949350505050565b6004546001600160a01b031681565b6004546001600160a01b03163314610d4b576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b600855565b60085481565b6004546001600160a01b03163314610db5576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b6001600160a01b03821660008181526002602090815260409182902080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff166801000000000000000063ffffffff87169081029190911790915582519384529083015280517fdf754dcc54212b1583a43e52dc93c9a33b0a5310fe26ccefbb832a384577e72d9281900390910190a15050565b6004546001600160a01b03163314610ea8576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b60068190556040805182815290517f9fe8f70a914cfc48197ae6ab66b8c3b2e611c7fa27ef9af879ad1fd494fd7b5b9181900360200190a150565b336001600160a01b037f00000000000000000000000066c64ecc3a6014733325a8f2ebee46b4ca3ed550161480610f2457506004546001600160a01b031633145b610f75576040805162461bcd60e51b815260206004820152601e60248201527f436f4669584374726c3a206f6e6c7920666163746f7279206f7220676f760000604482015290519081900360640190fd5b6001600160a01b0316600090815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6004546001600160a01b03163314611016576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b600055565b6000681b1ae4d6e2ef5000008210156110365750600061106b565b6110686402540be400610cac656a8077e73800611062670de0b6b3a76400008364c340748200896119d8565b90611a7c565b90505b919050565b33600090815260036020526040812054819081908190819060ff166110dc576040805162461bcd60e51b815260206004820152601d60248201527f436f4669584374726c3a2063616c6c6572206e6f7420616c6c6f776564000000604482015290519081900360640190fd5b6110e588611abe565b91955093509150600060ff881660048111156110fd57fe5b90506000600382600481111561110f57fe5b1415611128576111218a898888610c5e565b90506111ac565b600482600481111561113657fe5b1415611189576040805162461bcd60e51b815260206004820152601e60248201527f64697361626c6564206578706572696d656e74616c2066656174757265210000604482015290519081900360640190fd5b600282600481111561119757fe5b14156111ac576111a98a8988886111f8565b90505b6001546111b99082611e24565b6001600160a01b039a909a16600090815260026020526040902054999a959994985092965050506801000000000000000090910463ffffffff16925050565b600080600085806020019051608081101561121257600080fd5b50602080820151606090920151604080517f24334be8000000000000000000000000000000000000000000000000000000008152600481018a905260248101899052905193955090935060009233926324334be89260448082019391829003018186803b15801561128257600080fd5b505afa158015611296573d6000803e3d6000fd5b505050506040513d60208110156112ac57600080fd5b5051905060006112c8670de0b6b3a7640000610cac85856119d8565b9050886001600160a01b0316846001600160a01b0316146112f7576112ec81611645565b945050505050610cd5565b6113008161101b565b9998505050505050505050565b6005546001600160a01b031681565b6004546001600160a01b0316331461137b576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b60078190556040805182815290517f50305e979fe14d7795fbb7d2f90b6b2370220629d50fc15d87e78092a900b72c9181900360200190a150565b7f0000000000000000000000006cd5698e8854fb6879d6b1c694223b389b465dea81565b6004546001600160a01b03163314611439576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b600480546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915560408051918252517f4f386975ea1c2f7cf1845b08bee00626fbb624ecad16254d63d9bb9ba86526de9181900360200190a150565b60065481565b60036020526000908152604090205460ff1681565b7f00000000000000000000000066c64ecc3a6014733325a8f2ebee46b4ca3ed55081565b6001546001600160a01b03919091166000908152600260205260409020549091429168010000000000000000900463ffffffff1690565b600080600085806020019051608081101561153557600080fd5b50602081015160409091015190925090506001600160a01b038083169088161461156b5761156281611645565b92505050610cd5565b600061157b85610cac84896119d8565b90506115868161101b565b98975050505050505050565b6004546001600160a01b031633146115f1576040805162461bcd60e51b815260206004820152601660248201527f436f4669584374726c3a2021676f7665726e616e636500000000000000000000604482015290519081900360640190fd5b63ffffffff81166001819055604080516001600160a01b0385168152602081019290925280517f6b5a7bf27649aa058ceb45c028708f76f2b12277f096a828fd1db5b711e4188e9281900390910190a15050565b6000681b1ae4d6e2ef5000008210156116605750600061106b565b6110686402540be400610cac611685670de0b6b3a76400008264c6e2499e00886119d8565b65175fbf5ee80090611e24565b60075481565b6009547001000000000000000000000000000000009004600f0b81565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017815292518251600094606094938a169392918291908083835b602083106117685780518252601f199092019160209182019101611749565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146117ca576040519150601f19603f3d011682016040523d82523d6000602084013e6117cf565b606091505b50915091508180156117fd5750805115806117fd57508080602001905160208110156117fa57600080fd5b50515b6118385760405162461bcd60e51b81526004018080602001828103825260248152602001806120b76024913960400191505060405180910390fd5b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000178152925182516000946060949389169392918291908083835b602083106118eb5780518252601f1990920191602091820191016118cc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461194d576040519150601f19603f3d011682016040523d82523d6000602084013e611952565b606091505b5091509150818015611980575080511580611980575080806020019051602081101561197d57600080fd5b50515b6119d1576040805162461bcd60e51b815260206004820152601e60248201527f5472616e7366657248656c7065723a20415050524f56455f4641494c45440000604482015290519081900360640190fd5b5050505050565b6000826119e757506000611a34565b828202828482816119f457fe5b0414611a315760405162461bcd60e51b81526004018080602001828103825260218152602001806120736021913960400191505060405180910390fd5b90505b92915050565b6000611a3183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611e7e565b6000611a3183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611f20565b60008060008047905060007f0000000000000000000000006cd5698e8854fb6879d6b1c694223b389b465dea6001600160a01b0316638fe77e866040518163ffffffff1660e01b81526004018080602001828103825260128152602001807f6e6573742e76332e6f666665725072696365000000000000000000000000000081525060200191505060206040518083038186803b158015611b5e57600080fd5b505afa158015611b72573d6000803e3d6000fd5b505050506040513d6020811015611b8857600080fd5b5051604080517f08d0099e0000000000000000000000000000000000000000000000000000000081526001600160a01b038981166004830152600160248301529151929350606092918416916308d0099e913491604480830192600092919082900301818588803b158015611bfc57600080fd5b505af1158015611c10573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040526020811015611c3a57600080fd5b8101908080516040519392919084640100000000821115611c5a57600080fd5b908301906020820185811115611c6f57600080fd5b8251866020820283011164010000000082111715611c8c57600080fd5b82525081516020918201928201910280838360005b83811015611cb9578181015183820152602001611ca1565b5050505090500160405250505090508051600314611d1e576040805162461bcd60e51b815260206004820152601860248201527f436f4669584374726c3a20626164207072696365206c656e0000000000000000604482015290519081900360640190fd5b6000611d53600654611d4d84600281518110611d3657fe5b602002602001015143611a7c90919063ffffffff16565b906119d8565b90506000548110611dab576040805162461bcd60e51b815260206004820181905260248201527f436f4669584374726c3a206f72616c6365207072696365206f75746461746564604482015290519081900360640190fd5b6000611dc1611dba8647611a7c565b3490611a7c565b90508015611dd357611dd33382611f7a565b82600081518110611de057fe5b602002602001015183600181518110611df557fe5b602002602001015184600281518110611e0a57fe5b602002602001015197509750975050505050509193909250565b600082820183811015611a31576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008183611f0a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611ecf578181015183820152602001611eb7565b50505050905090810190601f168015611efc5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581611f1657fe5b0495945050505050565b60008184841115611f725760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611ecf578181015183820152602001611eb7565b505050900390565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b60208310611fc65780518252601f199092019160209182019101611fa7565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612028576040519150601f19603f3d011682016040523d82523d6000602084013e61202d565b606091505b505090508061206d5760405162461bcd60e51b81526004018080602001828103825260238152602001806120946023913960400191505060405180910390fd5b50505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775472616e7366657248656c7065723a204554485f5452414e534645525f4641494c45445472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c4544a264697066735822122081e864c7e9a87179a88dfb07064f4b38466a7ad525e45c2e7919b95fa6020f8164736f6c634300060c0033

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

0000000000000000000000006cd5698e8854fb6879d6b1c694223b389b465dea00000000000000000000000004abeda201850ac0124161f037efd70c74ddc74c00000000000000000000000066c64ecc3a6014733325a8f2ebee46b4ca3ed55000000000000000000000000075e360be6248bd46030c6818624a09403ef5ec21

-----Decoded View---------------
Arg [0] : _voteFactory (address): 0x6Cd5698E8854Fb6879d6B1C694223b389B465dea
Arg [1] : _nest (address): 0x04abEdA201850aC0124161F037Efd70c74ddC74C
Arg [2] : _factory (address): 0x66C64ecC3A6014733325a8f2EBEE46B4CA3ED550
Arg [3] : _kTable (address): 0x75E360Be6248Bd46030C6818624a09403EF5eC21

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000006cd5698e8854fb6879d6b1c694223b389b465dea
Arg [1] : 00000000000000000000000004abeda201850ac0124161f037efd70c74ddc74c
Arg [2] : 00000000000000000000000066c64ecc3a6014733325a8f2ebee46b4ca3ed550
Arg [3] : 00000000000000000000000075e360be6248bd46030c6818624a09403ef5ec21


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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