ETH Price: $2,115.75 (+1.10%)

Contract

0x8518054fa6b7E0d4834bfD152c9BA5BDB856FD2B
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Approve Migratio...118866082021-02-19 9:49:481849 days ago1613728188IN
0x8518054f...DB856FD2B
0 ETH0.00939682147
Remove Liquidity118731222021-02-17 8:04:341851 days ago1613549074IN
0x8518054f...DB856FD2B
0 ETH0.00865124130
Remove Liquidity118679522021-02-16 12:53:511852 days ago1613480031IN
0x8518054f...DB856FD2B
0 ETH0.00964946145
Add Liquidity118663322021-02-16 6:58:191852 days ago1613458699IN
0x8518054f...DB856FD2B
0 ETH0.0094701287
Add Liquidity118663122021-02-16 6:55:311852 days ago1613458531IN
0x8518054f...DB856FD2B
0 ETH0.01099526101.00000145
Remove Liquidity118631442021-02-15 19:03:221853 days ago1613415802IN
0x8518054f...DB856FD2B
0 ETH0.01217828183
Remove Liquidity118626012021-02-15 17:08:411853 days ago1613408921IN
0x8518054f...DB856FD2B
0 ETH0.01204518181
Prepare Migratio...118602072021-02-15 8:15:261853 days ago1613376926IN
0x8518054f...DB856FD2B
0 ETH0.0061667794.40000135
Remove Liquidity118599162021-02-15 7:14:471853 days ago1613373287IN
0x8518054f...DB856FD2B
0 ETH0.0079872120
Remove Liquidity118597312021-02-15 6:31:111853 days ago1613370671IN
0x8518054f...DB856FD2B
0 ETH0.00745068112
Remove Liquidity118582382021-02-15 1:06:061854 days ago1613351166IN
0x8518054f...DB856FD2B
0 ETH0.00905052136
Remove Liquidity118580842021-02-15 0:32:081854 days ago1613349128IN
0x8518054f...DB856FD2B
0 ETH0.0098491148
Add Liquidity118561712021-02-14 17:31:071854 days ago1613323867IN
0x8518054f...DB856FD2B
0 ETH0.01611009148
Remove Liquidity118518702021-02-14 1:44:341855 days ago1613267074IN
0x8518054f...DB856FD2B
0 ETH0.01131316170
Add Liquidity118497552021-02-13 17:51:101855 days ago1613238670IN
0x8518054f...DB856FD2B
0 ETH0.02808381258
Add Liquidity118466012021-02-13 6:04:001855 days ago1613196240IN
0x8518054f...DB856FD2B
0 ETH0.01368201125.70757253
Add Liquidity118465632021-02-13 5:55:441855 days ago1613195744IN
0x8518054f...DB856FD2B
0 ETH0.01203028128.2
Add Liquidity118399572021-02-12 5:41:341857 days ago1613108494IN
0x8518054f...DB856FD2B
0 ETH0.0099022591
Add Liquidity118398102021-02-12 5:09:521857 days ago1613106592IN
0x8518054f...DB856FD2B
0 ETH0.01621302148.962
Add Liquidity118397062021-02-12 4:45:011857 days ago1613105101IN
0x8518054f...DB856FD2B
0 ETH0.0103224110.00000134
Add Liquidity118354922021-02-11 13:17:021857 days ago1613049422IN
0x8518054f...DB856FD2B
0 ETH0.0163242150
Add Liquidity118349492021-02-11 11:17:411857 days ago1613042261IN
0x8518054f...DB856FD2B
0 ETH0.009384100
Add Liquidity118346162021-02-11 10:04:131857 days ago1613037853IN
0x8518054f...DB856FD2B
0 ETH0.0103420895
Add Liquidity118333182021-02-11 5:14:061858 days ago1613020446IN
0x8518054f...DB856FD2B
0 ETH0.013605125
Add Liquidity118327462021-02-11 3:08:171858 days ago1613012897IN
0x8518054f...DB856FD2B
0 ETH0.01154248106.05000001
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PreMiningPool

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <0.8.0;

import "../interface/IERC20.sol";
import "../interface/ILToken.sol";
import "../interface/IMigratablePool.sol";
import "../interface/IPreMiningPool.sol";
import "../utils/SafeERC20.sol";
import "../math/MixedSafeMathWithUnit.sol";
import "./MigratablePool.sol";

/**
 * @title Deri Protocol PreMining PerpetualPool Implementation
 */
contract PreMiningPool is IMigratablePool, IPreMiningPool, MigratablePool {

    using MixedSafeMathWithUnit for uint256;
    using MixedSafeMathWithUnit for int256;
    using SafeERC20 for IERC20;

    // Trading symbol
    string private _symbol;

    // Base token contract, all settlements are done in base token
    IERC20  private _bToken;
    // Base token decimals
    uint256 private _bDecimals;
    // Liquidity provider token contract
    ILToken private _lToken;

    // Minimum amount requirement when add liquidity
    uint256 private _minAddLiquidity;
    // Redemption fee ratio when removing liquidity
    uint256 private _redemptionFeeRatio;

    // Total liquidity pool holds
    uint256 private _liquidity;

    bool private _mutex;
    // Locker to prevent reentry
    modifier _lock_() {
        require(!_mutex, "PerpetualPool: reentry");
        _mutex = true;
        _;
        _mutex = false;
    }

    /**
     * @dev A dummy constructor, which deos not initialize any storage variables
     * A template will be deployed with no initialization and real pool will be cloned
     * from this template (same as create_forwarder_to mechanism in Vyper),
     * and use `initialize` to initialize all storage variables
     */
    constructor () {}

    /**
     * @dev See {IPreMiningPool}.{initialize}
     */
    function initialize(
        string memory symbol_,
        address[2] calldata addresses_,
        uint256[2] calldata parameters_
    ) public override {
        require(
            bytes(_symbol).length == 0 && _controller == address(0),
            "PerpetualPool: already initialized"
        );

        _controller = msg.sender;
        _symbol = symbol_;

        _bToken = IERC20(addresses_[0]);
        _bDecimals = _bToken.decimals();
        _lToken = ILToken(addresses_[1]);

        _minAddLiquidity = parameters_[0];
        _redemptionFeeRatio = parameters_[1];
    }

    /**
     * @dev See {IMigratablePool}.{approveMigration}
     */
    function approveMigration() public override _controller_ {
        require(
            _migrationTimestamp != 0 && block.timestamp >= _migrationTimestamp,
            "PerpetualPool: migrationTimestamp not met yet"
        );
        // approve new pool to pull all base tokens from this pool
        _bToken.safeApprove(_migrationDestination, uint256(-1));
        // set lToken to new pool, after redirecting lToken to new pool,
        // this pool will stop functioning
        _lToken.setPool(_migrationDestination);
    }

    /**
     * @dev See {IMigratablePool}.{executeMigration}
     */
    function executeMigration(address source) public override _controller_ {
        uint256 migrationTimestamp_ = IPreMiningPool(source).migrationTimestamp();
        address migrationDestination_ = IPreMiningPool(source).migrationDestination();
        require(
            migrationTimestamp_ != 0 && block.timestamp >= migrationTimestamp_,
            "PerpetualPool: migrationTimestamp not met yet"
        );
        require(
            migrationDestination_ == address(this),
            "PerpetualPool: executeMigration to not destination pool"
        );

        // migrate base token
        _bToken.safeTransferFrom(source, address(this), _bToken.balanceOf(source));
        // migrate state values
        _liquidity = IPreMiningPool(source).getStateValues();

        emit ExecuteMigration(_migrationTimestamp, source, address(this));
    }

    /**
     * @dev See {IPreMiningPool}.{symbol}
     */
    function symbol() public view override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IPreMiningPool}.{getAddresses}
     */
    function getAddresses() public view override returns (
        address bToken,
        address lToken
    ) {
        return (
            address(_bToken),
            address(_lToken)
        );
    }

    /**
     * @dev See {IPreMiningPool}.{getParameters}
     */
    function getParameters() public view override returns (
        uint256 minAddLiquidity,
        uint256 redemptionFeeRatio
    ) {
        return (
            _minAddLiquidity,
            _redemptionFeeRatio
        );
    }

    /**
     * @dev See {IPreMiningPool}.{getStateValues}
     */
    function getStateValues() public view override returns (
        uint256 liquidity
    ) {
        return _liquidity;
    }


    //================================================================================
    // Pool interactions
    //================================================================================

    /**
     * @dev See {IPreMiningPool}.{addLiquidity}
     */
    function addLiquidity(uint256 bAmount) public override {
        _addLiquidity(bAmount);
    }

    /**
     * @dev See {IPreMiningPool}.{removeLiquidity}
     */
    function removeLiquidity(uint256 lShares) public override {
        _removeLiquidity(lShares);
    }

    //================================================================================
    // Critical Logic
    //================================================================================

    /**
     * @dev Low level addLiquidity implementation
     */
    function _addLiquidity(uint256 bAmount) internal _lock_ {
        require(
            bAmount >= _minAddLiquidity,
            "PerpetualPool: add liquidity less than minimum requirement"
        );
        require(
            bAmount.reformat(_bDecimals) == bAmount,
            "PerpetualPool: _addLiquidity bAmount not valid"
        );

        bAmount = _deflationCompatibleSafeTransferFrom(msg.sender, address(this), bAmount);

        uint256 poolDynamicEquity = _liquidity;
        uint256 totalSupply = _lToken.totalSupply();
        uint256 lShares;
        if (totalSupply == 0) {
            lShares = bAmount;
        } else {
            lShares = bAmount.mul(totalSupply).div(poolDynamicEquity);
        }

        _lToken.mint(msg.sender, lShares);
        _liquidity = _liquidity.add(bAmount);

        emit AddLiquidity(msg.sender, lShares, bAmount);
    }

    /**
     * @dev Low level removeLiquidity implementation
     */
    function _removeLiquidity(uint256 lShares) internal _lock_ {
        require(lShares > 0, "PerpetualPool: remove 0 liquidity");
        uint256 balance = _lToken.balanceOf(msg.sender);
        require(
            lShares == balance || balance.sub(lShares) >= 10**18,
            "PerpetualPool: remaining liquidity shares must be 0 or at least 1"
        );

        uint256 poolDynamicEquity = _liquidity;
        uint256 totalSupply = _lToken.totalSupply();
        uint256 bAmount = lShares.mul(poolDynamicEquity).div(totalSupply);
        if (lShares < totalSupply) {
            bAmount = bAmount.sub(bAmount.mul(_redemptionFeeRatio));
        }
        bAmount = bAmount.reformat(_bDecimals);

        _liquidity = _liquidity.sub(bAmount);

        _lToken.burn(msg.sender, lShares);
        _bToken.safeTransfer(msg.sender, bAmount.rescale(_bDecimals));

        emit RemoveLiquidity(msg.sender, lShares, bAmount);
    }

    /**
     * @dev safeTransferFrom for base token with deflation protection
     * Returns the actual received amount in base token (as base 10**18)
     */
    function _deflationCompatibleSafeTransferFrom(address from, address to, uint256 amount) internal returns (uint256) {
        uint256 preBalance = _bToken.balanceOf(to);
        _bToken.safeTransferFrom(from, to, amount.rescale(_bDecimals));
        uint256 curBalance = _bToken.balanceOf(to);

        uint256 a = curBalance.sub(preBalance);
        uint256 b = 10**18;
        uint256 c = a * b;
        require(c / b == a, "PreMiningPool: _deflationCompatibleSafeTransferFrom multiplication overflows");

        uint256 actualReceivedAmount = c / (10 ** _bDecimals);
        return actualReceivedAmount;
    }

}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `amount` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /**
     * @dev Emitted when `amount` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `amount` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 amount);

    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the name.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
     * called.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() external view returns (uint8);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the allowance mechanism.
     * `amount` is then deducted from the caller's allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);

}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <0.8.0;

import "./IERC20.sol";

/**
 * @title Deri Protocol liquidity provider token interface
 */
interface ILToken is IERC20 {

    /**
     * @dev Set the pool address of this LToken
     * pool is the only controller of this contract
     * can only be called by current pool
     */
    function setPool(address newPool) external;

    /**
     * @dev Returns address of pool
     */
    function pool() external view returns (address);

    /**
     * @dev Mint LToken to `account` of `amount`
     *
     * Can only be called by pool
     * `account` cannot be zero address
     */
    function mint(address account, uint256 amount) external;

    /**
     * @dev Burn `amount` LToken of `account`
     *
     * Can only be called by pool
     * `account` cannot be zero address
     * `account` must owns at least `amount` LToken
     */
    function burn(address account, uint256 amount) external;

}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Deri Protocol migratable pool interface
 */
interface IMigratablePool {

    /**
     * @dev Emitted when migration is prepared
     * `source` pool will be migrated to `target` pool after `migrationTimestamp`
     */
    event PrepareMigration(uint256 migrationTimestamp, address source, address target);

    /**
     * @dev Emmited when migration is executed
     * `source` pool is migrated to `target` pool
     */
    event ExecuteMigration(uint256 migrationTimestamp, address source, address target);

    /**
     * @dev Set controller to `newController`
     *
     * can only be called by current controller or the controller has not been set
     */
    function setController(address newController) external;

    /**
     * @dev Returns address of current controller
     */
    function controller() external view returns (address);

    /**
     * @dev Returns the migrationTimestamp of this pool, zero means not set
     */
    function migrationTimestamp() external view returns (uint256);

    /**
     * @dev Returns the destination pool this pool will migrate to after grace period
     * zero address means not set
     */
    function migrationDestination() external view returns (address);

    /**
     * @dev Prepare a migration from this pool to `newPool` with `graceDays` as grace period
     * `graceDays` must be at least 3 days from now, allow users to verify the `newPool` code
     *
     * can only be called by controller
     */
    function prepareMigration(address newPool, uint256 graceDays) external;

    /**
     * @dev Approve migration to `newPool` when grace period ends
     * after approvement, current pool will stop functioning
     *
     * can only be called by controller
     */
    function approveMigration() external;

    /**
     * @dev Called from the `newPool` to migrate from `source` pool
     * the grace period of `source` pool must ends
     * current pool must be the destination pool set before grace period in the `source` pool
     *
     * can only be called by controller
     */
    function executeMigration(address source) external;

}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <0.8.0;

import "./IMigratablePool.sol";

/**
 * @title Deri Protocol PreMining PerpetualPool Interface
 */
interface IPreMiningPool is IMigratablePool {

    /**
     * @dev Emitted when `owner` add liquidity of `bAmount`,
     * and receive `lShares` liquidity token
     */
    event AddLiquidity(address indexed owner, uint256 lShares, uint256 bAmount);

    /**
     * @dev Emitted when `owner` burn `lShares` of liquidity token,
     * and receive `bAmount` in base token
     */
    event RemoveLiquidity(address indexed owner, uint256 lShares, uint256 bAmount);

    /**
     * @dev Initialize pool
     *
     * addresses:
     *      bToken
     *      lToken
     *
     * parameters:
     *      minAddLiquidity
     *      redemptionFeeRatio
     */
    function initialize(
        string memory symbol_,
        address[2] calldata addresses_,
        uint256[2] calldata parameters_
    ) external;

    /**
     * @dev Returns trading symbol
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns addresses of (bToken, pToken, lToken, oracle) in this pool
     */
    function getAddresses() external view returns (
        address bToken,
        address lToken
    );

    /**
     * @dev Returns parameters of this pool
     */
    function getParameters() external view returns (
        uint256 minAddLiquidity,
        uint256 redemptionFeeRatio
    );

    /**
     * @dev Returns currents state values of this pool
     */
    function getStateValues() external view returns (
        uint256 liquidity
    );

    /**
     * @dev Add liquidity of `bAmount` in base token
     *
     * New liquidity provider token will be issued to the provider
     */
    function addLiquidity(uint256 bAmount) external;

    /**
     * @dev Remove `lShares` of liquidity provider token
     *
     * The liquidity provider token will be burned and
     * the corresponding amount in base token will be sent to provider
     */
    function removeLiquidity(uint256 lShares) external;

}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "../interface/IERC20.sol";
import "../math/UnsignedSafeMath.sol";
import "./Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using UnsignedSafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @title Mixed safe math with base unit of 10**18
 */
library MixedSafeMathWithUnit {

    uint256 constant UONE = 10**18;
    uint256 constant UMAX = 2**255 - 1;

    int256 constant IONE = 10**18;
    int256 constant IMIN = -2**255;

    //================================================================================
    // Conversions
    //================================================================================

    /**
     * @dev Convert uint256 to int256
     */
    function utoi(uint256 a) internal pure returns (int256) {
        require(a <= UMAX, "MixedSafeMathWithUnit: convert uint256 to int256 overflow");
        int256 b = int256(a);
        return b;
    }

    /**
     * @dev Convert int256 to uint256
     */
    function itou(int256 a) internal pure returns (uint256) {
        require(a >= 0, "MixedSafeMathWithUnit: convert int256 to uint256 overflow");
        uint256 b = uint256(a);
        return b;
    }

    /**
     * @dev Take abs of int256
     */
    function abs(int256 a) internal pure returns (int256) {
        require(a != IMIN, "MixedSafeMathWithUnit: int256 abs overflow");
        if (a >= 0) {
            return a;
        } else {
            return -a;
        }
    }

    /**
     * @dev Take negation of int256
     */
    function neg(int256 a) internal pure returns (int256) {
        require(a != IMIN, "MixedSafeMathWithUnit: int256 negate overflow");
        return -a;
    }

    //================================================================================
    // Rescale and reformat
    //================================================================================

    function _rescale(uint256 a, uint256 decimals1, uint256 decimals2)
        internal pure returns (uint256)
    {
        uint256 scale1 = 10 ** decimals1;
        uint256 scale2 = 10 ** decimals2;
        uint256 b = a * scale2;
        require(b / scale2 == a, "MixedSafeMathWithUnit: rescale uint256 overflow");
        uint256 c = b / scale1;
        return c;
    }

    function _rescale(int256 a, uint256 decimals1, uint256 decimals2)
        internal pure returns (int256)
    {
        int256 scale1 = utoi(10 ** decimals1);
        int256 scale2 = utoi(10 ** decimals2);
        int256 b = a * scale2;
        require(b / scale2 == a, "MixedSafeMathWithUnit: rescale int256 overflow");
        int256 c = b / scale1;
        return c;
    }

    /**
     * @dev Rescales a value from 10**18 base to 10**decimals base
     */
    function rescale(uint256 a, uint256 decimals) internal pure returns (uint256) {
        return _rescale(a, 18, decimals);
    }

    function rescale(int256 a, uint256 decimals) internal pure returns (int256) {
        return _rescale(a, 18, decimals);
    }

    /**
     * @dev Reformat a value to be a valid 10**decimals base value
     * The formatted value is still in 10**18 base
     */
    function reformat(uint256 a, uint256 decimals) internal pure returns (uint256) {
        return _rescale(_rescale(a, 18, decimals), decimals, 18);
    }

    function reformat(int256 a, uint256 decimals) internal pure returns (int256) {
        return _rescale(_rescale(a, 18, decimals), decimals, 18);
    }


    //================================================================================
    // Addition
    //================================================================================

    /**
     * @dev Addition: uint256 + uint256
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "MixedSafeMathWithUnit: uint256 addition overflow");
        return c;
    }

    /**
     * @dev Addition: int256 + int256
     */
    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require(
            (b >= 0 && c >= a) || (b < 0 && c < a),
            "MixedSafeMathWithUnit: int256 addition overflow"
        );
        return c;
    }

    /**
     * @dev Addition: uint256 + int256
     * uint256(-b) will not overflow when b is IMIN
     */
    function add(uint256 a, int256 b) internal pure returns (uint256) {
        if (b >= 0) {
            return add(a, uint256(b));
        } else {
            return sub(a, uint256(-b));
        }
    }

    /**
     * @dev Addition: int256 + uint256
     */
    function add(int256 a, uint256 b) internal pure returns (int256) {
        return add(a, utoi(b));
    }

    //================================================================================
    // Subtraction
    //================================================================================

    /**
     * @dev Subtraction: uint256 - uint256
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(a >= b, "MixedSafeMathWithUnit: uint256 subtraction overflow");
        uint256 c = a - b;
        return c;
    }

    /**
     * @dev Subtraction: int256 - int256
     */
    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require(
            (b >= 0 && c <= a) || (b < 0 && c > a),
            "MixedSafeMathWithUnit: int256 subtraction overflow"
        );
        return c;
    }

    /**
     * @dev Subtraction: uint256 - int256
     * uint256(-b) will not overflow when b is IMIN
     */
    function sub(uint256 a, int256 b) internal pure returns (uint256) {
        if (b >= 0) {
            return sub(a, uint256(b));
        } else {
            return add(a, uint256(-b));
        }
    }

    /**
     * @dev Subtraction: int256 - uint256
     */
    function sub(int256 a, uint256 b) internal pure returns (int256) {
        return sub(a, utoi(b));
    }

    //================================================================================
    // Multiplication
    //================================================================================

    /**
     * @dev Multiplication: uint256 * uint256
     */
    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, "MixedSafeMathWithUnit: uint256 multiplication overflow");
        return c / UONE;
    }

    /**
     * @dev Multiplication: int256 * int256
     */
    function mul(int256 a, int256 b) internal pure returns (int256) {
        // 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;
        }
        require(!(a == -1 && b == IMIN), "MixedSafeMathWithUnit: int256 multiplication overflow");
        int256 c = a * b;
        require(c / a == b, "MixedSafeMathWithUnit: int256 multiplication overflow");
        return c / IONE;
    }

    /**
     * @dev Multiplication: uint256 * int256
     */
    function mul(uint256 a, int256 b) internal pure returns (uint256) {
        return mul(a, itou(b));
    }

    /**
     * @dev Multiplication: int256 * uint256
     */
    function mul(int256 a, uint256 b) internal pure returns (int256) {
        return mul(a, utoi(b));
    }

    //================================================================================
    // Division
    //================================================================================

    /**
     * @dev Division: uint256 / uint256
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "MixedSafeMathWithUnit: uint256 division by zero");
        uint256 c = a * UONE;
        require(
            c / UONE == a,
            "MixedSafeMathWithUnit: uint256 division internal multiplication overflow"
        );
        uint256 d = c / b;
        return d;
    }

    /**
     * @dev Division: int256 / int256
     */
    function div(int256 a, int256 b) internal pure returns (int256) {
        require(b != 0, "MixedSafeMathWithUnit: int256 division by zero");
        int256 c = a * IONE;
        require(
            c / IONE == a,
            "MixedSafeMathWithUnit: int256 division internal multiplication overflow"
        );
        require(!(c == IMIN && b == -1), "MixedSafeMathWithUnit: int256 division overflow");
        int256 d = c / b;
        return d;
    }

    /**
     * @dev Division: uint256 / int256
     */
    function div(uint256 a, int256 b) internal pure returns (uint256) {
        return div(a, itou(b));
    }

    /**
     * @dev Division: int256 / uint256
     */
    function div(int256 a, uint256 b) internal pure returns (int256) {
        return div(a, utoi(b));
    }

}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "../interface/IMigratablePool.sol";

/**
 * @dev Deri Protocol migratable pool implementation
 */
abstract contract MigratablePool is IMigratablePool {

    // Controller address
    address _controller;

    // Migration timestamp of this pool, zero means not set
    // Migration timestamp can only be set with a grace period at least 3 days, and the
    // `migrationDestination` pool address must be also set when setting migration timestamp,
    // users can use this grace period to verify the `migrationDestination` pool code
    uint256 _migrationTimestamp;

    // The new pool this pool will migrate to after grace period, zero address means not set
    address _migrationDestination;

    modifier _controller_() {
        require(msg.sender == _controller, "can only be called by current controller");
        _;
    }

    /**
     * @dev See {IMigratablePool}.{setController}
     */
    function setController(address newController) public override {
        require(newController != address(0), "MigratablePool: setController to 0 address");
        require(
            _controller == address(0) || msg.sender == _controller,
            "MigratablePool: setController can only be called by current controller or not set"
        );
        _controller = newController;
    }

    /**
     * @dev See {IMigratablePool}.{controller}
     */
    function controller() public view override returns (address) {
        return _controller;
    }

    /**
     * @dev See {IMigratablePool}.{migrationTimestamp}
     */
    function migrationTimestamp() public view override returns (uint256) {
        return _migrationTimestamp;
    }

    /**
     * @dev See {IMigratablePool}.{migrationDestination}
     */
    function migrationDestination() public view override returns (address) {
        return _migrationDestination;
    }

    /**
     * @dev See {IMigratablePool}.{prepareMigration}
     */
    function prepareMigration(address newPool, uint256 graceDays) public override _controller_ {
        require(newPool != address(0), "MigratablePool: prepareMigration to 0 address");
        require(graceDays >= 3 && graceDays <= 365, "MigratablePool: graceDays must be 3-365 days");

        _migrationTimestamp = block.timestamp + graceDays * 1 days;
        _migrationDestination = newPool;

        emit PrepareMigration(_migrationTimestamp, address(this), _migrationDestination);
    }

    /**
     * @dev See {IMigratablePool}.{approveMigration}
     *
     * This function will be implemented in inheriting contract
     * This function will change if there is an upgrade to existent pool
     */
    // function approveMigration() public virtual override _controller_ {}

    /**
     * @dev See {IMigratablePool}.{executeMigration}
     *
     * This function will be implemented in inheriting contract
     * This function will change if there is an upgrade to existent pool
     */
    // function executeMigration(address source) public virtual override _controller_ {}

}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @title Unsigned safe math
 */
library UnsignedSafeMath {

    /**
     * @dev Addition of unsigned integers, counterpart to `+`
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "UnsignedSafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Subtraction of unsigned integers, counterpart to `-`
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(a >= b, "UnsignedSafeMath: subtraction overflow");
        uint256 c = a - b;
        return c;
    }

    /**
     * @dev Multiplication of unsigned integers, counterpart to `*`
     */
    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, "UnsignedSafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Division of unsigned integers, counterpart to `/`
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "UnsignedSafeMath: division by zero");
        uint256 c = a / b;
        return c;
    }

    /**
     * @dev Modulo of unsigned integers, counterpart to `%`
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "UnsignedSafeMath: modulo by zero");
        uint256 c = a % b;
        return c;
    }

}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"lShares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bAmount","type":"uint256"}],"name":"AddLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"migrationTimestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"source","type":"address"},{"indexed":false,"internalType":"address","name":"target","type":"address"}],"name":"ExecuteMigration","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"migrationTimestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"source","type":"address"},{"indexed":false,"internalType":"address","name":"target","type":"address"}],"name":"PrepareMigration","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"lShares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bAmount","type":"uint256"}],"name":"RemoveLiquidity","type":"event"},{"inputs":[{"internalType":"uint256","name":"bAmount","type":"uint256"}],"name":"addLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"approveMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"source","type":"address"}],"name":"executeMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAddresses","outputs":[{"internalType":"address","name":"bToken","type":"address"},{"internalType":"address","name":"lToken","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getParameters","outputs":[{"internalType":"uint256","name":"minAddLiquidity","type":"uint256"},{"internalType":"uint256","name":"redemptionFeeRatio","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStateValues","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address[2]","name":"addresses_","type":"address[2]"},{"internalType":"uint256[2]","name":"parameters_","type":"uint256[2]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrationDestination","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"migrationTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newPool","type":"address"},{"internalType":"uint256","name":"graceDays","type":"uint256"}],"name":"prepareMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"lShares","type":"uint256"}],"name":"removeLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newController","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b50611f38806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379a87b191161008c5780639c8f9f23116100665780639c8f9f23146102fd578063a39fac121461031a578063a5ea11da14610351578063f77c479114610372576100ea565b806379a87b191461023657806392eefe9b1461025a57806395d89b4114610280576100ea565b806351dfdb48116100c857806351dfdb48146101c2578063547b4579146101e857806358c700a314610202578063677528cb1461020a576100ea565b806320a39957146100ef578063325564ec1461019d57806351c6590a146101a5575b600080fd5b61019b600480360360a081101561010557600080fd5b81019060208101813564010000000081111561012057600080fd5b82018360208201111561013257600080fd5b8035906020019184600183028401116401000000008311171561015457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295509293505060408301915061037a9050565b005b61019b6104bf565b61019b600480360360208110156101bb57600080fd5b50356105e0565b61019b600480360360208110156101d857600080fd5b50356001600160a01b03166105ec565b6101f06108fe565b60408051918252519081900360200190f35b6101f0610904565b61019b6004803603604081101561022057600080fd5b506001600160a01b03813516906020013561090a565b61023e610a57565b604080516001600160a01b039092168252519081900360200190f35b61019b6004803603602081101561027057600080fd5b50356001600160a01b0316610a66565b610288610b2a565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102c25781810151838201526020016102aa565b50505050905090810190601f1680156102ef5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61019b6004803603602081101561031357600080fd5b5035610bc0565b610322610bc9565b60405180836001600160a01b03168152602001826001600160a01b031681526020019250505060405180910390f35b610359610be0565b6040805192835260208301919091528051918290030190f35b61023e610bea565b600354600260001961010060018416150201909116041580156103a657506000546001600160a01b0316155b6103e15760405162461bcd60e51b8152600401808060200182810382526022815260200180611d066022913960400191505060405180910390fd5b600080546001600160a01b031916331790558251610406906003906020860190611a04565b50600480546001600160a01b0319166001600160a01b0384358116919091178083556040805163313ce56760e01b81529051919092169263313ce56792808201926020929091829003018186803b15801561046057600080fd5b505afa158015610474573d6000803e3d6000fd5b505050506040513d602081101561048a57600080fd5b505160ff16600555600680546001600160a01b0319166001600160a01b03602094850135161790558035600755013560085550565b6000546001600160a01b031633146105085760405162461bcd60e51b8152600401808060200182810382526028815260200180611af46028913960400191505060405180910390fd5b6001541580159061051b57506001544210155b6105565760405162461bcd60e51b815260040180806020018281038252602d815260200180611d28602d913960400191505060405180910390fd5b600254600454610575916001600160a01b039182169116600019610bf9565b6006546002546040805163221b8a9560e11b81526001600160a01b03928316600482015290519190921691634437152a91602480830192600092919082900301818387803b1580156105c657600080fd5b505af11580156105da573d6000803e3d6000fd5b50505050565b6105e981610d11565b50565b6000546001600160a01b031633146106355760405162461bcd60e51b8152600401808060200182810382526028815260200180611af46028913960400191505060405180910390fd5b6000816001600160a01b03166358c700a36040518163ffffffff1660e01b815260040160206040518083038186803b15801561067057600080fd5b505afa158015610684573d6000803e3d6000fd5b505050506040513d602081101561069a57600080fd5b5051604080516379a87b1960e01b815290519192506000916001600160a01b038516916379a87b19916004808301926020929190829003018186803b1580156106e257600080fd5b505afa1580156106f6573d6000803e3d6000fd5b505050506040513d602081101561070c57600080fd5b50519050811580159061071f5750814210155b61075a5760405162461bcd60e51b815260040180806020018281038252602d815260200180611d28602d913960400191505060405180910390fd5b6001600160a01b03811630146107a15760405162461bcd60e51b8152600401808060200182810382526037815260200180611bfd6037913960400191505060405180910390fd5b6108488330600460009054906101000a90046001600160a01b03166001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561080857600080fd5b505afa15801561081c573d6000803e3d6000fd5b505050506040513d602081101561083257600080fd5b50516004546001600160a01b0316929190610f7f565b826001600160a01b031663547b45796040518163ffffffff1660e01b815260040160206040518083038186803b15801561088157600080fd5b505afa158015610895573d6000803e3d6000fd5b505050506040513d60208110156108ab57600080fd5b5051600955600154604080519182526001600160a01b03851660208301523082820152517f18ce2512842fddee8c808fb717780a66007d1da9a942dd32625813c82d53c3429181900360600190a1505050565b60095490565b60015490565b6000546001600160a01b031633146109535760405162461bcd60e51b8152600401808060200182810382526028815260200180611af46028913960400191505060405180910390fd5b6001600160a01b0382166109985760405162461bcd60e51b815260040180806020018281038252602d815260200180611ac7602d913960400191505060405180910390fd5b600381101580156109ab575061016d8111155b6109e65760405162461bcd60e51b815260040180806020018281038252602c815260200180611e16602c913960400191505060405180910390fd5b62015180810242016001819055600280546001600160a01b0319166001600160a01b03858116919091179182905560408051938452306020850152911682820152517fe2a3b7ba8269be3ca7ba4627f844bb9abd978e9b05d290dc89d4b107f9e3dda7916060908290030190a15050565b6002546001600160a01b031690565b6001600160a01b038116610aab5760405162461bcd60e51b815260040180806020018281038252602a815260200180611cdc602a913960400191505060405180910390fd5b6000546001600160a01b03161580610acd57506000546001600160a01b031633145b610b085760405162461bcd60e51b8152600401808060200182810382526051815260200180611d556051913960600191505060405180910390fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60038054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610bb65780601f10610b8b57610100808354040283529160200191610bb6565b820191906000526020600020905b815481529060010190602001808311610b9957829003601f168201915b5050505050905090565b6105e981610fd9565b6004546006546001600160a01b0391821691169091565b6007546008549091565b6000546001600160a01b031690565b801580610c7f575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015610c5157600080fd5b505afa158015610c65573d6000803e3d6000fd5b505050506040513d6020811015610c7b57600080fd5b5051155b610cba5760405162461bcd60e51b8152600401808060200182810382526036815260200180611ecd6036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052610d0c9084906112fb565b505050565b600a5460ff1615610d62576040805162461bcd60e51b815260206004820152601660248201527550657270657475616c506f6f6c3a207265656e74727960501b604482015290519081900360640190fd5b600a805460ff19166001179055600754811015610db05760405162461bcd60e51b815260040180806020018281038252603a815260200180611c5a603a913960400191505060405180910390fd5b80610dc6600554836113ac90919063ffffffff16565b14610e025760405162461bcd60e51b815260040180806020018281038252602e815260200180611e42602e913960400191505060405180910390fd5b610e0d3330836113ce565b9050600060095490506000600660009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e6657600080fd5b505afa158015610e7a573d6000803e3d6000fd5b505050506040513d6020811015610e9057600080fd5b50519050600081610ea2575082610eb9565b610eb683610eb08685611586565b906115f1565b90505b600654604080516340c10f1960e01b81523360048201526024810184905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b158015610f0c57600080fd5b505af1158015610f20573d6000803e3d6000fd5b5050600954610f329250905085611690565b6009556040805182815260208101869052815133927f06239653922ac7bea6aa2b19dc486b9361821d37712eb796adfd38d81de278ca928290030190a25050600a805460ff191690555050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526105da9085906112fb565b600a5460ff161561102a576040805162461bcd60e51b815260206004820152601660248201527550657270657475616c506f6f6c3a207265656e74727960501b604482015290519081900360640190fd5b600a805460ff19166001179055806110735760405162461bcd60e51b8152600401808060200182810382526021815260200180611aa66021913960400191505060405180910390fd5b600654604080516370a0823160e01b815233600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156110be57600080fd5b505afa1580156110d2573d6000803e3d6000fd5b505050506040513d60208110156110e857600080fd5b505190508181148061110b5750670de0b6b3a764000061110882846116d4565b10155b6111465760405162461bcd60e51b8152600401808060200182810382526041815260200180611da66041913960600191505060405180910390fd5b600954600654604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561118e57600080fd5b505afa1580156111a2573d6000803e3d6000fd5b505050506040513d60208110156111b857600080fd5b5051905060006111cc82610eb08786611586565b9050818510156111f8576111f56111ee6008548361158690919063ffffffff16565b82906116d4565b90505b6005546112069082906113ac565b60095490915061121690826116d4565b60095560065460408051632770a7eb60e21b81523360048201526024810188905290516001600160a01b0390921691639dc29fac9160448082019260009290919082900301818387803b15801561126c57600080fd5b505af1158015611280573d6000803e3d6000fd5b505050506112b03361129d6005548461171b90919063ffffffff16565b6004546001600160a01b03169190611729565b6040805186815260208101839052815133927f0fbf06c058b90cb038a618f8c2acbf6145f8b3570fd1fa56abb8f0f3f05b36e8928290030190a25050600a805460ff19169055505050565b6000611350826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661177b9092919063ffffffff16565b805190915015610d0c5780806020019051602081101561136f57600080fd5b5051610d0c5760405162461bcd60e51b815260040180806020018281038252602a815260200180611e70602a913960400191505060405180910390fd5b60006113c56113bd84601285611792565b836012611792565b90505b92915050565b60048054604080516370a0823160e01b81526001600160a01b03868116948201949094529051600093849316916370a08231916024808301926020929190829003018186803b15801561142057600080fd5b505afa158015611434573d6000803e3d6000fd5b505050506040513d602081101561144a57600080fd5b5051600554909150611479908690869061146590879061171b565b6004546001600160a01b0316929190610f7f565b6000600460009054906101000a90046001600160a01b03166001600160a01b03166370a08231866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156114dd57600080fd5b505afa1580156114f1573d6000803e3d6000fd5b505050506040513d602081101561150757600080fd5b50519050600061151782846116d4565b9050670de0b6b3a764000080820282828204146115655760405162461bcd60e51b815260040180806020018281038252604c815260200180611b7b604c913960600191505060405180910390fd5b6000600554600a0a828161157557fe5b0496505050505050505b9392505050565b600082611595575060006113c8565b828202828482816115a257fe5b04146115df5760405162461bcd60e51b8152600401808060200182810382526036815260200180611bc76036913960400191505060405180910390fd5b670de0b6b3a764000090049392505050565b60008161162f5760405162461bcd60e51b815260040180806020018281038252602f815260200180611b4c602f913960400191505060405180910390fd5b670de0b6b3a7640000838102908104841461167b5760405162461bcd60e51b8152600401808060200182810382526048815260200180611c946048913960600191505060405180910390fd5b600083828161168657fe5b0495945050505050565b6000828201838110156113c55760405162461bcd60e51b8152600401808060200182810382526030815260200180611b1c6030913960400191505060405180910390fd5b6000818310156117155760405162461bcd60e51b8152600401808060200182810382526033815260200180611e9a6033913960400191505060405180910390fd5b50900390565b60006113c583601284611792565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610d0c9084906112fb565b606061178a84846000856117ff565b949350505050565b6000600a83810a9083900a858102868282816117aa57fe5b04146117e75760405162461bcd60e51b815260040180806020018281038252602f815260200180611de7602f913960400191505060405180910390fd5b60008382816117f257fe5b0498975050505050505050565b6060824710156118405760405162461bcd60e51b8152600401808060200182810382526026815260200180611c346026913960400191505060405180910390fd5b6118498561195a565b61189a576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b602083106118d85780518252601f1990920191602091820191016118b9565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811461193a576040519150601f19603f3d011682016040523d82523d6000602084013e61193f565b606091505b509150915061194f828286611960565b979650505050505050565b3b151590565b6060831561196f57508161157f565b82511561197f5782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156119c95781810151838201526020016119b1565b50505050905090810190601f1680156119f65780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611a3a5760008555611a80565b82601f10611a5357805160ff1916838001178555611a80565b82800160010185558215611a80579182015b82811115611a80578251825591602001919060010190611a65565b50611a8c929150611a90565b5090565b5b80821115611a8c5760008155600101611a9156fe50657270657475616c506f6f6c3a2072656d6f76652030206c69717569646974794d696772617461626c65506f6f6c3a20707265706172654d6967726174696f6e20746f2030206164647265737363616e206f6e6c792062652063616c6c65642062792063757272656e7420636f6e74726f6c6c65724d69786564536166654d61746857697468556e69743a2075696e74323536206164646974696f6e206f766572666c6f774d69786564536166654d61746857697468556e69743a2075696e74323536206469766973696f6e206279207a65726f5072654d696e696e67506f6f6c3a205f6465666c6174696f6e436f6d70617469626c65536166655472616e7366657246726f6d206d756c7469706c69636174696f6e206f766572666c6f77734d69786564536166654d61746857697468556e69743a2075696e74323536206d756c7469706c69636174696f6e206f766572666c6f7750657270657475616c506f6f6c3a20657865637574654d6967726174696f6e20746f206e6f742064657374696e6174696f6e20706f6f6c416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c50657270657475616c506f6f6c3a20616464206c6971756964697479206c657373207468616e206d696e696d756d20726571756972656d656e744d69786564536166654d61746857697468556e69743a2075696e74323536206469766973696f6e20696e7465726e616c206d756c7469706c69636174696f6e206f766572666c6f774d696772617461626c65506f6f6c3a20736574436f6e74726f6c6c657220746f2030206164647265737350657270657475616c506f6f6c3a20616c726561647920696e697469616c697a656450657270657475616c506f6f6c3a206d6967726174696f6e54696d657374616d70206e6f74206d6574207965744d696772617461626c65506f6f6c3a20736574436f6e74726f6c6c65722063616e206f6e6c792062652063616c6c65642062792063757272656e7420636f6e74726f6c6c6572206f72206e6f742073657450657270657475616c506f6f6c3a2072656d61696e696e67206c697175696469747920736861726573206d7573742062652030206f72206174206c6561737420314d69786564536166654d61746857697468556e69743a2072657363616c652075696e74323536206f766572666c6f774d696772617461626c65506f6f6c3a20677261636544617973206d75737420626520332d333635206461797350657270657475616c506f6f6c3a205f6164644c69717569646974792062416d6f756e74206e6f742076616c69645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644d69786564536166654d61746857697468556e69743a2075696e74323536207375627472616374696f6e206f766572666c6f775361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a26469706673582212205fd5578dc39503f339b8fd5259ea059bf534759f59cc95e4d17b798006c91f9864736f6c63430007060033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379a87b191161008c5780639c8f9f23116100665780639c8f9f23146102fd578063a39fac121461031a578063a5ea11da14610351578063f77c479114610372576100ea565b806379a87b191461023657806392eefe9b1461025a57806395d89b4114610280576100ea565b806351dfdb48116100c857806351dfdb48146101c2578063547b4579146101e857806358c700a314610202578063677528cb1461020a576100ea565b806320a39957146100ef578063325564ec1461019d57806351c6590a146101a5575b600080fd5b61019b600480360360a081101561010557600080fd5b81019060208101813564010000000081111561012057600080fd5b82018360208201111561013257600080fd5b8035906020019184600183028401116401000000008311171561015457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295509293505060408301915061037a9050565b005b61019b6104bf565b61019b600480360360208110156101bb57600080fd5b50356105e0565b61019b600480360360208110156101d857600080fd5b50356001600160a01b03166105ec565b6101f06108fe565b60408051918252519081900360200190f35b6101f0610904565b61019b6004803603604081101561022057600080fd5b506001600160a01b03813516906020013561090a565b61023e610a57565b604080516001600160a01b039092168252519081900360200190f35b61019b6004803603602081101561027057600080fd5b50356001600160a01b0316610a66565b610288610b2a565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102c25781810151838201526020016102aa565b50505050905090810190601f1680156102ef5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61019b6004803603602081101561031357600080fd5b5035610bc0565b610322610bc9565b60405180836001600160a01b03168152602001826001600160a01b031681526020019250505060405180910390f35b610359610be0565b6040805192835260208301919091528051918290030190f35b61023e610bea565b600354600260001961010060018416150201909116041580156103a657506000546001600160a01b0316155b6103e15760405162461bcd60e51b8152600401808060200182810382526022815260200180611d066022913960400191505060405180910390fd5b600080546001600160a01b031916331790558251610406906003906020860190611a04565b50600480546001600160a01b0319166001600160a01b0384358116919091178083556040805163313ce56760e01b81529051919092169263313ce56792808201926020929091829003018186803b15801561046057600080fd5b505afa158015610474573d6000803e3d6000fd5b505050506040513d602081101561048a57600080fd5b505160ff16600555600680546001600160a01b0319166001600160a01b03602094850135161790558035600755013560085550565b6000546001600160a01b031633146105085760405162461bcd60e51b8152600401808060200182810382526028815260200180611af46028913960400191505060405180910390fd5b6001541580159061051b57506001544210155b6105565760405162461bcd60e51b815260040180806020018281038252602d815260200180611d28602d913960400191505060405180910390fd5b600254600454610575916001600160a01b039182169116600019610bf9565b6006546002546040805163221b8a9560e11b81526001600160a01b03928316600482015290519190921691634437152a91602480830192600092919082900301818387803b1580156105c657600080fd5b505af11580156105da573d6000803e3d6000fd5b50505050565b6105e981610d11565b50565b6000546001600160a01b031633146106355760405162461bcd60e51b8152600401808060200182810382526028815260200180611af46028913960400191505060405180910390fd5b6000816001600160a01b03166358c700a36040518163ffffffff1660e01b815260040160206040518083038186803b15801561067057600080fd5b505afa158015610684573d6000803e3d6000fd5b505050506040513d602081101561069a57600080fd5b5051604080516379a87b1960e01b815290519192506000916001600160a01b038516916379a87b19916004808301926020929190829003018186803b1580156106e257600080fd5b505afa1580156106f6573d6000803e3d6000fd5b505050506040513d602081101561070c57600080fd5b50519050811580159061071f5750814210155b61075a5760405162461bcd60e51b815260040180806020018281038252602d815260200180611d28602d913960400191505060405180910390fd5b6001600160a01b03811630146107a15760405162461bcd60e51b8152600401808060200182810382526037815260200180611bfd6037913960400191505060405180910390fd5b6108488330600460009054906101000a90046001600160a01b03166001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561080857600080fd5b505afa15801561081c573d6000803e3d6000fd5b505050506040513d602081101561083257600080fd5b50516004546001600160a01b0316929190610f7f565b826001600160a01b031663547b45796040518163ffffffff1660e01b815260040160206040518083038186803b15801561088157600080fd5b505afa158015610895573d6000803e3d6000fd5b505050506040513d60208110156108ab57600080fd5b5051600955600154604080519182526001600160a01b03851660208301523082820152517f18ce2512842fddee8c808fb717780a66007d1da9a942dd32625813c82d53c3429181900360600190a1505050565b60095490565b60015490565b6000546001600160a01b031633146109535760405162461bcd60e51b8152600401808060200182810382526028815260200180611af46028913960400191505060405180910390fd5b6001600160a01b0382166109985760405162461bcd60e51b815260040180806020018281038252602d815260200180611ac7602d913960400191505060405180910390fd5b600381101580156109ab575061016d8111155b6109e65760405162461bcd60e51b815260040180806020018281038252602c815260200180611e16602c913960400191505060405180910390fd5b62015180810242016001819055600280546001600160a01b0319166001600160a01b03858116919091179182905560408051938452306020850152911682820152517fe2a3b7ba8269be3ca7ba4627f844bb9abd978e9b05d290dc89d4b107f9e3dda7916060908290030190a15050565b6002546001600160a01b031690565b6001600160a01b038116610aab5760405162461bcd60e51b815260040180806020018281038252602a815260200180611cdc602a913960400191505060405180910390fd5b6000546001600160a01b03161580610acd57506000546001600160a01b031633145b610b085760405162461bcd60e51b8152600401808060200182810382526051815260200180611d556051913960600191505060405180910390fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60038054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610bb65780601f10610b8b57610100808354040283529160200191610bb6565b820191906000526020600020905b815481529060010190602001808311610b9957829003601f168201915b5050505050905090565b6105e981610fd9565b6004546006546001600160a01b0391821691169091565b6007546008549091565b6000546001600160a01b031690565b801580610c7f575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015610c5157600080fd5b505afa158015610c65573d6000803e3d6000fd5b505050506040513d6020811015610c7b57600080fd5b5051155b610cba5760405162461bcd60e51b8152600401808060200182810382526036815260200180611ecd6036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052610d0c9084906112fb565b505050565b600a5460ff1615610d62576040805162461bcd60e51b815260206004820152601660248201527550657270657475616c506f6f6c3a207265656e74727960501b604482015290519081900360640190fd5b600a805460ff19166001179055600754811015610db05760405162461bcd60e51b815260040180806020018281038252603a815260200180611c5a603a913960400191505060405180910390fd5b80610dc6600554836113ac90919063ffffffff16565b14610e025760405162461bcd60e51b815260040180806020018281038252602e815260200180611e42602e913960400191505060405180910390fd5b610e0d3330836113ce565b9050600060095490506000600660009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e6657600080fd5b505afa158015610e7a573d6000803e3d6000fd5b505050506040513d6020811015610e9057600080fd5b50519050600081610ea2575082610eb9565b610eb683610eb08685611586565b906115f1565b90505b600654604080516340c10f1960e01b81523360048201526024810184905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b158015610f0c57600080fd5b505af1158015610f20573d6000803e3d6000fd5b5050600954610f329250905085611690565b6009556040805182815260208101869052815133927f06239653922ac7bea6aa2b19dc486b9361821d37712eb796adfd38d81de278ca928290030190a25050600a805460ff191690555050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526105da9085906112fb565b600a5460ff161561102a576040805162461bcd60e51b815260206004820152601660248201527550657270657475616c506f6f6c3a207265656e74727960501b604482015290519081900360640190fd5b600a805460ff19166001179055806110735760405162461bcd60e51b8152600401808060200182810382526021815260200180611aa66021913960400191505060405180910390fd5b600654604080516370a0823160e01b815233600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156110be57600080fd5b505afa1580156110d2573d6000803e3d6000fd5b505050506040513d60208110156110e857600080fd5b505190508181148061110b5750670de0b6b3a764000061110882846116d4565b10155b6111465760405162461bcd60e51b8152600401808060200182810382526041815260200180611da66041913960600191505060405180910390fd5b600954600654604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561118e57600080fd5b505afa1580156111a2573d6000803e3d6000fd5b505050506040513d60208110156111b857600080fd5b5051905060006111cc82610eb08786611586565b9050818510156111f8576111f56111ee6008548361158690919063ffffffff16565b82906116d4565b90505b6005546112069082906113ac565b60095490915061121690826116d4565b60095560065460408051632770a7eb60e21b81523360048201526024810188905290516001600160a01b0390921691639dc29fac9160448082019260009290919082900301818387803b15801561126c57600080fd5b505af1158015611280573d6000803e3d6000fd5b505050506112b03361129d6005548461171b90919063ffffffff16565b6004546001600160a01b03169190611729565b6040805186815260208101839052815133927f0fbf06c058b90cb038a618f8c2acbf6145f8b3570fd1fa56abb8f0f3f05b36e8928290030190a25050600a805460ff19169055505050565b6000611350826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661177b9092919063ffffffff16565b805190915015610d0c5780806020019051602081101561136f57600080fd5b5051610d0c5760405162461bcd60e51b815260040180806020018281038252602a815260200180611e70602a913960400191505060405180910390fd5b60006113c56113bd84601285611792565b836012611792565b90505b92915050565b60048054604080516370a0823160e01b81526001600160a01b03868116948201949094529051600093849316916370a08231916024808301926020929190829003018186803b15801561142057600080fd5b505afa158015611434573d6000803e3d6000fd5b505050506040513d602081101561144a57600080fd5b5051600554909150611479908690869061146590879061171b565b6004546001600160a01b0316929190610f7f565b6000600460009054906101000a90046001600160a01b03166001600160a01b03166370a08231866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156114dd57600080fd5b505afa1580156114f1573d6000803e3d6000fd5b505050506040513d602081101561150757600080fd5b50519050600061151782846116d4565b9050670de0b6b3a764000080820282828204146115655760405162461bcd60e51b815260040180806020018281038252604c815260200180611b7b604c913960600191505060405180910390fd5b6000600554600a0a828161157557fe5b0496505050505050505b9392505050565b600082611595575060006113c8565b828202828482816115a257fe5b04146115df5760405162461bcd60e51b8152600401808060200182810382526036815260200180611bc76036913960400191505060405180910390fd5b670de0b6b3a764000090049392505050565b60008161162f5760405162461bcd60e51b815260040180806020018281038252602f815260200180611b4c602f913960400191505060405180910390fd5b670de0b6b3a7640000838102908104841461167b5760405162461bcd60e51b8152600401808060200182810382526048815260200180611c946048913960600191505060405180910390fd5b600083828161168657fe5b0495945050505050565b6000828201838110156113c55760405162461bcd60e51b8152600401808060200182810382526030815260200180611b1c6030913960400191505060405180910390fd5b6000818310156117155760405162461bcd60e51b8152600401808060200182810382526033815260200180611e9a6033913960400191505060405180910390fd5b50900390565b60006113c583601284611792565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610d0c9084906112fb565b606061178a84846000856117ff565b949350505050565b6000600a83810a9083900a858102868282816117aa57fe5b04146117e75760405162461bcd60e51b815260040180806020018281038252602f815260200180611de7602f913960400191505060405180910390fd5b60008382816117f257fe5b0498975050505050505050565b6060824710156118405760405162461bcd60e51b8152600401808060200182810382526026815260200180611c346026913960400191505060405180910390fd5b6118498561195a565b61189a576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b602083106118d85780518252601f1990920191602091820191016118b9565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811461193a576040519150601f19603f3d011682016040523d82523d6000602084013e61193f565b606091505b509150915061194f828286611960565b979650505050505050565b3b151590565b6060831561196f57508161157f565b82511561197f5782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156119c95781810151838201526020016119b1565b50505050905090810190601f1680156119f65780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611a3a5760008555611a80565b82601f10611a5357805160ff1916838001178555611a80565b82800160010185558215611a80579182015b82811115611a80578251825591602001919060010190611a65565b50611a8c929150611a90565b5090565b5b80821115611a8c5760008155600101611a9156fe50657270657475616c506f6f6c3a2072656d6f76652030206c69717569646974794d696772617461626c65506f6f6c3a20707265706172654d6967726174696f6e20746f2030206164647265737363616e206f6e6c792062652063616c6c65642062792063757272656e7420636f6e74726f6c6c65724d69786564536166654d61746857697468556e69743a2075696e74323536206164646974696f6e206f766572666c6f774d69786564536166654d61746857697468556e69743a2075696e74323536206469766973696f6e206279207a65726f5072654d696e696e67506f6f6c3a205f6465666c6174696f6e436f6d70617469626c65536166655472616e7366657246726f6d206d756c7469706c69636174696f6e206f766572666c6f77734d69786564536166654d61746857697468556e69743a2075696e74323536206d756c7469706c69636174696f6e206f766572666c6f7750657270657475616c506f6f6c3a20657865637574654d6967726174696f6e20746f206e6f742064657374696e6174696f6e20706f6f6c416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c50657270657475616c506f6f6c3a20616464206c6971756964697479206c657373207468616e206d696e696d756d20726571756972656d656e744d69786564536166654d61746857697468556e69743a2075696e74323536206469766973696f6e20696e7465726e616c206d756c7469706c69636174696f6e206f766572666c6f774d696772617461626c65506f6f6c3a20736574436f6e74726f6c6c657220746f2030206164647265737350657270657475616c506f6f6c3a20616c726561647920696e697469616c697a656450657270657475616c506f6f6c3a206d6967726174696f6e54696d657374616d70206e6f74206d6574207965744d696772617461626c65506f6f6c3a20736574436f6e74726f6c6c65722063616e206f6e6c792062652063616c6c65642062792063757272656e7420636f6e74726f6c6c6572206f72206e6f742073657450657270657475616c506f6f6c3a2072656d61696e696e67206c697175696469747920736861726573206d7573742062652030206f72206174206c6561737420314d69786564536166654d61746857697468556e69743a2072657363616c652075696e74323536206f766572666c6f774d696772617461626c65506f6f6c3a20677261636544617973206d75737420626520332d333635206461797350657270657475616c506f6f6c3a205f6164644c69717569646974792062416d6f756e74206e6f742076616c69645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644d69786564536166654d61746857697468556e69743a2075696e74323536207375627472616374696f6e206f766572666c6f775361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a26469706673582212205fd5578dc39503f339b8fd5259ea059bf534759f59cc95e4d17b798006c91f9864736f6c63430007060033

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.