Contract 0xF7440b98b0DC9B54BFae68288a11C48dabFE7D07

Contract Overview

Balance:
0 Ether
Txn Hash
Method
Block
From
To
Value
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6Take Debt Snapsh...325458722022-07-04 18:28:245 hrs 28 mins ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377229 5
0x42d97d69c0eeb1d8b0e1b564c7bbd39e6e0bf333f256d127b0709b72bed2b665Take Debt Snapsh...325397032022-07-04 10:18:2013 hrs 39 mins ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00375835 5
0x18dd50c8504d3514e348f5525bb97ea40bef3254a8672f00b542f9bb1b71bebbTake Debt Snapsh...325335042022-07-04 2:08:2421 hrs 48 mins ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377238 5
0xd8a72d9490c761f7f9c85147722343b6c0e2e777447c55abbd5092e3fe2cb88aTake Debt Snapsh...325277742022-07-03 17:58:241 day 5 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00367441 5
0xaf2b59447c490650b150e0f4bbad5e29621c6c9c5c6d2e1695527a2924cb3d0eTake Debt Snapsh...325216082022-07-03 9:48:241 day 14 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00368841 5
0x1b816902015a438c6ee6f349e9d0728fd8c09a42447a6ff143bb4811de5ab128Take Debt Snapsh...325160092022-07-03 1:38:201 day 22 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00368841 5
0xd6f13b6b1eecfbea7aca2fe635f065b41c4ce053cea16f4cc7d3c49d086e0a95Take Debt Snapsh...325106452022-07-02 17:28:242 days 6 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00368841 5
0x63487bde9cc504389e511716bd08f86483c51429425ba365a3762ea06b7ea898Take Debt Snapsh...325043642022-07-02 9:18:322 days 14 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00368841 5
0x1b13e155e2228ff87ee4397770adcd6225a9c08b4a72f318502376d7d0aac2bfTake Debt Snapsh...324987242022-07-02 1:08:242 days 22 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377241 5
0x95caf6222e91f9399402b9778e54d25f3efc37d1a9c023feb314095c8d67edb9Take Debt Snapsh...324924842022-07-01 16:58:243 days 6 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377226 5
0x166b7417a524d16e867ae6377ad23fd7c9abf13d760688dcf75401e91451beeaTake Debt Snapsh...324861692022-07-01 8:48:243 days 15 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377229 5
0xc97e4c027319f333fc2e645cd9785861cd0c5fae24f1b1c2a98940b20f52a4b0Take Debt Snapsh...324802462022-07-01 0:38:203 days 23 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00375829 5
0x3972a728b70ca2dbd8155379e99026b086c642b66ccf7815ef7a8c156f63d5a0Take Debt Snapsh...324744502022-06-30 16:28:244 days 7 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377235 5
0x720c60da4689aaff03a400425a1b872d12cc3733f8eca060e4ba687492c6b69aTake Debt Snapsh...324682132022-06-30 8:18:244 days 15 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377229 5
0x8aa258e43121ed5cd8af7785df96470f09124b9b9bbdec99f39fdae10da54b76Take Debt Snapsh...324621842022-06-30 0:08:244 days 23 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377235 5
0x8696dae3eecd4b3888472258dc2671038a680e32305c24297540cfaf975dbc22Take Debt Snapsh...324560492022-06-29 15:58:245 days 7 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377238 5
0x29c6596b217d7456eb2077e06dd063a5b0215c683cda6829eb5bb1d02115e4a0Take Debt Snapsh...324490212022-06-29 7:48:245 days 16 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377232 5
0xf3aef698f25ba5955f7d75340083bdeb896450686c8ee9b8333ee103136ca551Take Debt Snapsh...324420992022-06-28 23:38:286 days 18 mins ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377229 5
0x5c04a1417fd66c47c7f7787488fa4f43593e881e09e272890b689d3dd7bf9f5cTake Debt Snapsh...324352182022-06-28 15:28:246 days 8 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377238 5
0x5f44d3d66d54b71583529fcd0ca008c8cbc4d93a5224be224f212a48e4d3ea91Take Debt Snapsh...324281712022-06-28 7:18:246 days 16 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377235 5
0xcaf206e6297caefddbc6292c0e014827580e710551004bf627026c6b28df8618Take Debt Snapsh...324210242022-06-27 23:08:287 days 48 mins ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00375838 5
0x1f1de6f76d60862372cc7fc825efab2eb036d1c5c19b6b4265d25b71f2e6b55dTake Debt Snapsh...324139622022-06-27 14:58:247 days 8 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377235 5
0x6b977495826e3f88ca1ca4e791a75ec5dce7cfb3588756d53c24d9b37b1a8f40Take Debt Snapsh...324071132022-06-27 6:48:247 days 17 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00377235 5
0x92fe532691032dcba1b0f982f20917bc822f5673a05bee51e72ef2980827f315Take Debt Snapsh...324004352022-06-26 22:38:248 days 1 hr ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00375838 5
0x7a2ee01bcd0257f00d44bc29fb8c2c88a11ffa3517c9da97a54bedf592bc7ee8Take Debt Snapsh...323936552022-06-26 14:28:248 days 9 hrs ago0x43f0fbc93622845f709fb52d503255f885dc9c9e IN  0xf7440b98b0dc9b54bfae68288a11c48dabfe7d070 Ether0.00368835 5
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x012a86834cd1600dc405fa1c7022425a484e34ea0 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x44af736495544a726ed15cb0ebe2d87a6bcc18320 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x53bae964339e8a742b5b47f6c10bbfa8ff138f340 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x53bae964339e8a742b5b47f6c10bbfa8ff138f340 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x86be944f673d77b93dc5f19655c915b002d42beb0 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x1da40f4d00109f71ea610a2dc0bf2698e19034b80 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0xc7b695f50cd76165d7b8d83d48c6c667b268af300 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0xa6b145cbcd9b530f2bd57d41a96c1768734d46cd0 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x42469fb09f53080f33a3a0fba97396f87b22b4290 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0xae8a6bdf406a9ed41f44d22e3fa7349aab715acc0 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0xd008f1a6804001cb700bb777aaf7161daeef68da0 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0xce3f505ab7e806e0ef80384ca5c9dbff637af6350 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x558d7b931828e47f5f2c95c319de8ea6ebb3c9f60 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x4bf55262c17388c13cdd9538a830b321914936670 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x61c427e53c8eaf052b6bf590f7e6cba3ee2fdec70 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x412c870daab642aa87715e2ea860d20e48e732670 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x61c427e53c8eaf052b6bf590f7e6cba3ee2fdec70 Ether
0x5efd612407465a94f0643faf2314a850fb55b4876023e510cd24dcfadfe146a6325458722022-07-04 18:28:245 hrs 28 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x648727a32112e6c233c1c5d8d57a9aa736ffb18b0 Ether
0x42d97d69c0eeb1d8b0e1b564c7bbd39e6e0bf333f256d127b0709b72bed2b665325397032022-07-04 10:18:2013 hrs 39 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x012a86834cd1600dc405fa1c7022425a484e34ea0 Ether
0x42d97d69c0eeb1d8b0e1b564c7bbd39e6e0bf333f256d127b0709b72bed2b665325397032022-07-04 10:18:2013 hrs 39 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x44af736495544a726ed15cb0ebe2d87a6bcc18320 Ether
0x42d97d69c0eeb1d8b0e1b564c7bbd39e6e0bf333f256d127b0709b72bed2b665325397032022-07-04 10:18:2013 hrs 39 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x53bae964339e8a742b5b47f6c10bbfa8ff138f340 Ether
0x42d97d69c0eeb1d8b0e1b564c7bbd39e6e0bf333f256d127b0709b72bed2b665325397032022-07-04 10:18:2013 hrs 39 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x53bae964339e8a742b5b47f6c10bbfa8ff138f340 Ether
0x42d97d69c0eeb1d8b0e1b564c7bbd39e6e0bf333f256d127b0709b72bed2b665325397032022-07-04 10:18:2013 hrs 39 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x86be944f673d77b93dc5f19655c915b002d42beb0 Ether
0x42d97d69c0eeb1d8b0e1b564c7bbd39e6e0bf333f256d127b0709b72bed2b665325397032022-07-04 10:18:2013 hrs 39 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0x1da40f4d00109f71ea610a2dc0bf2698e19034b80 Ether
0x42d97d69c0eeb1d8b0e1b564c7bbd39e6e0bf333f256d127b0709b72bed2b665325397032022-07-04 10:18:2013 hrs 39 mins ago 0xf7440b98b0dc9b54bfae68288a11c48dabfe7d07 0xc7b695f50cd76165d7b8d83d48c6c667b268af300 Ether
[ Download CSV Export 
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

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-03-16
*/

/*
   ____            __   __        __   _
  / __/__ __ ___  / /_ / /  ___  / /_ (_)__ __
 _\ \ / // // _ \/ __// _ \/ -_)/ __// / \ \ /
/___/ \_, //_//_/\__//_//_/\__/ \__//_/ /_\_\
     /___/

* Synthetix: DebtCache.sol
*
* Latest source (may be newer): https://github.com/Synthetixio/synthetix/blob/master/contracts/DebtCache.sol
* Docs: https://docs.synthetix.io/contracts/DebtCache
*
* Contract Dependencies: 
*	- BaseDebtCache
*	- IAddressResolver
*	- IDebtCache
*	- MixinResolver
*	- MixinSystemSettings
*	- Owned
* Libraries: 
*	- SafeDecimalMath
*	- SafeMath
*
* MIT License
* ===========
*
* Copyright (c) 2022 Synthetix
*
* 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.0;

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

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        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.synthetix.io/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;
    }

    // Computes `a - b`, setting the value to 0 if b > a.
    function floorsub(uint a, uint b) internal pure returns (uint) {
        return b >= a ? 0 : a - b;
    }

    /* ---------- Utilities ---------- */
    /*
     * Absolute value of the input, returned as a signed number.
     */
    function signedAbs(int x) internal pure returns (int) {
        return x < 0 ? -x : x;
    }

    /*
     * Absolute value of the input, returned as an unsigned number.
     */
    function abs(int x) internal pure returns (uint) {
        return uint(signedAbs(x));
    }
}


// https://docs.synthetix.io/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.synthetix.io/contracts/source/interfaces/iaddressresolver
interface IAddressResolver {
    function getAddress(bytes32 name) external view returns (address);

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

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


// https://docs.synthetix.io/contracts/source/interfaces/isynth
interface ISynth {
    // Views
    function currencyKey() external view returns (bytes32);

    function transferableSynths(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 Synthetix
    function burn(address account, uint amount) external;

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


// https://docs.synthetix.io/contracts/source/interfaces/iissuer
interface IIssuer {
    // Views
    function anySynthOrSNXRateIsInvalid() external view returns (bool anyRateInvalid);

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

    function availableSynthCount() external view returns (uint);

    function availableSynths(uint index) external view returns (ISynth);

    function canBurnSynths(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 issuanceRatio() external view returns (uint);

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

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

    function minimumStakeTime() external view returns (uint);

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

    function synths(bytes32 currencyKey) external view returns (ISynth);

    function getSynths(bytes32[] calldata currencyKeys) external view returns (ISynth[] memory);

    function synthsByAddress(address synthAddress) external view returns (bytes32);

    function totalIssuedSynths(bytes32 currencyKey, bool excludeOtherCollateral) external view returns (uint);

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

    // Restricted: used internally to Synthetix
    function issueSynths(address from, uint amount) external;

    function issueSynthsOnBehalf(
        address issueFor,
        address from,
        uint amount
    ) external;

    function issueMaxSynths(address from) external;

    function issueMaxSynthsOnBehalf(address issueFor, address from) external;

    function burnSynths(address from, uint amount) external;

    function burnSynthsOnBehalf(
        address burnForAddress,
        address from,
        uint amount
    ) external;

    function burnSynthsToTarget(address from) external;

    function burnSynthsToTargetOnBehalf(address burnForAddress, address from) external;

    function burnForRedemption(
        address deprecatedSynthProxy,
        address account,
        uint balance
    ) external;

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

    function setCurrentPeriodId(uint128 periodId) external;
}


// Inheritance


// Internal references


// https://docs.synthetix.io/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 getSynth(bytes32 key) external view returns (address) {
        IIssuer issuer = IIssuer(repository["Issuer"]);
        require(address(issuer) != address(0), "Cannot find Issuer address");
        return address(issuer.synths(key));
    }

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

    event AddressImported(bytes32 name, address destination);
}


// Internal references


// https://docs.synthetix.io/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.synthetix.io/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.synthetix.io/contracts/source/contracts/mixinsystemsettings
contract MixinSystemSettings is MixinResolver {
    // must match the one defined SystemSettingsLib, defined in both places due to sol v0.5 limitations
    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";
    /* ========== Exchange Fees Related ========== */
    bytes32 internal constant SETTING_EXCHANGE_FEE_RATE = "exchangeFeeRate";
    bytes32 internal constant SETTING_EXCHANGE_DYNAMIC_FEE_THRESHOLD = "exchangeDynamicFeeThreshold";
    bytes32 internal constant SETTING_EXCHANGE_DYNAMIC_FEE_WEIGHT_DECAY = "exchangeDynamicFeeWeightDecay";
    bytes32 internal constant SETTING_EXCHANGE_DYNAMIC_FEE_ROUNDS = "exchangeDynamicFeeRounds";
    bytes32 internal constant SETTING_EXCHANGE_MAX_DYNAMIC_FEE = "exchangeMaxDynamicFee";
    /* ========== End Exchange Fees Related ========== */
    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_CROSS_DOMAIN_FEE_PERIOD_CLOSE_GAS_LIMIT = "crossDomainCloseGasLimit";
    bytes32 internal constant SETTING_CROSS_DOMAIN_RELAY_GAS_LIMIT = "crossDomainRelayGasLimit";
    bytes32 internal constant SETTING_ETHER_WRAPPER_MAX_ETH = "etherWrapperMaxETH";
    bytes32 internal constant SETTING_ETHER_WRAPPER_MINT_FEE_RATE = "etherWrapperMintFeeRate";
    bytes32 internal constant SETTING_ETHER_WRAPPER_BURN_FEE_RATE = "etherWrapperBurnFeeRate";
    bytes32 internal constant SETTING_WRAPPER_MAX_TOKEN_AMOUNT = "wrapperMaxTokens";
    bytes32 internal constant SETTING_WRAPPER_MINT_FEE_RATE = "wrapperMintFeeRate";
    bytes32 internal constant SETTING_WRAPPER_BURN_FEE_RATE = "wrapperBurnFeeRate";
    bytes32 internal constant SETTING_INTERACTION_DELAY = "interactionDelay";
    bytes32 internal constant SETTING_COLLAPSE_FEE_RATE = "collapseFeeRate";
    bytes32 internal constant SETTING_ATOMIC_MAX_VOLUME_PER_BLOCK = "atomicMaxVolumePerBlock";
    bytes32 internal constant SETTING_ATOMIC_TWAP_WINDOW = "atomicTwapWindow";
    bytes32 internal constant SETTING_ATOMIC_EQUIVALENT_FOR_DEX_PRICING = "atomicEquivalentForDexPricing";
    bytes32 internal constant SETTING_ATOMIC_EXCHANGE_FEE_RATE = "atomicExchangeFeeRate";
    bytes32 internal constant SETTING_ATOMIC_PRICE_BUFFER = "atomicPriceBuffer";
    bytes32 internal constant SETTING_ATOMIC_VOLATILITY_CONSIDERATION_WINDOW = "atomicVolConsiderationWindow";
    bytes32 internal constant SETTING_ATOMIC_VOLATILITY_UPDATE_THRESHOLD = "atomicVolUpdateThreshold";

    bytes32 internal constant CONTRACT_FLEXIBLESTORAGE = "FlexibleStorage";

    enum CrossDomainMessageGasLimits {Deposit, Escrow, Reward, Withdrawal, CloseFeePeriod, Relay}

    struct DynamicFeeConfig {
        uint threshold;
        uint weightDecay;
        uint rounds;
        uint maxFee;
    }

    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 if (gasLimitType == CrossDomainMessageGasLimits.Relay) {
            return SETTING_CROSS_DOMAIN_RELAY_GAS_LIMIT;
        } else if (gasLimitType == CrossDomainMessageGasLimits.CloseFeePeriod) {
            return SETTING_CROSS_DOMAIN_FEE_PERIOD_CLOSE_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);
    }

    /* ========== Exchange Related Fees ========== */
    function getExchangeFeeRate(bytes32 currencyKey) internal view returns (uint) {
        return
            flexibleStorage().getUIntValue(
                SETTING_CONTRACT_NAME,
                keccak256(abi.encodePacked(SETTING_EXCHANGE_FEE_RATE, currencyKey))
            );
    }

    /// @notice Get exchange dynamic fee related keys
    /// @return threshold, weight decay, rounds, and max fee
    function getExchangeDynamicFeeConfig() internal view returns (DynamicFeeConfig memory) {
        bytes32[] memory keys = new bytes32[](4);
        keys[0] = SETTING_EXCHANGE_DYNAMIC_FEE_THRESHOLD;
        keys[1] = SETTING_EXCHANGE_DYNAMIC_FEE_WEIGHT_DECAY;
        keys[2] = SETTING_EXCHANGE_DYNAMIC_FEE_ROUNDS;
        keys[3] = SETTING_EXCHANGE_MAX_DYNAMIC_FEE;
        uint[] memory values = flexibleStorage().getUIntValues(SETTING_CONTRACT_NAME, keys);
        return DynamicFeeConfig({threshold: values[0], weightDecay: values[1], rounds: values[2], maxFee: values[3]});
    }

    /* ========== End Exchange Related Fees ========== */

    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 getEtherWrapperMaxETH() internal view returns (uint) {
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ETHER_WRAPPER_MAX_ETH);
    }

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

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

    function getWrapperMaxTokenAmount(address wrapper) internal view returns (uint) {
        return
            flexibleStorage().getUIntValue(
                SETTING_CONTRACT_NAME,
                keccak256(abi.encodePacked(SETTING_WRAPPER_MAX_TOKEN_AMOUNT, wrapper))
            );
    }

    function getWrapperMintFeeRate(address wrapper) internal view returns (int) {
        return
            flexibleStorage().getIntValue(
                SETTING_CONTRACT_NAME,
                keccak256(abi.encodePacked(SETTING_WRAPPER_MINT_FEE_RATE, wrapper))
            );
    }

    function getWrapperBurnFeeRate(address wrapper) internal view returns (int) {
        return
            flexibleStorage().getIntValue(
                SETTING_CONTRACT_NAME,
                keccak256(abi.encodePacked(SETTING_WRAPPER_BURN_FEE_RATE, wrapper))
            );
    }

    function getInteractionDelay(address collateral) internal view returns (uint) {
        return
            flexibleStorage().getUIntValue(
                SETTING_CONTRACT_NAME,
                keccak256(abi.encodePacked(SETTING_INTERACTION_DELAY, collateral))
            );
    }

    function getCollapseFeeRate(address collateral) internal view returns (uint) {
        return
            flexibleStorage().getUIntValue(
                SETTING_CONTRACT_NAME,
                keccak256(abi.encodePacked(SETTING_COLLAPSE_FEE_RATE, collateral))
            );
    }

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

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

    function getAtomicEquivalentForDexPricing(bytes32 currencyKey) internal view returns (address) {
        return
            flexibleStorage().getAddressValue(
                SETTING_CONTRACT_NAME,
                keccak256(abi.encodePacked(SETTING_ATOMIC_EQUIVALENT_FOR_DEX_PRICING, currencyKey))
            );
    }

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

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

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

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


interface IDebtCache {
    // Views

    function cachedDebt() external view returns (uint);

    function cachedSynthDebt(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 isInitialized() external view returns (bool);

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

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

    function totalNonSnxBackedDebt() external view returns (uint excludedDebt, bool isInvalid);

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

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

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

    // Mutative functions

    function updateCachedSynthDebts(bytes32[] calldata currencyKeys) external;

    function updateCachedSynthDebtWithRate(bytes32 currencyKey, uint currencyRate) external;

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

    function updateDebtCacheValidity(bool currentlyInvalid) external;

    function purgeCachedSynthDebt(bytes32 currencyKey) external;

    function takeDebtSnapshot() external;

    function recordExcludedDebtChange(bytes32 currencyKey, int256 delta) external;

    function updateCachedsUSDDebt(int amount) external;

    function importExcludedIssuedDebts(IDebtCache prevDebtCache, IIssuer prevIssuer) external;
}


interface IVirtualSynth {
    // 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 synth() external view returns (ISynth);

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


// https://docs.synthetix.io/contracts/source/interfaces/iexchanger
interface IExchanger {
    struct ExchangeEntrySettlement {
        bytes32 src;
        uint amount;
        bytes32 dest;
        uint reclaim;
        uint rebate;
        uint srcRoundIdAtPeriodEnd;
        uint destRoundIdAtPeriodEnd;
        uint timestamp;
    }

    struct ExchangeEntry {
        uint sourceRate;
        uint destinationRate;
        uint destinationAmount;
        uint exchangeFeeRate;
        uint exchangeDynamicFeeRate;
        uint roundIdForSrc;
        uint roundIdForDest;
    }

    // Views
    function calculateAmountAfterSettlement(
        address from,
        bytes32 currencyKey,
        uint amount,
        uint refunded
    ) external view returns (uint amountAfterSettlement);

    function isSynthRateInvalid(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);

    function dynamicFeeRateForExchange(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey)
        external
        view
        returns (uint feeRate, bool tooVolatile);

    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);

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

    // Mutative functions
    function exchange(
        address exchangeForAddress,
        address from,
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        address destinationAddress,
        bool virtualSynth,
        address rewardAddress,
        bytes32 trackingCode
    ) external returns (uint amountReceived, IVirtualSynth vSynth);

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

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

    function suspendSynthWithInvalidRate(bytes32 currencyKey) external;
}


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

    // 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 anyRateIsInvalidAtRound(bytes32[] calldata currencyKeys, uint[] calldata roundIds) external view returns (bool);

    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 effectiveValueAndRatesAtRound(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        uint roundIdForSrc,
        uint roundIdForDest
    )
        external
        view
        returns (
            uint value,
            uint sourceRate,
            uint destinationRate
        );

    function effectiveAtomicValueAndRates(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey
    )
        external
        view
        returns (
            uint value,
            uint systemValue,
            uint systemSourceRate,
            uint systemDestinationRate
        );

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

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

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

    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 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,
        uint roundId
    ) 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);

    function synthTooVolatileForAtomicExchange(bytes32 currencyKey) external view returns (bool);
}


// https://docs.synthetix.io/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 systemSuspended() external view returns (bool);

    function requireIssuanceActive() external view;

    function requireExchangeActive() external view;

    function requireFuturesActive() external view;

    function requireFuturesMarketActive(bytes32 marketKey) external view;

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

    function requireSynthActive(bytes32 currencyKey) external view;

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

    function requireSynthsActive(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 futuresSuspension() external view returns (bool suspended, uint248 reason);

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

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

    function futuresMarketSuspension(bytes32 marketKey) external view returns (bool suspended, uint248 reason);

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

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

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

    // Restricted functions
    function suspendIssuance(uint256 reason) external;

    function suspendSynth(bytes32 currencyKey, uint256 reason) external;

    function suspendFuturesMarket(bytes32 marketKey, uint256 reason) external;

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


// https://docs.synthetix.io/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 isSynthManaged(bytes32 currencyKey) external view returns (bool);

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

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

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

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

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

    function getShortRate(bytes32 synth) 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 areSynthsAndCurrenciesSet(bytes32[] calldata requiredSynthNamesInResolver, bytes32[] calldata synthKeys)
        external
        view
        returns (bool);

    function areShortableSynthsSet(bytes32[] calldata requiredSynthNamesInResolver, bytes32[] calldata synthKeys)
        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 addSynths(bytes32[] calldata synthNamesInResolver, bytes32[] calldata synthKeys) external;

    function removeSynths(bytes32[] calldata synths, bytes32[] calldata synthKeys) external;

    function addShortableSynths(bytes32[] calldata requiredSynthNamesInResolver, bytes32[] calldata synthKeys) external;

    function removeShortableSynths(bytes32[] calldata synths) external;

    // State mutative

    function incrementLongs(bytes32 synth, uint amount) external;

    function decrementLongs(bytes32 synth, uint amount) external;

    function incrementShorts(bytes32 synth, uint amount) external;

    function decrementShorts(bytes32 synth, uint amount) external;

    function accrueInterest(
        uint interestIndex,
        bytes32 currency,
        bool isShort
    ) external returns (uint difference, uint index);

    function updateBorrowRatesCollateral(uint rate) external;

    function updateShortRatesCollateral(bytes32 currency, uint rate) external;
}


interface IWETH {
    // 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);

    // WETH-specific functions.
    function deposit() external payable;

    function withdraw(uint amount) external;

    // Events
    event Transfer(address indexed from, address indexed to, uint value);
    event Approval(address indexed owner, address indexed spender, uint value);
    event Deposit(address indexed to, uint amount);
    event Withdrawal(address indexed to, uint amount);
}


// https://docs.synthetix.io/contracts/source/interfaces/ietherwrapper
contract IEtherWrapper {
    function mint(uint amount) external;

    function burn(uint amount) external;

    function distributeFees() external;

    function capacity() external view returns (uint);

    function getReserves() external view returns (uint);

    function totalIssuedSynths() external view returns (uint);

    function calculateMintFee(uint amount) public view returns (uint);

    function calculateBurnFee(uint amount) public view returns (uint);

    function maxETH() public view returns (uint256);

    function mintFeeRate() public view returns (uint256);

    function burnFeeRate() public view returns (uint256);

    function weth() public view returns (IWETH);
}


// https://docs.synthetix.io/contracts/source/interfaces/iwrapperfactory
interface IWrapperFactory {
    function isWrapper(address possibleWrapper) external view returns (bool);

    function createWrapper(
        IERC20 token,
        bytes32 currencyKey,
        bytes32 synthContractName
    ) external returns (address);

    function distributeFees() external;
}


interface IFuturesMarketManager {
    function markets(uint index, uint pageSize) external view returns (address[] memory);

    function numMarkets() external view returns (uint);

    function allMarkets() external view returns (address[] memory);

    function marketForKey(bytes32 marketKey) external view returns (address);

    function marketsForKeys(bytes32[] calldata marketKeys) external view returns (address[] memory);

    function totalDebt() external view returns (uint debt, bool isInvalid);
}


// Inheritance


// Libraries


// Internal references


// https://docs.synthetix.io/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 _cachedSynthDebt;
    mapping(bytes32 => uint) internal _excludedIssuedDebt;
    uint internal _cacheTimestamp;
    bool internal _cacheInvalid = true;

    // flag to ensure importing excluded debt is invoked only once
    bool public isInitialized = false; // public to avoid needing an event

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

    bytes32 internal constant sUSD = "sUSD";
    bytes32 internal constant sETH = "sETH";

    /* ========== 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_COLLATERALMANAGER = "CollateralManager";
    bytes32 private constant CONTRACT_ETHER_WRAPPER = "EtherWrapper";
    bytes32 private constant CONTRACT_FUTURESMARKETMANAGER = "FuturesMarketManager";
    bytes32 private constant CONTRACT_WRAPPER_FACTORY = "WrapperFactory";

    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[](8);
        newAddresses[0] = CONTRACT_ISSUER;
        newAddresses[1] = CONTRACT_EXCHANGER;
        newAddresses[2] = CONTRACT_EXRATES;
        newAddresses[3] = CONTRACT_SYSTEMSTATUS;
        newAddresses[4] = CONTRACT_COLLATERALMANAGER;
        newAddresses[5] = CONTRACT_WRAPPER_FACTORY;
        newAddresses[6] = CONTRACT_ETHER_WRAPPER;
        newAddresses[7] = CONTRACT_FUTURESMARKETMANAGER;
        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 collateralManager() internal view returns (ICollateralManager) {
        return ICollateralManager(requireAndGetAddress(CONTRACT_COLLATERALMANAGER));
    }

    function etherWrapper() internal view returns (IEtherWrapper) {
        return IEtherWrapper(requireAndGetAddress(CONTRACT_ETHER_WRAPPER));
    }

    function futuresMarketManager() internal view returns (IFuturesMarketManager) {
        return IFuturesMarketManager(requireAndGetAddress(CONTRACT_FUTURESMARKETMANAGER));
    }

    function wrapperFactory() internal view returns (IWrapperFactory) {
        return IWrapperFactory(requireAndGetAddress(CONTRACT_WRAPPER_FACTORY));
    }

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

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

    function cachedSynthDebt(bytes32 currencyKey) external view returns (uint) {
        return _cachedSynthDebt[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 _issuedSynthValues(bytes32[] memory currencyKeys, uint[] memory rates)
        internal
        view
        returns (uint[] memory values)
    {
        uint numValues = currencyKeys.length;
        values = new uint[](numValues);
        ISynth[] memory synths = issuer().getSynths(currencyKeys);

        for (uint i = 0; i < numValues; i++) {
            address synthAddress = address(synths[i]);
            require(synthAddress != address(0), "Synth does not exist");
            uint supply = IERC20(synthAddress).totalSupply();
            values[i] = supply.multiplyDecimalRound(rates[i]);
        }

        return (values);
    }

    function _currentSynthDebts(bytes32[] memory currencyKeys)
        internal
        view
        returns (
            uint[] memory snxIssuedDebts,
            uint _futuresDebt,
            uint _excludedDebt,
            bool anyRateIsInvalid
        )
    {
        (uint[] memory rates, bool isInvalid) = exchangeRates().ratesAndInvalidForCurrencies(currencyKeys);
        uint[] memory values = _issuedSynthValues(currencyKeys, rates);
        (uint excludedDebt, bool isAnyNonSnxDebtRateInvalid) = _totalNonSnxBackedDebt(currencyKeys, rates, isInvalid);
        (uint futuresDebt, bool futuresDebtIsInvalid) = futuresMarketManager().totalDebt();

        return (values, futuresDebt, excludedDebt, isInvalid || futuresDebtIsInvalid || isAnyNonSnxDebtRateInvalid);
    }

    function currentSynthDebts(bytes32[] calldata currencyKeys)
        external
        view
        returns (
            uint[] memory debtValues,
            uint futuresDebt,
            uint excludedDebt,
            bool anyRateIsInvalid
        )
    {
        return _currentSynthDebts(currencyKeys);
    }

    function _cachedSynthDebts(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] = _cachedSynthDebt[currencyKeys[i]];
        }
        return debts;
    }

    function cachedSynthDebts(bytes32[] calldata currencyKeys) external view returns (uint[] memory snxIssuedDebts) {
        return _cachedSynthDebts(currencyKeys);
    }

    function _excludedIssuedDebts(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] = _excludedIssuedDebt[currencyKeys[i]];
        }
        return debts;
    }

    function excludedIssuedDebts(bytes32[] calldata currencyKeys) external view returns (uint[] memory excludedDebts) {
        return _excludedIssuedDebts(currencyKeys);
    }

    /// used when migrating to new DebtCache instance in order to import the excluded debt records
    /// If this method is not run after upgrading the contract, the debt will be
    /// incorrect w.r.t to wrapper factory assets until the values are imported from
    /// previous instance of the contract
    /// Also, in addition to this method it's possible to use recordExcludedDebtChange since
    /// it's accessible to owner in case additional adjustments are required
    function importExcludedIssuedDebts(IDebtCache prevDebtCache, IIssuer prevIssuer) external onlyOwner {
        // this can only be run once so that recorded debt deltas aren't accidentally
        // lost or double counted
        require(!isInitialized, "already initialized");
        isInitialized = true;

        // get the currency keys from **previous** issuer, in case current issuer
        // doesn't have all the synths at this point
        // warning: if a synth won't be added to the current issuer before the next upgrade of this contract,
        // its entry will be lost (because it won't be in the prevIssuer for next time).
        // if for some reason this is a problem, it should be possible to use recordExcludedDebtChange() to amend
        bytes32[] memory keys = prevIssuer.availableCurrencyKeys();

        require(keys.length > 0, "previous Issuer has no synths");

        // query for previous debt records
        uint[] memory debts = prevDebtCache.excludedIssuedDebts(keys);

        // store the values
        for (uint i = 0; i < keys.length; i++) {
            if (debts[i] > 0) {
                // adding the values instead of overwriting in case some deltas were recorded in this
                // contract already (e.g. if the upgrade was not atomic)
                _excludedIssuedDebt[keys[i]] = _excludedIssuedDebt[keys[i]].add(debts[i]);
            }
        }
    }

    // Returns the total sUSD debt backed by non-SNX collateral.
    function totalNonSnxBackedDebt() external view returns (uint excludedDebt, bool isInvalid) {
        bytes32[] memory currencyKeys = issuer().availableCurrencyKeys();
        (uint[] memory rates, bool ratesAreInvalid) = exchangeRates().ratesAndInvalidForCurrencies(currencyKeys);

        return _totalNonSnxBackedDebt(currencyKeys, rates, ratesAreInvalid);
    }

    function _totalNonSnxBackedDebt(
        bytes32[] memory currencyKeys,
        uint[] memory rates,
        bool ratesAreInvalid
    ) internal view returns (uint excludedDebt, bool isInvalid) {
        // Calculate excluded debt.
        // 1. MultiCollateral long debt + short debt.
        (uint longValue, bool anyTotalLongRateIsInvalid) = collateralManager().totalLong();
        (uint shortValue, bool anyTotalShortRateIsInvalid) = collateralManager().totalShort();
        isInvalid = ratesAreInvalid || anyTotalLongRateIsInvalid || anyTotalShortRateIsInvalid;
        excludedDebt = longValue.add(shortValue);

        // 2. EtherWrapper.
        // Subtract sETH and sUSD issued by EtherWrapper.
        excludedDebt = excludedDebt.add(etherWrapper().totalIssuedSynths());

        // 3. WrapperFactory.
        // Get the debt issued by the Wrappers.
        for (uint i = 0; i < currencyKeys.length; i++) {
            excludedDebt = excludedDebt.add(_excludedIssuedDebt[currencyKeys[i]].multiplyDecimalRound(rates[i]));
        }

        return (excludedDebt, isInvalid);
    }

    function _currentDebt() internal view returns (uint debt, bool anyRateIsInvalid) {
        bytes32[] memory currencyKeys = issuer().availableCurrencyKeys();
        (uint[] memory rates, bool isInvalid) = exchangeRates().ratesAndInvalidForCurrencies(currencyKeys);

        // Sum all issued synth values based on their supply.
        uint[] memory values = _issuedSynthValues(currencyKeys, rates);
        (uint excludedDebt, bool isAnyNonSnxDebtRateInvalid) = _totalNonSnxBackedDebt(currencyKeys, rates, isInvalid);

        uint numValues = values.length;
        uint total;
        for (uint i; i < numValues; i++) {
            total = total.add(values[i]);
        }

        // Add in the debt accounted for by futures
        (uint futuresDebt, bool futuresDebtIsInvalid) = futuresMarketManager().totalDebt();
        total = total.add(futuresDebt);

        // Ensure that if the excluded non-SNX debt exceeds SNX-backed debt, no overflow occurs
        total = total < excludedDebt ? 0 : total.sub(excludedDebt);

        return (total, isInvalid || futuresDebtIsInvalid || isAnyNonSnxDebtRateInvalid);
    }

    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 updateCachedSynthDebts(bytes32[] calldata currencyKeys) external {}

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

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

    function updateDebtCacheValidity(bool currentlyInvalid) external {}

    function purgeCachedSynthDebt(bytes32 currencyKey) external {}

    function takeDebtSnapshot() external {}

    function recordExcludedDebtChange(bytes32 currencyKey, int256 delta) external {}

    function updateCachedsUSDDebt(int amount) external {}

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

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

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

    function _onlyIssuer() internal view {
        require(msg.sender == address(issuer()), "Sender is not Issuer");
    }

    modifier onlyIssuer() {
        _onlyIssuer();
        _;
    }

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

    modifier onlyIssuerOrExchanger() {
        _onlyIssuerOrExchanger();
        _;
    }

    function _onlyDebtIssuer() internal view {
        bool isWrapper = wrapperFactory().isWrapper(msg.sender);

        // owner included for debugging and fixing in emergency situation
        bool isOwner = msg.sender == owner;

        require(isOwner || isWrapper, "Only debt issuers may call this");
    }

    modifier onlyDebtIssuer() {
        _onlyDebtIssuer();
        _;
    }
}


// Libraries


// Inheritance


// https://docs.synthetix.io/contracts/source/contracts/debtcache
contract DebtCache is BaseDebtCache {
    using SafeDecimalMath for uint;

    bytes32 public constant CONTRACT_NAME = "DebtCache";

    constructor(address _owner, address _resolver) public BaseDebtCache(_owner, _resolver) {}

    bytes32 internal constant EXCLUDED_DEBT_KEY = "EXCLUDED_DEBT";
    bytes32 internal constant FUTURES_DEBT_KEY = "FUTURES_DEBT";

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

    // This function exists in case a synth is ever somehow removed without its snapshot being updated.
    function purgeCachedSynthDebt(bytes32 currencyKey) external onlyOwner {
        require(issuer().synths(currencyKey) == ISynth(0), "Synth exists");
        delete _cachedSynthDebt[currencyKey];
    }

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

        // The total SNX-backed debt is the debt of futures markets plus the debt of circulating synths.
        uint snxCollateralDebt = futuresDebt;
        _cachedSynthDebt[FUTURES_DEBT_KEY] = futuresDebt;
        uint numValues = values.length;
        for (uint i; i < numValues; i++) {
            uint value = values[i];
            snxCollateralDebt = snxCollateralDebt.add(value);
            _cachedSynthDebt[currencyKeys[i]] = value;
        }

        // Subtract out the excluded non-SNX backed debt from our total
        _cachedSynthDebt[EXCLUDED_DEBT_KEY] = excludedDebt;
        uint newDebt = snxCollateralDebt.floorsub(excludedDebt);
        _cachedDebt = newDebt;
        _cacheTimestamp = block.timestamp;
        emit DebtCacheUpdated(newDebt);
        emit DebtCacheSnapshotTaken(block.timestamp);

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

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

    function updateCachedSynthDebtWithRate(bytes32 currencyKey, uint currencyRate) external onlyIssuer {
        bytes32[] memory synthKeyArray = new bytes32[](1);
        synthKeyArray[0] = currencyKey;
        uint[] memory synthRateArray = new uint[](1);
        synthRateArray[0] = currencyRate;
        _updateCachedSynthDebtsWithRates(synthKeyArray, synthRateArray, false);
    }

    function updateCachedSynthDebtsWithRates(bytes32[] calldata currencyKeys, uint[] calldata currencyRates)
        external
        onlyIssuerOrExchanger
    {
        _updateCachedSynthDebtsWithRates(currencyKeys, currencyRates, false);
    }

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

    function recordExcludedDebtChange(bytes32 currencyKey, int256 delta) external onlyDebtIssuer {
        int256 newExcludedDebt = int256(_excludedIssuedDebt[currencyKey]) + delta;

        require(newExcludedDebt >= 0, "Excluded debt cannot become negative");

        _excludedIssuedDebt[currencyKey] = uint(newExcludedDebt);
    }

    function updateCachedsUSDDebt(int amount) external onlyIssuer {
        uint delta = SafeDecimalMath.abs(amount);
        if (amount > 0) {
            _cachedSynthDebt[sUSD] = _cachedSynthDebt[sUSD].add(delta);
            _cachedDebt = _cachedDebt.add(delta);
        } else {
            _cachedSynthDebt[sUSD] = _cachedSynthDebt[sUSD].sub(delta);
            _cachedDebt = _cachedDebt.sub(delta);
        }

        emit DebtCacheUpdated(_cachedDebt);
    }

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

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

    // Updated the global debt according to a rate/supply change in a subset of issued synths.
    function _updateCachedSynthDebtsWithRates(
        bytes32[] memory currencyKeys,
        uint[] memory currentRates,
        bool anyRateIsInvalid
    ) internal {
        uint numKeys = currencyKeys.length;
        require(numKeys == currentRates.length, "Input array lengths differ");

        // Compute the cached and current debt sum for the subset of synths provided.
        uint cachedSum;
        uint currentSum;
        uint[] memory currentValues = _issuedSynthValues(currencyKeys, currentRates);

        for (uint i = 0; i < numKeys; i++) {
            bytes32 key = currencyKeys[i];
            uint currentSynthDebt = currentValues[i];

            cachedSum = cachedSum.add(_cachedSynthDebt[key]);
            currentSum = currentSum.add(currentSynthDebt);

            _cachedSynthDebt[key] = currentSynthDebt;
        }

        // Apply the debt update.
        if (cachedSum != currentSum) {
            uint debt = _cachedDebt;
            // apply the delta between the cachedSum and currentSum
            // add currentSum before sub cachedSum to prevent overflow as cachedSum > debt for large amount of excluded debt
            debt = debt.add(currentSum).sub(cachedSum);
            _cachedDebt = debt;
            emit DebtCacheUpdated(debt);
        }

        // Invalidate the cache if necessary
        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":true,"inputs":[],"name":"CONTRACT_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"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":"cachedSynthDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32[]","name":"currencyKeys","type":"bytes32[]"}],"name":"cachedSynthDebts","outputs":[{"internalType":"uint256[]","name":"snxIssuedDebts","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":"currentSynthDebts","outputs":[{"internalType":"uint256[]","name":"debtValues","type":"uint256[]"},{"internalType":"uint256","name":"futuresDebt","type":"uint256"},{"internalType":"uint256","name":"excludedDebt","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":[{"internalType":"bytes32[]","name":"currencyKeys","type":"bytes32[]"}],"name":"excludedIssuedDebts","outputs":[{"internalType":"uint256[]","name":"excludedDebts","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IDebtCache","name":"prevDebtCache","type":"address"},{"internalType":"contract IIssuer","name":"prevIssuer","type":"address"}],"name":"importExcludedIssuedDebts","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"purgeCachedSynthDebt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"rebuildCache","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"},{"internalType":"int256","name":"delta","type":"int256"}],"name":"recordExcludedDebtChange","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":true,"inputs":[],"name":"totalNonSnxBackedDebt","outputs":[{"internalType":"uint256","name":"excludedDebt","type":"uint256"},{"internalType":"bool","name":"isInvalid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"},{"internalType":"uint256","name":"currencyRate","type":"uint256"}],"name":"updateCachedSynthDebtWithRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32[]","name":"currencyKeys","type":"bytes32[]"}],"name":"updateCachedSynthDebts","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32[]","name":"currencyKeys","type":"bytes32[]"},{"internalType":"uint256[]","name":"currencyRates","type":"uint256[]"}],"name":"updateCachedSynthDebtsWithRates","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"int256","name":"amount","type":"int256"}],"name":"updateCachedsUSDDebt","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"}]

60806040526008805461ff001960ff1990911660011716905534801561002457600080fd5b506040516134413803806134418339818101604052604081101561004757600080fd5b50805160209091015181818080836001600160a01b0381166100b0576040805162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b038316908117825560408051928352602083019190915280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a150600280546001600160a01b039092166001600160a01b031990921691909117905550505050506133038061013e6000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c8063741853601161010f578063af5355d8116100a2578063d0fffafd11610071578063d0fffafd14610707578063d685743a1461070f578063e3476cd414610732578063fc5247731461073a576101e5565b8063af5355d8146105f5578063b13cd785146105fd578063b7224ec71461066b578063cda218c714610699576101e5565b80638da5cb5b116100de5780638da5cb5b146105a55780638dd5bfbc146105ad5780639e3b92ca146105ca578063a5f27edb146105ed576101e5565b80637418536014610585578063759076e51461058d57806379ba509714610595578063899ffef41461059d576101e5565b80632992dba21161018757806342c7b8191161015657806342c7b8191461047d57806353a47bb71461049a578063614d08f8146104a25780636bf7c435146104aa576101e5565b80632992dba2146104085780632af64bd314610429578063392e53cd146104455780633a900a2e1461044d576101e5565b806307619a5f116101c357806307619a5f146102495780630fb38465146103075780631627540c1461032457806317b38db41461034a576101e5565b806304bd11e5146101ea57806304f3bcec1461020b578063053932621461022f575b600080fd5b6102096004803603602081101561020057600080fd5b50351515610742565b005b610213610756565b604080516001600160a01b039092168252519081900360200190f35b610237610765565b60408051918252519081900360200190f35b6102b76004803603602081101561025f57600080fd5b810190602081018135600160201b81111561027957600080fd5b82018360208201111561028b57600080fd5b803590602001918460208302840111600160201b831117156102ac57600080fd5b50909250905061076c565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156102f35781810151838201526020016102db565b505050509050019250505060405180910390f35b6102376004803603602081101561031d57600080fd5b50356107b3565b6102096004803603602081101561033a57600080fd5b50356001600160a01b03166107c5565b6102096004803603604081101561036057600080fd5b810190602081018135600160201b81111561037a57600080fd5b82018360208201111561038c57600080fd5b803590602001918460208302840111600160201b831117156103ad57600080fd5b919390929091602081019035600160201b8111156103ca57600080fd5b8201836020820111156103dc57600080fd5b803590602001918460208302840111600160201b831117156103fd57600080fd5b509092509050610821565b61041061089c565b6040805192835290151560208301528051918290030190f35b610431610b21565b604080519115158252519081900360200190f35b610431610c2b565b610455610c39565b6040805194855260208501939093529015158383015215156060830152519081900360800190f35b6102096004803603602081101561049357600080fd5b5035610c6a565b610213610d93565b610237610da2565b610518600480360360208110156104c057600080fd5b810190602081018135600160201b8111156104da57600080fd5b8201836020820111156104ec57600080fd5b803590602001918460208302840111600160201b8311171561050d57600080fd5b509092509050610db2565b604051808060200185815260200184815260200183151515158152602001828103825286818151815260200191508051906020019060200280838360005b8381101561056e578181015183820152602001610556565b505050509050019550505050505060405180910390f35b610209610e05565b610410610fcd565b610209610fe0565b6102b761109c565b610213611230565b610209600480360360208110156105c357600080fd5b503561123f565b610209600480360360408110156105e057600080fd5b508035906020013561131b565b610431611389565b610237611392565b6102b76004803603602081101561061357600080fd5b810190602081018135600160201b81111561062d57600080fd5b82018360208201111561063f57600080fd5b803590602001918460208302840111600160201b8311171561066057600080fd5b5090925090506113a1565b6102096004803603604081101561068157600080fd5b506001600160a01b03813581169160200135166113df565b610209600480360360208110156106af57600080fd5b810190602081018135600160201b8111156106c957600080fd5b8201836020820111156106db57600080fd5b803590602001918460208302840111600160201b831117156106fc57600080fd5b5090925090506117aa565b61023761193f565b6102096004803603604081101561072557600080fd5b5080359060200135611945565b6102096119d2565b610431611c84565b61074a611c91565b61075381611cf7565b50565b6002546001600160a01b031681565b6004545b90565b60606107aa838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d4492505050565b90505b92915050565b60009081526005602052604090205490565b6107cd611dd4565b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229181900360200190a150565b610829611e1d565b6108968484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201829052509250611e97915050565b50505050565b60008060606108a961200d565b6001600160a01b03166372cb051f6040518163ffffffff1660e01b815260040160006040518083038186803b1580156108e157600080fd5b505afa1580156108f5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561091e57600080fd5b8101908080516040519392919084600160201b82111561093d57600080fd5b90830190602082018581111561095257600080fd5b82518660208202830111600160201b8211171561096e57600080fd5b82525081516020918201928201910280838360005b8381101561099b578181015183820152602001610983565b505050509050016040525050509050606060006109b6612021565b6001600160a01b031663c8e5bbd5846040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b83811015610a145781810151838201526020016109fc565b505050509050019250505060006040518083038186803b158015610a3757600080fd5b505afa158015610a4b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040908152811015610a7457600080fd5b8101908080516040519392919084600160201b821115610a9357600080fd5b908301906020820185811115610aa857600080fd5b82518660208202830111600160201b82111715610ac457600080fd5b82525081516020918201928201910280838360005b83811015610af1578181015183820152602001610ad9565b50505050919091016040525060200151929450919250610b169150849050838361203c565b945094505050509091565b60006060610b2d61109c565b905060005b8151811015610c22576000828281518110610b4957fe5b6020908102919091018101516000818152600383526040908190205460025482516321f8a72160e01b81526004810185905292519395506001600160a01b03918216949116926321f8a721926024808201939291829003018186803b158015610bb157600080fd5b505afa158015610bc5573d6000803e3d6000fd5b505050506040513d6020811015610bdb57600080fd5b50516001600160a01b0316141580610c0857506000818152600360205260409020546001600160a01b0316155b15610c195760009350505050610769565b50600101610b32565b50600191505090565b600854610100900460ff1681565b6007546004546008546000928392839283929190829060ff16610c5b82612255565b94509450945094505090919293565b610c72611c91565b6000610c7d8261226e565b90506000821315610cf357631cd554d160e21b60005260056020526000805160206132af83398151915254610cb8908263ffffffff61227916565b631cd554d160e21b60005260056020526000805160206132af83398151915255600454610ceb908263ffffffff61227916565b600455610d5a565b631cd554d160e21b60005260056020526000805160206132af83398151915254610d23908263ffffffff6122d316565b631cd554d160e21b60005260056020526000805160206132af83398151915255600454610d56908263ffffffff6122d316565b6004555b60045460408051918252517f294a7c394e53042c7d754779562747d93b41db019dd4b970dd9b531db71be5999181900360200190a15050565b6001546001600160a01b031681565b6844656274436163686560b81b81565b60606000806000610df586868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061233092505050565b9299919850965090945092505050565b6060610e0f61109c565b905060005b8151811015610fc9576000828281518110610e2b57fe5b602090810291909101810151600254604080517f5265736f6c766572206d697373696e67207461726765743a2000000000000000818601526039808201859052825180830390910181526059820180845263dacb2d0160e01b9052605d8201858152607d83019384528151609d84015281519597506000966001600160a01b039095169563dacb2d01958995939492939260bd0191908501908083838c5b83811015610ee1578181015183820152602001610ec9565b50505050905090810190601f168015610f0e5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015610f2c57600080fd5b505afa158015610f40573d6000803e3d6000fd5b505050506040513d6020811015610f5657600080fd5b505160008381526003602090815260409182902080546001600160a01b0319166001600160a01b03851690811790915582518681529182015281519293507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68929081900390910190a15050600101610e14565b5050565b600080610fd861255c565b915091509091565b6001546001600160a01b031633146110295760405162461bcd60e51b81526004018080602001828103825260358152602001806132096035913960400191505060405180910390fd5b600054600154604080516001600160a01b03938416815292909116602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6060806110a76128fc565b60408051600880825261012082019092529192506060919060208201610100803883390190505090506524b9b9bab2b960d11b816000815181106110e757fe5b6020026020010181815250506822bc31b430b733b2b960b91b8160018151811061110d57fe5b6020026020010181815250506c45786368616e6765526174657360981b8160028151811061113757fe5b6020026020010181815250506b53797374656d53746174757360a01b8160038151811061116057fe5b6020026020010181815250507021b7b63630ba32b930b626b0b730b3b2b960791b8160048151811061118e57fe5b6020026020010181815250506d57726170706572466163746f727960901b816005815181106111b957fe5b6020026020010181815250506b22ba3432b92bb930b83832b960a11b816006815181106111e257fe5b60200260200101818152505073233aba3ab932b9a6b0b935b2ba26b0b730b3b2b960611b8160078151811061121357fe5b602002602001018181525050611229828261294d565b9250505090565b6000546001600160a01b031681565b611247611dd4565b600061125161200d565b6001600160a01b03166332608039836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561129457600080fd5b505afa1580156112a8573d6000803e3d6000fd5b505050506040513d60208110156112be57600080fd5b50516001600160a01b03161461130a576040805162461bcd60e51b815260206004820152600c60248201526b53796e74682065786973747360a01b604482015290519081900360640190fd5b600090815260056020526040812055565b611323612a09565b6000828152600660205260408120548201908112156113735760405162461bcd60e51b81526004018080602001828103825260248152602001806131e56024913960400191505060405180910390fd5b6000928352600660205260409092209190915550565b60085460ff1690565b600061139c612aff565b905090565b60606107aa838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612bae92505050565b6113e7611dd4565b600854610100900460ff161561143a576040805162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b6008805461ff001916610100179055604080516372cb051f60e01b815290516060916001600160a01b038416916372cb051f91600480820192600092909190829003018186803b15801561148d57600080fd5b505afa1580156114a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156114ca57600080fd5b8101908080516040519392919084600160201b8211156114e957600080fd5b9083019060208201858111156114fe57600080fd5b82518660208202830111600160201b8211171561151a57600080fd5b82525081516020918201928201910280838360005b8381101561154757818101518382015260200161152f565b50505050905001604052505050905060008151116115ac576040805162461bcd60e51b815260206004820152601d60248201527f70726576696f75732049737375657220686173206e6f2073796e746873000000604482015290519081900360640190fd5b6060836001600160a01b03166307619a5f836040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b8381101561160d5781810151838201526020016115f5565b505050509050019250505060006040518083038186803b15801561163057600080fd5b505afa158015611644573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561166d57600080fd5b8101908080516040519392919084600160201b82111561168c57600080fd5b9083019060208201858111156116a157600080fd5b82518660208202830111600160201b821117156116bd57600080fd5b82525081516020918201928201910280838360005b838110156116ea5781810151838201526020016116d2565b50505050905001604052505050905060008090505b82518110156117a357600082828151811061171657fe5b6020026020010151111561179b5761177082828151811061173357fe5b60200260200101516006600086858151811061174b57fe5b602002602001015181526020019081526020016000205461227990919063ffffffff16565b6006600085848151811061178057fe5b60200260200101518152602001908152602001600020819055505b6001016116ff565b5050505050565b6117b2612c36565b606060006117be612021565b6001600160a01b031663c8e5bbd585856040518363ffffffff1660e01b815260040180806020018281038252848482818152602001925060200280828437600081840152601f19601f820116905080830192505050935050505060006040518083038186803b15801561183057600080fd5b505afa158015611844573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604090815281101561186d57600080fd5b8101908080516040519392919084600160201b82111561188c57600080fd5b9083019060208201858111156118a157600080fd5b82518660208202830111600160201b821117156118bd57600080fd5b82525081516020918201928201910280838360005b838110156118ea5781810151838201526020016118d2565b505050509190910160408181526020938401518a850280840186019092528a8352969850959650610896959094508993508892839250850190849080828437600092019190915250869250859150611e979050565b60075490565b61194d611c91565b60408051600180825281830190925260609160208083019080388339019050509050828160008151811061197d57fe5b602090810291909101015260408051600180825281830190925260609181602001602082028038833901905050905082816000815181106119ba57fe5b60200260200101818152505061089682826000611e97565b6119da612c36565b60606119e461200d565b6001600160a01b03166372cb051f6040518163ffffffff1660e01b815260040160006040518083038186803b158015611a1c57600080fd5b505afa158015611a30573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611a5957600080fd5b8101908080516040519392919084600160201b821115611a7857600080fd5b908301906020820185811115611a8d57600080fd5b82518660208202830111600160201b82111715611aa957600080fd5b82525081516020918201928201910280838360005b83811015611ad6578181015183820152602001611abe565b50505050905001604052505050905060606000806000611af585612330565b6b11955515549154d7d111509560a21b600090815260056020527fb03402a6fc396b42a4a74df8120873f820800f1398191168ef707a9051d6d76e849055845194985092965090945092508491905b81811015611bae576000878281518110611b5a57fe5b60200260200101519050611b77818561227990919063ffffffff16565b935080600560008b8581518110611b8a57fe5b60209081029190910181015182528101919091526040016000205550600101611b44565b506c115610d31551115117d1115095609a1b600090815260056020527fbca14b7b4212dd98a4b255832d862779dccd9aba14592c2e2c4e62d4efc07bc7859055611bfe838663ffffffff612c9c16565b6004819055426007556040805182815290519192507f294a7c394e53042c7d754779562747d93b41db019dd4b970dd9b531db71be599919081900360200190a16040805142815290517fc481e742c89630d4b1a5ed3a0fc624c1c41ed463bd00ac26a7e93c71e932126f9181900360200190a1611c7a84611cf7565b5050505050505050565b600061139c600754612255565b611c9961200d565b6001600160a01b0316336001600160a01b031614611cf5576040805162461bcd60e51b815260206004820152601460248201527329b2b73232b91034b9903737ba1024b9b9bab2b960611b604482015290519081900360640190fd5b565b60085460ff16151581151514610753576008805460ff19168215159081179091556040517f8eebec690c34bbf0fe0d5b93e442beaf16bdaf99052569581de2dcb3e31a53a790600090a250565b6060600082519050606081604051908082528060200260200182016040528015611d78578160200160208202803883390190505b50905060005b82811015611dcc5760066000868381518110611d9657fe5b6020026020010151815260200190815260200160002054828281518110611db957fe5b6020908102919091010152600101611d7e565b509392505050565b6000546001600160a01b03163314611cf55760405162461bcd60e51b815260040180806020018281038252602f81526020018061325f602f913960400191505060405180910390fd5b611e2561200d565b6001600160a01b0316336001600160a01b03161480611e5c5750611e47612cb7565b6001600160a01b0316336001600160a01b0316145b611cf55760405162461bcd60e51b815260040180806020018281038252602181526020018061323e6021913960400191505060405180910390fd5b825182518114611eee576040805162461bcd60e51b815260206004820152601a60248201527f496e707574206172726179206c656e6774687320646966666572000000000000604482015290519081900360640190fd5b6000806060611efd8787612cce565b905060005b84811015611f8c576000888281518110611f1857fe5b602002602001015190506000838381518110611f3057fe5b60200260200101519050611f6060056000848152602001908152602001600020548761227990919063ffffffff16565b9550611f72858263ffffffff61227916565b600092835260056020526040909220559250600101611f02565b50818314611ff557600454611fb784611fab838663ffffffff61227916565b9063ffffffff6122d316565b60048190556040805182815290519192507f294a7c394e53042c7d754779562747d93b41db019dd4b970dd9b531db71be599919081900360200190a1505b84156120045761200485611cf7565b50505050505050565b600061139c6524b9b9bab2b960d11b612f99565b600061139c6c45786368616e6765526174657360981b612f99565b60008060008061204a613076565b6001600160a01b0316631e33fc6b6040518163ffffffff1660e01b8152600401604080518083038186803b15801561208157600080fd5b505afa158015612095573d6000803e3d6000fd5b505050506040513d60408110156120ab57600080fd5b50805160209091015190925090506000806120c4613076565b6001600160a01b031663ad79a8586040518163ffffffff1660e01b8152600401604080518083038186803b1580156120fb57600080fd5b505afa15801561210f573d6000803e3d6000fd5b505050506040513d604081101561212557600080fd5b5080516020909101519092509050868061213c5750825b806121445750805b9450612156848363ffffffff61227916565b95506121d4612163613095565b6001600160a01b031663ee5f3f5c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561219b57600080fd5b505afa1580156121af573d6000803e3d6000fd5b505050506040513d60208110156121c557600080fd5b5051879063ffffffff61227916565b955060005b89518110156122485761223e6122318a83815181106121f457fe5b6020026020010151600660008e868151811061220c57fe5b60200260200101518152602001908152602001600020546130af90919063ffffffff16565b889063ffffffff61227916565b96506001016121d9565b5050505050935093915050565b6000814203612262612aff565b10806107ad5750501590565b60006107ad826130c4565b6000828201838110156107aa576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008282111561232a576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6060600080600060606000612343612021565b6001600160a01b031663c8e5bbd5886040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b838110156123a1578181015183820152602001612389565b505050509050019250505060006040518083038186803b1580156123c457600080fd5b505afa1580156123d8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604090815281101561240157600080fd5b8101908080516040519392919084600160201b82111561242057600080fd5b90830190602082018581111561243557600080fd5b82518660208202830111600160201b8211171561245157600080fd5b82525081516020918201928201910280838360005b8381101561247e578181015183820152602001612466565b50505050919091016040525060200151929450919250606091506124a490508884612cce565b90506000806124b48a868661203c565b915091506000806124c36130da565b6001600160a01b031663fc7b9c186040518163ffffffff1660e01b8152600401604080518083038186803b1580156124fa57600080fd5b505afa15801561250e573d6000803e3d6000fd5b505050506040513d604081101561252457600080fd5b5080516020909101519092509050848285888061253e5750835b806125465750855b9a509a509a509a50505050505050509193509193565b600080606061256961200d565b6001600160a01b03166372cb051f6040518163ffffffff1660e01b815260040160006040518083038186803b1580156125a157600080fd5b505afa1580156125b5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156125de57600080fd5b8101908080516040519392919084600160201b8211156125fd57600080fd5b90830190602082018581111561261257600080fd5b82518660208202830111600160201b8211171561262e57600080fd5b82525081516020918201928201910280838360005b8381101561265b578181015183820152602001612643565b50505050905001604052505050905060606000612676612021565b6001600160a01b031663c8e5bbd5846040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b838110156126d45781810151838201526020016126bc565b505050509050019250505060006040518083038186803b1580156126f757600080fd5b505afa15801561270b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604090815281101561273457600080fd5b8101908080516040519392919084600160201b82111561275357600080fd5b90830190602082018581111561276857600080fd5b82518660208202830111600160201b8211171561278457600080fd5b82525081516020918201928201910280838360005b838110156127b1578181015183820152602001612799565b50505050919091016040525060200151929450919250606091506127d790508484612cce565b90506000806127e786868661203c565b845191935091506000805b8281101561282a5761282086828151811061280957fe5b60200260200101518361227990919063ffffffff16565b91506001016127f2565b506000806128366130da565b6001600160a01b031663fc7b9c186040518163ffffffff1660e01b8152600401604080518083038186803b15801561286d57600080fd5b505afa158015612881573d6000803e3d6000fd5b505050506040513d604081101561289757600080fd5b50805160209091015190925090506128b5838363ffffffff61227916565b92508583106128d3576128ce838763ffffffff6122d316565b6128d6565b60005b92508288806128e25750815b806128ea5750855b9b509b50505050505050505050509091565b604080516001808252818301909252606091602080830190803883390190505090506e466c657869626c6553746f7261676560881b8160008151811061293e57fe5b60200260200101818152505090565b6060815183510160405190808252806020026020018201604052801561297d578160200160208202803883390190505b50905060005b83518110156129bf5783818151811061299857fe5b60200260200101518282815181106129ac57fe5b6020908102919091010152600101612983565b5060005b8251811015612a02578281815181106129d857fe5b60200260200101518282865101815181106129ef57fe5b60209081029190910101526001016129c3565b5092915050565b6000612a136130fc565b6001600160a01b031663e0aa2797336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612a6857600080fd5b505afa158015612a7c573d6000803e3d6000fd5b505050506040513d6020811015612a9257600080fd5b50516000549091506001600160a01b031633148080612aae5750815b610fc9576040805162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920646562742069737375657273206d61792063616c6c207468697300604482015290519081900360640190fd5b6000612b09613118565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b7464656274536e617073686f745374616c6554696d6560581b6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b158015612b7d57600080fd5b505afa158015612b91573d6000803e3d6000fd5b505050506040513d6020811015612ba757600080fd5b5051905090565b6060600082519050606081604051908082528060200260200182016040528015612be2578160200160208202803883390190505b50905060005b82811015611dcc5760056000868381518110612c0057fe5b6020026020010151815260200190815260200160002054828281518110612c2357fe5b6020908102919091010152600101612be8565b6000546001600160a01b03163314611cf557612c50613135565b6001600160a01b031663086dabd16040518163ffffffff1660e01b815260040160006040518083038186803b158015612c8857600080fd5b505afa158015610896573d6000803e3d6000fd5b600082821015612cae578183036107aa565b50600092915050565b600061139c6822bc31b430b733b2b960b91b612f99565b606060008351905080604051908082528060200260200182016040528015612d00578160200160208202803883390190505b5091506060612d0d61200d565b6001600160a01b0316633b6afe40866040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b83811015612d6b578181015183820152602001612d53565b505050509050019250505060006040518083038186803b158015612d8e57600080fd5b505afa158015612da2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612dcb57600080fd5b8101908080516040519392919084600160201b821115612dea57600080fd5b908301906020820185811115612dff57600080fd5b82518660208202830111600160201b82111715612e1b57600080fd5b82525081516020918201928201910280838360005b83811015612e48578181015183820152602001612e30565b50505050905001604052505050905060008090505b82811015612f90576000828281518110612e7357fe5b6020026020010151905060006001600160a01b0316816001600160a01b03161415612edc576040805162461bcd60e51b815260206004820152601460248201527314de5b9d1a08191bd95cc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b6000816001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612f1757600080fd5b505afa158015612f2b573d6000803e3d6000fd5b505050506040513d6020811015612f4157600080fd5b50518751909150612f6f90889085908110612f5857fe5b6020026020010151826130af90919063ffffffff16565b868481518110612f7b57fe5b60209081029190910101525050600101612e5d565b50505092915050565b600081815260036020908152604080832054815170026b4b9b9b4b7339030b2323932b9b99d1607d1b9381019390935260318084018690528251808503909101815260519093019091526001600160a01b03169081612a025760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561303b578181015183820152602001613023565b50505050905090810190601f1680156130685780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b600061139c7021b7b63630ba32b930b626b0b730b3b2b960791b612f99565b600061139c6b22ba3432b92bb930b83832b960a11b612f99565b60006107aa8383670de0b6b3a764000061314f565b60008082126130d357816107ad565b5060000390565b600061139c73233aba3ab932b9a6b0b935b2ba26b0b730b3b2b960611b612f99565b600061139c6d57726170706572466163746f727960901b612f99565b600061139c6e466c657869626c6553746f7261676560881b612f99565b600061139c6b53797374656d53746174757360a01b612f99565b600080600a8304613166868663ffffffff61318b16565b8161316d57fe5b0490506005600a82061061317f57600a015b600a9004949350505050565b60008261319a575060006107ad565b828202828482816131a757fe5b04146107aa5760405162461bcd60e51b815260040180806020018281038252602181526020018061328e6021913960400191505060405180910390fdfe4578636c7564656420646562742063616e6e6f74206265636f6d65206e65676174697665596f75206d757374206265206e6f6d696e61746564206265666f726520796f752063616e20616363657074206f776e65727368697053656e646572206973206e6f7420497373756572206f722045786368616e6765724f6e6c792074686520636f6e7472616374206f776e6572206d617920706572666f726d207468697320616374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7774c62d09fbc50aefae0794a9a068f786a692826fbdfe63828ec23a875865823fa265627a7a723158202400349b111f11971a00e184852baa1066b223ca1073e686cd4d88dad61c585864736f6c6343000510003200000000000000000000000073570075092502472e4b61a7058df1a4a1db12f2000000000000000000000000242a3df52c375bee81b1c668741d7c63af68fdd2

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

00000000000000000000000073570075092502472e4b61a7058df1a4a1db12f2000000000000000000000000242a3df52c375bee81b1c668741d7c63af68fdd2

-----Decoded View---------------
Arg [0] : _owner (address): 0x73570075092502472e4b61a7058df1a4a1db12f2
Arg [1] : _resolver (address): 0x242a3df52c375bee81b1c668741d7c63af68fdd2

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000073570075092502472e4b61a7058df1a4a1db12f2
Arg [1] : 000000000000000000000000242a3df52c375bee81b1c668741d7c63af68fdd2


Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading

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