ETH Price: $3,357.06 (-0.79%)
Gas: 1 Gwei

Contract

0xf5FAB5DBD2f3bf675dE4cB76517d4767013cfB55
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Transfer Ownersh...117369262021-01-27 9:11:311249 days ago1611738691IN
0xf5FAB5DB...7013cfB55
0 ETH0.0042495396
Accept Ownership117369162021-01-27 9:09:021249 days ago1611738542IN
0xf5FAB5DB...7013cfB55
0 ETH0.0019736190
Transfer Ownersh...114519562020-12-14 15:34:141293 days ago1607960054IN
0xf5FAB5DB...7013cfB55
0 ETH0.0040813292.2
Withdraw Tokens114519542020-12-14 15:33:361293 days ago1607960016IN
0xf5FAB5DB...7013cfB55
0 ETH0.0027759498
Accept Ownership114519502020-12-14 15:32:561293 days ago1607959976IN
0xf5FAB5DB...7013cfB55
0 ETH0.0021490498
Transfer Ownersh...110396462020-10-12 8:19:291356 days ago1602490769IN
0xf5FAB5DB...7013cfB55
0 ETH0.0022131849.99737311
0x60806040110396422020-10-12 8:19:071356 days ago1602490747IN
 Create: LiquidityProtectionStore
0 ETH0.0874549549.99737311

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
LiquidityProtectionStore

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-10-12
*/

// File: solidity/contracts/utility/interfaces/IOwned.sol

// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity 0.6.12;

/*
    Owned contract interface
*/
interface IOwned {
    // this function isn't since the compiler emits automatically generated getter functions as external
    function owner() external view returns (address);

    function transferOwnership(address _newOwner) external;
    function acceptOwnership() external;
}

// File: solidity/contracts/converter/interfaces/IConverterAnchor.sol


pragma solidity 0.6.12;


/*
    Converter Anchor interface
*/
interface IConverterAnchor is IOwned {
}

// File: solidity/contracts/token/interfaces/IERC20Token.sol


pragma solidity 0.6.12;

/*
    ERC20 Standard Token interface
*/
interface IERC20Token {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
    function totalSupply() external view returns (uint256);
    function balanceOf(address _owner) external view returns (uint256);
    function allowance(address _owner, address _spender) external view returns (uint256);

    function transfer(address _to, uint256 _value) external returns (bool);
    function transferFrom(address _from, address _to, uint256 _value) external returns (bool);
    function approve(address _spender, uint256 _value) external returns (bool);
}

// File: solidity/contracts/token/interfaces/IDSToken.sol


pragma solidity 0.6.12;




/*
    DSToken interface
*/
interface IDSToken is IConverterAnchor, IERC20Token {
    function issue(address _to, uint256 _amount) external;
    function destroy(address _from, uint256 _amount) external;
}

// File: solidity/contracts/liquidity-protection/interfaces/ILiquidityProtectionStore.sol


pragma solidity 0.6.12;





/*
    Liquidity Protection Store interface
*/
interface ILiquidityProtectionStore is IOwned {
    function addPoolToWhitelist(IConverterAnchor _anchor) external;
    function removePoolFromWhitelist(IConverterAnchor _anchor) external;
    function isPoolWhitelisted(IConverterAnchor _anchor) external view returns (bool);

    function withdrawTokens(IERC20Token _token, address _to, uint256 _amount) external;

    function protectedLiquidity(uint256 _id)
        external
        view
        returns (address, IDSToken, IERC20Token, uint256, uint256, uint256, uint256, uint256);

    function addProtectedLiquidity(
        address _provider,
        IDSToken _poolToken,
        IERC20Token _reserveToken,
        uint256 _poolAmount,
        uint256 _reserveAmount,
        uint256 _reserveRateN,
        uint256 _reserveRateD,
        uint256 _timestamp
    ) external returns (uint256);

    function updateProtectedLiquidityAmounts(uint256 _id, uint256 _poolNewAmount, uint256 _reserveNewAmount) external;
    function removeProtectedLiquidity(uint256 _id) external;
    
    function lockedBalance(address _provider, uint256 _index) external view returns (uint256, uint256);
    function lockedBalanceRange(address _provider, uint256 _startIndex, uint256 _endIndex) external view returns (uint256[] memory, uint256[] memory);

    function addLockedBalance(address _provider, uint256 _reserveAmount, uint256 _expirationTime) external returns (uint256);
    function removeLockedBalance(address _provider, uint256 _index) external;

    function systemBalance(IERC20Token _poolToken) external view returns (uint256);
    function incSystemBalance(IERC20Token _poolToken, uint256 _poolAmount) external;
    function decSystemBalance(IERC20Token _poolToken, uint256 _poolAmount ) external;
}

// File: solidity/contracts/utility/Owned.sol


pragma solidity 0.6.12;


/**
  * @dev Provides support and utilities for contract ownership
*/
contract Owned is IOwned {
    address public override owner;
    address public newOwner;

    /**
      * @dev triggered when the owner is updated
      *
      * @param _prevOwner previous owner
      * @param _newOwner  new owner
    */
    event OwnerUpdate(address indexed _prevOwner, address indexed _newOwner);

    /**
      * @dev initializes a new Owned instance
    */
    constructor() public {
        owner = msg.sender;
    }

    // allows execution by the owner only
    modifier ownerOnly {
        _ownerOnly();
        _;
    }

    // error message binary size optimization
    function _ownerOnly() internal view {
        require(msg.sender == owner, "ERR_ACCESS_DENIED");
    }

    /**
      * @dev allows transferring the contract ownership
      * the new owner still needs to accept the transfer
      * can only be called by the contract owner
      *
      * @param _newOwner    new contract owner
    */
    function transferOwnership(address _newOwner) public override ownerOnly {
        require(_newOwner != owner, "ERR_SAME_OWNER");
        newOwner = _newOwner;
    }

    /**
      * @dev used by a new owner to accept an ownership transfer
    */
    function acceptOwnership() override public {
        require(msg.sender == newOwner, "ERR_ACCESS_DENIED");
        emit OwnerUpdate(owner, newOwner);
        owner = newOwner;
        newOwner = address(0);
    }
}

// File: solidity/contracts/utility/SafeMath.sol


pragma solidity 0.6.12;

/**
  * @dev Library for basic math operations with overflow/underflow protection
*/
library SafeMath {
    /**
      * @dev returns the sum of _x and _y, reverts if the calculation overflows
      *
      * @param _x   value 1
      * @param _y   value 2
      *
      * @return sum
    */
    function add(uint256 _x, uint256 _y) internal pure returns (uint256) {
        uint256 z = _x + _y;
        require(z >= _x, "ERR_OVERFLOW");
        return z;
    }

    /**
      * @dev returns the difference of _x minus _y, reverts if the calculation underflows
      *
      * @param _x   minuend
      * @param _y   subtrahend
      *
      * @return difference
    */
    function sub(uint256 _x, uint256 _y) internal pure returns (uint256) {
        require(_x >= _y, "ERR_UNDERFLOW");
        return _x - _y;
    }

    /**
      * @dev returns the product of multiplying _x by _y, reverts if the calculation overflows
      *
      * @param _x   factor 1
      * @param _y   factor 2
      *
      * @return product
    */
    function mul(uint256 _x, uint256 _y) internal pure returns (uint256) {
        // gas optimization
        if (_x == 0)
            return 0;

        uint256 z = _x * _y;
        require(z / _x == _y, "ERR_OVERFLOW");
        return z;
    }

    /**
      * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
      *
      * @param _x   dividend
      * @param _y   divisor
      *
      * @return quotient
    */
    function div(uint256 _x, uint256 _y) internal pure returns (uint256) {
        require(_y > 0, "ERR_DIVIDE_BY_ZERO");
        uint256 c = _x / _y;
        return c;
    }
}

// File: solidity/contracts/utility/TokenHandler.sol


pragma solidity 0.6.12;


contract TokenHandler {
    bytes4 private constant APPROVE_FUNC_SELECTOR = bytes4(keccak256("approve(address,uint256)"));
    bytes4 private constant TRANSFER_FUNC_SELECTOR = bytes4(keccak256("transfer(address,uint256)"));
    bytes4 private constant TRANSFER_FROM_FUNC_SELECTOR = bytes4(keccak256("transferFrom(address,address,uint256)"));

    /**
      * @dev executes the ERC20 token's `approve` function and reverts upon failure
      * the main purpose of this function is to prevent a non standard ERC20 token
      * from failing silently
      *
      * @param _token   ERC20 token address
      * @param _spender approved address
      * @param _value   allowance amount
    */
    function safeApprove(IERC20Token _token, address _spender, uint256 _value) internal {
        (bool success, bytes memory data) = address(_token).call(abi.encodeWithSelector(APPROVE_FUNC_SELECTOR, _spender, _value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'ERR_APPROVE_FAILED');
    }

    /**
      * @dev executes the ERC20 token's `transfer` function and reverts upon failure
      * the main purpose of this function is to prevent a non standard ERC20 token
      * from failing silently
      *
      * @param _token   ERC20 token address
      * @param _to      target address
      * @param _value   transfer amount
    */
    function safeTransfer(IERC20Token _token, address _to, uint256 _value) internal {
       (bool success, bytes memory data) = address(_token).call(abi.encodeWithSelector(TRANSFER_FUNC_SELECTOR, _to, _value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'ERR_TRANSFER_FAILED');
    }

    /**
      * @dev executes the ERC20 token's `transferFrom` function and reverts upon failure
      * the main purpose of this function is to prevent a non standard ERC20 token
      * from failing silently
      *
      * @param _token   ERC20 token address
      * @param _from    source address
      * @param _to      target address
      * @param _value   transfer amount
    */
    function safeTransferFrom(IERC20Token _token, address _from, address _to, uint256 _value) internal {
       (bool success, bytes memory data) = address(_token).call(abi.encodeWithSelector(TRANSFER_FROM_FUNC_SELECTOR, _from, _to, _value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'ERR_TRANSFER_FROM_FAILED');
    }
}

// File: solidity/contracts/utility/Utils.sol


pragma solidity 0.6.12;

/**
  * @dev Utilities & Common Modifiers
*/
contract Utils {
    // verifies that a value is greater than zero
    modifier greaterThanZero(uint256 _value) {
        _greaterThanZero(_value);
        _;
    }

    // error message binary size optimization
    function _greaterThanZero(uint256 _value) internal pure {
        require(_value > 0, "ERR_ZERO_VALUE");
    }

    // validates an address - currently only checks that it isn't null
    modifier validAddress(address _address) {
        _validAddress(_address);
        _;
    }

    // error message binary size optimization
    function _validAddress(address _address) internal pure {
        require(_address != address(0), "ERR_INVALID_ADDRESS");
    }

    // verifies that the address is different than this contract address
    modifier notThis(address _address) {
        _notThis(_address);
        _;
    }

    // error message binary size optimization
    function _notThis(address _address) internal view {
        require(_address != address(this), "ERR_ADDRESS_IS_SELF");
    }
}

// File: solidity/contracts/liquidity-protection/LiquidityProtectionStore.sol


pragma solidity 0.6.12;






/**
  * @dev The Liquidity Protection Store contract serves as the storage of the liquidity protection
  * mechanism. It holds the data and tokens and is non upgradable.
  *
*/
contract LiquidityProtectionStore is ILiquidityProtectionStore, Owned, TokenHandler, Utils {
    using SafeMath for uint256;

    struct PoolIndex {
        bool isValid;
        uint256 value;
    }

    struct ProtectedLiquidity {
        address provider;           // liquidity provider
        uint256 index;              // index in the provider liquidity ids array
        IDSToken poolToken;         // pool token address
        IERC20Token reserveToken;   // reserve token address
        uint256 poolAmount;         // pool token amount
        uint256 reserveAmount;      // reserve token amount
        uint256 reserveRateN;       // rate of 1 protected reserve token in units of the other reserve token (numerator)
        uint256 reserveRateD;       // rate of 1 protected reserve token in units of the other reserve token (denominator)
        uint256 timestamp;          // timestamp
    }

    struct LockedBalance {
        uint256 amount;         // amount of network tokens
        uint256 expirationTime; // lock expiration time
    }

    // list of whitelisted pools and mapping of pool anchor address -> index in the pool whitelist for quick access
    IConverterAnchor[] private poolWhitelist;
    mapping(IConverterAnchor => PoolIndex) private poolWhitelistIndices;

    // protected liquidity by provider
    uint256 private nextProtectedLiquidityId;
    mapping (address => uint256[]) private protectedLiquidityIdsByProvider;
    mapping (uint256 => ProtectedLiquidity) private protectedLiquidities;

    // user locked network token balances
    mapping (address => LockedBalance[]) private lockedBalances;

    // system balances
    mapping (IERC20Token => uint256) private systemBalances;

    // total protected pool supplies / reserve amounts
    mapping (IDSToken =>    uint256) private totalProtectedPoolAmounts;
    mapping (IDSToken =>    mapping (IERC20Token => uint256)) private totalProtectedReserveAmounts;

    /**
      * @dev triggered when the pool whitelist is updated
      *
      * @param _poolAnchor  pool anchor
      * @param _added       true if the pool was added to the whitelist, false if it was removed
    */
    event PoolWhitelistUpdated(
        IConverterAnchor indexed _poolAnchor,
        bool _added
    );

    /**
      * @dev triggered when liquidity protection is added
      *
      * @param _provider        liquidity provider
      * @param _poolToken       pool token address
      * @param _reserveToken    reserve token address
      * @param _poolAmount      amount of pool tokens
      * @param _reserveAmount   amount of reserve tokens
    */
    event ProtectionAdded(
        address indexed _provider,
        IDSToken indexed    _poolToken,
        IERC20Token indexed _reserveToken,
        uint256 _poolAmount,
        uint256 _reserveAmount
    );

    /**
      * @dev triggered when liquidity protection is updated
      *
      * @param _provider            liquidity provider
      * @param _prevPoolAmount      previous amount of pool tokens
      * @param _prevReserveAmount   previous amount of reserve tokens
      * @param _newPoolAmount       new amount of pool tokens
      * @param _newReserveAmount    new amount of reserve tokens
    */
    event ProtectionUpdated(
        address indexed _provider,
        uint256 _prevPoolAmount,
        uint256 _prevReserveAmount,
        uint256 _newPoolAmount,
        uint256 _newReserveAmount
    );

    /**
      * @dev triggered when liquidity protection is removed
      *
      * @param _provider        liquidity provider
      * @param _poolToken       pool token address
      * @param _reserveToken    reserve token address
      * @param _poolAmount      amount of pool tokens
      * @param _reserveAmount   amount of reserve tokens
    */
    event ProtectionRemoved(
        address indexed _provider,
        IDSToken indexed    _poolToken,
        IERC20Token indexed _reserveToken,
        uint256 _poolAmount,
        uint256 _reserveAmount
    );

    /**
      * @dev triggered when network tokens are locked
      *
      * @param _provider        provider of the network tokens
      * @param _amount          amount of network tokens
      * @param _expirationTime  lock expiration time
    */
    event BalanceLocked(
        address indexed _provider,
        uint256 _amount,
        uint256 _expirationTime
    );

    /**
      * @dev triggered when network tokens are unlocked
      *
      * @param _provider    provider of the network tokens
      * @param _amount      amount of network tokens
    */
    event BalanceUnlocked(
        address indexed _provider,
        uint256 _amount
    );

    /**
      * @dev triggered when the system balance for a given token is updated
      *
      * @param _token       token address
      * @param _prevAmount  previous amount
      * @param _newAmount   new amount
    */
    event SystemBalanceUpdated(
        IERC20Token _token,
        uint256 _prevAmount,
        uint256 _newAmount
    );

    /**
      * @dev adds a pool to the whitelist
      * can only be called by the contract owner
      *
      * @param _poolAnchor pool anchor
    */
    function addPoolToWhitelist(IConverterAnchor _poolAnchor)
        external
        override
        ownerOnly
        validAddress(address(_poolAnchor))
        notThis(address(_poolAnchor))
    {
        // validate input
        PoolIndex storage poolIndex = poolWhitelistIndices[_poolAnchor];
        require(!poolIndex.isValid, "ERR_POOL_ALREADY_WHITELISTED");

        poolIndex.value = poolWhitelist.length;
        poolWhitelist.push(_poolAnchor);
        poolIndex.isValid = true;

        emit PoolWhitelistUpdated(_poolAnchor, true);
    }

    /**
      * @dev removes a pool from the whitelist
      * can only be called by the contract owner
      *
      * @param _poolAnchor pool anchor
    */
    function removePoolFromWhitelist(IConverterAnchor _poolAnchor)
        external
        override
        ownerOnly
        validAddress(address(_poolAnchor))
        notThis(address(_poolAnchor))
    {
        // validate input
        PoolIndex storage poolIndex = poolWhitelistIndices[_poolAnchor];
        require(poolIndex.isValid, "ERR_POOL_NOT_WHITELISTED");

        uint256 index = poolIndex.value;
        uint256 length = poolWhitelist.length;
        assert(length > 0);

        uint256 lastIndex = length - 1;
        if (index < lastIndex) {
            IConverterAnchor lastAnchor = poolWhitelist[lastIndex];
            poolWhitelistIndices[lastAnchor].value = index;
            poolWhitelist[index] = lastAnchor;
        }

        poolWhitelist.pop();
        delete poolWhitelistIndices[_poolAnchor];

        emit PoolWhitelistUpdated(_poolAnchor, false);
    }

    /**
      * @dev returns the number of whitelisted pools
      *
      * @return number of whitelisted pools
    */
    function whitelistedPoolCount() external view returns (uint256) {
        return poolWhitelist.length;
    }

    /**
      * @dev returns the list of whitelisted pools
      *
      * @return list of whitelisted pools
    */
    function whitelistedPools() external view returns (IConverterAnchor[] memory) {
        return poolWhitelist;
    }

    /**
      * @dev returns the whitelisted pool at a given index
      *
      * @param _index index
      * @return whitelisted pool anchor
    */
    function whitelistedPool(uint256 _index) external view returns (IConverterAnchor) {
        return poolWhitelist[_index];
    }

    /**
      * @dev checks whether a given pool is whitelisted
      *
      * @param _poolAnchor pool anchor
      * @return true if the given pool is whitelisted, false otherwise
    */
    function isPoolWhitelisted(IConverterAnchor _poolAnchor) external view override returns (bool) {
        return poolWhitelistIndices[_poolAnchor].isValid;
    }

    /**
      * @dev withdraws tokens held by the contract
      * can only be called by the contract owner
      *
      * @param _token   token address
      * @param _to      recipient address
      * @param _amount  amount to withdraw
    */
    function withdrawTokens(IERC20Token _token, address _to, uint256 _amount)
        external
        override
        ownerOnly
        validAddress(_to)
        notThis(_to)
    {
        safeTransfer(_token, _to, _amount);
    }

    /**
      * @dev returns the number of protected liquidities for the given provider
      *
      * @param _provider    liquidity provider
      * @return number of protected liquidities
    */
    function protectedLiquidityCount(address _provider) external view returns (uint256) {
        return protectedLiquidityIdsByProvider[_provider].length;
    }

    /**
      * @dev returns the list of protected liquidity ids for the given provider
      *
      * @param _provider    liquidity provider
      * @return protected liquidity ids
    */
    function protectedLiquidityIds(address _provider) external view returns (uint256[] memory) {
        return protectedLiquidityIdsByProvider[_provider];
    }

    /**
      * @dev returns the id of a protected liquidity for the given provider at a specific index
      *
      * @param _provider    liquidity provider
      * @param _index       protected liquidity index
      * @return protected liquidity id
    */
    function protectedLiquidityId(address _provider, uint256 _index) external view returns (uint256) {
        return protectedLiquidityIdsByProvider[_provider][_index];
    }

    /**
      * @dev returns an existing protected liquidity details
      *
      * @param _id  protected liquidity id
      *
      * @return liquidity provider
      * @return pool token address
      * @return reserve token address
      * @return pool token amount
      * @return reserve token amount
      * @return rate of 1 protected reserve token in units of the other reserve token (numerator)
      * @return rate of 1 protected reserve token in units of the other reserve token (denominator)
      * @return timestamp
    */
    function protectedLiquidity(uint256 _id)
        external
        view
        override
        returns (address, IDSToken,    IERC20Token, uint256, uint256, uint256, uint256, uint256) 
    {
        ProtectedLiquidity storage liquidity = protectedLiquidities[_id];
        return (
            liquidity.provider,
            liquidity.poolToken,
            liquidity.reserveToken,
            liquidity.poolAmount,
            liquidity.reserveAmount,
            liquidity.reserveRateN,
            liquidity.reserveRateD,
            liquidity.timestamp
        );
    }

    /**
      * @dev adds protected liquidity
      * can only be called by the contract owner
      *
      * @param _provider        liquidity provider
      * @param _poolToken       pool token address
      * @param _reserveToken    reserve token address
      * @param _poolAmount      pool token amount
      * @param _reserveAmount   reserve token amount
      * @param _reserveRateN    rate of 1 protected reserve token in units of the other reserve token (numerator)
      * @param _reserveRateD    rate of 1 protected reserve token in units of the other reserve token (denominator)
      * @param _timestamp       timestamp
      * @return new protected liquidity id
    */
    function addProtectedLiquidity(
        address _provider,
        IDSToken _poolToken,   
        IERC20Token _reserveToken,
        uint256 _poolAmount,
        uint256 _reserveAmount,
        uint256 _reserveRateN,
        uint256 _reserveRateD,
        uint256 _timestamp
    ) external override ownerOnly returns (uint256) {
        // validate input
        require(
            _provider != address(0) &&
            _provider != address(this) &&
            address(_poolToken) != address(0) &&
            address(_poolToken) != address(this) &&
            address(_reserveToken) != address(0) &&
            address(_reserveToken) != address(this),
            "ERR_INVALID_ADDRESS"
        );
        require(
            _poolAmount > 0 &&
            _reserveAmount > 0 &&
            _reserveRateN > 0 &&
            _reserveRateD > 0 &&
            _timestamp > 0,
            "ERR_ZERO_VALUE"
        );


        // add the protected liquidity
        uint256[] storage ids = protectedLiquidityIdsByProvider[_provider];
        uint256 id = nextProtectedLiquidityId;
        nextProtectedLiquidityId += 1;

        protectedLiquidities[id] = ProtectedLiquidity({
            provider: _provider,
            index: ids.length,
            poolToken: _poolToken,
            reserveToken: _reserveToken,
            poolAmount: _poolAmount,
            reserveAmount: _reserveAmount,
            reserveRateN: _reserveRateN,
            reserveRateD: _reserveRateD,
            timestamp: _timestamp
        });

        ids.push(id);

        // update the total amounts
        totalProtectedPoolAmounts[_poolToken] = totalProtectedPoolAmounts[_poolToken].add(_poolAmount);
        totalProtectedReserveAmounts[_poolToken][_reserveToken] = totalProtectedReserveAmounts[_poolToken][_reserveToken].add(_reserveAmount);

        emit ProtectionAdded(_provider, _poolToken, _reserveToken, _poolAmount, _reserveAmount);
        return id;
    }

    /**
      * @dev updates an existing protected liquidity pool/reserve amounts
      * can only be called by the contract owner
      *
      * @param _id                  protected liquidity id
      * @param _newPoolAmount       new pool tokens amount
      * @param _newReserveAmount    new reserve tokens amount
    */
    function updateProtectedLiquidityAmounts(uint256 _id, uint256 _newPoolAmount, uint256 _newReserveAmount)
        external
        override
        ownerOnly
        greaterThanZero(_newPoolAmount)
        greaterThanZero(_newReserveAmount)
    {
        // update the protected liquidity
        ProtectedLiquidity storage liquidity = protectedLiquidities[_id];

        // validate input
        address provider = liquidity.provider;
        require(provider != address(0), "ERR_INVALID_ID");

        IDSToken poolToken    = liquidity.poolToken;
        IERC20Token reserveToken = liquidity.reserveToken;
        uint256 prevPoolAmount = liquidity.poolAmount;
        uint256 prevReserveAmount = liquidity.reserveAmount;
        liquidity.poolAmount = _newPoolAmount;
        liquidity.reserveAmount = _newReserveAmount;

        // update the total amounts
        totalProtectedPoolAmounts[poolToken] = totalProtectedPoolAmounts[poolToken].add(_newPoolAmount).sub(prevPoolAmount);
        totalProtectedReserveAmounts[poolToken][reserveToken] = totalProtectedReserveAmounts[poolToken][reserveToken].add(_newReserveAmount).sub(prevReserveAmount);

        emit ProtectionUpdated(provider, prevPoolAmount, prevReserveAmount, _newPoolAmount, _newReserveAmount);
    }

    /**
      * @dev removes protected liquidity
      * can only be called by the contract owner
      *
      * @param _id  protected liquidity id
    */
    function removeProtectedLiquidity(uint256 _id) external override ownerOnly {
        // remove the protected liquidity
        ProtectedLiquidity storage liquidity = protectedLiquidities[_id];

        // validate input
        address provider = liquidity.provider;
        require(provider != address(0), "ERR_INVALID_ID");

        uint256 index = liquidity.index;
        IDSToken poolToken    = liquidity.poolToken;
        IERC20Token reserveToken = liquidity.reserveToken;
        uint256 poolAmount = liquidity.poolAmount;
        uint256 reserveAmount = liquidity.reserveAmount;
        delete protectedLiquidities[_id];

        uint256[] storage ids = protectedLiquidityIdsByProvider[provider];
        uint256 length = ids.length;
        assert(length > 0);

        uint256 lastIndex = length - 1;
        if (index < lastIndex) {
            uint256 lastId = ids[lastIndex];
            ids[index] = lastId;
            protectedLiquidities[lastId].index = index;
        }

        ids.pop();

        // update the total amounts
        totalProtectedPoolAmounts[poolToken] = totalProtectedPoolAmounts[poolToken].sub(poolAmount);
        totalProtectedReserveAmounts[poolToken][reserveToken] = totalProtectedReserveAmounts[poolToken][reserveToken].sub(reserveAmount);

        emit ProtectionRemoved(provider, poolToken, reserveToken, poolAmount, reserveAmount);
    }

    /**
      * @dev returns the number of network token locked balances for a given provider
      *
      * @param _provider    locked balances provider
      * @return the number of network token locked balances
    */
    function lockedBalanceCount(address _provider) external view returns (uint256) {
        return lockedBalances[_provider].length;
    }

    /**
      * @dev returns an existing locked network token balance details
      *
      * @param _provider    locked balances provider
      * @param _index       start index
      * @return amount of network tokens
      * @return lock expiration time
    */
    function lockedBalance(address _provider, uint256 _index) external view override returns (uint256, uint256) {
        LockedBalance storage balance = lockedBalances[_provider][_index];
        return (
            balance.amount,
            balance.expirationTime
        );
    }

    /**
      * @dev returns a range of locked network token balances for a given provider
      *
      * @param _provider    locked balances provider
      * @param _startIndex  start index
      * @param _endIndex    end index (exclusive)
      * @return locked amounts
      * @return expiration times
    */
    function lockedBalanceRange(address _provider, uint256 _startIndex, uint256 _endIndex)
        external
        view
        override
        returns (uint256[] memory, uint256[] memory)
    {
        // limit the end index by the number of locked balances
        if (_endIndex > lockedBalances[_provider].length) {
            _endIndex = lockedBalances[_provider].length;
        }

        // ensure that the end index is higher than the start index
        require(_endIndex > _startIndex, "ERR_INVALID_INDICES");

        // get the locked balances for the given range and return them
        uint256 length = _endIndex - _startIndex;
        uint256[] memory amounts = new uint256[](length);
        uint256[] memory expirationTimes = new uint256[](length);

        for (uint256 i = 0; i < length; i++) {
            LockedBalance storage balance = lockedBalances[_provider][_startIndex + i];
            amounts[i] = balance.amount;
            expirationTimes[i] = balance.expirationTime;
        }

        return (amounts, expirationTimes);
    }

    /**
      * @dev adds new locked network token balance
      * can only be called by the contract owner
      *
      * @param _provider        liquidity provider
      * @param _amount          token amount
      * @param _expirationTime  lock expiration time
      * @return new locked balance index
    */
    function addLockedBalance(address _provider, uint256 _amount, uint256 _expirationTime)
        external
        override
        ownerOnly
        validAddress(_provider)
        notThis(_provider)
        greaterThanZero(_amount)
        greaterThanZero(_expirationTime)
        returns (uint256)
    {
        lockedBalances[_provider].push(LockedBalance({
            amount: _amount,
            expirationTime: _expirationTime
        }));

        emit BalanceLocked(_provider, _amount, _expirationTime);
        return lockedBalances[_provider].length - 1;
    }

    /**
      * @dev removes a locked network token balance
      * can only be called by the contract owner
      *
      * @param _provider    liquidity provider
      * @param _index       index of the locked balance
    */
    function removeLockedBalance(address _provider, uint256 _index)
        external
        override
        ownerOnly
        validAddress(_provider)
    {
        LockedBalance[] storage balances = lockedBalances[_provider];
        uint256 length = balances.length;
        
        // validate input
        require(_index < length, "ERR_INVALID_INDEX");

        uint256 amount = balances[_index].amount;
        uint256 lastIndex = length - 1;
        if (_index < lastIndex) {
            balances[_index] = balances[lastIndex];
        }

        balances.pop();

        emit BalanceUnlocked(_provider, amount);
    }

    /**
      * @dev returns the system balance for a given token
      *
      * @param _token   token address
      * @return system balance
    */
    function systemBalance(IERC20Token _token) external view override returns (uint256) {
        return systemBalances[_token];
    }

    /**
      * @dev increases the system balance for a given token
      * can only be called by the contract owner
      *
      * @param _token   token address
      * @param _amount  token amount
    */
    function incSystemBalance(IERC20Token _token, uint256 _amount)
        external
        override
        ownerOnly
        validAddress(address(_token))
    {
        uint256 prevAmount = systemBalances[_token];
        uint256 newAmount = prevAmount.add(_amount);
        systemBalances[_token] = newAmount;

        emit SystemBalanceUpdated(_token, prevAmount, newAmount);
    }

    /**
      * @dev decreases the system balance for a given token
      * can only be called by the contract owner
      *
      * @param _token   token address
      * @param _amount  token amount
    */
    function decSystemBalance(IERC20Token _token, uint256 _amount)
        external
        override
        ownerOnly
        validAddress(address(_token))
    {
        uint256 prevAmount = systemBalances[_token];
        uint256 newAmount = prevAmount.sub(_amount);
        systemBalances[_token] = newAmount;

        emit SystemBalanceUpdated(_token, prevAmount, newAmount);
    }

    /**
      * @dev returns the total protected pool token amount for a given pool
      *
      * @param _poolToken   pool token address
      * @return total protected amount
    */
    function totalProtectedPoolAmount(IDSToken _poolToken)    external view returns (uint256) {
        return totalProtectedPoolAmounts[_poolToken];
    }

    /**
      * @dev returns the total protected reserve amount for a given pool
      *
      * @param _poolToken       pool token address
      * @param _reserveToken    reserve token address
      * @return total protected amount
    */
    function totalProtectedReserveAmount(IDSToken _poolToken,    IERC20Token _reserveToken) external view returns (uint256) {
        return totalProtectedReserveAmounts[_poolToken][_reserveToken];
    }
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_expirationTime","type":"uint256"}],"name":"BalanceLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"BalanceUnlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_prevOwner","type":"address"},{"indexed":true,"internalType":"address","name":"_newOwner","type":"address"}],"name":"OwnerUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IConverterAnchor","name":"_poolAnchor","type":"address"},{"indexed":false,"internalType":"bool","name":"_added","type":"bool"}],"name":"PoolWhitelistUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_provider","type":"address"},{"indexed":true,"internalType":"contract IDSToken","name":"_poolToken","type":"address"},{"indexed":true,"internalType":"contract IERC20Token","name":"_reserveToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_poolAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_reserveAmount","type":"uint256"}],"name":"ProtectionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_provider","type":"address"},{"indexed":true,"internalType":"contract IDSToken","name":"_poolToken","type":"address"},{"indexed":true,"internalType":"contract IERC20Token","name":"_reserveToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_poolAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_reserveAmount","type":"uint256"}],"name":"ProtectionRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"_prevPoolAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_prevReserveAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newPoolAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newReserveAmount","type":"uint256"}],"name":"ProtectionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20Token","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_prevAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newAmount","type":"uint256"}],"name":"SystemBalanceUpdated","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_expirationTime","type":"uint256"}],"name":"addLockedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IConverterAnchor","name":"_poolAnchor","type":"address"}],"name":"addPoolToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"},{"internalType":"contract IDSToken","name":"_poolToken","type":"address"},{"internalType":"contract IERC20Token","name":"_reserveToken","type":"address"},{"internalType":"uint256","name":"_poolAmount","type":"uint256"},{"internalType":"uint256","name":"_reserveAmount","type":"uint256"},{"internalType":"uint256","name":"_reserveRateN","type":"uint256"},{"internalType":"uint256","name":"_reserveRateD","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"addProtectedLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Token","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"decSystemBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Token","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"incSystemBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IConverterAnchor","name":"_poolAnchor","type":"address"}],"name":"isPoolWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"lockedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"}],"name":"lockedBalanceCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"},{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_endIndex","type":"uint256"}],"name":"lockedBalanceRange","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"protectedLiquidity","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"contract IDSToken","name":"","type":"address"},{"internalType":"contract IERC20Token","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"}],"name":"protectedLiquidityCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"protectedLiquidityId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"}],"name":"protectedLiquidityIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"removeLockedBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IConverterAnchor","name":"_poolAnchor","type":"address"}],"name":"removePoolFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"removeProtectedLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Token","name":"_token","type":"address"}],"name":"systemBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IDSToken","name":"_poolToken","type":"address"}],"name":"totalProtectedPoolAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IDSToken","name":"_poolToken","type":"address"},{"internalType":"contract IERC20Token","name":"_reserveToken","type":"address"}],"name":"totalProtectedReserveAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_newPoolAmount","type":"uint256"},{"internalType":"uint256","name":"_newReserveAmount","type":"uint256"}],"name":"updateProtectedLiquidityAmounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"whitelistedPool","outputs":[{"internalType":"contract IConverterAnchor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistedPoolCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistedPools","outputs":[{"internalType":"contract IConverterAnchor[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Token","name":"_token","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b50600080546001600160a01b03191633179055611e4b806100326000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c806379ba5097116100f9578063d4ee1d9011610097578063f2fde38b11610071578063f2fde38b14610613578063f4206dea14610639578063fb6c03fa14610704578063fd589e5014610730576101c4565b8063d4ee1d90146105d1578063dbae3a5d146105d9578063e01e80eb1461060b576101c4565b806396ad435b116100d357806396ad435b1461052e578063ab99c6511461055c578063b089cde814610582578063d3d1e7bd146105ab576101c4565b806379ba5097146104f25780638da5cb5b146104fa57806390e0661b14610502576101c4565b8063434798851161016657806357dac2ec1161014057806357dac2ec146104245780635e35359e1461044a57806361d5f087146104805780636f366b71146104d5576101c4565b806343479885146103395780635121220c146103915780635290ffbb146103b7576101c4565b80632b26a982116101a25780632b26a982146102565780632fb4f04a14610290578063332100fa146102d557806337fc38df14610301576101c4565b806315116c20146101c957806319c6a5e4146102025780631b26d75314610230575b600080fd5b6101e6600480360360208110156101df57600080fd5b5035610756565b604080516001600160a01b039092168252519081900360200190f35b61022e6004803603604081101561021857600080fd5b506001600160a01b038135169060200135610780565b005b61022e6004803603602081101561024657600080fd5b50356001600160a01b031661081b565b61027c6004803603602081101561026c57600080fd5b50356001600160a01b03166109cc565b604080519115158252519081900360200190f35b6102bc600480360360408110156102a657600080fd5b506001600160a01b0381351690602001356109ea565b6040805192835260208301919091528051918290030190f35b61022e600480360360408110156102eb57600080fd5b506001600160a01b038135169060200135610a38565b6103276004803603602081101561031757600080fd5b50356001600160a01b0316610a6e565b60408051918252519081900360200190f35b610341610a89565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561037d578181015183820152602001610365565b505050509050019250505060405180910390f35b610327600480360360208110156103a757600080fd5b50356001600160a01b0316610aeb565b6103d4600480360360208110156103cd57600080fd5b5035610b06565b604080516001600160a01b03998a168152978916602089015295909716868601526060860193909352608085019190915260a084015260c083015260e08201929092529051908190036101000190f35b6103276004803603602081101561043a57600080fd5b50356001600160a01b0316610b59565b61022e6004803603606081101561046057600080fd5b506001600160a01b03813581169160208101359091169060400135610b74565b610327600480360361010081101561049757600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060808101359060a08101359060c08101359060e00135610ba2565b61022e600480360360208110156104eb57600080fd5b5035610fa9565b61022e6111fe565b6101e66112b5565b61022e6004803603604081101561051857600080fd5b506001600160a01b0381351690602001356112c4565b6103276004803603604081101561054457600080fd5b506001600160a01b038135811691602001351661141c565b61022e6004803603602081101561057257600080fd5b50356001600160a01b0316611447565b61022e6004803603606081101561059857600080fd5b508035906020810135906040013561156d565b610341600480360360208110156105c157600080fd5b50356001600160a01b03166116fd565b6101e6611769565b610327600480360360608110156105ef57600080fd5b506001600160a01b038135169060208101359060400135611778565b61032761185b565b61022e6004803603602081101561062957600080fd5b50356001600160a01b0316611861565b61066b6004803603606081101561064f57600080fd5b506001600160a01b0381351690602081013590604001356118df565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156106af578181015183820152602001610697565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156106ee5781810151838201526020016106d6565b5050505090500194505050505060405180910390f35b6103276004803603604081101561071a57600080fd5b506001600160a01b038135169060200135611a8a565b6103276004803603602081101561074657600080fd5b50356001600160a01b0316611ac1565b60006002828154811061076557fe5b6000918252602090912001546001600160a01b031692915050565b610788611adc565b8161079281611b31565b6001600160a01b038316600090815260086020526040812054906107b68285611b85565b6001600160a01b03861660008181526008602090815260409182902084905581519283528201859052818101839052519192507f407aa06211cf8eec4798e12787e05d8e5ba13eab80aac8df1b59ed5db8520197919081900360600190a15050505050565b610823611adc565b8061082d81611b31565b8161083781611bd2565b6001600160a01b0383166000908152600360205260409020805460ff166108a5576040805162461bcd60e51b815260206004820152601860248201527f4552525f504f4f4c5f4e4f545f57484954454c49535445440000000000000000604482015290519081900360640190fd5b6001810154600254806108b457fe5b60001981018083101561093d576000600282815481106108d057fe5b60009182526020808320909101546001600160a01b0316808352600390915260409091206001018590556002805491925082918690811061090d57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550505b600280548061094857fe5b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b038916808352600382526040808420805460ff1916815560010184905580519384525190927fb7acd3c0ece90b3e568f5796fdf644dd4f98535f18b425552d5920e7f82af3e492908290030190a250505050505050565b6001600160a01b031660009081526003602052604090205460ff1690565b6001600160a01b038216600090815260076020526040812080548291829185908110610a1257fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b610a40611adc565b81610a4a81611b31565b6001600160a01b038316600090815260086020526040812054906107b68285611c26565b6001600160a01b031660009081526007602052604090205490565b60606002805480602002602001604051908101604052809291908181526020018280548015610ae157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ac3575b5050505050905090565b6001600160a01b031660009081526008602052604090205490565b6000908152600660208190526040909120805460028201546003830154600484015460058501549585015460078601546008909601546001600160a01b0395861698948616979590931695919493909290565b6001600160a01b031660009081526005602052604090205490565b610b7c611adc565b81610b8681611b31565b82610b9081611bd2565b610b9b858585611c76565b5050505050565b6000610bac611adc565b6001600160a01b03891615801590610bcd57506001600160a01b0389163014155b8015610be157506001600160a01b03881615155b8015610bf657506001600160a01b0388163014155b8015610c0a57506001600160a01b03871615155b8015610c1f57506001600160a01b0387163014155b610c66576040805162461bcd60e51b81526020600482015260136024820152724552525f494e56414c49445f4144445245535360681b604482015290519081900360640190fd5b600086118015610c765750600085115b8015610c825750600084115b8015610c8e5750600083115b8015610c9a5750600082115b610cdc576040805162461bcd60e51b815260206004820152600e60248201526d4552525f5a45524f5f56414c554560901b604482015290519081900360640190fd5b6000600560008b6001600160a01b03166001600160a01b0316815260200190815260200160002090506000600454905060016004600082825401925050819055506040518061012001604052808c6001600160a01b03168152602001838054905081526020018b6001600160a01b031681526020018a6001600160a01b03168152602001898152602001888152602001878152602001868152602001858152506006600083815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a0820151816005015560c0820151816006015560e08201518160070155610100820151816008015590505081819080600181540180825580915050600190039060005260206000200160009091909190915055610eb688600960008d6001600160a01b03166001600160a01b0316815260200190815260200160002054611c2690919063ffffffff16565b6001600160a01b03808c16600090815260096020908152604080832094909455600a8152838220928d168252919091522054610ef29088611c26565b600a60008c6001600160a01b03166001600160a01b0316815260200190815260200160002060008b6001600160a01b03166001600160a01b0316815260200190815260200160002081905550886001600160a01b03168a6001600160a01b03168c6001600160a01b03167f3ad050950cfb9657a985fbfebb84c6e7c799d8c08e4fc412cb84e9bd2e68f8cd8b8b604051808381526020018281526020019250505060405180910390a49a9950505050505050505050565b610fb1611adc565b600081815260066020526040902080546001600160a01b03168061100d576040805162461bcd60e51b815260206004820152600e60248201526d11549497d253959053125117d25160921b604482015290519081900360640190fd5b6001828101546002808501546003808701546004808901546005808b015460008d815260066020818152604080842080546001600160a01b031990811682559e81018590559b8c0180548f169055988b018054909d16909c559489018190558883018190559388018490556007880184905560089097018390556001600160a01b038a811684529852929020805495969384169593909116939192806110af57fe5b6000198101808810156111075760008382815481106110ca57fe5b9060005260206000200154905080848a815481106110e457fe5b600091825260208083209091019290925591825260069052604090206001018890555b8280548061111157fe5b6000828152602080822083016000199081018390559092019092556001600160a01b038916825260099052604090205461114b9086611b85565b6001600160a01b03808916600090815260096020908152604080832094909455600a8152838220928a1682529190915220546111879085611b85565b6001600160a01b038089166000818152600a602090815260408083208c8616808552908352928190209590955584518a81529081018990528451919492938e16927feafbca2ddc06778be021087babbeda29033997e4e461abdc6d5bf30a0f14a02592918290030190a45050505050505050505050565b6001546001600160a01b03163314611251576040805162461bcd60e51b815260206004820152601160248201527011549497d050d0d154d4d7d11153925151607a1b604482015290519081900360640190fd5b600154600080546040516001600160a01b0393841693909116917f343765429aea5a34b3ff6a3785a98a5abb2597aca87bfbb58632c173d585373a91a360018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6000546001600160a01b031681565b6112cc611adc565b816112d681611b31565b6001600160a01b03831660009081526007602052604090208054808410611338576040805162461bcd60e51b815260206004820152601160248201527008aa4a4be929cac82989288be929c888ab607b1b604482015290519081900360640190fd5b600082858154811061134657fe5b600091825260209091206002909102015490506000198201808610156113ab5783818154811061137257fe5b906000526020600020906002020184878154811061138c57fe5b6000918252602090912082546002909202019081556001918201549101555b838054806113b557fe5b600082815260208082206002600019909401938402018281556001019190915591556040805184815290516001600160a01b038a16927f43e8fb9d4f009c90c55a3fa108b177b794704d61af7af6f6512db7883f8ed843928290030190a250505050505050565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205490565b61144f611adc565b8061145981611b31565b8161146381611bd2565b6001600160a01b0383166000908152600360205260409020805460ff16156114d2576040805162461bcd60e51b815260206004820152601c60248201527f4552525f504f4f4c5f414c52454144595f57484954454c495354454400000000604482015290519081900360640190fd5b60028054600180840182905580820183556000929092527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0387166001600160a01b03199091168117909155825460ff191682178355604080519283525190917fb7acd3c0ece90b3e568f5796fdf644dd4f98535f18b425552d5920e7f82af3e4919081900360200190a250505050565b611575611adc565b8161157f81611dcf565b8161158981611dcf565b600085815260066020526040902080546001600160a01b0316806115e5576040805162461bcd60e51b815260206004820152600e60248201526d11549497d253959053125117d25160921b604482015290519081900360640190fd5b60028201546003830154600484018054600586018054928b90558990556001600160a01b0393841660008181526009602052604090205490949093169290919061163b908390611635908d611c26565b90611b85565b6001600160a01b03808616600090815260096020908152604080832094909455600a8152838220928716825291909152205461167d908290611635908c611c26565b6001600160a01b038086166000908152600a6020908152604080832088851684528252918290209390935580518581529283018490528281018d9052606083018c905251908716917f4b40353ab8113f910f903abef8926205420b70265d2a3db18168b0dff00dff0d919081900360800190a25050505050505050505050565b6001600160a01b03811660009081526005602090815260409182902080548351818402810184019094528084526060939283018282801561175d57602002820191906000526020600020905b815481526020019060010190808311611749575b50505050509050919050565b6001546001600160a01b031681565b6000611782611adc565b8361178c81611b31565b8461179681611bd2565b846117a081611dcf565b846117aa81611dcf565b6001600160a01b0388166000818152600760209081526040808320815180830183528c81528084018c815282546001818101855593875295859020915160029096029091019485555193019290925581518a815290810189905281517f931ca4971b116a87c466516714a76b130f47bd6627f93d3c351f672f95070365929181900390910190a26001600160a01b038816600090815260076020526040902054600019019450505050509392505050565b60025490565b611869611adc565b6000546001600160a01b03828116911614156118bd576040805162461bcd60e51b815260206004820152600e60248201526d22a9292fa9a0a6a2afa7aba722a960911b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0383166000908152600760205260409020546060908190831115611920576001600160a01b03851660009081526007602052604090205492505b83831161196a576040805162461bcd60e51b81526020600482015260136024820152724552525f494e56414c49445f494e444943455360681b604482015290519081900360640190fd5b83830360608167ffffffffffffffff8111801561198657600080fd5b506040519080825280602002602001820160405280156119b0578160200160208202803683370190505b50905060608267ffffffffffffffff811180156119cc57600080fd5b506040519080825280602002602001820160405280156119f6578160200160208202803683370190505b50905060005b83811015611a7c576001600160a01b038916600090815260076020526040812080548a8401908110611a2a57fe5b906000526020600020906002020190508060000154848381518110611a4b57fe5b6020026020010181815250508060010154838381518110611a6857fe5b6020908102919091010152506001016119fc565b509097909650945050505050565b6001600160a01b0382166000908152600560205260408120805483908110611aae57fe5b9060005260206000200154905092915050565b6001600160a01b031660009081526009602052604090205490565b6000546001600160a01b03163314611b2f576040805162461bcd60e51b815260206004820152601160248201527011549497d050d0d154d4d7d11153925151607a1b604482015290519081900360640190fd5b565b6001600160a01b038116611b82576040805162461bcd60e51b81526020600482015260136024820152724552525f494e56414c49445f4144445245535360681b604482015290519081900360640190fd5b50565b600081831015611bcc576040805162461bcd60e51b815260206004820152600d60248201526c4552525f554e444552464c4f5760981b604482015290519081900360640190fd5b50900390565b6001600160a01b038116301415611b82576040805162461bcd60e51b815260206004820152601360248201527222a9292fa0a2222922a9a9afa4a9afa9a2a62360691b604482015290519081900360640190fd5b600082820183811015611c6f576040805162461bcd60e51b815260206004820152600c60248201526b4552525f4f564552464c4f5760a01b604482015290519081900360640190fd5b9392505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b178152925182516000946060949389169392918291908083835b60208310611cf35780518252601f199092019160209182019101611cd4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611d55576040519150601f19603f3d011682016040523d82523d6000602084013e611d5a565b606091505b5091509150818015611d88575080511580611d885750808060200190516020811015611d8557600080fd5b50515b610b9b576040805162461bcd60e51b815260206004820152601360248201527211549497d514905394d1915497d19052531151606a1b604482015290519081900360640190fd5b60008111611b82576040805162461bcd60e51b815260206004820152600e60248201526d4552525f5a45524f5f56414c554560901b604482015290519081900360640190fdfea2646970667358221220fff03297952beb25e69834207ecfd8aa83e711979ca02f72feff84ab5624e13564736f6c634300060c0033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101c45760003560e01c806379ba5097116100f9578063d4ee1d9011610097578063f2fde38b11610071578063f2fde38b14610613578063f4206dea14610639578063fb6c03fa14610704578063fd589e5014610730576101c4565b8063d4ee1d90146105d1578063dbae3a5d146105d9578063e01e80eb1461060b576101c4565b806396ad435b116100d357806396ad435b1461052e578063ab99c6511461055c578063b089cde814610582578063d3d1e7bd146105ab576101c4565b806379ba5097146104f25780638da5cb5b146104fa57806390e0661b14610502576101c4565b8063434798851161016657806357dac2ec1161014057806357dac2ec146104245780635e35359e1461044a57806361d5f087146104805780636f366b71146104d5576101c4565b806343479885146103395780635121220c146103915780635290ffbb146103b7576101c4565b80632b26a982116101a25780632b26a982146102565780632fb4f04a14610290578063332100fa146102d557806337fc38df14610301576101c4565b806315116c20146101c957806319c6a5e4146102025780631b26d75314610230575b600080fd5b6101e6600480360360208110156101df57600080fd5b5035610756565b604080516001600160a01b039092168252519081900360200190f35b61022e6004803603604081101561021857600080fd5b506001600160a01b038135169060200135610780565b005b61022e6004803603602081101561024657600080fd5b50356001600160a01b031661081b565b61027c6004803603602081101561026c57600080fd5b50356001600160a01b03166109cc565b604080519115158252519081900360200190f35b6102bc600480360360408110156102a657600080fd5b506001600160a01b0381351690602001356109ea565b6040805192835260208301919091528051918290030190f35b61022e600480360360408110156102eb57600080fd5b506001600160a01b038135169060200135610a38565b6103276004803603602081101561031757600080fd5b50356001600160a01b0316610a6e565b60408051918252519081900360200190f35b610341610a89565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561037d578181015183820152602001610365565b505050509050019250505060405180910390f35b610327600480360360208110156103a757600080fd5b50356001600160a01b0316610aeb565b6103d4600480360360208110156103cd57600080fd5b5035610b06565b604080516001600160a01b03998a168152978916602089015295909716868601526060860193909352608085019190915260a084015260c083015260e08201929092529051908190036101000190f35b6103276004803603602081101561043a57600080fd5b50356001600160a01b0316610b59565b61022e6004803603606081101561046057600080fd5b506001600160a01b03813581169160208101359091169060400135610b74565b610327600480360361010081101561049757600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060808101359060a08101359060c08101359060e00135610ba2565b61022e600480360360208110156104eb57600080fd5b5035610fa9565b61022e6111fe565b6101e66112b5565b61022e6004803603604081101561051857600080fd5b506001600160a01b0381351690602001356112c4565b6103276004803603604081101561054457600080fd5b506001600160a01b038135811691602001351661141c565b61022e6004803603602081101561057257600080fd5b50356001600160a01b0316611447565b61022e6004803603606081101561059857600080fd5b508035906020810135906040013561156d565b610341600480360360208110156105c157600080fd5b50356001600160a01b03166116fd565b6101e6611769565b610327600480360360608110156105ef57600080fd5b506001600160a01b038135169060208101359060400135611778565b61032761185b565b61022e6004803603602081101561062957600080fd5b50356001600160a01b0316611861565b61066b6004803603606081101561064f57600080fd5b506001600160a01b0381351690602081013590604001356118df565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156106af578181015183820152602001610697565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156106ee5781810151838201526020016106d6565b5050505090500194505050505060405180910390f35b6103276004803603604081101561071a57600080fd5b506001600160a01b038135169060200135611a8a565b6103276004803603602081101561074657600080fd5b50356001600160a01b0316611ac1565b60006002828154811061076557fe5b6000918252602090912001546001600160a01b031692915050565b610788611adc565b8161079281611b31565b6001600160a01b038316600090815260086020526040812054906107b68285611b85565b6001600160a01b03861660008181526008602090815260409182902084905581519283528201859052818101839052519192507f407aa06211cf8eec4798e12787e05d8e5ba13eab80aac8df1b59ed5db8520197919081900360600190a15050505050565b610823611adc565b8061082d81611b31565b8161083781611bd2565b6001600160a01b0383166000908152600360205260409020805460ff166108a5576040805162461bcd60e51b815260206004820152601860248201527f4552525f504f4f4c5f4e4f545f57484954454c49535445440000000000000000604482015290519081900360640190fd5b6001810154600254806108b457fe5b60001981018083101561093d576000600282815481106108d057fe5b60009182526020808320909101546001600160a01b0316808352600390915260409091206001018590556002805491925082918690811061090d57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550505b600280548061094857fe5b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b038916808352600382526040808420805460ff1916815560010184905580519384525190927fb7acd3c0ece90b3e568f5796fdf644dd4f98535f18b425552d5920e7f82af3e492908290030190a250505050505050565b6001600160a01b031660009081526003602052604090205460ff1690565b6001600160a01b038216600090815260076020526040812080548291829185908110610a1257fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b610a40611adc565b81610a4a81611b31565b6001600160a01b038316600090815260086020526040812054906107b68285611c26565b6001600160a01b031660009081526007602052604090205490565b60606002805480602002602001604051908101604052809291908181526020018280548015610ae157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ac3575b5050505050905090565b6001600160a01b031660009081526008602052604090205490565b6000908152600660208190526040909120805460028201546003830154600484015460058501549585015460078601546008909601546001600160a01b0395861698948616979590931695919493909290565b6001600160a01b031660009081526005602052604090205490565b610b7c611adc565b81610b8681611b31565b82610b9081611bd2565b610b9b858585611c76565b5050505050565b6000610bac611adc565b6001600160a01b03891615801590610bcd57506001600160a01b0389163014155b8015610be157506001600160a01b03881615155b8015610bf657506001600160a01b0388163014155b8015610c0a57506001600160a01b03871615155b8015610c1f57506001600160a01b0387163014155b610c66576040805162461bcd60e51b81526020600482015260136024820152724552525f494e56414c49445f4144445245535360681b604482015290519081900360640190fd5b600086118015610c765750600085115b8015610c825750600084115b8015610c8e5750600083115b8015610c9a5750600082115b610cdc576040805162461bcd60e51b815260206004820152600e60248201526d4552525f5a45524f5f56414c554560901b604482015290519081900360640190fd5b6000600560008b6001600160a01b03166001600160a01b0316815260200190815260200160002090506000600454905060016004600082825401925050819055506040518061012001604052808c6001600160a01b03168152602001838054905081526020018b6001600160a01b031681526020018a6001600160a01b03168152602001898152602001888152602001878152602001868152602001858152506006600083815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a0820151816005015560c0820151816006015560e08201518160070155610100820151816008015590505081819080600181540180825580915050600190039060005260206000200160009091909190915055610eb688600960008d6001600160a01b03166001600160a01b0316815260200190815260200160002054611c2690919063ffffffff16565b6001600160a01b03808c16600090815260096020908152604080832094909455600a8152838220928d168252919091522054610ef29088611c26565b600a60008c6001600160a01b03166001600160a01b0316815260200190815260200160002060008b6001600160a01b03166001600160a01b0316815260200190815260200160002081905550886001600160a01b03168a6001600160a01b03168c6001600160a01b03167f3ad050950cfb9657a985fbfebb84c6e7c799d8c08e4fc412cb84e9bd2e68f8cd8b8b604051808381526020018281526020019250505060405180910390a49a9950505050505050505050565b610fb1611adc565b600081815260066020526040902080546001600160a01b03168061100d576040805162461bcd60e51b815260206004820152600e60248201526d11549497d253959053125117d25160921b604482015290519081900360640190fd5b6001828101546002808501546003808701546004808901546005808b015460008d815260066020818152604080842080546001600160a01b031990811682559e81018590559b8c0180548f169055988b018054909d16909c559489018190558883018190559388018490556007880184905560089097018390556001600160a01b038a811684529852929020805495969384169593909116939192806110af57fe5b6000198101808810156111075760008382815481106110ca57fe5b9060005260206000200154905080848a815481106110e457fe5b600091825260208083209091019290925591825260069052604090206001018890555b8280548061111157fe5b6000828152602080822083016000199081018390559092019092556001600160a01b038916825260099052604090205461114b9086611b85565b6001600160a01b03808916600090815260096020908152604080832094909455600a8152838220928a1682529190915220546111879085611b85565b6001600160a01b038089166000818152600a602090815260408083208c8616808552908352928190209590955584518a81529081018990528451919492938e16927feafbca2ddc06778be021087babbeda29033997e4e461abdc6d5bf30a0f14a02592918290030190a45050505050505050505050565b6001546001600160a01b03163314611251576040805162461bcd60e51b815260206004820152601160248201527011549497d050d0d154d4d7d11153925151607a1b604482015290519081900360640190fd5b600154600080546040516001600160a01b0393841693909116917f343765429aea5a34b3ff6a3785a98a5abb2597aca87bfbb58632c173d585373a91a360018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6000546001600160a01b031681565b6112cc611adc565b816112d681611b31565b6001600160a01b03831660009081526007602052604090208054808410611338576040805162461bcd60e51b815260206004820152601160248201527008aa4a4be929cac82989288be929c888ab607b1b604482015290519081900360640190fd5b600082858154811061134657fe5b600091825260209091206002909102015490506000198201808610156113ab5783818154811061137257fe5b906000526020600020906002020184878154811061138c57fe5b6000918252602090912082546002909202019081556001918201549101555b838054806113b557fe5b600082815260208082206002600019909401938402018281556001019190915591556040805184815290516001600160a01b038a16927f43e8fb9d4f009c90c55a3fa108b177b794704d61af7af6f6512db7883f8ed843928290030190a250505050505050565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205490565b61144f611adc565b8061145981611b31565b8161146381611bd2565b6001600160a01b0383166000908152600360205260409020805460ff16156114d2576040805162461bcd60e51b815260206004820152601c60248201527f4552525f504f4f4c5f414c52454144595f57484954454c495354454400000000604482015290519081900360640190fd5b60028054600180840182905580820183556000929092527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0387166001600160a01b03199091168117909155825460ff191682178355604080519283525190917fb7acd3c0ece90b3e568f5796fdf644dd4f98535f18b425552d5920e7f82af3e4919081900360200190a250505050565b611575611adc565b8161157f81611dcf565b8161158981611dcf565b600085815260066020526040902080546001600160a01b0316806115e5576040805162461bcd60e51b815260206004820152600e60248201526d11549497d253959053125117d25160921b604482015290519081900360640190fd5b60028201546003830154600484018054600586018054928b90558990556001600160a01b0393841660008181526009602052604090205490949093169290919061163b908390611635908d611c26565b90611b85565b6001600160a01b03808616600090815260096020908152604080832094909455600a8152838220928716825291909152205461167d908290611635908c611c26565b6001600160a01b038086166000908152600a6020908152604080832088851684528252918290209390935580518581529283018490528281018d9052606083018c905251908716917f4b40353ab8113f910f903abef8926205420b70265d2a3db18168b0dff00dff0d919081900360800190a25050505050505050505050565b6001600160a01b03811660009081526005602090815260409182902080548351818402810184019094528084526060939283018282801561175d57602002820191906000526020600020905b815481526020019060010190808311611749575b50505050509050919050565b6001546001600160a01b031681565b6000611782611adc565b8361178c81611b31565b8461179681611bd2565b846117a081611dcf565b846117aa81611dcf565b6001600160a01b0388166000818152600760209081526040808320815180830183528c81528084018c815282546001818101855593875295859020915160029096029091019485555193019290925581518a815290810189905281517f931ca4971b116a87c466516714a76b130f47bd6627f93d3c351f672f95070365929181900390910190a26001600160a01b038816600090815260076020526040902054600019019450505050509392505050565b60025490565b611869611adc565b6000546001600160a01b03828116911614156118bd576040805162461bcd60e51b815260206004820152600e60248201526d22a9292fa9a0a6a2afa7aba722a960911b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0383166000908152600760205260409020546060908190831115611920576001600160a01b03851660009081526007602052604090205492505b83831161196a576040805162461bcd60e51b81526020600482015260136024820152724552525f494e56414c49445f494e444943455360681b604482015290519081900360640190fd5b83830360608167ffffffffffffffff8111801561198657600080fd5b506040519080825280602002602001820160405280156119b0578160200160208202803683370190505b50905060608267ffffffffffffffff811180156119cc57600080fd5b506040519080825280602002602001820160405280156119f6578160200160208202803683370190505b50905060005b83811015611a7c576001600160a01b038916600090815260076020526040812080548a8401908110611a2a57fe5b906000526020600020906002020190508060000154848381518110611a4b57fe5b6020026020010181815250508060010154838381518110611a6857fe5b6020908102919091010152506001016119fc565b509097909650945050505050565b6001600160a01b0382166000908152600560205260408120805483908110611aae57fe5b9060005260206000200154905092915050565b6001600160a01b031660009081526009602052604090205490565b6000546001600160a01b03163314611b2f576040805162461bcd60e51b815260206004820152601160248201527011549497d050d0d154d4d7d11153925151607a1b604482015290519081900360640190fd5b565b6001600160a01b038116611b82576040805162461bcd60e51b81526020600482015260136024820152724552525f494e56414c49445f4144445245535360681b604482015290519081900360640190fd5b50565b600081831015611bcc576040805162461bcd60e51b815260206004820152600d60248201526c4552525f554e444552464c4f5760981b604482015290519081900360640190fd5b50900390565b6001600160a01b038116301415611b82576040805162461bcd60e51b815260206004820152601360248201527222a9292fa0a2222922a9a9afa4a9afa9a2a62360691b604482015290519081900360640190fd5b600082820183811015611c6f576040805162461bcd60e51b815260206004820152600c60248201526b4552525f4f564552464c4f5760a01b604482015290519081900360640190fd5b9392505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b178152925182516000946060949389169392918291908083835b60208310611cf35780518252601f199092019160209182019101611cd4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611d55576040519150601f19603f3d011682016040523d82523d6000602084013e611d5a565b606091505b5091509150818015611d88575080511580611d885750808060200190516020811015611d8557600080fd5b50515b610b9b576040805162461bcd60e51b815260206004820152601360248201527211549497d514905394d1915497d19052531151606a1b604482015290519081900360640190fd5b60008111611b82576040805162461bcd60e51b815260206004820152600e60248201526d4552525f5a45524f5f56414c554560901b604482015290519081900360640190fdfea2646970667358221220fff03297952beb25e69834207ecfd8aa83e711979ca02f72feff84ab5624e13564736f6c634300060c0033

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  ]

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.