Contract 0x411a1c0130608be3aa97bc116ef183decb431fc3 1

Contract Overview

Balance:
0 DEV
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156aTake Debt Snapsh...22133192022-05-26 6:37:12492 days 23 hrs ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0xca74c5c14c66cc40a3e08d56d5273c9e34f4c4df8ff708e0cc8239d70c71b233Take Debt Snapsh...22132992022-05-26 6:32:06492 days 23 hrs ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x74e4881da673324b2f903dcbd9aa99f56412a02db162da24d56c4a9eba6978c3Take Debt Snapsh...22132822022-05-26 6:27:12492 days 23 hrs ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x4c2592ec0188e9692aec10639ddbd732cba0c4f042866af098d5adf8f36187c2Take Debt Snapsh...22132632022-05-26 6:22:06492 days 23 hrs ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x8c1a26627f08d0df586e973863e8fa2248563f7baccdd587619d6e2e53a898e4Take Debt Snapsh...22132452022-05-26 6:17:12492 days 23 hrs ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0xa649e85b6911cde4a213fd2aab252a63a56ff13dba2e4a9273ae7ad569ffac6eTake Debt Snapsh...22132292022-05-26 6:12:24492 days 23 hrs ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0xdfb77c66b0e83adc10eb963913a36d36e9a72a60393522f0a2cd95ca73ca58c4Take Debt Snapsh...22132082022-05-26 6:07:06492 days 23 hrs ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0xb304ce69ee9d36a63eabf70b8a1c143d08d06c0138ef0b5cea1f23b1857bfdb3Take Debt Snapsh...22131902022-05-26 6:02:12492 days 23 hrs ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x0d6abf42389f267b26952f3228ade66a71154414d1f7a5208efe7b4ee1c7821cTake Debt Snapsh...22131722022-05-26 5:57:12493 days ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x57314beb2cc5bc210263dab1e30b29605e4daad3774ec44a8be4bcd5b4707770Take Debt Snapsh...22131522022-05-26 5:52:12493 days 5 mins ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x32606963f9064f21ffe569cbb642638efa4c5f2dd1efff03ca7c516a3bed5eeeTake Debt Snapsh...22131312022-05-26 5:47:12493 days 10 mins ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x4b9131de4b4a8f68c307c871dd7bbb23fa5b84021943bd8654a212f7a15cf508Take Debt Snapsh...22131132022-05-26 5:42:18493 days 14 mins ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x90a885f0772fd7948e66242c2a929284f23de702537b4615f4ec4adcdebdd7bdTake Debt Snapsh...22130952022-05-26 5:37:06493 days 20 mins ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x0cee18737c5fcf76155e114fb868ba1d78b281c808fab60cd35da46c32412f6dTake Debt Snapsh...22130772022-05-26 5:32:06493 days 25 mins ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0xb5c315f077993cbd672999858894b5b97a458cdec5dc8637f1b4ff8d2fbfdab0Take Debt Snapsh...22130592022-05-26 5:27:12493 days 30 mins ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0xac7d2ab3d4eb39bad85fea0de42bd69735fbacada649c8d06b37589512ed1064Take Debt Snapsh...22130412022-05-26 5:22:24493 days 34 mins ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x9a00b8bf1fdc27adfb626cabab1d89c694a7f822300ddd44a8d52e3a6c993f50Take Debt Snapsh...22130252022-05-26 5:17:18493 days 39 mins ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0xabc435c503b37ac297bf14fe27a8d2f48b1c4e64fc0663f5c8f39e7422558c56Take Debt Snapsh...22130072022-05-26 5:12:12493 days 45 mins ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x6cc17c95e4524045cda45761d95c3e27946c0d2f2f670acc437a48f7dd6a0d72Take Debt Snapsh...22129882022-05-26 5:07:12493 days 50 mins ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0xbfd9144ea9cf56a105ed9674953ae126647603a7178aca71ff554f10f971c623Take Debt Snapsh...22129712022-05-26 5:02:12493 days 55 mins ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x28853a04ebf99795bf6445822bc02c76903b1a814d233a57411f37ed187ac14dTake Debt Snapsh...22129532022-05-26 4:57:12493 days 1 hr ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0xc2f1dd550eb75cb3a9e0ae37756b5b01190152e934b4dcfba60c0d92b860ec62Take Debt Snapsh...22129362022-05-26 4:52:06493 days 1 hr ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0xde7ec86e44111ff68f16ab1097ef34069cc5b5ff20dabdd2ed8846f9c8880fdeTake Debt Snapsh...22129162022-05-26 4:47:12493 days 1 hr ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x196cc82e9fc3627b97edddfd7794d5155d948858d2ac591d226d23269060c3b5Take Debt Snapsh...22128972022-05-26 4:42:12493 days 1 hr ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
0x2e43be6d3175e64df00eb61d3efc98bedb8a005fdfe13d88961935e3b89075a2Take Debt Snapsh...22128782022-05-26 4:37:06493 days 1 hr ago0x08a76fb0b5511b0a10dc4141c4dad6e2471803ba IN 0x411a1c0130608be3aa97bc116ef183decb431fc30 DEV0.00367432
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xf59c437b4c69b34609492a908ffa7434262a29550 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xf59c437b4c69b34609492a908ffa7434262a29550 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30x6444fd3939cf7436180d3f36863a4cd76af1f1cb0 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xf59c437b4c69b34609492a908ffa7434262a29550 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30x21d2dba3735f50c9322c82ff8c3f38795e935fff0 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xf59c437b4c69b34609492a908ffa7434262a29550 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30x535bfd64269f47a75b4726b6a1c7cf09e8067c820 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xf59c437b4c69b34609492a908ffa7434262a29550 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xcee9a9422805ad92f7f39363f134dcc8e521601d0 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30x5b1eac26c2c3f27a73cf435d8a55b1b0aa0d593e0 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xf59c437b4c69b34609492a908ffa7434262a29550 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30x83532ce06e71046ce9001f7d9d4d939ce71adf050 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xf59c437b4c69b34609492a908ffa7434262a29550 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30x0b4b942d18c2c21e5738bb63e9805b85dfd4a3a80 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30x6b8a35974584871eddfea2dad0870e5825829fa20 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xf59c437b4c69b34609492a908ffa7434262a29550 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30x042893d0f45bdb324cd8d77312db5d4f1c24e5280 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xc645e3b3e1d061f6a45325a1fe296012df790da90 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xb9b3e8aa83dc6cbd955b9bd798f38f8aeba848b60 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xc645e3b3e1d061f6a45325a1fe296012df790da90 DEV
0x4d527aeb37ba8146d173da42b952fa6288812430acd6f1748ccd63c1c1d9156a22133192022-05-26 6:37:12492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xba6adc87ca52588afa08471f4e2fec477563f9630 DEV
0xca74c5c14c66cc40a3e08d56d5273c9e34f4c4df8ff708e0cc8239d70c71b23322132992022-05-26 6:32:06492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xf59c437b4c69b34609492a908ffa7434262a29550 DEV
0xca74c5c14c66cc40a3e08d56d5273c9e34f4c4df8ff708e0cc8239d70c71b23322132992022-05-26 6:32:06492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xf59c437b4c69b34609492a908ffa7434262a29550 DEV
0xca74c5c14c66cc40a3e08d56d5273c9e34f4c4df8ff708e0cc8239d70c71b23322132992022-05-26 6:32:06492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30x6444fd3939cf7436180d3f36863a4cd76af1f1cb0 DEV
0xca74c5c14c66cc40a3e08d56d5273c9e34f4c4df8ff708e0cc8239d70c71b23322132992022-05-26 6:32:06492 days 23 hrs ago 0x411a1c0130608be3aa97bc116ef183decb431fc30xf59c437b4c69b34609492a908ffa7434262a29550 DEV
[ Download CSV Export 
Index Block
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DebtCache

Compiler Version
v0.5.16+commit.9c3226ce

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at moonbase.moonscan.io on 2022-01-11
*/

/*
    ___            _       ___  _                          
    | .\ ___  _ _ <_> ___ | __><_>._ _  ___ ._ _  ___  ___ 
    |  _// ._>| '_>| ||___|| _> | || ' |<_> || ' |/ | '/ ._>
    |_|  \___.|_|  |_|     |_|  |_||_|_|<___||_|_|\_|_.\___.
    
* PeriFinance: DebtCache.sol
*
* Latest source (may be newer): https://github.com/perifinance/peri-finance/blob/master/contracts/DebtCache.sol
* Docs: Will be added in the future. 
* https://docs.peri.finance/contracts/source/contracts/DebtCache
*
* Contract Dependencies: 
*	- BaseDebtCache
*	- IAddressResolver
*	- IDebtCache
*	- MixinResolver
*	- MixinSystemSettings
*	- Owned
* Libraries: 
*	- SafeDecimalMath
*	- SafeMath
*
* MIT License
* ===========
*
* Copyright (c) 2022 PeriFinance
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*/



pragma solidity 0.5.16;

// https://docs.peri.finance/contracts/source/contracts/owned
contract Owned {
    address public owner;
    address public nominatedOwner;

    constructor(address _owner) public {
        require(_owner != address(0), "Owner address cannot be 0");
        owner = _owner;
        emit OwnerChanged(address(0), _owner);
    }

    function nominateNewOwner(address _owner) external onlyOwner {
        nominatedOwner = _owner;
        emit OwnerNominated(_owner);
    }

    function acceptOwnership() external {
        require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership");
        emit OwnerChanged(owner, nominatedOwner);
        owner = nominatedOwner;
        nominatedOwner = address(0);
    }

    modifier onlyOwner {
        _onlyOwner();
        _;
    }

    function _onlyOwner() private view {
        require(msg.sender == owner, "Only the contract owner may perform this action");
    }

    event OwnerNominated(address newOwner);
    event OwnerChanged(address oldOwner, address newOwner);
}


// https://docs.peri.finance/contracts/source/interfaces/iaddressresolver
interface IAddressResolver {
    function getAddress(bytes32 name) external view returns (address);

    function getPynth(bytes32 key) external view returns (address);

    function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address);
}


// https://docs.peri.finance/contracts/source/interfaces/ipynth
interface IPynth {
    // Views
    function currencyKey() external view returns (bytes32);

    function transferablePynths(address account) external view returns (uint);

    // Mutative functions
    function transferAndSettle(address to, uint value) external returns (bool);

    function transferFromAndSettle(
        address from,
        address to,
        uint value
    ) external returns (bool);

    // Restricted: used internally to PeriFinance
    function burn(address account, uint amount) external;

    function issue(address account, uint amount) external;
}


// https://docs.peri.finance/contracts/source/interfaces/iissuer
interface IIssuer {
    // Views
    function anyPynthOrPERIRateIsInvalid() external view returns (bool anyRateInvalid);

    function availableCurrencyKeys() external view returns (bytes32[] memory);

    function availablePynthCount() external view returns (uint);

    function availablePynths(uint index) external view returns (IPynth);

    function canBurnPynths(address account) external view returns (bool);

    function collateral(address account) external view returns (uint);

    function collateralisationRatio(address issuer) external view returns (uint);

    function collateralisationRatioAndAnyRatesInvalid(address _issuer)
        external
        view
        returns (uint cratio, bool anyRateIsInvalid);

    function debtBalanceOf(address issuer, bytes32 currencyKey) external view returns (uint debtBalance);

    function lastIssueEvent(address account) external view returns (uint);

    function maxIssuablePynths(address issuer) external view returns (uint maxIssuable);

    function externalTokenQuota(
        address _account,
        uint _addtionalpUSD,
        uint _addtionalExToken,
        bool _isIssue
    ) external view returns (uint);

    function remainingIssuablePynths(address issuer)
        external
        view
        returns (
            uint maxIssuable,
            uint alreadyIssued,
            uint totalSystemDebt
        );

    function pynths(bytes32 currencyKey) external view returns (IPynth);

    function getPynths(bytes32[] calldata currencyKeys) external view returns (IPynth[] memory);

    function pynthsByAddress(address pynthAddress) external view returns (bytes32);

    function totalIssuedPynths(bytes32 currencyKey, bool excludeEtherCollateral) external view returns (uint, bool);

    function transferablePeriFinanceAndAnyRateIsInvalid(address account, uint balance)
        external
        view
        returns (uint transferable, bool anyRateIsInvalid);

    function amountsToFitClaimable(address _account) external view returns (uint burnAmount, uint exTokenAmountToUnstake);

    // Restricted: used internally to PeriFinance
    function issuePynths(
        address _issuer,
        bytes32 _currencyKey,
        uint _issueAmount
    ) external;

    function issueMaxPynths(address _issuer) external;

    function issuePynthsToMaxQuota(address _issuer, bytes32 _currencyKey) external;

    function burnPynths(
        address _from,
        bytes32 _currencyKey,
        uint _burnAmount
    ) external;

    function fitToClaimable(address _from) external;

    function exit(address _from) external;

    function liquidateDelinquentAccount(
        address account,
        uint pusdAmount,
        address liquidator
    ) external returns (uint totalRedeemed, uint amountToLiquidate);
}


// Inheritance


// Internal references


// https://docs.peri.finance/contracts/source/contracts/addressresolver
contract AddressResolver is Owned, IAddressResolver {
    mapping(bytes32 => address) public repository;

    constructor(address _owner) public Owned(_owner) {}

    /* ========== RESTRICTED FUNCTIONS ========== */

    function importAddresses(bytes32[] calldata names, address[] calldata destinations) external onlyOwner {
        require(names.length == destinations.length, "Input lengths must match");

        for (uint i = 0; i < names.length; i++) {
            bytes32 name = names[i];
            address destination = destinations[i];
            repository[name] = destination;
            emit AddressImported(name, destination);
        }
    }

    /* ========= PUBLIC FUNCTIONS ========== */

    function rebuildCaches(MixinResolver[] calldata destinations) external {
        for (uint i = 0; i < destinations.length; i++) {
            destinations[i].rebuildCache();
        }
    }

    /* ========== VIEWS ========== */

    function areAddressesImported(bytes32[] calldata names, address[] calldata destinations) external view returns (bool) {
        for (uint i = 0; i < names.length; i++) {
            if (repository[names[i]] != destinations[i]) {
                return false;
            }
        }
        return true;
    }

    function getAddress(bytes32 name) external view returns (address) {
        return repository[name];
    }

    function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address) {
        address _foundAddress = repository[name];
        require(_foundAddress != address(0), reason);
        return _foundAddress;
    }

    function getPynth(bytes32 key) external view returns (address) {
        IIssuer issuer = IIssuer(repository["Issuer"]);
        require(address(issuer) != address(0), "Cannot find Issuer address");
        return address(issuer.pynths(key));
    }

    /* ========== EVENTS ========== */

    event AddressImported(bytes32 name, address destination);
}


// solhint-disable payable-fallback

// https://docs.peri.finance/contracts/source/contracts/readproxy
contract ReadProxy is Owned {
    address public target;

    constructor(address _owner) public Owned(_owner) {}

    function setTarget(address _target) external onlyOwner {
        target = _target;
        emit TargetUpdated(target);
    }

    function() external {
        // The basics of a proxy read call
        // Note that msg.sender in the underlying will always be the address of this contract.
        assembly {
            calldatacopy(0, 0, calldatasize)

            // Use of staticcall - this will revert if the underlying function mutates state
            let result := staticcall(gas, sload(target_slot), 0, calldatasize, 0, 0)
            returndatacopy(0, 0, returndatasize)

            if iszero(result) {
                revert(0, returndatasize)
            }
            return(0, returndatasize)
        }
    }

    event TargetUpdated(address newTarget);
}


// Inheritance


// Internal references


// https://docs.peri.finance/contracts/source/contracts/mixinresolver
contract MixinResolver {
    AddressResolver public resolver;

    mapping(bytes32 => address) private addressCache;

    constructor(address _resolver) internal {
        resolver = AddressResolver(_resolver);
    }

    /* ========== INTERNAL FUNCTIONS ========== */

    function combineArrays(bytes32[] memory first, bytes32[] memory second)
        internal
        pure
        returns (bytes32[] memory combination)
    {
        combination = new bytes32[](first.length + second.length);

        for (uint i = 0; i < first.length; i++) {
            combination[i] = first[i];
        }

        for (uint j = 0; j < second.length; j++) {
            combination[first.length + j] = second[j];
        }
    }

    /* ========== PUBLIC FUNCTIONS ========== */

    // Note: this function is public not external in order for it to be overridden and invoked via super in subclasses
    function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {}

    function rebuildCache() public {
        bytes32[] memory requiredAddresses = resolverAddressesRequired();
        // The resolver must call this function whenver it updates its state
        for (uint i = 0; i < requiredAddresses.length; i++) {
            bytes32 name = requiredAddresses[i];
            // Note: can only be invoked once the resolver has all the targets needed added
            address destination =
                resolver.requireAndGetAddress(name, string(abi.encodePacked("Resolver missing target: ", name)));
            addressCache[name] = destination;
            emit CacheUpdated(name, destination);
        }
    }

    /* ========== VIEWS ========== */

    function isResolverCached() external view returns (bool) {
        bytes32[] memory requiredAddresses = resolverAddressesRequired();
        for (uint i = 0; i < requiredAddresses.length; i++) {
            bytes32 name = requiredAddresses[i];
            // false if our cache is invalid or if the resolver doesn't have the required address
            if (resolver.getAddress(name) != addressCache[name] || addressCache[name] == address(0)) {
                return false;
            }
        }

        return true;
    }

    /* ========== INTERNAL FUNCTIONS ========== */

    function requireAndGetAddress(bytes32 name) internal view returns (address) {
        address _foundAddress = addressCache[name];
        require(_foundAddress != address(0), string(abi.encodePacked("Missing address: ", name)));
        return _foundAddress;
    }

    /* ========== EVENTS ========== */

    event CacheUpdated(bytes32 name, address destination);
}


// https://docs.peri.finance/contracts/source/interfaces/iflexiblestorage
interface IFlexibleStorage {
    // Views
    function getUIntValue(bytes32 contractName, bytes32 record) external view returns (uint);

    function getUIntValues(bytes32 contractName, bytes32[] calldata records) external view returns (uint[] memory);

    function getIntValue(bytes32 contractName, bytes32 record) external view returns (int);

    function getIntValues(bytes32 contractName, bytes32[] calldata records) external view returns (int[] memory);

    function getAddressValue(bytes32 contractName, bytes32 record) external view returns (address);

    function getAddressValues(bytes32 contractName, bytes32[] calldata records) external view returns (address[] memory);

    function getBoolValue(bytes32 contractName, bytes32 record) external view returns (bool);

    function getBoolValues(bytes32 contractName, bytes32[] calldata records) external view returns (bool[] memory);

    function getBytes32Value(bytes32 contractName, bytes32 record) external view returns (bytes32);

    function getBytes32Values(bytes32 contractName, bytes32[] calldata records) external view returns (bytes32[] memory);

    // Mutative functions
    function deleteUIntValue(bytes32 contractName, bytes32 record) external;

    function deleteIntValue(bytes32 contractName, bytes32 record) external;

    function deleteAddressValue(bytes32 contractName, bytes32 record) external;

    function deleteBoolValue(bytes32 contractName, bytes32 record) external;

    function deleteBytes32Value(bytes32 contractName, bytes32 record) external;

    function setUIntValue(
        bytes32 contractName,
        bytes32 record,
        uint value
    ) external;

    function setUIntValues(
        bytes32 contractName,
        bytes32[] calldata records,
        uint[] calldata values
    ) external;

    function setIntValue(
        bytes32 contractName,
        bytes32 record,
        int value
    ) external;

    function setIntValues(
        bytes32 contractName,
        bytes32[] calldata records,
        int[] calldata values
    ) external;

    function setAddressValue(
        bytes32 contractName,
        bytes32 record,
        address value
    ) external;

    function setAddressValues(
        bytes32 contractName,
        bytes32[] calldata records,
        address[] calldata values
    ) external;

    function setBoolValue(
        bytes32 contractName,
        bytes32 record,
        bool value
    ) external;

    function setBoolValues(
        bytes32 contractName,
        bytes32[] calldata records,
        bool[] calldata values
    ) external;

    function setBytes32Value(
        bytes32 contractName,
        bytes32 record,
        bytes32 value
    ) external;

    function setBytes32Values(
        bytes32 contractName,
        bytes32[] calldata records,
        bytes32[] calldata values
    ) external;
}


// Internal references


// https://docs.peri.finance/contracts/source/contracts/mixinsystemsettings
contract MixinSystemSettings is MixinResolver {
    bytes32 internal constant SETTING_CONTRACT_NAME = "SystemSettings";

    bytes32 internal constant SETTING_WAITING_PERIOD_SECS = "waitingPeriodSecs";
    bytes32 internal constant SETTING_PRICE_DEVIATION_THRESHOLD_FACTOR = "priceDeviationThresholdFactor";
    bytes32 internal constant SETTING_ISSUANCE_RATIO = "issuanceRatio";
    bytes32 internal constant SETTING_FEE_PERIOD_DURATION = "feePeriodDuration";
    bytes32 internal constant SETTING_TARGET_THRESHOLD = "targetThreshold";
    bytes32 internal constant SETTING_LIQUIDATION_DELAY = "liquidationDelay";
    bytes32 internal constant SETTING_LIQUIDATION_RATIO = "liquidationRatio";
    bytes32 internal constant SETTING_LIQUIDATION_PENALTY = "liquidationPenalty";
    bytes32 internal constant SETTING_RATE_STALE_PERIOD = "rateStalePeriod";
    bytes32 internal constant SETTING_EXCHANGE_FEE_RATE = "exchangeFeeRate";
    bytes32 internal constant SETTING_MINIMUM_STAKE_TIME = "minimumStakeTime";
    bytes32 internal constant SETTING_AGGREGATOR_WARNING_FLAGS = "aggregatorWarningFlags";
    bytes32 internal constant SETTING_TRADING_REWARDS_ENABLED = "tradingRewardsEnabled";
    bytes32 internal constant SETTING_DEBT_SNAPSHOT_STALE_TIME = "debtSnapshotStaleTime";
    bytes32 internal constant SETTING_CROSS_DOMAIN_DEPOSIT_GAS_LIMIT = "crossDomainDepositGasLimit";
    bytes32 internal constant SETTING_CROSS_DOMAIN_ESCROW_GAS_LIMIT = "crossDomainEscrowGasLimit";
    bytes32 internal constant SETTING_CROSS_DOMAIN_REWARD_GAS_LIMIT = "crossDomainRewardGasLimit";
    bytes32 internal constant SETTING_CROSS_DOMAIN_WITHDRAWAL_GAS_LIMIT = "crossDomainWithdrawalGasLimit";
    bytes32 internal constant SETTING_EXTERNAL_TOKEN_QUOTA = "externalTokenQuota";
    bytes32 internal constant SETTING_BRIDGE_TRANSFER_GAS_COST = "bridgeTransferGasCost";
    bytes32 internal constant SETTING_BRIDGE_CLAIM_GAS_COST = "bridgeClaimGasCost";

    bytes32 internal constant CONTRACT_FLEXIBLESTORAGE = "FlexibleStorage";

    enum CrossDomainMessageGasLimits {Deposit, Escrow, Reward, Withdrawal}

    constructor(address _resolver) internal MixinResolver(_resolver) {}

    function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {
        addresses = new bytes32[](1);
        addresses[0] = CONTRACT_FLEXIBLESTORAGE;
    }

    function flexibleStorage() internal view returns (IFlexibleStorage) {
        return IFlexibleStorage(requireAndGetAddress(CONTRACT_FLEXIBLESTORAGE));
    }

    function _getGasLimitSetting(CrossDomainMessageGasLimits gasLimitType) internal pure returns (bytes32) {
        if (gasLimitType == CrossDomainMessageGasLimits.Deposit) {
            return SETTING_CROSS_DOMAIN_DEPOSIT_GAS_LIMIT;
        } else if (gasLimitType == CrossDomainMessageGasLimits.Escrow) {
            return SETTING_CROSS_DOMAIN_ESCROW_GAS_LIMIT;
        } else if (gasLimitType == CrossDomainMessageGasLimits.Reward) {
            return SETTING_CROSS_DOMAIN_REWARD_GAS_LIMIT;
        } else if (gasLimitType == CrossDomainMessageGasLimits.Withdrawal) {
            return SETTING_CROSS_DOMAIN_WITHDRAWAL_GAS_LIMIT;
        } else {
            revert("Unknown gas limit type");
        }
    }

    function getCrossDomainMessageGasLimit(CrossDomainMessageGasLimits gasLimitType) internal view returns (uint) {
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, _getGasLimitSetting(gasLimitType));
    }

    function getTradingRewardsEnabled() internal view returns (bool) {
        return flexibleStorage().getBoolValue(SETTING_CONTRACT_NAME, SETTING_TRADING_REWARDS_ENABLED);
    }

    function getWaitingPeriodSecs() internal view returns (uint) {
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_WAITING_PERIOD_SECS);
    }

    function getPriceDeviationThresholdFactor() internal view returns (uint) {
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_PRICE_DEVIATION_THRESHOLD_FACTOR);
    }

    function getIssuanceRatio() internal view returns (uint) {
        // lookup on flexible storage directly for gas savings (rather than via SystemSettings)
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ISSUANCE_RATIO);
    }

    function getFeePeriodDuration() internal view returns (uint) {
        // lookup on flexible storage directly for gas savings (rather than via SystemSettings)
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_FEE_PERIOD_DURATION);
    }

    function getTargetThreshold() internal view returns (uint) {
        // lookup on flexible storage directly for gas savings (rather than via SystemSettings)
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_TARGET_THRESHOLD);
    }

    function getLiquidationDelay() internal view returns (uint) {
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_DELAY);
    }

    function getLiquidationRatio() internal view returns (uint) {
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_RATIO);
    }

    function getLiquidationPenalty() internal view returns (uint) {
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_PENALTY);
    }

    function getRateStalePeriod() internal view returns (uint) {
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_RATE_STALE_PERIOD);
    }

    function getExchangeFeeRate(bytes32 currencyKey) internal view returns (uint) {
        return
            flexibleStorage().getUIntValue(
                SETTING_CONTRACT_NAME,
                keccak256(abi.encodePacked(SETTING_EXCHANGE_FEE_RATE, currencyKey))
            );
    }

    function getMinimumStakeTime() internal view returns (uint) {
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_MINIMUM_STAKE_TIME);
    }

    function getAggregatorWarningFlags() internal view returns (address) {
        return flexibleStorage().getAddressValue(SETTING_CONTRACT_NAME, SETTING_AGGREGATOR_WARNING_FLAGS);
    }

    function getDebtSnapshotStaleTime() internal view returns (uint) {
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_DEBT_SNAPSHOT_STALE_TIME);
    }

    function getExternalTokenQuota() internal view returns (uint) {
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_EXTERNAL_TOKEN_QUOTA);
    }

    function getBridgeTransferGasCost() internal view returns (uint) {
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_BRIDGE_TRANSFER_GAS_COST);
    }

    function getBridgeClaimGasCost() internal view returns (uint) {
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_BRIDGE_CLAIM_GAS_COST);
    }
}


interface IDebtCache {
    // Views

    function cachedDebt() external view returns (uint);

    function cachedPynthDebt(bytes32 currencyKey) external view returns (uint);

    function cacheTimestamp() external view returns (uint);

    function cacheInvalid() external view returns (bool);

    function cacheStale() external view returns (bool);

    function currentPynthDebts(bytes32[] calldata currencyKeys)
        external
        view
        returns (uint[] memory debtValues, bool anyRateIsInvalid);

    function cachedPynthDebts(bytes32[] calldata currencyKeys) external view returns (uint[] memory debtValues);

    function currentDebt() external view returns (uint debt, bool anyRateIsInvalid);

    function cacheInfo()
        external
        view
        returns (
            uint debt,
            uint timestamp,
            bool isInvalid,
            bool isStale
        );

    // Mutative functions

    function updateCachedPynthDebts(bytes32[] calldata currencyKeys) external;

    function updateCachedPynthDebtWithRate(bytes32 currencyKey, uint currencyRate) external;

    function updateCachedPynthDebtsWithRates(bytes32[] calldata currencyKeys, uint[] calldata currencyRates) external;

    function updateDebtCacheValidity(bool currentlyInvalid) external;

    function purgeCachedPynthDebt(bytes32 currencyKey) external;

    function takeDebtSnapshot() external;
}


/**
 * @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) {
        require(b <= a, "SafeMath: subtraction overflow");
        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-solidity/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) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, "SafeMath: division by zero");
        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) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}


// Libraries


// https://docs.peri.finance/contracts/source/libraries/safedecimalmath
library SafeDecimalMath {
    using SafeMath for uint;

    /* Number of decimal places in the representations. */
    uint8 public constant decimals = 18;
    uint8 public constant highPrecisionDecimals = 27;

    /* The number representing 1.0. */
    uint public constant UNIT = 10**uint(decimals);

    /* The number representing 1.0 for higher fidelity numbers. */
    uint public constant PRECISE_UNIT = 10**uint(highPrecisionDecimals);
    uint private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR = 10**uint(highPrecisionDecimals - decimals);

    /**
     * @return Provides an interface to UNIT.
     */
    function unit() external pure returns (uint) {
        return UNIT;
    }

    /**
     * @return Provides an interface to PRECISE_UNIT.
     */
    function preciseUnit() external pure returns (uint) {
        return PRECISE_UNIT;
    }

    /**
     * @return The result of multiplying x and y, interpreting the operands as fixed-point
     * decimals.
     *
     * @dev A unit factor is divided out after the product of x and y is evaluated,
     * so that product must be less than 2**256. As this is an integer division,
     * the internal division always rounds down. This helps save on gas. Rounding
     * is more expensive on gas.
     */
    function multiplyDecimal(uint x, uint y) internal pure returns (uint) {
        /* Divide by UNIT to remove the extra factor introduced by the product. */
        return x.mul(y) / UNIT;
    }

    /**
     * @return The result of safely multiplying x and y, interpreting the operands
     * as fixed-point decimals of the specified precision unit.
     *
     * @dev The operands should be in the form of a the specified unit factor which will be
     * divided out after the product of x and y is evaluated, so that product must be
     * less than 2**256.
     *
     * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
     * Rounding is useful when you need to retain fidelity for small decimal numbers
     * (eg. small fractions or percentages).
     */
    function _multiplyDecimalRound(
        uint x,
        uint y,
        uint precisionUnit
    ) private pure returns (uint) {
        /* Divide by UNIT to remove the extra factor introduced by the product. */
        uint quotientTimesTen = x.mul(y) / (precisionUnit / 10);

        if (quotientTimesTen % 10 >= 5) {
            quotientTimesTen += 10;
        }

        return quotientTimesTen / 10;
    }

    /**
     * @return The result of safely multiplying x and y, interpreting the operands
     * as fixed-point decimals of a precise unit.
     *
     * @dev The operands should be in the precise unit factor which will be
     * divided out after the product of x and y is evaluated, so that product must be
     * less than 2**256.
     *
     * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
     * Rounding is useful when you need to retain fidelity for small decimal numbers
     * (eg. small fractions or percentages).
     */
    function multiplyDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) {
        return _multiplyDecimalRound(x, y, PRECISE_UNIT);
    }

    /**
     * @return The result of safely multiplying x and y, interpreting the operands
     * as fixed-point decimals of a standard unit.
     *
     * @dev The operands should be in the standard unit factor which will be
     * divided out after the product of x and y is evaluated, so that product must be
     * less than 2**256.
     *
     * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
     * Rounding is useful when you need to retain fidelity for small decimal numbers
     * (eg. small fractions or percentages).
     */
    function multiplyDecimalRound(uint x, uint y) internal pure returns (uint) {
        return _multiplyDecimalRound(x, y, UNIT);
    }

    /**
     * @return The result of safely dividing x and y. The return value is a high
     * precision decimal.
     *
     * @dev y is divided after the product of x and the standard precision unit
     * is evaluated, so the product of x and UNIT must be less than 2**256. As
     * this is an integer division, the result is always rounded down.
     * This helps save on gas. Rounding is more expensive on gas.
     */
    function divideDecimal(uint x, uint y) internal pure returns (uint) {
        /* Reintroduce the UNIT factor that will be divided out by y. */
        return x.mul(UNIT).div(y);
    }

    /**
     * @return The result of safely dividing x and y. The return value is as a rounded
     * decimal in the precision unit specified in the parameter.
     *
     * @dev y is divided after the product of x and the specified precision unit
     * is evaluated, so the product of x and the specified precision unit must
     * be less than 2**256. The result is rounded to the nearest increment.
     */
    function _divideDecimalRound(
        uint x,
        uint y,
        uint precisionUnit
    ) private pure returns (uint) {
        uint resultTimesTen = x.mul(precisionUnit * 10).div(y);

        if (resultTimesTen % 10 >= 5) {
            resultTimesTen += 10;
        }

        return resultTimesTen / 10;
    }

    /**
     * @return The result of safely dividing x and y. The return value is as a rounded
     * standard precision decimal.
     *
     * @dev y is divided after the product of x and the standard precision unit
     * is evaluated, so the product of x and the standard precision unit must
     * be less than 2**256. The result is rounded to the nearest increment.
     */
    function divideDecimalRound(uint x, uint y) internal pure returns (uint) {
        return _divideDecimalRound(x, y, UNIT);
    }

    /**
     * @return The result of safely dividing x and y. The return value is as a rounded
     * high precision decimal.
     *
     * @dev y is divided after the product of x and the high precision unit
     * is evaluated, so the product of x and the high precision unit must
     * be less than 2**256. The result is rounded to the nearest increment.
     */
    function divideDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) {
        return _divideDecimalRound(x, y, PRECISE_UNIT);
    }

    /**
     * @dev Convert a standard decimal representation to a high precision one.
     */
    function decimalToPreciseDecimal(uint i) internal pure returns (uint) {
        return i.mul(UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR);
    }

    /**
     * @dev Convert a high precision decimal to a standard decimal representation.
     */
    function preciseDecimalToDecimal(uint i) internal pure returns (uint) {
        uint quotientTimesTen = i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10);

        if (quotientTimesTen % 10 >= 5) {
            quotientTimesTen += 10;
        }

        return quotientTimesTen / 10;
    }

    /**
     * @dev Round down the value with given number
     */
    function roundDownDecimal(uint x, uint d) internal pure returns (uint) {
        return x.div(10**d).mul(10**d);
    }

    /**
     * @dev Round up the value with given number
     */
    function roundUpDecimal(uint x, uint d) internal pure returns (uint) {
        uint _decimal = 10**d;

        if (x % _decimal > 0) {
            x = x.add(10**d);
        }

        return x.div(_decimal).mul(_decimal);
    }
}


interface IVirtualPynth {
    // Views
    function balanceOfUnderlying(address account) external view returns (uint);

    function rate() external view returns (uint);

    function readyToSettle() external view returns (bool);

    function secsLeftInWaitingPeriod() external view returns (uint);

    function settled() external view returns (bool);

    function pynth() external view returns (IPynth);

    // Mutative functions
    function settle(address account) external;
}


// https://docs.peri.finance/contracts/source/interfaces/iexchanger
interface IExchanger {
    // Views
    function calculateAmountAfterSettlement(
        address from,
        bytes32 currencyKey,
        uint amount,
        uint refunded
    ) external view returns (uint amountAfterSettlement);

    function isPynthRateInvalid(bytes32 currencyKey) external view returns (bool);

    function maxSecsLeftInWaitingPeriod(address account, bytes32 currencyKey) external view returns (uint);

    function settlementOwing(address account, bytes32 currencyKey)
        external
        view
        returns (
            uint reclaimAmount,
            uint rebateAmount,
            uint numEntries
        );

    function hasWaitingPeriodOrSettlementOwing(address account, bytes32 currencyKey) external view returns (bool);

    function feeRateForExchange(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey)
        external
        view
        returns (uint exchangeFeeRate);

    function getAmountsForExchange(
        uint sourceAmount,
        bytes32 sourceCurrencyKey,
        bytes32 destinationCurrencyKey
    )
        external
        view
        returns (
            uint amountReceived,
            uint fee,
            uint exchangeFeeRate
        );

    function priceDeviationThresholdFactor() external view returns (uint);

    function waitingPeriodSecs() external view returns (uint);

    // Mutative functions
    function exchange(
        address from,
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        address destinationAddress
    ) external returns (uint amountReceived);

    function exchangeOnBehalf(
        address exchangeForAddress,
        address from,
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey
    ) external returns (uint amountReceived);

    function exchangeWithTracking(
        address from,
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        address destinationAddress,
        address originator,
        bytes32 trackingCode
    ) external returns (uint amountReceived);

    function exchangeOnBehalfWithTracking(
        address exchangeForAddress,
        address from,
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        address originator,
        bytes32 trackingCode
    ) external returns (uint amountReceived);

    function exchangeWithVirtual(
        address from,
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        address destinationAddress,
        bytes32 trackingCode
    ) external returns (uint amountReceived, IVirtualPynth vPynth);

    function settle(address from, bytes32 currencyKey)
        external
        returns (
            uint reclaimed,
            uint refunded,
            uint numEntries
        );

    function setLastExchangeRateForPynth(bytes32 currencyKey, uint rate) external;

    function suspendPynthWithInvalidRate(bytes32 currencyKey) external;
}


// https://docs.peri.finance/contracts/source/interfaces/iexchangerates
interface IExchangeRates {
    // Structs
    struct RateAndUpdatedTime {
        uint216 rate;
        uint40 time;
    }

    struct InversePricing {
        uint entryPoint;
        uint upperLimit;
        uint lowerLimit;
        bool frozenAtUpperLimit;
        bool frozenAtLowerLimit;
    }

    // Views
    function aggregators(bytes32 currencyKey) external view returns (address);

    function aggregatorWarningFlags() external view returns (address);

    function anyRateIsInvalid(bytes32[] calldata currencyKeys) external view returns (bool);

    function canFreezeRate(bytes32 currencyKey) external view returns (bool);

    function currentRoundForRate(bytes32 currencyKey) external view returns (uint);

    function currenciesUsingAggregator(address aggregator) external view returns (bytes32[] memory);

    function effectiveValue(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey
    ) external view returns (uint value);

    function effectiveValueAndRates(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey
    )
        external
        view
        returns (
            uint value,
            uint sourceRate,
            uint destinationRate
        );

    function effectiveValueAtRound(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        uint roundIdForSrc,
        uint roundIdForDest
    ) external view returns (uint value);

    function getCurrentRoundId(bytes32 currencyKey) external view returns (uint);

    function getLastRoundIdBeforeElapsedSecs(
        bytes32 currencyKey,
        uint startingRoundId,
        uint startingTimestamp,
        uint timediff
    ) external view returns (uint);

    function inversePricing(bytes32 currencyKey)
        external
        view
        returns (
            uint entryPoint,
            uint upperLimit,
            uint lowerLimit,
            bool frozenAtUpperLimit,
            bool frozenAtLowerLimit
        );

    function lastRateUpdateTimes(bytes32 currencyKey) external view returns (uint256);

    function oracle() external view returns (address);

    function rateAndTimestampAtRound(bytes32 currencyKey, uint roundId) external view returns (uint rate, uint time);

    function rateAndUpdatedTime(bytes32 currencyKey) external view returns (uint rate, uint time);

    function rateAndInvalid(bytes32 currencyKey) external view returns (uint rate, bool isInvalid);

    function rateForCurrency(bytes32 currencyKey) external view returns (uint);

    function rateIsFlagged(bytes32 currencyKey) external view returns (bool);

    function rateIsFrozen(bytes32 currencyKey) external view returns (bool);

    function rateIsInvalid(bytes32 currencyKey) external view returns (bool);

    function rateIsStale(bytes32 currencyKey) external view returns (bool);

    function rateStalePeriod() external view returns (uint);

    function ratesAndUpdatedTimeForCurrencyLastNRounds(bytes32 currencyKey, uint numRounds)
        external
        view
        returns (uint[] memory rates, uint[] memory times);

    function ratesAndInvalidForCurrencies(bytes32[] calldata currencyKeys)
        external
        view
        returns (uint[] memory rates, bool anyRateInvalid);

    function ratesForCurrencies(bytes32[] calldata currencyKeys) external view returns (uint[] memory);

    // Mutative functions
    function freezeRate(bytes32 currencyKey) external;
}


// https://docs.peri.finance/contracts/source/interfaces/isystemstatus
interface ISystemStatus {
    struct Status {
        bool canSuspend;
        bool canResume;
    }

    struct Suspension {
        bool suspended;
        // reason is an integer code,
        // 0 => no reason, 1 => upgrading, 2+ => defined by system usage
        uint248 reason;
    }

    // Views
    function accessControl(bytes32 section, address account) external view returns (bool canSuspend, bool canResume);

    function requireSystemActive() external view;

    function requireIssuanceActive() external view;

    function requireExchangeActive() external view;

    function requireExchangeBetweenPynthsAllowed(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) external view;

    function requirePynthActive(bytes32 currencyKey) external view;

    function requirePynthsActive(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) external view;

    function systemSuspension() external view returns (bool suspended, uint248 reason);

    function issuanceSuspension() external view returns (bool suspended, uint248 reason);

    function exchangeSuspension() external view returns (bool suspended, uint248 reason);

    function pynthExchangeSuspension(bytes32 currencyKey) external view returns (bool suspended, uint248 reason);

    function pynthSuspension(bytes32 currencyKey) external view returns (bool suspended, uint248 reason);

    function getPynthExchangeSuspensions(bytes32[] calldata pynths)
        external
        view
        returns (bool[] memory exchangeSuspensions, uint256[] memory reasons);

    function getPynthSuspensions(bytes32[] calldata pynths)
        external
        view
        returns (bool[] memory suspensions, uint256[] memory reasons);

    // Restricted functions
    function suspendPynth(bytes32 currencyKey, uint256 reason) external;

    function updateAccessControl(
        bytes32 section,
        address account,
        bool canSuspend,
        bool canResume
    ) external;
}


// https://docs.peri.finance/contracts/source/interfaces/iethercollateral
interface IEtherCollateral {
    // Views
    function totalIssuedPynths() external view returns (uint256);

    function totalLoansCreated() external view returns (uint256);

    function totalOpenLoanCount() external view returns (uint256);

    // Mutative functions
    function openLoan() external payable returns (uint256 loanID);

    function closeLoan(uint256 loanID) external;

    function liquidateUnclosedLoan(address _loanCreatorsAddress, uint256 _loanID) external;
}


// https://docs.peri.finance/contracts/source/interfaces/iethercollateralsusd
interface IEtherCollateralpUSD {
    // Views
    function totalIssuedPynths() external view returns (uint256);

    function totalLoansCreated() external view returns (uint256);

    function totalOpenLoanCount() external view returns (uint256);

    // Mutative functions
    function openLoan(uint256 _loanAmount) external payable returns (uint256 loanID);

    function closeLoan(uint256 loanID) external;

    function liquidateUnclosedLoan(address _loanCreatorsAddress, uint256 _loanID) external;

    function depositCollateral(address account, uint256 loanID) external payable;

    function withdrawCollateral(uint256 loanID, uint256 withdrawAmount) external;

    function repayLoan(
        address _loanCreatorsAddress,
        uint256 _loanID,
        uint256 _repayAmount
    ) external;
}


// https://docs.peri.finance/contracts/source/interfaces/ierc20
interface IERC20 {
    // ERC20 Optional Views
    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);

    // Views
    function totalSupply() external view returns (uint);

    function balanceOf(address owner) external view returns (uint);

    function allowance(address owner, address spender) external view returns (uint);

    // Mutative functions
    function transfer(address to, uint value) external returns (bool);

    function approve(address spender, uint value) external returns (bool);

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

    // Events
    event Transfer(address indexed from, address indexed to, uint value);

    event Approval(address indexed owner, address indexed spender, uint value);
}


interface ICollateralManager {
    // Manager information
    function hasCollateral(address collateral) external view returns (bool);

    function isPynthManaged(bytes32 currencyKey) external view returns (bool);

    // State information
    function long(bytes32 pynth) external view returns (uint amount);

    function short(bytes32 pynth) external view returns (uint amount);

    function totalLong() external view returns (uint pusdValue, bool anyRateIsInvalid);

    function totalShort() external view returns (uint pusdValue, bool anyRateIsInvalid);

    function getBorrowRate() external view returns (uint borrowRate, bool anyRateIsInvalid);

    function getShortRate(bytes32 pynth) external view returns (uint shortRate, bool rateIsInvalid);

    function getRatesAndTime(uint index)
        external
        view
        returns (
            uint entryRate,
            uint lastRate,
            uint lastUpdated,
            uint newIndex
        );

    function getShortRatesAndTime(bytes32 currency, uint index)
        external
        view
        returns (
            uint entryRate,
            uint lastRate,
            uint lastUpdated,
            uint newIndex
        );

    function exceedsDebtLimit(uint amount, bytes32 currency) external view returns (bool canIssue, bool anyRateIsInvalid);

    function arePynthsAndCurrenciesSet(bytes32[] calldata requiredPynthNamesInResolver, bytes32[] calldata pynthKeys)
        external
        view
        returns (bool);

    function areShortablePynthsSet(bytes32[] calldata requiredPynthNamesInResolver, bytes32[] calldata pynthKeys)
        external
        view
        returns (bool);

    // Loans
    function getNewLoanId() external returns (uint id);

    // Manager mutative
    function addCollaterals(address[] calldata collaterals) external;

    function removeCollaterals(address[] calldata collaterals) external;

    function addPynths(bytes32[] calldata pynthNamesInResolver, bytes32[] calldata pynthKeys) external;

    function removePynths(bytes32[] calldata pynths, bytes32[] calldata pynthKeys) external;

    function addShortablePynths(bytes32[2][] calldata requiredPynthAndInverseNamesInResolver, bytes32[] calldata pynthKeys)
        external;

    function removeShortablePynths(bytes32[] calldata pynths) external;

    // State mutative
    function updateBorrowRates(uint rate) external;

    function updateShortRates(bytes32 currency, uint rate) external;

    function incrementLongs(bytes32 pynth, uint amount) external;

    function decrementLongs(bytes32 pynth, uint amount) external;

    function incrementShorts(bytes32 pynth, uint amount) external;

    function decrementShorts(bytes32 pynth, uint amount) external;
}


// Inheritance


// Libraries


// Internal references


// https://docs.peri.finance/contracts/source/contracts/debtcache
contract BaseDebtCache is Owned, MixinSystemSettings, IDebtCache {
    using SafeMath for uint;
    using SafeDecimalMath for uint;

    uint internal _cachedDebt;
    mapping(bytes32 => uint) internal _cachedPynthDebt;
    uint internal _cacheTimestamp;
    bool internal _cacheInvalid = true;

    /* ========== ENCODED NAMES ========== */

    bytes32 internal constant pUSD = "pUSD";
    bytes32 internal constant pETH = "pETH";

    /* ========== ADDRESS RESOLVER CONFIGURATION ========== */

    bytes32 private constant CONTRACT_ISSUER = "Issuer";
    bytes32 private constant CONTRACT_EXCHANGER = "Exchanger";
    bytes32 private constant CONTRACT_EXRATES = "ExchangeRates";
    bytes32 private constant CONTRACT_SYSTEMSTATUS = "SystemStatus";
    bytes32 private constant CONTRACT_ETHERCOLLATERAL = "EtherCollateral";
    bytes32 private constant CONTRACT_ETHERCOLLATERAL_PUSD = "EtherCollateralpUSD";
    bytes32 private constant CONTRACT_COLLATERALMANAGER = "CollateralManager";

    constructor(address _owner, address _resolver) public Owned(_owner) MixinSystemSettings(_resolver) {}

    /* ========== VIEWS ========== */

    function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {
        bytes32[] memory existingAddresses = MixinSystemSettings.resolverAddressesRequired();
        bytes32[] memory newAddresses = new bytes32[](7);
        newAddresses[0] = CONTRACT_ISSUER;
        newAddresses[1] = CONTRACT_EXCHANGER;
        newAddresses[2] = CONTRACT_EXRATES;
        newAddresses[3] = CONTRACT_SYSTEMSTATUS;
        newAddresses[4] = CONTRACT_ETHERCOLLATERAL;
        newAddresses[5] = CONTRACT_ETHERCOLLATERAL_PUSD;
        newAddresses[6] = CONTRACT_COLLATERALMANAGER;
        addresses = combineArrays(existingAddresses, newAddresses);
    }

    function issuer() internal view returns (IIssuer) {
        return IIssuer(requireAndGetAddress(CONTRACT_ISSUER));
    }

    function exchanger() internal view returns (IExchanger) {
        return IExchanger(requireAndGetAddress(CONTRACT_EXCHANGER));
    }

    function exchangeRates() internal view returns (IExchangeRates) {
        return IExchangeRates(requireAndGetAddress(CONTRACT_EXRATES));
    }

    function systemStatus() internal view returns (ISystemStatus) {
        return ISystemStatus(requireAndGetAddress(CONTRACT_SYSTEMSTATUS));
    }

    function etherCollateral() internal view returns (IEtherCollateral) {
        return IEtherCollateral(requireAndGetAddress(CONTRACT_ETHERCOLLATERAL));
    }

    function etherCollateralpUSD() internal view returns (IEtherCollateralpUSD) {
        return IEtherCollateralpUSD(requireAndGetAddress(CONTRACT_ETHERCOLLATERAL_PUSD));
    }

    function collateralManager() internal view returns (ICollateralManager) {
        return ICollateralManager(requireAndGetAddress(CONTRACT_COLLATERALMANAGER));
    }

    function debtSnapshotStaleTime() external view returns (uint) {
        return getDebtSnapshotStaleTime();
    }

    function cachedDebt() external view returns (uint) {
        return _cachedDebt;
    }

    function cachedPynthDebt(bytes32 currencyKey) external view returns (uint) {
        return _cachedPynthDebt[currencyKey];
    }

    function cacheTimestamp() external view returns (uint) {
        return _cacheTimestamp;
    }

    function cacheInvalid() external view returns (bool) {
        return _cacheInvalid;
    }

    function _cacheStale(uint timestamp) internal view returns (bool) {
        // Note a 0 timestamp means that the cache is uninitialised.
        // We'll keep the check explicitly in case the stale time is
        // ever set to something higher than the current unix time (e.g. to turn off staleness).
        return getDebtSnapshotStaleTime() < block.timestamp - timestamp || timestamp == 0;
    }

    function cacheStale() external view returns (bool) {
        return _cacheStale(_cacheTimestamp);
    }

    function _issuedPynthValues(bytes32[] memory currencyKeys, uint[] memory rates) internal view returns (uint[] memory) {
        uint numValues = currencyKeys.length;
        uint[] memory values = new uint[](numValues);
        IPynth[] memory pynths = issuer().getPynths(currencyKeys);

        for (uint i = 0; i < numValues; i++) {
            bytes32 key = currencyKeys[i];
            address pynthAddress = address(pynths[i]);
            require(pynthAddress != address(0), "Pynth does not exist");
            uint supply = IERC20(pynthAddress).totalSupply();

            if (collateralManager().isPynthManaged(key)) {
                uint collateralIssued = collateralManager().long(key);

                // this is an edge case --
                // if a pynth other than pUSD is only issued by non PERI collateral
                // the long value will exceed the supply if there was a minting fee,
                // so we check explicitly and 0 it out to prevent
                // a safesub overflow.

                if (collateralIssued > supply) {
                    supply = 0;
                } else {
                    supply = supply.sub(collateralIssued);
                }
            }

            bool ispUSD = key == pUSD;
            if (ispUSD || key == pETH) {
                IEtherCollateral etherCollateralContract =
                    ispUSD ? IEtherCollateral(address(etherCollateralpUSD())) : etherCollateral();
                uint etherCollateralSupply = etherCollateralContract.totalIssuedPynths();
                supply = supply.sub(etherCollateralSupply);
            }

            values[i] = supply.multiplyDecimalRound(rates[i]);
        }
        return values;
    }

    function _currentPynthDebts(bytes32[] memory currencyKeys)
        internal
        view
        returns (uint[] memory periIssuedDebts, bool anyRateIsInvalid)
    {
        (uint[] memory rates, bool isInvalid) = exchangeRates().ratesAndInvalidForCurrencies(currencyKeys);
        return (_issuedPynthValues(currencyKeys, rates), isInvalid);
    }

    function currentPynthDebts(bytes32[] calldata currencyKeys)
        external
        view
        returns (uint[] memory debtValues, bool anyRateIsInvalid)
    {
        return _currentPynthDebts(currencyKeys);
    }

    function _cachedPynthDebts(bytes32[] memory currencyKeys) internal view returns (uint[] memory) {
        uint numKeys = currencyKeys.length;
        uint[] memory debts = new uint[](numKeys);
        for (uint i = 0; i < numKeys; i++) {
            debts[i] = _cachedPynthDebt[currencyKeys[i]];
        }
        return debts;
    }

    function cachedPynthDebts(bytes32[] calldata currencyKeys) external view returns (uint[] memory periIssuedDebts) {
        return _cachedPynthDebts(currencyKeys);
    }

    function _currentDebt() internal view returns (uint debt, bool anyRateIsInvalid) {
        (uint[] memory values, bool isInvalid) = _currentPynthDebts(issuer().availableCurrencyKeys());
        uint numValues = values.length;
        uint total;
        for (uint i; i < numValues; i++) {
            total = total.add(values[i]);
        }

        // subtract the USD value of all shorts.
        (uint pusdValue, bool shortInvalid) = collateralManager().totalShort();

        total = total.sub(pusdValue);

        isInvalid = isInvalid || shortInvalid;

        return (total, isInvalid);
    }

    function currentDebt() external view returns (uint debt, bool anyRateIsInvalid) {
        return _currentDebt();
    }

    function cacheInfo()
        external
        view
        returns (
            uint debt,
            uint timestamp,
            bool isInvalid,
            bool isStale
        )
    {
        uint time = _cacheTimestamp;
        return (_cachedDebt, time, _cacheInvalid, _cacheStale(time));
    }

    /* ========== MUTATIVE FUNCTIONS ========== */

    // Stub out all mutative functions as no-ops;
    // since they do nothing, there are no restrictions

    function updateCachedPynthDebts(bytes32[] calldata currencyKeys) external {}

    function updateCachedPynthDebtWithRate(bytes32 currencyKey, uint currencyRate) external {}

    function updateCachedPynthDebtsWithRates(bytes32[] calldata currencyKeys, uint[] calldata currencyRates) external {}

    function updateDebtCacheValidity(bool currentlyInvalid) external {}

    function purgeCachedPynthDebt(bytes32 currencyKey) external {}

    function takeDebtSnapshot() external {}

    /* ========== MODIFIERS ========== */

    function _requireSystemActiveIfNotOwner() internal view {
        if (msg.sender != owner) {
            systemStatus().requireSystemActive();
        }
    }

    modifier requireSystemActiveIfNotOwner() {
        _requireSystemActiveIfNotOwner();
        _;
    }

    function _onlyIssuerOrExchangerorPynthpUSD() internal view {
        IPynth pynthpUSD = issuer().pynths(pUSD);
        require(
            msg.sender == address(issuer()) || msg.sender == address(exchanger()) || msg.sender == address(pynthpUSD),
            "Sender is not Issuer or Exchanger or pynthpUSD"
        );
    }

    modifier onlyIssuerOrExchangerOrPynthpUSD() {
        _onlyIssuerOrExchangerorPynthpUSD();
        _;
    }
}


// Inheritance


// https://docs.peri.finance/contracts/source/contracts/debtcache
contract DebtCache is BaseDebtCache {
    constructor(address _owner, address _resolver) public BaseDebtCache(_owner, _resolver) {}

    /* ========== MUTATIVE FUNCTIONS ========== */

    // This function exists in case a pynth is ever somehow removed without its snapshot being updated.
    function purgeCachedPynthDebt(bytes32 currencyKey) external onlyOwner {
        require(issuer().pynths(currencyKey) == IPynth(0), "Pynth exists");
        delete _cachedPynthDebt[currencyKey];
    }

    function takeDebtSnapshot() external requireSystemActiveIfNotOwner {
        bytes32[] memory currencyKeys = issuer().availableCurrencyKeys();
        (uint[] memory values, bool isInvalid) = _currentPynthDebts(currencyKeys);

        // Subtract the USD value of all shorts.
        (uint shortValue, ) = collateralManager().totalShort();

        uint numValues = values.length;
        uint periCollateralDebt;
        for (uint i; i < numValues; i++) {
            uint value = values[i];

            periCollateralDebt = periCollateralDebt.add(value);
            _cachedPynthDebt[currencyKeys[i]] = value;
        }

        _cachedDebt = periCollateralDebt.sub(shortValue);
        _cacheTimestamp = block.timestamp;
        emit DebtCacheUpdated(periCollateralDebt);
        emit DebtCacheSnapshotTaken(block.timestamp);

        // (in)validate the cache if necessary
        _updateDebtCacheValidity(isInvalid);
    }

    function updateCachedPynthDebts(bytes32[] calldata currencyKeys) external requireSystemActiveIfNotOwner {
        (uint[] memory rates, bool anyRateInvalid) = exchangeRates().ratesAndInvalidForCurrencies(currencyKeys);
        _updateCachedPynthDebtsWithRates(currencyKeys, rates, anyRateInvalid);
    }

    function updateCachedPynthDebtWithRate(bytes32 currencyKey, uint currencyRate)
        external
        onlyIssuerOrExchangerOrPynthpUSD
    {
        bytes32[] memory pynthKeyArray = new bytes32[](1);
        pynthKeyArray[0] = currencyKey;
        uint[] memory pynthRateArray = new uint[](1);
        pynthRateArray[0] = currencyRate;
        _updateCachedPynthDebtsWithRates(pynthKeyArray, pynthRateArray, false);
    }

    function updateCachedPynthDebtsWithRates(bytes32[] calldata currencyKeys, uint[] calldata currencyRates)
        external
        onlyIssuerOrExchangerOrPynthpUSD
    {
        _updateCachedPynthDebtsWithRates(currencyKeys, currencyRates, false);
    }

    function updateDebtCacheValidity(bool currentlyInvalid) external onlyIssuerOrExchangerOrPynthpUSD {
        _updateDebtCacheValidity(currentlyInvalid);
    }

    /* ========== INTERNAL FUNCTIONS ========== */

    function _updateDebtCacheValidity(bool currentlyInvalid) internal {
        if (_cacheInvalid != currentlyInvalid) {
            _cacheInvalid = currentlyInvalid;
            emit DebtCacheValidityChanged(currentlyInvalid);
        }
    }

    function _updateCachedPynthDebtsWithRates(
        bytes32[] memory currencyKeys,
        uint[] memory currentRates,
        bool anyRateIsInvalid
    ) internal {
        uint numKeys = currencyKeys.length;
        require(numKeys == currentRates.length, "Input array lengths differ");

        // Update the cached values for each pynth, saving the sums as we go.
        uint cachedSum;
        uint currentSum;
        uint[] memory currentValues = _issuedPynthValues(currencyKeys, currentRates);
        for (uint i = 0; i < numKeys; i++) {
            bytes32 key = currencyKeys[i];
            uint currentPynthDebt = currentValues[i];
            cachedSum = cachedSum.add(_cachedPynthDebt[key]);
            currentSum = currentSum.add(currentPynthDebt);
            _cachedPynthDebt[key] = currentPynthDebt;
        }

        // Compute the difference and apply it to the snapshot
        if (cachedSum != currentSum) {
            uint debt = _cachedDebt;
            // This requirement should never fail, as the total debt snapshot is the sum of the individual pynth
            // debt snapshots.
            require(cachedSum <= debt, "Cached pynth sum exceeds total debt");
            debt = debt.sub(cachedSum).add(currentSum);
            _cachedDebt = debt;
            emit DebtCacheUpdated(debt);
        }

        // A partial update can invalidate the debt cache, but a full snapshot must be performed in order
        // to re-validate it.
        if (anyRateIsInvalid) {
            _updateDebtCacheValidity(anyRateIsInvalid);
        }
    }

    /* ========== EVENTS ========== */

    event DebtCacheUpdated(uint cachedDebt);
    event DebtCacheSnapshotTaken(uint timestamp);
    event DebtCacheValidityChanged(bool indexed isInvalid);
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_resolver","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"name","type":"bytes32"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"CacheUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"DebtCacheSnapshotTaken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cachedDebt","type":"uint256"}],"name":"DebtCacheUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"isInvalid","type":"bool"}],"name":"DebtCacheValidityChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cacheInfo","outputs":[{"internalType":"uint256","name":"debt","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bool","name":"isInvalid","type":"bool"},{"internalType":"bool","name":"isStale","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cacheInvalid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cacheStale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cacheTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cachedDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"}],"name":"cachedPynthDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32[]","name":"currencyKeys","type":"bytes32[]"}],"name":"cachedPynthDebts","outputs":[{"internalType":"uint256[]","name":"periIssuedDebts","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentDebt","outputs":[{"internalType":"uint256","name":"debt","type":"uint256"},{"internalType":"bool","name":"anyRateIsInvalid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32[]","name":"currencyKeys","type":"bytes32[]"}],"name":"currentPynthDebts","outputs":[{"internalType":"uint256[]","name":"debtValues","type":"uint256[]"},{"internalType":"bool","name":"anyRateIsInvalid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"debtSnapshotStaleTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isResolverCached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"}],"name":"purgeCachedPynthDebt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"rebuildCache","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"resolver","outputs":[{"internalType":"contract AddressResolver","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"resolverAddressesRequired","outputs":[{"internalType":"bytes32[]","name":"addresses","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"takeDebtSnapshot","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"},{"internalType":"uint256","name":"currencyRate","type":"uint256"}],"name":"updateCachedPynthDebtWithRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32[]","name":"currencyKeys","type":"bytes32[]"}],"name":"updateCachedPynthDebts","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32[]","name":"currencyKeys","type":"bytes32[]"},{"internalType":"uint256[]","name":"currencyRates","type":"uint256[]"}],"name":"updateCachedPynthDebtsWithRates","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"currentlyInvalid","type":"bool"}],"name":"updateDebtCacheValidity","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

60806040526007805460ff1916600117905534801561001d57600080fd5b5060405161261e38038061261e8339818101604052604081101561004057600080fd5b50805160209091015181818080836001600160a01b0381166100a9576040805162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b038316908117825560408051928352602083019190915280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a150600280546001600160a01b039092166001600160a01b031990921691909117905550505050506124e7806101376000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c80638da5cb5b116100c3578063dae3de981161007c578063dae3de98146103dd578063e3476cd41461044b578063f7cc999f14610453578063fa9f18d314610470578063fc524773146104de578063fca28f74146104e657610158565b80638da5cb5b146102e25780639f98fb49146102ea578063a5f27edb146103a8578063af5355d8146103b0578063d0fffafd146103b8578063d6576c84146103c057610158565b806353a47bb71161011557806353a47bb71461022e5780637418536014610236578063759076e51461023e57806379ba50971461025f5780638376a78214610267578063899ffef41461028a57610158565b806304bd11e51461015d57806304f3bcec1461017e57806305393262146101a25780631627540c146101bc5780632af64bd3146101e25780633a900a2e146101fe575b600080fd5b61017c6004803603602081101561017357600080fd5b503515156105b3565b005b6101866105c7565b604080516001600160a01b039092168252519081900360200190f35b6101aa6105d6565b60408051918252519081900360200190f35b61017c600480360360208110156101d257600080fd5b50356001600160a01b03166105dd565b6101ea610639565b604080519115158252519081900360200190f35b610206610743565b6040805194855260208501939093529015158383015215156060830152519081900360800190f35b610186610774565b61017c610783565b61024661094b565b6040805192835290151560208301528051918290030190f35b61017c61095e565b61017c6004803603604081101561027d57600080fd5b5080359060200135610a1a565b610292610aad565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156102ce5781810151838201526020016102b6565b505050509050019250505060405180910390f35b610186610c17565b61017c6004803603604081101561030057600080fd5b810190602081018135600160201b81111561031a57600080fd5b82018360208201111561032c57600080fd5b803590602001918460208302840111600160201b8311171561034d57600080fd5b919390929091602081019035600160201b81111561036a57600080fd5b82018360208201111561037c57600080fd5b803590602001918460208302840111600160201b8311171561039d57600080fd5b509092509050610c26565b6101ea610c9b565b6101aa610ca4565b6101aa610cb3565b61017c600480360360208110156103d657600080fd5b5035610cb9565b610292600480360360208110156103f357600080fd5b810190602081018135600160201b81111561040d57600080fd5b82018360208201111561041f57600080fd5b803590602001918460208302840111600160201b8311171561044057600080fd5b509092509050610d95565b61017c610ddc565b6101aa6004803603602081101561046957600080fd5b503561106f565b61017c6004803603602081101561048657600080fd5b810190602081018135600160201b8111156104a057600080fd5b8201836020820111156104b257600080fd5b803590602001918460208302840111600160201b831117156104d357600080fd5b509092509050611081565b6101ea611216565b610554600480360360208110156104fc57600080fd5b810190602081018135600160201b81111561051657600080fd5b82018360208201111561052857600080fd5b803590602001918460208302840111600160201b8311171561054957600080fd5b509092509050611223565b604051808060200183151515158152602001828103825284818151815260200191508051906020019060200280838360005b8381101561059e578181015183820152602001610586565b50505050905001935050505060405180910390f35b6105bb61126e565b6105c48161137d565b50565b6002546001600160a01b031681565b6004545b90565b6105e56113ca565b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229181900360200190a150565b60006060610645610aad565b905060005b815181101561073a57600082828151811061066157fe5b6020908102919091018101516000818152600383526040908190205460025482516321f8a72160e01b81526004810185905292519395506001600160a01b03918216949116926321f8a721926024808201939291829003018186803b1580156106c957600080fd5b505afa1580156106dd573d6000803e3d6000fd5b505050506040513d60208110156106f357600080fd5b50516001600160a01b031614158061072057506000818152600360205260409020546001600160a01b0316155b1561073157600093505050506105da565b5060010161064a565b50600191505090565b6006546004546007546000928392839283929190829060ff1661076582611415565b94509450945094505090919293565b6001546001600160a01b031681565b606061078d610aad565b905060005b81518110156109475760008282815181106107a957fe5b602090810291909101810151600254604080517f5265736f6c766572206d697373696e67207461726765743a2000000000000000818601526039808201859052825180830390910181526059820180845263dacb2d0160e01b9052605d8201858152607d83019384528151609d84015281519597506000966001600160a01b039095169563dacb2d01958995939492939260bd0191908501908083838c5b8381101561085f578181015183820152602001610847565b50505050905090810190601f16801561088c5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b1580156108aa57600080fd5b505afa1580156108be573d6000803e3d6000fd5b505050506040513d60208110156108d457600080fd5b505160008381526003602090815260409182902080546001600160a01b0319166001600160a01b03851690811790915582518681529182015281519293507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68929081900390910190a15050600101610792565b5050565b60008061095661142e565b915091509091565b6001546001600160a01b031633146109a75760405162461bcd60e51b81526004018080602001828103825260358152602001806124006035913960400191505060405180910390fd5b600054600154604080516001600160a01b03938416815292909116602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b610a2261126e565b604080516001808252818301909252606091602080830190803883390190505090508281600081518110610a5257fe5b60209081029190910101526040805160018082528183019092526060918160200160208202803883390190505090508281600081518110610a8f57fe5b602002602001018181525050610aa78282600061162c565b50505050565b606080610ab86117e1565b6040805160078082526101008201909252919250606091906020820160e0803883390190505090506524b9b9bab2b960d11b81600081518110610af757fe5b6020026020010181815250506822bc31b430b733b2b960b91b81600181518110610b1d57fe5b6020026020010181815250506c45786368616e6765526174657360981b81600281518110610b4757fe5b6020026020010181815250506b53797374656d53746174757360a01b81600381518110610b7057fe5b6020026020010181815250506e115d1a195c90dbdb1b185d195c985b608a1b81600481518110610b9c57fe5b60200260200101818152505072115d1a195c90dbdb1b185d195c985b1c1554d1606a1b81600581518110610bcc57fe5b6020026020010181815250507021b7b63630ba32b930b626b0b730b3b2b960791b81600681518110610bfa57fe5b602002602001018181525050610c108282611832565b9250505090565b6000546001600160a01b031681565b610c2e61126e565b610aa7848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284376000920182905250925061162c915050565b60075460ff1690565b6000610cae6118ee565b905090565b60065490565b610cc16113ca565b6000610ccb61199d565b6001600160a01b03166357ad4663836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610d0e57600080fd5b505afa158015610d22573d6000803e3d6000fd5b505050506040513d6020811015610d3857600080fd5b50516001600160a01b031614610d84576040805162461bcd60e51b815260206004820152600c60248201526b50796e74682065786973747360a01b604482015290519081900360640190fd5b600090815260056020526040812055565b6060610dd38383808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506119b192505050565b90505b92915050565b610de4611a41565b6060610dee61199d565b6001600160a01b03166372cb051f6040518163ffffffff1660e01b815260040160006040518083038186803b158015610e2657600080fd5b505afa158015610e3a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610e6357600080fd5b8101908080516040519392919084600160201b821115610e8257600080fd5b908301906020820185811115610e9757600080fd5b82518660208202830111600160201b82111715610eb357600080fd5b82525081516020918201928201910280838360005b83811015610ee0578181015183820152602001610ec8565b50505050905001604052505050905060606000610efc83611aa7565b915091506000610f0a611c20565b6001600160a01b031663ad79a8586040518163ffffffff1660e01b8152600401604080518083038186803b158015610f4157600080fd5b505afa158015610f55573d6000803e3d6000fd5b505050506040513d6040811015610f6b57600080fd5b505183519091506000805b82811015610fe0576000868281518110610f8c57fe5b60200260200101519050610fa98184611c3f90919063ffffffff16565b925080600560008a8581518110610fbc57fe5b60209081029190910181015182528101919091526040016000205550600101610f76565b50610ff1818463ffffffff611c9916565b600455426006556040805182815290517f294a7c394e53042c7d754779562747d93b41db019dd4b970dd9b531db71be5999181900360200190a16040805142815290517fc481e742c89630d4b1a5ed3a0fc624c1c41ed463bd00ac26a7e93c71e932126f9181900360200190a16110678461137d565b505050505050565b60009081526005602052604090205490565b611089611a41565b60606000611095611cf6565b6001600160a01b031663c8e5bbd585856040518363ffffffff1660e01b815260040180806020018281038252848482818152602001925060200280828437600081840152601f19601f820116905080830192505050935050505060006040518083038186803b15801561110757600080fd5b505afa15801561111b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604090815281101561114457600080fd5b8101908080516040519392919084600160201b82111561116357600080fd5b90830190602082018581111561117857600080fd5b82518660208202830111600160201b8211171561119457600080fd5b82525081516020918201928201910280838360005b838110156111c15781810151838201526020016111a9565b505050509190910160408181526020938401518a850280840186019092528a8352969850959650610aa795909450899350889283925085019084908082843760009201919091525086925085915061162c9050565b6000610cae600654611415565b60606000611263848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611aa792505050565b915091509250929050565b600061127861199d565b6001600160a01b03166357ad4663631c1554d160e21b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156112c257600080fd5b505afa1580156112d6573d6000803e3d6000fd5b505050506040513d60208110156112ec57600080fd5b505190506112f861199d565b6001600160a01b0316336001600160a01b0316148061132f575061131a611d11565b6001600160a01b0316336001600160a01b0316145b806113425750336001600160a01b038216145b6105c45760405162461bcd60e51b815260040180806020018281038252602e815260200180612485602e913960400191505060405180910390fd5b60075460ff161515811515146105c4576007805460ff19168215159081179091556040517f8eebec690c34bbf0fe0d5b93e442beaf16bdaf99052569581de2dcb3e31a53a790600090a250565b6000546001600160a01b031633146114135760405162461bcd60e51b815260040180806020018281038252602f815260200180612435602f913960400191505060405180910390fd5b565b60008142036114226118ee565b1080610dd65750501590565b6000806060600061154461144061199d565b6001600160a01b03166372cb051f6040518163ffffffff1660e01b815260040160006040518083038186803b15801561147857600080fd5b505afa15801561148c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156114b557600080fd5b8101908080516040519392919084600160201b8211156114d457600080fd5b9083019060208201858111156114e957600080fd5b82518660208202830111600160201b8211171561150557600080fd5b82525081516020918201928201910280838360005b8381101561153257818101518382015260200161151a565b50505050905001604052505050611aa7565b815191935091506000805b828110156115875761157d85828151811061156657fe5b602002602001015183611c3f90919063ffffffff16565b915060010161154f565b50600080611593611c20565b6001600160a01b031663ad79a8586040518163ffffffff1660e01b8152600401604080518083038186803b1580156115ca57600080fd5b505afa1580156115de573d6000803e3d6000fd5b505050506040513d60408110156115f457600080fd5b5080516020909101519092509050611612838363ffffffff611c9916565b9250848061161d5750805b92975091955050505050509091565b825182518114611683576040805162461bcd60e51b815260206004820152601a60248201527f496e707574206172726179206c656e6774687320646966666572000000000000604482015290519081900360640190fd5b60008060606116928787611d28565b905060005b848110156117215760008882815181106116ad57fe5b6020026020010151905060008383815181106116c557fe5b602002602001015190506116f5600560008481526020019081526020016000205487611c3f90919063ffffffff16565b9550611707858263ffffffff611c3f16565b600092835260056020526040909220559250600101611697565b508183146117c9576004548084111561176b5760405162461bcd60e51b81526004018080602001828103825260238152602001806123dd6023913960400191505060405180910390fd5b61178b8361177f838763ffffffff611c9916565b9063ffffffff611c3f16565b60048190556040805182815290519192507f294a7c394e53042c7d754779562747d93b41db019dd4b970dd9b531db71be599919081900360200190a1505b84156117d8576117d88561137d565b50505050505050565b604080516001808252818301909252606091602080830190803883390190505090506e466c657869626c6553746f7261676560881b8160008151811061182357fe5b60200260200101818152505090565b60608151835101604051908082528060200260200182016040528015611862578160200160208202803883390190505b50905060005b83518110156118a45783818151811061187d57fe5b602002602001015182828151811061189157fe5b6020908102919091010152600101611868565b5060005b82518110156118e7578281815181106118bd57fe5b60200260200101518282865101815181106118d457fe5b60209081029190910101526001016118a8565b5092915050565b60006118f86121eb565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b7464656274536e617073686f745374616c6554696d6560581b6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801561196c57600080fd5b505afa158015611980573d6000803e3d6000fd5b505050506040513d602081101561199657600080fd5b5051905090565b6000610cae6524b9b9bab2b960d11b612204565b60606000825190506060816040519080825280602002602001820160405280156119e5578160200160208202803883390190505b50905060005b82811015611a395760056000868381518110611a0357fe5b6020026020010151815260200190815260200160002054828281518110611a2657fe5b60209081029190910101526001016119eb565b509392505050565b6000546001600160a01b0316331461141357611a5b6122e1565b6001600160a01b031663086dabd16040518163ffffffff1660e01b815260040160006040518083038186803b158015611a9357600080fd5b505afa158015610aa7573d6000803e3d6000fd5b6060600060606000611ab7611cf6565b6001600160a01b031663c8e5bbd5866040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b83811015611b15578181015183820152602001611afd565b505050509050019250505060006040518083038186803b158015611b3857600080fd5b505afa158015611b4c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040908152811015611b7557600080fd5b8101908080516040519392919084600160201b821115611b9457600080fd5b908301906020820185811115611ba957600080fd5b82518660208202830111600160201b82111715611bc557600080fd5b82525081516020918201928201910280838360005b83811015611bf2578181015183820152602001611bda565b50505050919091016040525060200151929450919250611c16915086905083611d28565b9350915050915091565b6000610cae7021b7b63630ba32b930b626b0b730b3b2b960791b612204565b600082820183811015610dd3576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082821115611cf0576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000610cae6c45786368616e6765526174657360981b612204565b6000610cae6822bc31b430b733b2b960b91b612204565b6060600083519050606081604051908082528060200260200182016040528015611d5c578160200160208202803883390190505b5090506060611d6961199d565b6001600160a01b0316631db63a33876040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b83811015611dc7578181015183820152602001611daf565b505050509050019250505060006040518083038186803b158015611dea57600080fd5b505afa158015611dfe573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611e2757600080fd5b8101908080516040519392919084600160201b821115611e4657600080fd5b908301906020820185811115611e5b57600080fd5b82518660208202830111600160201b82111715611e7757600080fd5b82525081516020918201928201910280838360005b83811015611ea4578181015183820152602001611e8c565b50505050905001604052505050905060008090505b838110156121e0576000878281518110611ecf57fe5b602002602001015190506000838381518110611ee757fe5b6020026020010151905060006001600160a01b0316816001600160a01b03161415611f50576040805162461bcd60e51b8152602060048201526014602482015273141e5b9d1a08191bd95cc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b6000816001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f8b57600080fd5b505afa158015611f9f573d6000803e3d6000fd5b505050506040513d6020811015611fb557600080fd5b50519050611fc1611c20565b6001600160a01b03166342e32f13846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561200457600080fd5b505afa158015612018573d6000803e3d6000fd5b505050506040513d602081101561202e57600080fd5b5051156120d657600061203f611c20565b6001600160a01b031663d2f00475856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561208257600080fd5b505afa158015612096573d6000803e3d6000fd5b505050506040513d60208110156120ac57600080fd5b50519050818111156120c157600091506120d4565b6120d1828263ffffffff611c9916565b91505b505b631c1554d160e21b831480806120f25750630e08aa8960e31b84145b156121935760008161210b576121066122fb565b612113565b612113612318565b90506000816001600160a01b03166357b219206040518163ffffffff1660e01b815260040160206040518083038186803b15801561215057600080fd5b505afa158015612164573d6000803e3d6000fd5b505050506040513d602081101561217a57600080fd5b5051905061218e848263ffffffff611c9916565b935050505b6121b98a86815181106121a257fe5b60200260200101518361233990919063ffffffff16565b8786815181106121c557fe5b6020908102919091010152505060019092019150611eb99050565b509095945050505050565b6000610cae6e466c657869626c6553746f7261676560881b5b600081815260036020908152604080832054815170026b4b9b9b4b7339030b2323932b9b99d1607d1b9381019390935260318084018690528251808503909101815260519093019091526001600160a01b031690816118e75760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156122a657818101518382015260200161228e565b50505050905090810190601f1680156122d35780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6000610cae6b53797374656d53746174757360a01b612204565b6000610cae6e115d1a195c90dbdb1b185d195c985b608a1b612204565b6000610cae72115d1a195c90dbdb1b185d195c985b1c1554d1606a1b612204565b6000610dd38383670de0b6b3a7640000848067016345785d8a000061235e8686612383565b8161236557fe5b0490506005600a82061061237757600a015b600a9004949350505050565b60008261239257506000610dd6565b8282028284828161239f57fe5b0414610dd35760405162461bcd60e51b81526004018080602001828103825260218152602001806124646021913960400191505060405180910390fdfe4361636865642070796e74682073756d206578636565647320746f74616c2064656274596f75206d757374206265206e6f6d696e61746564206265666f726520796f752063616e20616363657074206f776e6572736869704f6e6c792074686520636f6e7472616374206f776e6572206d617920706572666f726d207468697320616374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7753656e646572206973206e6f7420497373756572206f722045786368616e676572206f722070796e746870555344a265627a7a723158201255a1e8b8b81586db1e0d227fdf2a31ece8463f93252df7378453a2857bf43264736f6c63430005100032000000000000000000000000166220468aff631290b7e1ddff7f45b052de832400000000000000000000000022f5d16097cf2396d6c893a77ea3b97234c0c114

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

000000000000000000000000166220468aff631290b7e1ddff7f45b052de832400000000000000000000000022f5d16097cf2396d6c893a77ea3b97234c0c114

-----Decoded View---------------
Arg [0] : _owner (address): 0x166220468aff631290b7e1ddff7f45b052de8324
Arg [1] : _resolver (address): 0x22f5d16097cf2396d6c893a77ea3b97234c0c114

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000166220468aff631290b7e1ddff7f45b052de8324
Arg [1] : 00000000000000000000000022f5d16097cf2396d6c893a77ea3b97234c0c114


Deployed ByteCode Sourcemap

60426:4772:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60426:4772:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62913:159;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62913:159:0;;;;:::i;:::-;;10269:31;;;:::i;:::-;;;;-1:-1:-1;;;;;10269:31:0;;;;;;;;;;;;;;53973:88;;;:::i;:::-;;;;;;;;;;;;;;;;2211:141;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;2211:141:0;-1:-1:-1;;;;;2211:141:0;;:::i;11964:537::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;58572:313;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1980:29;;;:::i;11258:657::-;;;:::i;58444:120::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;2360:271;;;:::i;62208:432::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62208:432:0;;;;;;;:::i;52073:669::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;52073:669:0;;;;;;;;;;;;;;;;;1953:20;;;:::i;62648:257::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;62648:257:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;62648:257:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;62648:257:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;62648:257:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;62648:257:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;62648:257:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;62648:257:0;;-1:-1:-1;62648:257:0;-1:-1:-1;62648:257:0;:::i;54311:92::-;;;:::i;53851:114::-;;;:::i;54207:96::-;;;:::i;60725:202::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60725:202:0;;:::i;57643:170::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;57643:170:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;57643:170:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;57643:170:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;57643:170:0;;-1:-1:-1;57643:170:0;-1:-1:-1;57643:170:0;:::i;60935:951::-;;;:::i;54069:130::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54069:130:0;;:::i;61894:306::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;61894:306:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;61894:306:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;61894:306:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;61894:306:0;;-1:-1:-1;61894:306:0;-1:-1:-1;61894:306:0;:::i;54823:105::-;;;:::i;57065:222::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;57065:222:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;57065:222:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;57065:222:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;57065:222:0;;-1:-1:-1;57065:222:0;-1:-1:-1;57065:222:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;57065:222:0;;;;;;;;;;;;;;;;;;62913:159;60275:35;:33;:35::i;:::-;63022:42;63047:16;63022:24;:42::i;:::-;62913:159;:::o;10269:31::-;;;-1:-1:-1;;;;;10269:31:0;;:::o;53973:88::-;54042:11;;53973:88;;:::o;2211:141::-;2669:12;:10;:12::i;:::-;2283:14;:23;;-1:-1:-1;;;;;2283:23:0;;-1:-1:-1;;;;;;2283:23:0;;;;;;;;2322:22;;;;;;;;;;;;;;;;2211:141;:::o;11964:537::-;12015:4;12032:34;12069:27;:25;:27::i;:::-;12032:64;-1:-1:-1;12112:6:0;12107:363;12128:17;:24;12124:1;:28;12107:363;;;12174:12;12189:17;12207:1;12189:20;;;;;;;;;;;;;;;;;;;12356:18;;;;:12;:18;;;;;;;;12327:8;;:25;;-1:-1:-1;;;12327:25:0;;;;;;;;;;12189:20;;-1:-1:-1;;;;;;12356:18:0;;;;12327:8;;;:19;;:25;;;;;12189:20;12327:25;;;;;;:8;:25;;;5:2:-1;;;;30:1;27;20:12;5:2;12327:25:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;12327:25:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12327:25:0;-1:-1:-1;;;;;12327:47:0;;;;:83;;-1:-1:-1;12408:1:0;12378:18;;;:12;:18;;;;;;-1:-1:-1;;;;;12378:18:0;:32;12327:83;12323:136;;;12438:5;12431:12;;;;;;;12323:136;-1:-1:-1;12154:3:0;;12107:363;;;;12489:4;12482:11;;;11964:537;:::o;58572:313::-;58791:15;;58825:11;;58844:13;;58657:9;;;;;;;;58791:15;58825:11;58791:15;;58844:13;;58859:17;58791:15;58859:11;:17::i;:::-;58817:60;;;;;;;;;58572:313;;;;:::o;1980:29::-;;;-1:-1:-1;;;;;1980:29:0;;:::o;11258:657::-;11300:34;11337:27;:25;:27::i;:::-;11300:64;-1:-1:-1;11458:6:0;11453:455;11474:17;:24;11470:1;:28;11453:455;;;11520:12;11535:17;11553:1;11535:20;;;;;;;;;;;;;;;;;;;11702:8;;11745:51;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;11745:51:0;;;;;;-1:-1:-1;;;11702:96:0;;;;;;;;;;;;;;;;;;;;;;11535:20;;-1:-1:-1;11663:19:0;;-1:-1:-1;;;;;11702:8:0;;;;:29;;11535:20;;11745:51;;11702:96;;;;;;;;;;;;;11663:19;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;11702:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11702:96:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;11702:96:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11702:96:0;11813:18;;;;:12;11702:96;11813:18;;;;;;;;:32;;-1:-1:-1;;;;;;11813:32:0;-1:-1:-1;;;;;11813:32:0;;;;;;;;11865:31;;;;;;;;;;;11702:96;;-1:-1:-1;11865:31:0;;;;;;;;;;;-1:-1:-1;;11500:3:0;;11453:455;;;;11258:657;:::o;58444:120::-;58490:9;58501:21;58542:14;:12;:14::i;:::-;58535:21;;;;58444:120;;:::o;2360:271::-;2429:14;;-1:-1:-1;;;;;2429:14:0;2415:10;:28;2407:94;;;;-1:-1:-1;;;2407:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2530:5;;;2537:14;2517:35;;;-1:-1:-1;;;;;2530:5:0;;;2517:35;;2537:14;;;;2517:35;;;;;;;;;;;;;;;;2571:14;;;;2563:22;;-1:-1:-1;;;;;;2563:22:0;;;-1:-1:-1;;;;;2571:14:0;;2563:22;;;;2596:27;;;2360:271::o;62208:432::-;60275:35;:33;:35::i;:::-;62396:16;;;62410:1;62396:16;;;;;;;;;62363:30;;62396:16;;;;;;105:10:-1;62396:16:0;88:34:-1;136:17;;-1:-1;62396:16:0;62363:49;;62442:11;62423:13;62437:1;62423:16;;;;;;;;;;;;;;;;;:30;62495:13;;;62506:1;62495:13;;;;;;;;;62464:28;;62495:13;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;62495:13:0;62464:44;;62539:12;62519:14;62534:1;62519:17;;;;;;;;;;;;;:32;;;;;62562:70;62595:13;62610:14;62626:5;62562:32;:70::i;:::-;60321:1;;62208:432;;:::o;52073:669::-;52131:26;52170:34;52207:47;:45;:47::i;:::-;52297:16;;;52311:1;52297:16;;;;;;;;;52170:84;;-1:-1:-1;52265:29:0;;52297:16;;;;17:15:-1;;105:10;52297:16:0;88:34:-1;136:17;;-1:-1;52297:16:0;52265:48;;-1:-1:-1;;;52324:12:0;52337:1;52324:15;;;;;;;;;;;;;:33;;;;;-1:-1:-1;;;52368:12:0;52381:1;52368:15;;;;;;;;;;;;;:36;;;;;-1:-1:-1;;;52415:12:0;52428:1;52415:15;;;;;;;;;;;;;:34;;;;;-1:-1:-1;;;52460:12:0;52473:1;52460:15;;;;;;;;;;;;;:39;;;;;-1:-1:-1;;;52510:12:0;52523:1;52510:15;;;;;;;;;;;;;:42;;;;;-1:-1:-1;;;52563:12:0;52576:1;52563:15;;;;;;;;;;;;;:47;;;;;-1:-1:-1;;;52621:12:0;52634:1;52621:15;;;;;;;;;;;;;:44;;;;;52688:46;52702:17;52721:12;52688:13;:46::i;:::-;52676:58;;52073:669;;;:::o;1953:20::-;;;-1:-1:-1;;;;;1953:20:0;;:::o;62648:257::-;60275:35;:33;:35::i;:::-;62829:68;62862:12;;62829:68;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;62829:68:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62876:13:0;;-1:-1:-1;62876:13:0;;;;62829:68;;;62876:13;;62829:68;62876:13;62829:68;1:33:-1;99:1;81:16;;74:27;;;-1:-1;99:1;-1:-1;62829:32:0;;-1:-1:-1;;62829:68:0:i;54311:92::-;54382:13;;;;54311:92;:::o;53851:114::-;53907:4;53931:26;:24;:26::i;:::-;53924:33;;53851:114;:::o;54207:96::-;54280:15;;54207:96;:::o;60725:202::-;2669:12;:10;:12::i;:::-;60853:1;60814:8;:6;:8::i;:::-;-1:-1:-1;;;;;60814:15:0;;60830:11;60814:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60814:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60814:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60814:28:0;-1:-1:-1;;;;;60814:41:0;;60806:66;;;;;-1:-1:-1;;;60806:66:0;;;;;;;;;;;;-1:-1:-1;;;60806:66:0;;;;;;;;;;;;;;;60890:29;;;;:16;:29;;;;;60883:36;60725:202::o;57643:170::-;57725:29;57774:31;57792:12;;57774:31;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;57774:17:0;;-1:-1:-1;;;57774:31:0:i;:::-;57767:38;;57643:170;;;;;:::o;60935:951::-;59822:32;:30;:32::i;:::-;61013:29;61045:8;:6;:8::i;:::-;-1:-1:-1;;;;;61045:30:0;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61045:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61045:32:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;61045:32:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;61045:32:0;;;;;;;;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;-1:-1;;;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;373:25;;-1:-1;61045:32:0;;421:4:-1;412:14;;;;61045:32:0;;;;;412:14:-1;61045:32:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;61045:32:0;;;;;;;;;;;61013:64;;61089:20;61111:14;61129:32;61148:12;61129:18;:32::i;:::-;61088:73;;;;61225:15;61246:19;:17;:19::i;:::-;-1:-1:-1;;;;;61246:30:0;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61246:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61246:32:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;61246:32:0;61308:13;;61246:32;;-1:-1:-1;61291:14:0;;61366:205;61383:9;61379:1;:13;61366:205;;;61414:10;61427:6;61434:1;61427:9;;;;;;;;;;;;;;61414:22;;61474:29;61497:5;61474:18;:22;;:29;;;;:::i;:::-;61453:50;;61554:5;61518:16;:33;61535:12;61548:1;61535:15;;;;;;;;;;;;;;;;;;;61518:33;;;;;;;;;;-1:-1:-1;61518:33:0;:41;-1:-1:-1;61394:3:0;;61366:205;;;-1:-1:-1;61597:34:0;:18;61620:10;61597:34;:22;:34;:::i;:::-;61583:11;:48;61660:15;61642;:33;61691:36;;;;;;;;;;;;;;;;;61743:39;;;61766:15;61743:39;;;;;;;;;;;;;61843:35;61868:9;61843:24;:35::i;:::-;59865:1;;;;;;60935:951::o;54069:130::-;54138:4;54162:29;;;:16;:29;;;;;;;54069:130::o;61894:306::-;59822:32;:30;:32::i;:::-;62010:19;62031;62054:15;:13;:15::i;:::-;-1:-1:-1;;;;;62054:44:0;;62099:12;;62054:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;62054:58:0;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62054:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62054:58:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;62054:58:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;;;5:11;;2:2;;;29:1;26;19:12;2:2;62054:58:0;;;;;;;;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;-1:-1;;;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;373:25;;-1:-1;62054:58:0;;421:4:-1;412:14;;;;62054:58:0;;;;;412:14:-1;62054:58:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;-1:-1;;;;62054:58:0;;;;;;;;;;;;;62123:69;;;;;;;;;;;;;;62009:103;;-1:-1:-1;62054:58:0;;-1:-1:-1;62123:69:0;;62054:58;;-1:-1:-1;62156:12:0;;-1:-1:-1;62156:12:0;;;;-1:-1:-1;62123:69:0;;;62156:12;;62123:69;62156:12;62123:69;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;62170:5:0;;-1:-1:-1;62177:14:0;;-1:-1:-1;62123:32:0;;-1:-1:-1;62123:69:0:i;54823:105::-;54868:4;54892:28;54904:15;;54892:11;:28::i;57065:222::-;57175:24;57201:21;57247:32;57266:12;;57247:32;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;57247:18:0;;-1:-1:-1;;;57247:32:0:i;:::-;57240:39;;;;57065:222;;;;;:::o;59882:330::-;59952:16;59971:8;:6;:8::i;:::-;-1:-1:-1;;;;;59971:15:0;;-1:-1:-1;;;59971:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59971:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59971:21:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59971:21:0;;-1:-1:-1;60047:8:0;:6;:8::i;:::-;-1:-1:-1;;;;;60025:31:0;:10;-1:-1:-1;;;;;60025:31:0;;:69;;;;60082:11;:9;:11::i;:::-;-1:-1:-1;;;;;60060:34:0;:10;-1:-1:-1;;;;;60060:34:0;;60025:69;:105;;;-1:-1:-1;60098:10:0;-1:-1:-1;;;;;60098:32:0;;;60025:105;60003:201;;;;-1:-1:-1;;;60003:201:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63134:244;63215:13;;;;:33;;;;;;63211:160;;63265:13;:32;;-1:-1:-1;;63265:32:0;;;;;;;;;;63317:42;;;;-1:-1:-1;;63317:42:0;63134:244;:::o;2709:133::-;2777:5;;-1:-1:-1;;;;;2777:5:0;2763:10;:19;2755:79;;;;-1:-1:-1;;;2755:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2709:133::o;54411:404::-;54471:4;54780:9;54762:15;:27;54733:26;:24;:26::i;:::-;:56;:74;;;-1:-1:-1;;54793:14:0;;54411:404::o;57821:615::-;57868:9;57879:21;57914:20;57936:14;57954:52;57973:8;:6;:8::i;:::-;-1:-1:-1;;;;;57973:30:0;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57973:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57973:32:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;57973:32:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;57973:32:0;;;;;;;;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;-1:-1;;;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;373:25;;-1:-1;57973:32:0;;421:4:-1;412:14;;;;57973:32:0;;;;;412:14:-1;57973:32:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;57973:32:0;;;;;;;;;;;57954:18;:52::i;:::-;58034:13;;57913:93;;-1:-1:-1;57913:93:0;-1:-1:-1;58017:14:0;;58079:88;58096:9;58092:1;:13;58079:88;;;58135:20;58145:6;58152:1;58145:9;;;;;;;;;;;;;;58135:5;:9;;:20;;;;:::i;:::-;58127:28;-1:-1:-1;58107:3:0;;58079:88;;;;58230:14;58246:17;58267:19;:17;:19::i;:::-;-1:-1:-1;;;;;58267:30:0;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58267:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58267:32:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58267:32:0;;;;;;;;;-1:-1:-1;58267:32:0;-1:-1:-1;58320:20:0;:5;58267:32;58320:20;:9;:20;:::i;:::-;58312:28;;58365:9;:25;;;;58378:12;58365:25;58411:5;;-1:-1:-1;58353:37:0;;-1:-1:-1;;;;;;57821:615:0;;:::o;63386:1607::-;63579:19;;63628;;63617:30;;63609:69;;;;;-1:-1:-1;;;63609:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;63770:14;63795:15;63821:27;63851:46;63870:12;63884;63851:18;:46::i;:::-;63821:76;-1:-1:-1;63913:6:0;63908:324;63929:7;63925:1;:11;63908:324;;;63958:11;63972:12;63985:1;63972:15;;;;;;;;;;;;;;63958:29;;64002:21;64026:13;64040:1;64026:16;;;;;;;;;;;;;;64002:40;;64069:36;64083:16;:21;64100:3;64083:21;;;;;;;;;;;;64069:9;:13;;:36;;;;:::i;:::-;64057:48;-1:-1:-1;64133:32:0;:10;64148:16;64133:32;:14;:32;:::i;:::-;64180:21;;;;:16;:21;;;;;;:40;64120:45;-1:-1:-1;63938:3:0;;63908:324;;;;64325:10;64312:9;:23;64308:437;;64364:11;;64544:17;;;;64536:65;;;;-1:-1:-1;;;64536:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64623:35;64647:10;64623:19;:4;64632:9;64623:19;:8;:19;:::i;:::-;:23;:35;:23;:35;:::i;:::-;64673:11;:18;;;64711:22;;;;;;;;64616:42;;-1:-1:-1;64711:22:0;;;;;;;;;;64308:437;;64899:16;64895:91;;;64932:42;64957:16;64932:24;:42::i;:::-;63386:1607;;;;;;;:::o;18283:183::-;18392:16;;;18406:1;18392:16;;;;;;;;;18341:26;;18392:16;;;;;;105:10:-1;18392:16:0;88:34:-1;136:17;;-1:-1;18392:16:0;18380:28;;-1:-1:-1;;;18419:9:0;18429:1;18419:12;;;;;;;;;;;;;:39;;;;;18283:183;:::o;10524:458::-;10646:28;10735:6;:13;10720:5;:12;:28;10706:43;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;10706:43:0;-1:-1:-1;10692:57:0;-1:-1:-1;10767:6:0;10762:92;10783:5;:12;10779:1;:16;10762:92;;;10834:5;10840:1;10834:8;;;;;;;;;;;;;;10817:11;10829:1;10817:14;;;;;;;;;;;;;;;;;:25;10797:3;;10762:92;;;-1:-1:-1;10871:6:0;10866:109;10887:6;:13;10883:1;:17;10866:109;;;10954:6;10961:1;10954:9;;;;;;;;;;;;;;10922:11;10949:1;10934:5;:12;:16;10922:29;;;;;;;;;;;;;;;;;:41;10902:3;;10866:109;;;;10524:458;;;;:::o;22337:178::-;22396:4;22420:17;:15;:17::i;:::-;-1:-1:-1;;;;;22420:30:0;;-1:-1:-1;;;;;;22420:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22420:87:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22420:87:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22420:87:0;;-1:-1:-1;22337:178:0;:::o;52750:122::-;52791:7;52826:37;-1:-1:-1;;;52826:20:0;:37::i;57295:340::-;57376:13;57402:12;57417;:19;57402:34;;57447:19;57480:7;57469:19;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;57469:19:0;-1:-1:-1;57447:41:0;-1:-1:-1;57504:6:0;57499:106;57520:7;57516:1;:11;57499:106;;;57560:16;:33;57577:12;57590:1;57577:15;;;;;;;;;;;;;;57560:33;;;;;;;;;;;;57549:5;57555:1;57549:8;;;;;;;;;;;;;;;;;:44;57529:3;;57499:106;;;-1:-1:-1;57622:5:0;57295:340;-1:-1:-1;;;57295:340:0:o;59600:162::-;59685:5;;-1:-1:-1;;;;;59685:5:0;59671:10;:19;59667:88;;59707:14;:12;:14::i;:::-;-1:-1:-1;;;;;59707:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59707:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;56702:355:0;56811:29;56842:21;56882:19;56903:14;56921:15;:13;:15::i;:::-;-1:-1:-1;;;;;56921:44:0;;56966:12;56921:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;56921:58:0;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56921:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56921:58:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;56921:58:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;;;5:11;;2:2;;;29:1;26;19:12;2:2;56921:58:0;;;;;;;;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;-1:-1;;;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;373:25;;-1:-1;56921:58:0;;421:4:-1;412:14;;;;56921:58:0;;;;;412:14:-1;56921:58:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;-1:-1;;;;56921:58:0;;;;;;-1:-1:-1;56921:58:0;;;56881:98;;-1:-1:-1;56921:58:0;;-1:-1:-1;56998:39:0;;-1:-1:-1;57017:12:0;;-1:-1:-1;56881:98:0;56998:18;:39::i;:::-;56990:59;-1:-1:-1;57039:9:0;-1:-1:-1;;56702:355:0;;;:::o;53677:166::-;53729:18;53786:48;-1:-1:-1;;;53786:20:0;:48::i;25356:181::-;25414:7;25446:5;;;25470:6;;;;25462:46;;;;;-1:-1:-1;;;25462:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;25812:184;25870:7;25903:1;25898;:6;;25890:49;;;;;-1:-1:-1;;;25890:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25962:5:0;;;25812:184::o;53022:144::-;53070:14;53119:38;-1:-1:-1;;;53119:20:0;:38::i;52880:134::-;52924:10;52965:40;-1:-1:-1;;;52965:20:0;:40::i;54936:1758::-;55039:13;55065:14;55082:12;:19;55065:36;;55112:20;55146:9;55135:21;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;55135:21:0;;55112:44;;55167:22;55192:8;:6;:8::i;:::-;-1:-1:-1;;;;;55192:18:0;;55211:12;55192:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;55192:32:0;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55192:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55192:32:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;55192:32:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;55192:32:0;;;;;;;;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;-1:-1;;;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;373:25;;-1:-1;55192:32:0;;421:4:-1;412:14;;;;55192:32:0;;;;;412:14:-1;55192:32:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;55192:32:0;;;;;;;;;;;55167:57;;55242:6;55251:1;55242:10;;55237:1426;55258:9;55254:1;:13;55237:1426;;;55289:11;55303:12;55316:1;55303:15;;;;;;;;;;;;;;55289:29;;55333:20;55364:6;55371:1;55364:9;;;;;;;;;;;;;;55333:41;;55421:1;-1:-1:-1;;;;;55397:26:0;:12;-1:-1:-1;;;;;55397:26:0;;;55389:59;;;;;-1:-1:-1;;;55389:59:0;;;;;;;;;;;;-1:-1:-1;;;55389:59:0;;;;;;;;;;;;;;;55463:11;55484:12;-1:-1:-1;;;;;55477:32:0;;:34;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55477:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55477:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55477:34:0;;-1:-1:-1;55532:19:0;:17;:19::i;:::-;-1:-1:-1;;;;;55532:34:0;;55567:3;55532:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55532:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55532:39:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55532:39:0;55528:647;;;55592:21;55616:19;:17;:19::i;:::-;-1:-1:-1;;;;;55616:24:0;;55641:3;55616:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55616:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55616:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55616:29:0;;-1:-1:-1;55994:25:0;;;55990:170;;;56053:1;56044:10;;55990:170;;;56112:28;:6;56123:16;56112:28;:10;:28;:::i;:::-;56103:37;;55990:170;55528:647;;-1:-1:-1;;;56205:11:0;;;;56235:21;;;-1:-1:-1;;;56245:3:0;:11;56235:21;56231:355;;;56277:40;56341:6;:77;;56401:17;:15;:17::i;:::-;56341:77;;;56375:21;:19;:21::i;:::-;56277:141;;56437:26;56466:23;-1:-1:-1;;;;;56466:41:0;;:43;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56466:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56466:43:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56466:43:0;;-1:-1:-1;56537:33:0;:6;56466:43;56537:33;:10;:33;:::i;:::-;56528:42;;56231:355;;;56614:37;56642:5;56648:1;56642:8;;;;;;;;;;;;;;56614:6;:27;;:37;;;;:::i;:::-;56602:6;56609:1;56602:9;;;;;;;;;;;;;;;;;:49;-1:-1:-1;;55269:3:0;;;;;-1:-1:-1;55237:1426:0;;-1:-1:-1;55237:1426:0;;-1:-1:-1;56680:6:0;;54936:1758;-1:-1:-1;;;;;54936:1758:0:o;18474:158::-;18524:16;18577:46;-1:-1:-1;;;12563:268:0;12630:7;12674:18;;;:12;:18;;;;;;;;;12747:43;;-1:-1:-1;;;12747:43:0;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;12747:43:0;;;;;;;-1:-1:-1;;;;;12674:18:0;;12711:27;12703:89;;;;-1:-1:-1;;;12703:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;12703:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53174:146;53221:13;53268:43;-1:-1:-1;;;53268:20:0;:43::i;53328:158::-;53378:16;53431:46;-1:-1:-1;;;53431:20:0;:46::i;53494:175::-;53548:20;53609:51;-1:-1:-1;;;53609:20:0;:51::i;32105:134::-;32174:4;32198:33;32220:1;32223;28517:18;32174:4;;30615:18;30603:8;32220:1;32223;30603:5;:8::i;:::-;:31;;;;;;;-1:-1:-1;30676:1:0;30670:2;30603:31;30651:21;:26;30647:81;;30714:2;30694:22;30647:81;30766:2;30747:21;;;;-1:-1:-1;;;;30355:421:0:o;26247:470::-;26305:7;26549:6;26545:47;;-1:-1:-1;26579:1:0;26572:8;;26545:47;26616:5;;;26620:1;26616;:5;:1;26640:5;;;;;:10;26632:56;;;;-1:-1:-1;;;26632:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Swarm Source

bzzr://1255a1e8b8b81586db1e0d227fdf2a31ece8463f93252df7378453a2857bf432
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading