ETH Price: $2,198.93 (-11.13%)

Contract

0xe6b0a782f61f9409516C3e87042042945Ce0305f
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
LiquidityRegistry

Compiler Version
v0.7.4+commit.3f05b770

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 14 : LiquidityRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/math/Math.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/EnumerableSet.sol";

import "./interfaces/IPolicyBook.sol";
import "./interfaces/IPolicyBookRegistry.sol";
import "./interfaces/IContractsRegistry.sol";
import "./interfaces/ILiquidityRegistry.sol";
import "./interfaces/IBMICoverStaking.sol";

import "./abstract/AbstractDependant.sol";

import "./Globals.sol";

contract LiquidityRegistry is ILiquidityRegistry, AbstractDependant {
    using SafeMath for uint256;
    using Math for uint256;
    using EnumerableSet for EnumerableSet.AddressSet;

    IPolicyBookRegistry public policyBookRegistry;
    IBMICoverStaking public bmiCoverStaking;

    // User address => policy books array
    mapping(address => EnumerableSet.AddressSet) private _policyBooks;

    event PolicyBookAdded(address _userAddr, address _policyBookAddress);
    event PolicyBookRemoved(address _userAddr, address _policyBookAddress);

    modifier onlyEligibleContracts() {
        require(
            msg.sender == address(bmiCoverStaking) || policyBookRegistry.isPolicyBook(msg.sender),
            "LR: Not an eligible contract"
        );
        _;
    }

    function setDependencies(IContractsRegistry _contractsRegistry)
        external
        override
        onlyInjectorOrZero
    {
        policyBookRegistry = IPolicyBookRegistry(
            _contractsRegistry.getPolicyBookRegistryContract()
        );
        bmiCoverStaking = IBMICoverStaking(_contractsRegistry.getBMICoverStakingContract());
    }

    function tryToAddPolicyBook(address _userAddr, address _policyBookAddr)
        external
        override
        onlyEligibleContracts
    {
        if (
            IERC20(_policyBookAddr).balanceOf(_userAddr) > 0 ||
            bmiCoverStaking.balanceOf(_userAddr) > 0
        ) {
            _policyBooks[_userAddr].add(_policyBookAddr);

            emit PolicyBookAdded(_userAddr, _policyBookAddr);
        }
    }

    function tryToRemovePolicyBook(address _userAddr, address _policyBookAddr)
        external
        override
        onlyEligibleContracts
    {
        if (
            IERC20(_policyBookAddr).balanceOf(_userAddr) == 0 &&
            bmiCoverStaking.balanceOf(_userAddr) == 0 &&
            IPolicyBook(_policyBookAddr).getWithdrawalStatus(_userAddr) ==
            IPolicyBook.WithdrawalStatus.NONE
        ) {
            _policyBooks[_userAddr].remove(_policyBookAddr);

            emit PolicyBookRemoved(_userAddr, _policyBookAddr);
        }
    }

    function getPolicyBooksArrLength(address _userAddr) external view override returns (uint256) {
        return _policyBooks[_userAddr].length();
    }

    function getPolicyBooksArr(address _userAddr)
        external
        view
        override
        returns (address[] memory _resultArr)
    {
        uint256 _policyBooksArrLength = _policyBooks[_userAddr].length();

        _resultArr = new address[](_policyBooksArrLength);

        for (uint256 i = 0; i < _policyBooksArrLength; i++) {
            _resultArr[i] = _policyBooks[_userAddr].at(i);
        }
    }

    /// @notice _bmiXRatio comes with 10**18 precision
    function getLiquidityInfos(
        address _userAddr,
        uint256 _offset,
        uint256 _limit
    ) external view override returns (LiquidityInfo[] memory _resultArr) {
        uint256 _to = (_offset.add(_limit)).min(_policyBooks[_userAddr].length()).max(_offset);

        _resultArr = new LiquidityInfo[](_to - _offset);

        for (uint256 i = _offset; i < _to; i++) {
            address _currentPolicyBookAddr = _policyBooks[_userAddr].at(i);

            (uint256 _lockedAmount, , ) =
                IPolicyBook(_currentPolicyBookAddr).withdrawalsInfo(_userAddr);
            uint256 _availableAmount =
                IERC20(address(_currentPolicyBookAddr)).balanceOf(_userAddr);

            uint256 _bmiXRaito = IPolicyBook(_currentPolicyBookAddr).convertBMIXToSTBL(10**18);

            _resultArr[i - _offset] = LiquidityInfo(
                _currentPolicyBookAddr,
                _lockedAmount,
                _availableAmount,
                _bmiXRaito
            );
        }
    }

    function getWithdrawalRequests(
        address _userAddr,
        uint256 _offset,
        uint256 _limit
    )
        external
        view
        override
        returns (uint256 _arrLength, WithdrawalRequestInfo[] memory _resultArr)
    {
        uint256 _to = (_offset.add(_limit)).min(_policyBooks[_userAddr].length()).max(_offset);

        _resultArr = new WithdrawalRequestInfo[](_to - _offset);

        for (uint256 i = _offset; i < _to; i++) {
            IPolicyBook _currentPolicyBook = IPolicyBook(_policyBooks[_userAddr].at(i));

            (uint256 _requestAmount, uint256 _readyToWithdrawDate, bool withdrawalAllowed) =
                _currentPolicyBook.withdrawalsInfo(_userAddr);

            IPolicyBook.WithdrawalStatus _currentStatus =
                _currentPolicyBook.getWithdrawalStatus(_userAddr);

            if (withdrawalAllowed || _currentStatus == IPolicyBook.WithdrawalStatus.NONE) {
                continue;
            }

            uint256 _endWithdrawDate;

            if (block.timestamp > _readyToWithdrawDate) {
                _endWithdrawDate = _readyToWithdrawDate.add(
                    _currentPolicyBook.READY_TO_WITHDRAW_PERIOD()
                );
            }

            (uint256 coverTokens, uint256 liquidity) =
                _currentPolicyBook.getNewCoverAndLiquidity();

            _resultArr[_arrLength] = WithdrawalRequestInfo(
                address(_currentPolicyBook),
                _requestAmount,
                _currentPolicyBook.convertBMIXToSTBL(_requestAmount),
                liquidity.sub(coverTokens),
                _readyToWithdrawDate,
                _endWithdrawDate
            );

            _arrLength++;
        }
    }

    function getWithdrawalSet(
        address _userAddr,
        uint256 _offset,
        uint256 _limit
    ) external view override returns (uint256 _arrLength, WithdrawalSetInfo[] memory _resultArr) {
        uint256 _to = (_offset.add(_limit)).min(_policyBooks[_userAddr].length()).max(_offset);

        _resultArr = new WithdrawalSetInfo[](_to - _offset);

        for (uint256 i = _offset; i < _to; i++) {
            IPolicyBook _currentPolicyBook = IPolicyBook(_policyBooks[_userAddr].at(i));

            (uint256 _requestAmount, , bool withdrawalAllowed) =
                _currentPolicyBook.withdrawalsInfo(_userAddr);

            if (!withdrawalAllowed) {
                continue;
            }

            (uint256 coverTokens, uint256 liquidity) =
                _currentPolicyBook.getNewCoverAndLiquidity();

            _resultArr[_arrLength] = WithdrawalSetInfo(
                address(_currentPolicyBook),
                _requestAmount,
                _currentPolicyBook.convertBMIXToSTBL(_requestAmount),
                liquidity.sub(coverTokens)
            );

            _arrLength++;
        }
    }
}

File 2 of 14 : Globals.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

uint256 constant SECONDS_IN_THE_YEAR = 365 * 24 * 60 * 60; // 365 days * 24 hours * 60 minutes * 60 seconds
uint256 constant MAX_INT = type(uint256).max;

uint256 constant DECIMALS18 = 10**18;

uint256 constant PRECISION = 10**25;
uint256 constant PERCENTAGE_100 = 100 * PRECISION;

uint256 constant BLOCKS_PER_DAY = 6450;
uint256 constant BLOCKS_PER_YEAR = BLOCKS_PER_DAY * 365;

uint256 constant APY_TOKENS = DECIMALS18;

File 3 of 14 : AbstractDependant.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.4;

import "../interfaces/IContractsRegistry.sol";

abstract contract AbstractDependant {
    /// @dev keccak256(AbstractDependant.setInjector(address)) - 1
    bytes32 private constant _INJECTOR_SLOT =
        0xd6b8f2e074594ceb05d47c27386969754b6ad0c15e5eb8f691399cd0be980e76;

    modifier onlyInjectorOrZero() {
        address _injector = injector();

        require(_injector == address(0) || _injector == msg.sender, "Dependant: Not an injector");
        _;
    }

    function setInjector(address _injector) external onlyInjectorOrZero {
        bytes32 slot = _INJECTOR_SLOT;

        assembly {
            sstore(slot, _injector)
        }
    }

    /// @dev has to apply onlyInjectorOrZero() modifier
    function setDependencies(IContractsRegistry) external virtual;

    function injector() public view returns (address _injector) {
        bytes32 slot = _INJECTOR_SLOT;

        assembly {
            _injector := sload(slot)
        }
    }
}

File 4 of 14 : IBMICoverStaking.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

interface IBMICoverStaking {
    struct StakingInfo {
        address policyBookAddress;
        uint256 stakedBMIXAmount;
    }

    struct PolicyBookInfo {
        uint256 totalStakedSTBL;
        uint256 rewardPerBlock;
        uint256 stakingAPY;
        uint256 liquidityAPY;
    }

    struct UserInfo {
        uint256 totalStakedBMIX;
        uint256 totalStakedSTBL;
        uint256 totalBmiReward;
    }

    struct NFTsInfo {
        uint256 nftIndex;
        string uri;
        uint256 stakedBMIXAmount;
        uint256 stakedSTBLAmount;
        uint256 reward;
    }

    function aggregateNFTs(address policyBookAddress, uint256[] calldata tokenIds) external;

    function stakeBMIX(uint256 amount, address policyBookAddress) external;

    function stakeBMIXWithPermit(
        uint256 bmiXAmount,
        address policyBookAddress,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    function stakeBMIXFrom(address user, uint256 amount) external;

    function stakeBMIXFromWithPermit(
        address user,
        uint256 bmiXAmount,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    function getPolicyBookAPY(address policyBookAddress) external view returns (uint256);

    function restakeBMIProfit(uint256 tokenId) external;

    function restakeStakerBMIProfit(address policyBookAddress) external;

    function withdrawBMIProfit(uint256 tokenID) external;

    function withdrawStakerBMIProfit(address policyBookAddress) external;

    function withdrawFundsWithProfit(uint256 tokenID) external;

    function withdrawStakerFundsWithProfit(address policyBookAddress) external;

    function stakingInfoByToken(uint256 tokenID) external view returns (StakingInfo memory);

    /// @notice exhaustive information about staker's stakes
    /// @param staker is a user to return information for
    /// @param policyBooksAddresses is an array of PolicyBooks to check the stakes in
    /// @param offset is a starting ordinal number of user's NFT
    /// @param limit is a number of NFTs to check per function's call
    /// @return policyBooksInfo - an array of infos (totalStakedSTBL, rewardPerBlock (in BMI), stakingAPY, liquidityAPY)
    /// @return usersInfo - an array of user's info per PolicyBook (totalStakedBMIX, totalStakedSTBL, totalBmiReward)
    /// @return nftsCount - number of NFTs for each respective PolicyBook
    /// @return nftsInfo - 2 dimensional array of NFTs info per each PolicyBook
    ///     (nftIndex, uri, stakedBMIXAmount, stakedSTBLAmount, reward (in BMI))
    function stakingInfoByStaker(
        address staker,
        address[] calldata policyBooksAddresses,
        uint256 offset,
        uint256 limit
    )
        external
        view
        returns (
            PolicyBookInfo[] memory policyBooksInfo,
            UserInfo[] memory usersInfo,
            uint256[] memory nftsCount,
            NFTsInfo[][] memory nftsInfo
        );

    function getSlashedBMIProfit(uint256 tokenId) external view returns (uint256);

    function getBMIProfit(uint256 tokenId) external view returns (uint256);

    function getSlashedStakerBMIProfit(
        address staker,
        address policyBookAddress,
        uint256 offset,
        uint256 limit
    ) external view returns (uint256 totalProfit);

    function getStakerBMIProfit(
        address staker,
        address policyBookAddress,
        uint256 offset,
        uint256 limit
    ) external view returns (uint256 totalProfit);

    function totalStaked(address user) external view returns (uint256);

    function totalStakedSTBL(address user) external view returns (uint256);

    function stakedByNFT(uint256 tokenId) external view returns (uint256);

    function stakedSTBLByNFT(uint256 tokenId) external view returns (uint256);

    function policyBookByNFT(uint256 tokenId) external view returns (address);

    function balanceOf(address user) external view returns (uint256);

    function ownerOf(uint256 tokenId) external view returns (address);

    function tokenOfOwnerByIndex(address user, uint256 index) external view returns (uint256);
}

File 5 of 14 : IClaimingRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

import "./IPolicyBookFabric.sol";

interface IClaimingRegistry {
    enum ClaimStatus {
        CAN_CLAIM,
        UNCLAIMABLE,
        PENDING,
        AWAITING_CALCULATION,
        REJECTED_CAN_APPEAL,
        REJECTED,
        ACCEPTED
    }

    struct ClaimInfo {
        address claimer;
        address policyBookAddress;
        string evidenceURI;
        uint256 dateSubmitted;
        uint256 dateEnded;
        bool appeal;
        ClaimStatus status;
        uint256 claimAmount;
    }

    /// @notice returns anonymous voting duration
    function anonymousVotingDuration(uint256 index) external view returns (uint256);

    /// @notice returns the whole voting duration
    function votingDuration(uint256 index) external view returns (uint256);

    /// @notice returns how many time should pass before anyone could calculate a claim result
    function anyoneCanCalculateClaimResultAfter(uint256 index) external view returns (uint256);

    /// @notice returns true if a user can buy new policy of specified PolicyBook
    function canBuyNewPolicy(address buyer, address policyBookAddress)
        external
        view
        returns (bool);

    /// @notice submits new PolicyBook claim for the user
    function submitClaim(
        address user,
        address policyBookAddress,
        string calldata evidenceURI,
        uint256 cover,
        bool appeal
    ) external returns (uint256);

    /// @notice returns true if the claim with this index exists
    function claimExists(uint256 index) external view returns (bool);

    /// @notice returns claim submition time
    function claimSubmittedTime(uint256 index) external view returns (uint256);

    /// @notice returns claim end time or zero in case it is pending
    function claimEndTime(uint256 index) external view returns (uint256);

    /// @notice returns true if the claim is anonymously votable
    function isClaimAnonymouslyVotable(uint256 index) external view returns (bool);

    /// @notice returns true if the claim is exposably votable
    function isClaimExposablyVotable(uint256 index) external view returns (bool);

    /// @notice returns true if claim is anonymously votable or exposably votable
    function isClaimVotable(uint256 index) external view returns (bool);

    /// @notice returns true if a claim can be calculated by anyone
    function canClaimBeCalculatedByAnyone(uint256 index) external view returns (bool);

    /// @notice returns true if this claim is pending or awaiting
    function isClaimPending(uint256 index) external view returns (bool);

    /// @notice returns how many claims the holder has
    function countPolicyClaimerClaims(address user) external view returns (uint256);

    /// @notice returns how many pending claims are there
    function countPendingClaims() external view returns (uint256);

    /// @notice returns how many claims are there
    function countClaims() external view returns (uint256);

    /// @notice returns a claim index of it's claimer and an ordinal number
    function claimOfOwnerIndexAt(address claimer, uint256 orderIndex)
        external
        view
        returns (uint256);

    /// @notice returns pending claim index by its ordinal index
    function pendingClaimIndexAt(uint256 orderIndex) external view returns (uint256);

    /// @notice returns claim index by its ordinal index
    function claimIndexAt(uint256 orderIndex) external view returns (uint256);

    /// @notice returns current active claim index by policybook and claimer
    function claimIndex(address claimer, address policyBookAddress)
        external
        view
        returns (uint256);

    /// @notice returns true if the claim is appealed
    function isClaimAppeal(uint256 index) external view returns (bool);

    /// @notice returns current status of a claim
    function policyStatus(address claimer, address policyBookAddress)
        external
        view
        returns (ClaimStatus);

    /// @notice returns current status of a claim
    function claimStatus(uint256 index) external view returns (ClaimStatus);

    /// @notice returns the claim owner (claimer)
    function claimOwner(uint256 index) external view returns (address);

    /// @notice returns the claim PolicyBook
    function claimPolicyBook(uint256 index) external view returns (address);

    /// @notice returns claim info by its index
    function claimInfo(uint256 index) external view returns (ClaimInfo memory _claimInfo);

    /// @notice marks the user's claim as Accepted
    function acceptClaim(uint256 index) external;

    /// @notice marks the user's claim as Rejected
    function rejectClaim(uint256 index) external;
}

File 6 of 14 : IContractsRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

interface IContractsRegistry {
    function getUniswapRouterContract() external view returns (address);

    function getUniswapBMIToETHPairContract() external view returns (address);

    function getWETHContract() external view returns (address);

    function getUSDTContract() external view returns (address);

    function getBMIContract() external view returns (address);

    function getPriceFeedContract() external view returns (address);

    function getPolicyBookRegistryContract() external view returns (address);

    function getPolicyBookFabricContract() external view returns (address);

    function getBMICoverStakingContract() external view returns (address);

    function getRewardsGeneratorContract() external view returns (address);

    function getBMIUtilityNFTContract() external view returns (address);

    function getLiquidityMiningContract() external view returns (address);

    function getClaimingRegistryContract() external view returns (address);

    function getPolicyRegistryContract() external view returns (address);

    function getLiquidityRegistryContract() external view returns (address);

    function getClaimVotingContract() external view returns (address);

    function getReinsurancePoolContract() external view returns (address);

    function getPolicyBookAdminContract() external view returns (address);

    function getPolicyQuoteContract() external view returns (address);

    function getLegacyBMIStakingContract() external view returns (address);

    function getBMIStakingContract() external view returns (address);

    function getSTKBMIContract() external view returns (address);

    function getVBMIContract() external view returns (address);

    function getLegacyLiquidityMiningStakingContract() external view returns (address);

    function getLiquidityMiningStakingContract() external view returns (address);

    function getReputationSystemContract() external view returns (address);
}

File 7 of 14 : ILiquidityRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

interface ILiquidityRegistry {
    struct LiquidityInfo {
        address policyBookAddr;
        uint256 lockedAmount;
        uint256 availableAmount;
        uint256 bmiXRatio; // multiply availableAmount by this num to get stable coin
    }

    struct WithdrawalRequestInfo {
        address policyBookAddr;
        uint256 requestAmount;
        uint256 requestSTBLAmount;
        uint256 availableLiquidity;
        uint256 readyToWithdrawDate;
        uint256 endWithdrawDate;
    }

    struct WithdrawalSetInfo {
        address policyBookAddr;
        uint256 requestAmount;
        uint256 requestSTBLAmount;
        uint256 availableSTBLAmount;
    }

    function tryToAddPolicyBook(address _userAddr, address _policyBookAddr) external;

    function tryToRemovePolicyBook(address _userAddr, address _policyBookAddr) external;

    function getPolicyBooksArrLength(address _userAddr) external view returns (uint256);

    function getPolicyBooksArr(address _userAddr)
        external
        view
        returns (address[] memory _resultArr);

    function getLiquidityInfos(
        address _userAddr,
        uint256 _offset,
        uint256 _limit
    ) external view returns (LiquidityInfo[] memory _resultArr);

    function getWithdrawalRequests(
        address _userAddr,
        uint256 _offset,
        uint256 _limit
    ) external view returns (uint256 _arrLength, WithdrawalRequestInfo[] memory _resultArr);

    function getWithdrawalSet(
        address _userAddr,
        uint256 _offset,
        uint256 _limit
    ) external view returns (uint256 _arrLength, WithdrawalSetInfo[] memory _resultArr);
}

File 8 of 14 : IPolicyBook.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

import "./IPolicyBookFabric.sol";
import "./IClaimingRegistry.sol";

interface IPolicyBook {
    enum WithdrawalStatus {NONE, PENDING, READY, EXPIRED}

    struct PolicyHolder {
        uint256 coverTokens;
        uint256 startEpochNumber;
        uint256 endEpochNumber;
        uint256 paid;
    }

    struct WithdrawalInfo {
        uint256 withdrawalAmount;
        uint256 readyToWithdrawDate;
        bool withdrawalAllowed;
    }

    function EPOCH_DURATION() external view returns (uint256);

    function READY_TO_WITHDRAW_PERIOD() external view returns (uint256);

    function whitelisted() external view returns (bool);

    function epochStartTime() external view returns (uint256);

    // @TODO: should we let DAO to change contract address?
    /// @notice Returns address of contract this PolicyBook covers, access: ANY
    /// @return _contract is address of covered contract
    function insuranceContractAddress() external view returns (address _contract);

    /// @notice Returns type of contract this PolicyBook covers, access: ANY
    /// @return _type is type of contract
    function contractType() external view returns (IPolicyBookFabric.ContractType _type);

    function totalLiquidity() external view returns (uint256);

    function totalCoverTokens() external view returns (uint256);

    function withdrawalsInfo(address _userAddr)
        external
        view
        returns (
            uint256 _withdrawalAmount,
            uint256 _readyToWithdrawDate,
            bool _withdrawalAllowed
        );

    function __PolicyBook_init(
        address _insuranceContract,
        IPolicyBookFabric.ContractType _contractType,
        string calldata _description,
        string calldata _projectSymbol
    ) external;

    function whitelist(bool _whitelisted) external;

    function getEpoch(uint256 time) external view returns (uint256);

    /// @notice get STBL equivalent
    function convertBMIXToSTBL(uint256 _amount) external view returns (uint256);

    /// @notice get BMIX equivalent
    function convertSTBLToBMIX(uint256 _amount) external view returns (uint256);

    /// @notice returns how many BMI tokens needs to approve in order to submit a claim
    function getClaimApprovalAmount(address user) external view returns (uint256);

    /// @notice submits new claim of the policy book
    function submitClaimAndInitializeVoting(string calldata evidenceURI) external;

    /// @notice submits new appeal claim of the policy book
    function submitAppealAndInitializeVoting(string calldata evidenceURI) external;

    /// @notice updates info on claim acceptance
    function commitClaim(
        address claimer,
        uint256 claimAmount,
        uint256 claimEndTime,
        IClaimingRegistry.ClaimStatus status
    ) external;

    /// @notice function to get precise current cover and liquidity
    function getNewCoverAndLiquidity()
        external
        view
        returns (uint256 newTotalCoverTokens, uint256 newTotalLiquidity);

    /// @notice view function to get precise policy price
    function getPolicyPrice(uint256 _epochsNumber, uint256 _coverTokens)
        external
        view
        returns (uint256 totalSeconds, uint256 totalPrice);

    function buyPolicyFor(
        address _buyer,
        uint256 _epochsNumber,
        uint256 _coverTokens
    ) external;

    /// @notice Let user to buy policy by supplying stable coin, access: ANY
    /// @param _durationSeconds is number of seconds to cover
    /// @param _coverTokens is number of tokens to cover
    function buyPolicy(uint256 _durationSeconds, uint256 _coverTokens) external;

    function updateEpochsInfo() external;

    function secondsToEndCurrentEpoch() external view returns (uint256);

    /// @notice Let user to add liquidity by supplying stable coin, access: ANY
    /// @param _liqudityAmount is amount of stable coin tokens to secure
    function addLiquidity(uint256 _liqudityAmount) external;

    /// @notice Let eligible contracts add liqiudity for another user by supplying stable coin
    /// @param _liquidityHolderAddr is address of address to assign cover
    /// @param _liqudityAmount is amount of stable coin tokens to secure
    function addLiquidityFor(address _liquidityHolderAddr, uint256 _liqudityAmount) external;

    function addLiquidityAndStake(uint256 _liquidityAmount, uint256 _stakeSTBLAmount) external;

    function getAvailableBMIXWithdrawableAmount(address _userAddr) external view returns (uint256);

    function getWithdrawalStatus(address _userAddr) external view returns (WithdrawalStatus);

    function requestWithdrawal(uint256 _tokensToWithdraw) external;

    function requestWithdrawalWithPermit(
        uint256 _tokensToWithdraw,
        uint8 _v,
        bytes32 _r,
        bytes32 _s
    ) external;

    function unlockTokens() external;

    /// @notice Let user to withdraw deposited liqiudity, access: ANY
    function withdrawLiquidity() external;

    function getAPY() external view returns (uint256);

    /// @notice Getting user stats, access: ANY
    function userStats(address _user) external view returns (PolicyHolder memory);

    /// @notice Getting number stats, access: ANY
    /// @return _maxCapacities is a max token amount that a user can buy
    /// @return _totalSTBLLiquidity is PolicyBook's liquidity
    /// @return _stakedSTBL is how much stable coin are staked on this PolicyBook
    /// @return _annualProfitYields is its APY
    /// @return _annualInsuranceCost is percentage of cover tokens that is required to be paid for 1 year of insurance
    function numberStats()
        external
        view
        returns (
            uint256 _maxCapacities,
            uint256 _totalSTBLLiquidity,
            uint256 _stakedSTBL,
            uint256 _annualProfitYields,
            uint256 _annualInsuranceCost,
            uint256 _bmiXRatio
        );

    /// @notice Getting info, access: ANY
    /// @return _symbol is the symbol of PolicyBook (bmiXCover)
    /// @return _insuredContract is an addres of insured contract
    /// @return _contractType is a type of insured contract
    /// @return _whitelisted is a state of whitelisting
    function info()
        external
        view
        returns (
            string memory _symbol,
            address _insuredContract,
            IPolicyBookFabric.ContractType _contractType,
            bool _whitelisted
        );
}

File 9 of 14 : IPolicyBookFabric.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.4;

interface IPolicyBookFabric {
    enum ContractType {CONTRACT, STABLECOIN, SERVICE, EXCHANGE}

    /// @notice Create new Policy Book contract, access: ANY
    /// @param _contract is Contract to create policy book for
    /// @param _contractType is Contract to create policy book for
    /// @param _description is bmiXCover token desription for this policy book
    /// @param _projectSymbol replaces x in bmiXCover token symbol
    /// @param _initialDeposit is an amount user deposits on creation (addLiquidity())
    /// @return _policyBook is address of created contract
    function create(
        address _contract,
        ContractType _contractType,
        string calldata _description,
        string calldata _projectSymbol,
        uint256 _initialDeposit
    ) external returns (address);
}

File 10 of 14 : IPolicyBookRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

import "./IPolicyBookFabric.sol";

interface IPolicyBookRegistry {
    struct PolicyBookStats {
        string symbol;
        address insuredContract;
        IPolicyBookFabric.ContractType contractType;
        uint256 maxCapacity;
        uint256 totalSTBLLiquidity;
        uint256 stakedSTBL;
        uint256 APY;
        uint256 annualInsuranceCost;
        uint256 bmiXRatio;
        bool whitelisted;
    }

    /// @notice Adds PolicyBook to registry, access: PolicyFabric
    function add(
        address insuredContract,
        IPolicyBookFabric.ContractType contractType,
        address policyBook
    ) external;

    function whitelist(address policyBookAddress, bool whitelisted) external;

    /// @notice returns required allowances for the policybooks
    function getPoliciesPrices(
        address[] calldata policyBooks,
        uint256[] calldata epochsNumbers,
        uint256[] calldata coversTokens
    ) external view returns (uint256[] memory _durations, uint256[] memory _allowances);

    /// @notice Buys a batch of policies
    function buyPolicyBatch(
        address[] calldata policyBooks,
        uint256[] calldata epochsNumbers,
        uint256[] calldata coversTokens
    ) external;

    /// @notice Checks if provided address is a PolicyBook
    function isPolicyBook(address policyBook) external view returns (bool);

    /// @notice Returns number of registered PolicyBooks with certain contract type
    function countByType(IPolicyBookFabric.ContractType contractType)
        external
        view
        returns (uint256);

    /// @notice Returns number of registered PolicyBooks, access: ANY
    function count() external view returns (uint256);

    function countByTypeWhitelisted(IPolicyBookFabric.ContractType contractType)
        external
        view
        returns (uint256);

    function countWhitelisted() external view returns (uint256);

    /// @notice Listing registered PolicyBooks with certain contract type, access: ANY
    /// @return _policyBooksArr is array of registered PolicyBook addresses with certain contract type
    function listByType(
        IPolicyBookFabric.ContractType contractType,
        uint256 offset,
        uint256 limit
    ) external view returns (address[] memory _policyBooksArr);

    /// @notice Listing registered PolicyBooks, access: ANY
    /// @return _policyBooksArr is array of registered PolicyBook addresses
    function list(uint256 offset, uint256 limit)
        external
        view
        returns (address[] memory _policyBooksArr);

    function listByTypeWhitelisted(
        IPolicyBookFabric.ContractType contractType,
        uint256 offset,
        uint256 limit
    ) external view returns (address[] memory _policyBooksArr);

    function listWhitelisted(uint256 offset, uint256 limit)
        external
        view
        returns (address[] memory _policyBooksArr);

    /// @notice Listing registered PolicyBooks with stats and certain contract type, access: ANY
    function listWithStatsByType(
        IPolicyBookFabric.ContractType contractType,
        uint256 offset,
        uint256 limit
    ) external view returns (address[] memory _policyBooksArr, PolicyBookStats[] memory _stats);

    /// @notice Listing registered PolicyBooks with stats, access: ANY
    function listWithStats(uint256 offset, uint256 limit)
        external
        view
        returns (address[] memory _policyBooksArr, PolicyBookStats[] memory _stats);

    function listWithStatsByTypeWhitelisted(
        IPolicyBookFabric.ContractType contractType,
        uint256 offset,
        uint256 limit
    ) external view returns (address[] memory _policyBooksArr, PolicyBookStats[] memory _stats);

    function listWithStatsWhitelisted(uint256 offset, uint256 limit)
        external
        view
        returns (address[] memory _policyBooksArr, PolicyBookStats[] memory _stats);

    /// @notice Getting stats from policy books, access: ANY
    /// @param policyBooks is list of PolicyBooks addresses
    function stats(address[] calldata policyBooks)
        external
        view
        returns (PolicyBookStats[] memory _stats);

    /// @notice Return existing Policy Book contract, access: ANY
    /// @param insuredContract is contract address to lookup for created IPolicyBook
    function policyBookFor(address insuredContract) external view returns (address);

    /// @notice Getting stats from policy books, access: ANY
    /// @param insuredContracts is list of insuredContracts in registry
    function statsByInsuredContracts(address[] calldata insuredContracts)
        external
        view
        returns (PolicyBookStats[] memory _stats);
}

File 11 of 14 : Math.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

File 12 of 14 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

File 13 of 14 : IERC20.sol
// 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 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 Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool);

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

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

File 14 of 14 : EnumerableSet.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;

        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) { // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            bytes32 lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        require(set._values.length > index, "EnumerableSet: index out of bounds");
        return set._values[index];
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(value)));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(value)));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(value)));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint256(_at(set._inner, index)));
    }


    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }
}

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

Contract Security Audit

Contract ABI

API
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_userAddr","type":"address"},{"indexed":false,"internalType":"address","name":"_policyBookAddress","type":"address"}],"name":"PolicyBookAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_userAddr","type":"address"},{"indexed":false,"internalType":"address","name":"_policyBookAddress","type":"address"}],"name":"PolicyBookRemoved","type":"event"},{"inputs":[],"name":"bmiCoverStaking","outputs":[{"internalType":"contract IBMICoverStaking","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddr","type":"address"},{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getLiquidityInfos","outputs":[{"components":[{"internalType":"address","name":"policyBookAddr","type":"address"},{"internalType":"uint256","name":"lockedAmount","type":"uint256"},{"internalType":"uint256","name":"availableAmount","type":"uint256"},{"internalType":"uint256","name":"bmiXRatio","type":"uint256"}],"internalType":"struct ILiquidityRegistry.LiquidityInfo[]","name":"_resultArr","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddr","type":"address"}],"name":"getPolicyBooksArr","outputs":[{"internalType":"address[]","name":"_resultArr","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddr","type":"address"}],"name":"getPolicyBooksArrLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddr","type":"address"},{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getWithdrawalRequests","outputs":[{"internalType":"uint256","name":"_arrLength","type":"uint256"},{"components":[{"internalType":"address","name":"policyBookAddr","type":"address"},{"internalType":"uint256","name":"requestAmount","type":"uint256"},{"internalType":"uint256","name":"requestSTBLAmount","type":"uint256"},{"internalType":"uint256","name":"availableLiquidity","type":"uint256"},{"internalType":"uint256","name":"readyToWithdrawDate","type":"uint256"},{"internalType":"uint256","name":"endWithdrawDate","type":"uint256"}],"internalType":"struct ILiquidityRegistry.WithdrawalRequestInfo[]","name":"_resultArr","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddr","type":"address"},{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getWithdrawalSet","outputs":[{"internalType":"uint256","name":"_arrLength","type":"uint256"},{"components":[{"internalType":"address","name":"policyBookAddr","type":"address"},{"internalType":"uint256","name":"requestAmount","type":"uint256"},{"internalType":"uint256","name":"requestSTBLAmount","type":"uint256"},{"internalType":"uint256","name":"availableSTBLAmount","type":"uint256"}],"internalType":"struct ILiquidityRegistry.WithdrawalSetInfo[]","name":"_resultArr","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"injector","outputs":[{"internalType":"address","name":"_injector","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"policyBookRegistry","outputs":[{"internalType":"contract IPolicyBookRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IContractsRegistry","name":"_contractsRegistry","type":"address"}],"name":"setDependencies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_injector","type":"address"}],"name":"setInjector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddr","type":"address"},{"internalType":"address","name":"_policyBookAddr","type":"address"}],"name":"tryToAddPolicyBook","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddr","type":"address"},{"internalType":"address","name":"_policyBookAddr","type":"address"}],"name":"tryToRemovePolicyBook","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b50611ad9806100206000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063786521de11610071578063786521de146101495780638389cb18146101695780638cb941cc1461017e578063b1d3404a14610191578063cef3c93a146101a4578063eca51feb146101c4576100b4565b806302cd2959146100b957806307e2ad2f146100d757806314b49c76146100df57806320421cb31461010057806346171610146101205780634d2dc7ad14610128575b600080fd5b6100c16101d7565b6040516100ce919061188c565b60405180910390f35b6100c16101e6565b6100f26100ed366004611784565b6101f5565b6040516100ce929190611a12565b61011361010e366004611714565b6104b6565b6040516100ce9190611949565b6100c16104df565b61013b610136366004611784565b610504565b6040516100ce929190611989565b61015c610157366004611784565b6108d8565b6040516100ce9190611907565b61017c610177366004611714565b610b87565b005b61017c61018c366004611714565b610d2d565b61017c61019f36600461174c565b610dcd565b6101b76101b2366004611714565b610ff5565b6040516100ce91906118ba565b61017c6101d236600461174c565b6110c0565b6001546001600160a01b031681565b6000546001600160a01b031681565b6000606060006102458561023f61022f600260008b6001600160a01b03166001600160a01b03168152602001908152602001600020611361565b610239898961136c565b906113cf565b906113e5565b905084810367ffffffffffffffff8111801561026057600080fd5b5060405190808252806020026020018201604052801561029a57816020015b610287611694565b81526020019060019003908161027f5790505b509150845b818110156104ac576001600160a01b03871660009081526002602052604081206102c990836113f5565b9050600080826001600160a01b031663bd5ed2988b6040518263ffffffff1660e01b81526004016102fa919061188c565b60606040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034a919061182c565b92505091508061035c575050506104a4565b600080846001600160a01b031663ff81decd6040518163ffffffff1660e01b8152600401604080518083038186803b15801561039757600080fd5b505afa1580156103ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103cf9190611809565b915091506040518060800160405280866001600160a01b03168152602001858152602001866001600160a01b0316634596426f876040518263ffffffff1660e01b815260040161041f9190611949565b60206040518083038186803b15801561043757600080fd5b505afa15801561044b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046f91906117f1565b815260200161047e8385611401565b815250888a8151811061048d57fe5b602090810291909101015250506001909601955050505b60010161029f565b5050935093915050565b6001600160a01b03811660009081526002602052604081206104d790611361565b90505b919050565b7fd6b8f2e074594ceb05d47c27386969754b6ad0c15e5eb8f691399cd0be980e765490565b60006060600061053e8561023f61022f600260008b6001600160a01b03166001600160a01b03168152602001908152602001600020611361565b905084810367ffffffffffffffff8111801561055957600080fd5b5060405190808252806020026020018201604052801561059357816020015b6105806116c5565b8152602001906001900390816105785790505b509150845b818110156104ac576001600160a01b03871660009081526002602052604081206105c290836113f5565b90506000806000836001600160a01b031663bd5ed2988c6040518263ffffffff1660e01b81526004016105f5919061188c565b60606040518083038186803b15801561060d57600080fd5b505afa158015610621573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610645919061182c565b9250925092506000846001600160a01b0316637491687e8d6040518263ffffffff1660e01b8152600401610679919061188c565b60206040518083038186803b15801561069157600080fd5b505afa1580156106a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c991906117d2565b905081806106e2575060008160038111156106e057fe5b145b156106f15750505050506108d0565b60008342111561077957610776866001600160a01b0316630f36c97e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561073757600080fd5b505afa15801561074b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076f91906117f1565b859061136c565b90505b600080876001600160a01b031663ff81decd6040518163ffffffff1660e01b8152600401604080518083038186803b1580156107b457600080fd5b505afa1580156107c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ec9190611809565b915091506040518060c00160405280896001600160a01b03168152602001888152602001896001600160a01b0316634596426f8a6040518263ffffffff1660e01b815260040161083c9190611949565b60206040518083038186803b15801561085457600080fd5b505afa158015610868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088c91906117f1565b815260200161089b8385611401565b8152602001878152602001848152508b8d815181106108b657fe5b602090810291909101015250506001909901985050505050505b600101610598565b6060600061091a8461023f610910600260008a6001600160a01b03166001600160a01b03168152602001908152602001600020611361565b610239888861136c565b905083810367ffffffffffffffff8111801561093557600080fd5b5060405190808252806020026020018201604052801561096f57816020015b61095c611694565b8152602001906001900390816109545790505b509150835b81811015610b7e576001600160a01b038616600090815260026020526040812061099e90836113f5565b90506000816001600160a01b031663bd5ed298896040518263ffffffff1660e01b81526004016109ce919061188c565b60606040518083038186803b1580156109e657600080fd5b505afa1580156109fa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1e919061182c565b505090506000826001600160a01b03166370a082318a6040518263ffffffff1660e01b8152600401610a50919061188c565b60206040518083038186803b158015610a6857600080fd5b505afa158015610a7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa091906117f1565b90506000836001600160a01b0316634596426f670de0b6b3a76400006040518263ffffffff1660e01b8152600401610ad89190611949565b60206040518083038186803b158015610af057600080fd5b505afa158015610b04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2891906117f1565b90506040518060800160405280856001600160a01b0316815260200184815260200183815260200182815250878a870381518110610b6257fe5b6020026020010181905250505050508080600101915050610974565b50509392505050565b6000610b916104df565b90506001600160a01b0381161580610bb157506001600160a01b03811633145b610c02576040805162461bcd60e51b815260206004820152601a60248201527f446570656e64616e743a204e6f7420616e20696e6a6563746f72000000000000604482015290519081900360640190fd5b816001600160a01b031663dc9c563f6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3b57600080fd5b505afa158015610c4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c739190611730565b6000806101000a8154816001600160a01b0302191690836001600160a01b03160217905550816001600160a01b031663f0f8c04e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cd157600080fd5b505afa158015610ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d099190611730565b600180546001600160a01b0319166001600160a01b03929092169190911790555050565b6000610d376104df565b90506001600160a01b0381161580610d5757506001600160a01b03811633145b610da8576040805162461bcd60e51b815260206004820152601a60248201527f446570656e64616e743a204e6f7420616e20696e6a6563746f72000000000000604482015290519081900360640190fd5b507fd6b8f2e074594ceb05d47c27386969754b6ad0c15e5eb8f691399cd0be980e7655565b6001546001600160a01b0316331480610e615750600054604051634c3b9f1960e01b81526001600160a01b0390911690634c3b9f1990610e1190339060040161188c565b60206040518083038186803b158015610e2957600080fd5b505afa158015610e3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6191906117b8565b610e865760405162461bcd60e51b8152600401610e7d90611952565b60405180910390fd5b6040516370a0823160e01b81526000906001600160a01b038316906370a0823190610eb590869060040161188c565b60206040518083038186803b158015610ecd57600080fd5b505afa158015610ee1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0591906117f1565b1180610f8f57506001546040516370a0823160e01b81526000916001600160a01b0316906370a0823190610f3d90869060040161188c565b60206040518083038186803b158015610f5557600080fd5b505afa158015610f69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8d91906117f1565b115b15610ff1576001600160a01b0382166000908152600260205260409020610fb69082611443565b507f3328fd8f943c41c5a828e9cd282bbb7f6fe22c6d6aab6b0aecb281152e95f5db8282604051610fe89291906118a0565b60405180910390a15b5050565b6001600160a01b03811660009081526002602052604081206060919061101a90611361565b90508067ffffffffffffffff8111801561103357600080fd5b5060405190808252806020026020018201604052801561105d578160200160208202803683370190505b50915060005b818110156110b9576001600160a01b038416600090815260026020526040902061108d90826113f5565b83828151811061109957fe5b6001600160a01b0390921660209283029190910190910152600101611063565b5050919050565b6001546001600160a01b03163314806111545750600054604051634c3b9f1960e01b81526001600160a01b0390911690634c3b9f199061110490339060040161188c565b60206040518083038186803b15801561111c57600080fd5b505afa158015611130573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115491906117b8565b6111705760405162461bcd60e51b8152600401610e7d90611952565b6040516370a0823160e01b81526001600160a01b038216906370a082319061119c90859060040161188c565b60206040518083038186803b1580156111b457600080fd5b505afa1580156111c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ec91906117f1565b15801561127657506001546040516370a0823160e01b81526001600160a01b03909116906370a082319061122490859060040161188c565b60206040518083038186803b15801561123c57600080fd5b505afa158015611250573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127491906117f1565b155b801561130857506000604051633a48b43f60e11b81526001600160a01b03831690637491687e906112ab90869060040161188c565b60206040518083038186803b1580156112c357600080fd5b505afa1580156112d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fb91906117d2565b600381111561130657fe5b145b15610ff1576001600160a01b038216600090815260026020526040902061132f9082611458565b507f6d54f12ecde3b7722ace8d0e2f302652acc082a8206901a784e0915ba3bd15928282604051610fe89291906118a0565b60006104d78261146d565b6000828201838110156113c6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b60008183106113de57816113c6565b5090919050565b6000818310156113de57816113c6565b60006113c68383611471565b60006113c683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114d5565b60006113c6836001600160a01b03841661156c565b60006113c6836001600160a01b0384166115b6565b5490565b815460009082106114b35760405162461bcd60e51b8152600401808060200182810382526022815260200180611a826022913960400191505060405180910390fd5b8260000182815481106114c257fe5b9060005260206000200154905092915050565b600081848411156115645760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611529578181015183820152602001611511565b50505050905090810190601f1680156115565780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000611578838361167c565b6115ae575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556113c9565b5060006113c9565b6000818152600183016020526040812054801561167257835460001980830191908101906000908790839081106115e957fe5b906000526020600020015490508087600001848154811061160657fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061163657fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506113c9565b60009150506113c9565b60009081526001919091016020526040902054151590565b604051806080016040528060006001600160a01b031681526020016000815260200160008152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b805180151581146104da57600080fd5b600060208284031215611725578081fd5b81356113c681611a69565b600060208284031215611741578081fd5b81516113c681611a69565b6000806040838503121561175e578081fd5b823561176981611a69565b9150602083013561177981611a69565b809150509250929050565b600080600060608486031215611798578081fd5b83356117a381611a69565b95602085013595506040909401359392505050565b6000602082840312156117c9578081fd5b6113c682611704565b6000602082840312156117e3578081fd5b8151600481106113c6578182fd5b600060208284031215611802578081fd5b5051919050565b6000806040838503121561181b578182fd5b505080516020909101519092909150565b600080600060608486031215611840578283fd5b835192506020840151915061185760408501611704565b90509250925092565b80516001600160a01b031682526020808201519083015260408082015190830152606090810151910152565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6020808252825182820181905260009190848201906040850190845b818110156118fb5783516001600160a01b0316835292840192918401916001016118d6565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156118fb57611936838551611860565b9284019260809290920191600101611923565b90815260200190565b6020808252601c908201527f4c523a204e6f7420616e20656c696769626c6520636f6e747261637400000000604082015260600190565b6000604080830185845260208281860152818651808452606093508387019150828801865b82811015611a0357815180516001600160a01b031685528581015186860152878101518886015286810151878601526080808201519086015260a0908101519085015260c090930192908401906001016119ae565b50919998505050505050505050565b60006040820184835260206040818501528185518084526060860191508287019350845b81811015611a5c57611a49838651611860565b9383019360809290920191600101611a36565b5090979650505050505050565b6001600160a01b0381168114611a7e57600080fd5b5056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473a26469706673582212202b5010b12c55c1b7c6018dead398085e37a9d1487646f496a1f576b6f973f70f64736f6c63430007040033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100b45760003560e01c8063786521de11610071578063786521de146101495780638389cb18146101695780638cb941cc1461017e578063b1d3404a14610191578063cef3c93a146101a4578063eca51feb146101c4576100b4565b806302cd2959146100b957806307e2ad2f146100d757806314b49c76146100df57806320421cb31461010057806346171610146101205780634d2dc7ad14610128575b600080fd5b6100c16101d7565b6040516100ce919061188c565b60405180910390f35b6100c16101e6565b6100f26100ed366004611784565b6101f5565b6040516100ce929190611a12565b61011361010e366004611714565b6104b6565b6040516100ce9190611949565b6100c16104df565b61013b610136366004611784565b610504565b6040516100ce929190611989565b61015c610157366004611784565b6108d8565b6040516100ce9190611907565b61017c610177366004611714565b610b87565b005b61017c61018c366004611714565b610d2d565b61017c61019f36600461174c565b610dcd565b6101b76101b2366004611714565b610ff5565b6040516100ce91906118ba565b61017c6101d236600461174c565b6110c0565b6001546001600160a01b031681565b6000546001600160a01b031681565b6000606060006102458561023f61022f600260008b6001600160a01b03166001600160a01b03168152602001908152602001600020611361565b610239898961136c565b906113cf565b906113e5565b905084810367ffffffffffffffff8111801561026057600080fd5b5060405190808252806020026020018201604052801561029a57816020015b610287611694565b81526020019060019003908161027f5790505b509150845b818110156104ac576001600160a01b03871660009081526002602052604081206102c990836113f5565b9050600080826001600160a01b031663bd5ed2988b6040518263ffffffff1660e01b81526004016102fa919061188c565b60606040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034a919061182c565b92505091508061035c575050506104a4565b600080846001600160a01b031663ff81decd6040518163ffffffff1660e01b8152600401604080518083038186803b15801561039757600080fd5b505afa1580156103ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103cf9190611809565b915091506040518060800160405280866001600160a01b03168152602001858152602001866001600160a01b0316634596426f876040518263ffffffff1660e01b815260040161041f9190611949565b60206040518083038186803b15801561043757600080fd5b505afa15801561044b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046f91906117f1565b815260200161047e8385611401565b815250888a8151811061048d57fe5b602090810291909101015250506001909601955050505b60010161029f565b5050935093915050565b6001600160a01b03811660009081526002602052604081206104d790611361565b90505b919050565b7fd6b8f2e074594ceb05d47c27386969754b6ad0c15e5eb8f691399cd0be980e765490565b60006060600061053e8561023f61022f600260008b6001600160a01b03166001600160a01b03168152602001908152602001600020611361565b905084810367ffffffffffffffff8111801561055957600080fd5b5060405190808252806020026020018201604052801561059357816020015b6105806116c5565b8152602001906001900390816105785790505b509150845b818110156104ac576001600160a01b03871660009081526002602052604081206105c290836113f5565b90506000806000836001600160a01b031663bd5ed2988c6040518263ffffffff1660e01b81526004016105f5919061188c565b60606040518083038186803b15801561060d57600080fd5b505afa158015610621573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610645919061182c565b9250925092506000846001600160a01b0316637491687e8d6040518263ffffffff1660e01b8152600401610679919061188c565b60206040518083038186803b15801561069157600080fd5b505afa1580156106a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c991906117d2565b905081806106e2575060008160038111156106e057fe5b145b156106f15750505050506108d0565b60008342111561077957610776866001600160a01b0316630f36c97e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561073757600080fd5b505afa15801561074b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076f91906117f1565b859061136c565b90505b600080876001600160a01b031663ff81decd6040518163ffffffff1660e01b8152600401604080518083038186803b1580156107b457600080fd5b505afa1580156107c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ec9190611809565b915091506040518060c00160405280896001600160a01b03168152602001888152602001896001600160a01b0316634596426f8a6040518263ffffffff1660e01b815260040161083c9190611949565b60206040518083038186803b15801561085457600080fd5b505afa158015610868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088c91906117f1565b815260200161089b8385611401565b8152602001878152602001848152508b8d815181106108b657fe5b602090810291909101015250506001909901985050505050505b600101610598565b6060600061091a8461023f610910600260008a6001600160a01b03166001600160a01b03168152602001908152602001600020611361565b610239888861136c565b905083810367ffffffffffffffff8111801561093557600080fd5b5060405190808252806020026020018201604052801561096f57816020015b61095c611694565b8152602001906001900390816109545790505b509150835b81811015610b7e576001600160a01b038616600090815260026020526040812061099e90836113f5565b90506000816001600160a01b031663bd5ed298896040518263ffffffff1660e01b81526004016109ce919061188c565b60606040518083038186803b1580156109e657600080fd5b505afa1580156109fa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1e919061182c565b505090506000826001600160a01b03166370a082318a6040518263ffffffff1660e01b8152600401610a50919061188c565b60206040518083038186803b158015610a6857600080fd5b505afa158015610a7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa091906117f1565b90506000836001600160a01b0316634596426f670de0b6b3a76400006040518263ffffffff1660e01b8152600401610ad89190611949565b60206040518083038186803b158015610af057600080fd5b505afa158015610b04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2891906117f1565b90506040518060800160405280856001600160a01b0316815260200184815260200183815260200182815250878a870381518110610b6257fe5b6020026020010181905250505050508080600101915050610974565b50509392505050565b6000610b916104df565b90506001600160a01b0381161580610bb157506001600160a01b03811633145b610c02576040805162461bcd60e51b815260206004820152601a60248201527f446570656e64616e743a204e6f7420616e20696e6a6563746f72000000000000604482015290519081900360640190fd5b816001600160a01b031663dc9c563f6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3b57600080fd5b505afa158015610c4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c739190611730565b6000806101000a8154816001600160a01b0302191690836001600160a01b03160217905550816001600160a01b031663f0f8c04e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cd157600080fd5b505afa158015610ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d099190611730565b600180546001600160a01b0319166001600160a01b03929092169190911790555050565b6000610d376104df565b90506001600160a01b0381161580610d5757506001600160a01b03811633145b610da8576040805162461bcd60e51b815260206004820152601a60248201527f446570656e64616e743a204e6f7420616e20696e6a6563746f72000000000000604482015290519081900360640190fd5b507fd6b8f2e074594ceb05d47c27386969754b6ad0c15e5eb8f691399cd0be980e7655565b6001546001600160a01b0316331480610e615750600054604051634c3b9f1960e01b81526001600160a01b0390911690634c3b9f1990610e1190339060040161188c565b60206040518083038186803b158015610e2957600080fd5b505afa158015610e3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6191906117b8565b610e865760405162461bcd60e51b8152600401610e7d90611952565b60405180910390fd5b6040516370a0823160e01b81526000906001600160a01b038316906370a0823190610eb590869060040161188c565b60206040518083038186803b158015610ecd57600080fd5b505afa158015610ee1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0591906117f1565b1180610f8f57506001546040516370a0823160e01b81526000916001600160a01b0316906370a0823190610f3d90869060040161188c565b60206040518083038186803b158015610f5557600080fd5b505afa158015610f69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8d91906117f1565b115b15610ff1576001600160a01b0382166000908152600260205260409020610fb69082611443565b507f3328fd8f943c41c5a828e9cd282bbb7f6fe22c6d6aab6b0aecb281152e95f5db8282604051610fe89291906118a0565b60405180910390a15b5050565b6001600160a01b03811660009081526002602052604081206060919061101a90611361565b90508067ffffffffffffffff8111801561103357600080fd5b5060405190808252806020026020018201604052801561105d578160200160208202803683370190505b50915060005b818110156110b9576001600160a01b038416600090815260026020526040902061108d90826113f5565b83828151811061109957fe5b6001600160a01b0390921660209283029190910190910152600101611063565b5050919050565b6001546001600160a01b03163314806111545750600054604051634c3b9f1960e01b81526001600160a01b0390911690634c3b9f199061110490339060040161188c565b60206040518083038186803b15801561111c57600080fd5b505afa158015611130573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115491906117b8565b6111705760405162461bcd60e51b8152600401610e7d90611952565b6040516370a0823160e01b81526001600160a01b038216906370a082319061119c90859060040161188c565b60206040518083038186803b1580156111b457600080fd5b505afa1580156111c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ec91906117f1565b15801561127657506001546040516370a0823160e01b81526001600160a01b03909116906370a082319061122490859060040161188c565b60206040518083038186803b15801561123c57600080fd5b505afa158015611250573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127491906117f1565b155b801561130857506000604051633a48b43f60e11b81526001600160a01b03831690637491687e906112ab90869060040161188c565b60206040518083038186803b1580156112c357600080fd5b505afa1580156112d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fb91906117d2565b600381111561130657fe5b145b15610ff1576001600160a01b038216600090815260026020526040902061132f9082611458565b507f6d54f12ecde3b7722ace8d0e2f302652acc082a8206901a784e0915ba3bd15928282604051610fe89291906118a0565b60006104d78261146d565b6000828201838110156113c6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b60008183106113de57816113c6565b5090919050565b6000818310156113de57816113c6565b60006113c68383611471565b60006113c683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114d5565b60006113c6836001600160a01b03841661156c565b60006113c6836001600160a01b0384166115b6565b5490565b815460009082106114b35760405162461bcd60e51b8152600401808060200182810382526022815260200180611a826022913960400191505060405180910390fd5b8260000182815481106114c257fe5b9060005260206000200154905092915050565b600081848411156115645760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611529578181015183820152602001611511565b50505050905090810190601f1680156115565780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000611578838361167c565b6115ae575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556113c9565b5060006113c9565b6000818152600183016020526040812054801561167257835460001980830191908101906000908790839081106115e957fe5b906000526020600020015490508087600001848154811061160657fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061163657fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506113c9565b60009150506113c9565b60009081526001919091016020526040902054151590565b604051806080016040528060006001600160a01b031681526020016000815260200160008152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b805180151581146104da57600080fd5b600060208284031215611725578081fd5b81356113c681611a69565b600060208284031215611741578081fd5b81516113c681611a69565b6000806040838503121561175e578081fd5b823561176981611a69565b9150602083013561177981611a69565b809150509250929050565b600080600060608486031215611798578081fd5b83356117a381611a69565b95602085013595506040909401359392505050565b6000602082840312156117c9578081fd5b6113c682611704565b6000602082840312156117e3578081fd5b8151600481106113c6578182fd5b600060208284031215611802578081fd5b5051919050565b6000806040838503121561181b578182fd5b505080516020909101519092909150565b600080600060608486031215611840578283fd5b835192506020840151915061185760408501611704565b90509250925092565b80516001600160a01b031682526020808201519083015260408082015190830152606090810151910152565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6020808252825182820181905260009190848201906040850190845b818110156118fb5783516001600160a01b0316835292840192918401916001016118d6565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156118fb57611936838551611860565b9284019260809290920191600101611923565b90815260200190565b6020808252601c908201527f4c523a204e6f7420616e20656c696769626c6520636f6e747261637400000000604082015260600190565b6000604080830185845260208281860152818651808452606093508387019150828801865b82811015611a0357815180516001600160a01b031685528581015186860152878101518886015286810151878601526080808201519086015260a0908101519085015260c090930192908401906001016119ae565b50919998505050505050505050565b60006040820184835260206040818501528185518084526060860191508287019350845b81811015611a5c57611a49838651611860565b9383019360809290920191600101611a36565b5090979650505050505050565b6001600160a01b0381168114611a7e57600080fd5b5056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473a26469706673582212202b5010b12c55c1b7c6018dead398085e37a9d1487646f496a1f576b6f973f70f64736f6c63430007040033

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

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.