Contract 0x2bAf929DBff85A8148D339EA122c8dcbd055F30a

Contract Overview

Balance:
0 Ether
Txn Hash
Method
Block
From
To
Value
0x649f2c52f3a0475470902807019cf92c74be6d43dbe6d3923ff93417e394caef0x60806040315767772022-05-13 5:40:0052 days 19 hrs ago0x73570075092502472e4b61a7058df1a4a1db12f2 IN  Create: Synthetix0 Ether0.00449611 1
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x46824bfaafd049fb0af9a45159a88e595bbbb9f70 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f 0x2baf929dbff85a8148d339ea122c8dcbd055f30a0 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x46824bfaafd049fb0af9a45159a88e595bbbb9f70 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f 0x2baf929dbff85a8148d339ea122c8dcbd055f30a0 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x46824bfaafd049fb0af9a45159a88e595bbbb9f70 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f 0x2baf929dbff85a8148d339ea122c8dcbd055f30a0 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f0 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x46824bfaafd049fb0af9a45159a88e595bbbb9f70 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x46824bfaafd049fb0af9a45159a88e595bbbb9f70 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x46824bfaafd049fb0af9a45159a88e595bbbb9f70 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x46824bfaafd049fb0af9a45159a88e595bbbb9f70 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x46824bfaafd049fb0af9a45159a88e595bbbb9f70 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x46824bfaafd049fb0af9a45159a88e595bbbb9f70 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x923f8f53c9bd1f0c84745394e47ea31c5949ef960 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x648727a32112e6c233c1c5d8d57a9aa736ffb18b0 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f 0x2baf929dbff85a8148d339ea122c8dcbd055f30a0 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f 0x2baf929dbff85a8148d339ea122c8dcbd055f30a0 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x46824bfaafd049fb0af9a45159a88e595bbbb9f70 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f 0x2baf929dbff85a8148d339ea122c8dcbd055f30a0 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x46824bfaafd049fb0af9a45159a88e595bbbb9f70 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f 0x2baf929dbff85a8148d339ea122c8dcbd055f30a0 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x46824bfaafd049fb0af9a45159a88e595bbbb9f70 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f 0x2baf929dbff85a8148d339ea122c8dcbd055f30a0 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f0 Ether
0x0104cfdb114e94f1db6a9841f226109efa2b9cebfe48177c105d8b9faf969b14317618172022-05-23 8:29:4842 days 16 hrs ago 0x2baf929dbff85a8148d339ea122c8dcbd055f30a 0x46824bfaafd049fb0af9a45159a88e595bbbb9f70 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Synthetix

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-05-13
*/

/*

⚠⚠⚠ WARNING WARNING WARNING ⚠⚠⚠

This is a TARGET contract - DO NOT CONNECT TO IT DIRECTLY IN YOUR CONTRACTS or DAPPS!

This contract has an associated PROXY that MUST be used for all integrations - this TARGET will be REPLACED in an upcoming Synthetix release!
The proxy for this contract can be found here:

https://contracts.synthetix.io/kovan/ProxySynthetix

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

* Synthetix: Synthetix.sol
*
* Latest source (may be newer): https://github.com/Synthetixio/synthetix/blob/master/contracts/Synthetix.sol
* Docs: https://docs.synthetix.io/contracts/Synthetix
*
* Contract Dependencies: 
*	- BaseSynthetix
*	- ExternStateToken
*	- IAddressResolver
*	- IERC20
*	- ISynthetix
*	- MixinResolver
*	- Owned
*	- Proxyable
*	- State
* Libraries: 
*	- SafeDecimalMath
*	- SafeMath
*	- VestingEntries
*
* 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.4.24;

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


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


// Inheritance


// Internal references


// https://docs.synthetix.io/contracts/source/contracts/proxy
contract Proxy is Owned {
    Proxyable public target;

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

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

    function _emit(
        bytes calldata callData,
        uint numTopics,
        bytes32 topic1,
        bytes32 topic2,
        bytes32 topic3,
        bytes32 topic4
    ) external onlyTarget {
        uint size = callData.length;
        bytes memory _callData = callData;

        assembly {
            /* The first 32 bytes of callData contain its length (as specified by the abi).
             * Length is assumed to be a uint256 and therefore maximum of 32 bytes
             * in length. It is also leftpadded to be a multiple of 32 bytes.
             * This means moving call_data across 32 bytes guarantees we correctly access
             * the data itself. */
            switch numTopics
                case 0 {
                    log0(add(_callData, 32), size)
                }
                case 1 {
                    log1(add(_callData, 32), size, topic1)
                }
                case 2 {
                    log2(add(_callData, 32), size, topic1, topic2)
                }
                case 3 {
                    log3(add(_callData, 32), size, topic1, topic2, topic3)
                }
                case 4 {
                    log4(add(_callData, 32), size, topic1, topic2, topic3, topic4)
                }
        }
    }

    // solhint-disable no-complex-fallback
    function() external payable {
        // Mutable call setting Proxyable.messageSender as this is using call not delegatecall
        target.setMessageSender(msg.sender);

        assembly {
            let free_ptr := mload(0x40)
            calldatacopy(free_ptr, 0, calldatasize)

            /* We must explicitly forward ether to the underlying contract as well. */
            let result := call(gas, sload(target_slot), callvalue, free_ptr, calldatasize, 0, 0)
            returndatacopy(free_ptr, 0, returndatasize)

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

    modifier onlyTarget {
        require(Proxyable(msg.sender) == target, "Must be proxy target");
        _;
    }

    event TargetUpdated(Proxyable newTarget);
}


// Inheritance


// Internal references


// https://docs.synthetix.io/contracts/source/contracts/proxyable
contract Proxyable is Owned {
    // This contract should be treated like an abstract contract

    /* The proxy this contract exists behind. */
    Proxy public proxy;

    /* The caller of the proxy, passed through to this contract.
     * Note that every function using this member must apply the onlyProxy or
     * optionalProxy modifiers, otherwise their invocations can use stale values. */
    address public messageSender;

    constructor(address payable _proxy) internal {
        // This contract is abstract, and thus cannot be instantiated directly
        require(owner != address(0), "Owner must be set");

        proxy = Proxy(_proxy);
        emit ProxyUpdated(_proxy);
    }

    function setProxy(address payable _proxy) external onlyOwner {
        proxy = Proxy(_proxy);
        emit ProxyUpdated(_proxy);
    }

    function setMessageSender(address sender) external onlyProxy {
        messageSender = sender;
    }

    modifier onlyProxy {
        _onlyProxy();
        _;
    }

    function _onlyProxy() private view {
        require(Proxy(msg.sender) == proxy, "Only the proxy can call");
    }

    modifier optionalProxy {
        _optionalProxy();
        _;
    }

    function _optionalProxy() private {
        if (Proxy(msg.sender) != proxy && messageSender != msg.sender) {
            messageSender = msg.sender;
        }
    }

    modifier optionalProxy_onlyOwner {
        _optionalProxy_onlyOwner();
        _;
    }

    // solhint-disable-next-line func-name-mixedcase
    function _optionalProxy_onlyOwner() private {
        if (Proxy(msg.sender) != proxy && messageSender != msg.sender) {
            messageSender = msg.sender;
        }
        require(messageSender == owner, "Owner only function");
    }

    event ProxyUpdated(address proxyAddress);
}


/**
 * @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));
    }
}


// Inheritance


// https://docs.synthetix.io/contracts/source/contracts/state
contract State is Owned {
    // the address of the contract that can modify variables
    // this can only be changed by the owner of this contract
    address public associatedContract;

    constructor(address _associatedContract) internal {
        // This contract is abstract, and thus cannot be instantiated directly
        require(owner != address(0), "Owner must be set");

        associatedContract = _associatedContract;
        emit AssociatedContractUpdated(_associatedContract);
    }

    /* ========== SETTERS ========== */

    // Change the associated contract to a new address
    function setAssociatedContract(address _associatedContract) external onlyOwner {
        associatedContract = _associatedContract;
        emit AssociatedContractUpdated(_associatedContract);
    }

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

    modifier onlyAssociatedContract {
        require(msg.sender == associatedContract, "Only the associated contract can perform this action");
        _;
    }

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

    event AssociatedContractUpdated(address associatedContract);
}


// Inheritance


// https://docs.synthetix.io/contracts/source/contracts/tokenstate
contract TokenState is Owned, State {
    /* ERC20 fields. */
    mapping(address => uint) public balanceOf;
    mapping(address => mapping(address => uint)) public allowance;

    constructor(address _owner, address _associatedContract) public Owned(_owner) State(_associatedContract) {}

    /* ========== SETTERS ========== */

    /**
     * @notice Set ERC20 allowance.
     * @dev Only the associated contract may call this.
     * @param tokenOwner The authorising party.
     * @param spender The authorised party.
     * @param value The total value the authorised party may spend on the
     * authorising party's behalf.
     */
    function setAllowance(
        address tokenOwner,
        address spender,
        uint value
    ) external onlyAssociatedContract {
        allowance[tokenOwner][spender] = value;
    }

    /**
     * @notice Set the balance in a given account
     * @dev Only the associated contract may call this.
     * @param account The account whose value to set.
     * @param value The new balance of the given account.
     */
    function setBalanceOf(address account, uint value) external onlyAssociatedContract {
        balanceOf[account] = value;
    }
}


// Inheritance


// Libraries


// Internal references


// https://docs.synthetix.io/contracts/source/contracts/externstatetoken
contract ExternStateToken is Owned, Proxyable {
    using SafeMath for uint;
    using SafeDecimalMath for uint;

    /* ========== STATE VARIABLES ========== */

    /* Stores balances and allowances. */
    TokenState public tokenState;

    /* Other ERC20 fields. */
    string public name;
    string public symbol;
    uint public totalSupply;
    uint8 public decimals;

    constructor(
        address payable _proxy,
        TokenState _tokenState,
        string memory _name,
        string memory _symbol,
        uint _totalSupply,
        uint8 _decimals,
        address _owner
    ) public Owned(_owner) Proxyable(_proxy) {
        tokenState = _tokenState;

        name = _name;
        symbol = _symbol;
        totalSupply = _totalSupply;
        decimals = _decimals;
    }

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

    /**
     * @notice Returns the ERC20 allowance of one party to spend on behalf of another.
     * @param owner The party authorising spending of their funds.
     * @param spender The party spending tokenOwner's funds.
     */
    function allowance(address owner, address spender) public view returns (uint) {
        return tokenState.allowance(owner, spender);
    }

    /**
     * @notice Returns the ERC20 token balance of a given account.
     */
    function balanceOf(address account) external view returns (uint) {
        return tokenState.balanceOf(account);
    }

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

    /**
     * @notice Set the address of the TokenState contract.
     * @dev This can be used to "pause" transfer functionality, by pointing the tokenState at 0x000..
     * as balances would be unreachable.
     */
    function setTokenState(TokenState _tokenState) external optionalProxy_onlyOwner {
        tokenState = _tokenState;
        emitTokenStateUpdated(address(_tokenState));
    }

    function _internalTransfer(
        address from,
        address to,
        uint value
    ) internal returns (bool) {
        /* Disallow transfers to irretrievable-addresses. */
        require(to != address(0) && to != address(this) && to != address(proxy), "Cannot transfer to this address");

        // Insufficient balance will be handled by the safe subtraction.
        tokenState.setBalanceOf(from, tokenState.balanceOf(from).sub(value));
        tokenState.setBalanceOf(to, tokenState.balanceOf(to).add(value));

        // Emit a standard ERC20 transfer event
        emitTransfer(from, to, value);

        return true;
    }

    /**
     * @dev Perform an ERC20 token transfer. Designed to be called by transfer functions possessing
     * the onlyProxy or optionalProxy modifiers.
     */
    function _transferByProxy(
        address from,
        address to,
        uint value
    ) internal returns (bool) {
        return _internalTransfer(from, to, value);
    }

    /*
     * @dev Perform an ERC20 token transferFrom. Designed to be called by transferFrom functions
     * possessing the optionalProxy or optionalProxy modifiers.
     */
    function _transferFromByProxy(
        address sender,
        address from,
        address to,
        uint value
    ) internal returns (bool) {
        /* Insufficient allowance will be handled by the safe subtraction. */
        tokenState.setAllowance(from, sender, tokenState.allowance(from, sender).sub(value));
        return _internalTransfer(from, to, value);
    }

    /**
     * @notice Approves spender to transfer on the message sender's behalf.
     */
    function approve(address spender, uint value) public optionalProxy returns (bool) {
        address sender = messageSender;

        tokenState.setAllowance(sender, spender, value);
        emitApproval(sender, spender, value);
        return true;
    }

    /* ========== EVENTS ========== */
    function addressToBytes32(address input) internal pure returns (bytes32) {
        return bytes32(uint256(uint160(input)));
    }

    event Transfer(address indexed from, address indexed to, uint value);
    bytes32 internal constant TRANSFER_SIG = keccak256("Transfer(address,address,uint256)");

    function emitTransfer(
        address from,
        address to,
        uint value
    ) internal {
        proxy._emit(abi.encode(value), 3, TRANSFER_SIG, addressToBytes32(from), addressToBytes32(to), 0);
    }

    event Approval(address indexed owner, address indexed spender, uint value);
    bytes32 internal constant APPROVAL_SIG = keccak256("Approval(address,address,uint256)");

    function emitApproval(
        address owner,
        address spender,
        uint value
    ) internal {
        proxy._emit(abi.encode(value), 3, APPROVAL_SIG, addressToBytes32(owner), addressToBytes32(spender), 0);
    }

    event TokenStateUpdated(address newTokenState);
    bytes32 internal constant TOKENSTATEUPDATED_SIG = keccak256("TokenStateUpdated(address)");

    function emitTokenStateUpdated(address newTokenState) internal {
        proxy._emit(abi.encode(newTokenState), 1, TOKENSTATEUPDATED_SIG, 0, 0, 0);
    }
}


// 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 allNetworksDebtInfo()
        external
        view
        returns (
            uint256 debt,
            uint256 sharesSupply,
            bool isStale
        );

    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 setCurrentPeriodId(uint128 periodId) external;

    function liquidateAccount(address account, bool isSelfLiquidation)
        external
        returns (uint totalRedeemed, uint amountToLiquidate);

    function issueSynthsWithoutDebt(
        bytes32 currencyKey,
        address to,
        uint amount
    ) external returns (bool rateInvalid);

    function burnSynthsWithoutDebt(
        bytes32 currencyKey,
        address to,
        uint amount
    ) external returns (bool rateInvalid);
}


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


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/isynthetix
interface ISynthetix {
    // 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 collateral(address account) external view returns (uint);

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

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

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

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

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

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

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

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

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

    function transferableSynthetix(address account) external view returns (uint transferable);

    // Mutative Functions
    function burnSynths(uint amount) external;

    function burnSynthsOnBehalf(address burnForAddress, uint amount) external;

    function burnSynthsToTarget() external;

    function burnSynthsToTargetOnBehalf(address burnForAddress) external;

    function exchange(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey
    ) external returns (uint amountReceived);

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

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

    function exchangeWithTrackingForInitiator(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        address rewardAddress,
        bytes32 trackingCode
    ) external returns (uint amountReceived);

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

    function exchangeWithVirtual(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        bytes32 trackingCode
    ) external returns (uint amountReceived, IVirtualSynth vSynth);

    function exchangeAtomically(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        bytes32 trackingCode,
        uint minAmount
    ) external returns (uint amountReceived);

    function issueMaxSynths() external;

    function issueMaxSynthsOnBehalf(address issueForAddress) external;

    function issueSynths(uint amount) external;

    function issueSynthsOnBehalf(address issueForAddress, uint amount) external;

    function mint() external returns (bool);

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

    // Liquidations
    function liquidateDelinquentAccount(address account) external returns (bool);

    function liquidateSelf() external returns (bool);

    // Restricted Functions

    function mintSecondary(address account, uint amount) external;

    function mintSecondaryRewards(uint amount) external;

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


// 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/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,
        uint minAmount
    ) 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/irewardsdistribution
interface IRewardsDistribution {
    // Structs
    struct DistributionData {
        address destination;
        uint amount;
    }

    // Views
    function authority() external view returns (address);

    function distributions(uint index) external view returns (address destination, uint amount); // DistributionData

    function distributionsLength() external view returns (uint);

    // Mutative Functions
    function distributeRewards(uint amount) external returns (bool);
}


interface ILiquidator {
    // Views
    function issuanceRatio() external view returns (uint);

    function liquidationDelay() external view returns (uint);

    function liquidationRatio() external view returns (uint);

    function liquidationEscrowDuration() external view returns (uint);

    function liquidationPenalty() external view returns (uint);

    function selfLiquidationPenalty() external view returns (uint);

    function liquidateReward() external view returns (uint);

    function flagReward() external view returns (uint);

    function liquidationCollateralRatio() external view returns (uint);

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

    function getLiquidationCallerForAccount(address account) external view returns (address);

    function isLiquidationOpen(address account, bool isSelfLiquidation) external view returns (bool);

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

    function calculateAmountToFixCollateral(
        uint debtBalance,
        uint collateral,
        uint penalty
    ) external view returns (uint);

    // Mutative Functions
    function flagAccountForLiquidation(address account) external;

    // Restricted: used internally to Synthetix contracts
    function removeAccountInLiquidation(address account) external;

    function checkAndRemoveAccountInLiquidation(address account) external;
}


interface ILiquidatorRewards {
    // Views

    function earned(address account) external view returns (uint256);

    // Mutative

    function getReward(address account) external;

    function notifyRewardAmount(uint256 reward) external;

    function updateEntry(address account) external;
}


// Inheritance


// Internal references


contract BaseSynthetix is IERC20, ExternStateToken, MixinResolver, ISynthetix {
    // ========== STATE VARIABLES ==========

    // Available Synths which can be used with the system
    string public constant TOKEN_NAME = "Synthetix Network Token";
    string public constant TOKEN_SYMBOL = "SNX";
    uint8 public constant DECIMALS = 18;
    bytes32 public constant sUSD = "sUSD";

    // ========== ADDRESS RESOLVER CONFIGURATION ==========
    bytes32 private constant CONTRACT_SYSTEMSTATUS = "SystemStatus";
    bytes32 private constant CONTRACT_EXCHANGER = "Exchanger";
    bytes32 private constant CONTRACT_ISSUER = "Issuer";
    bytes32 private constant CONTRACT_REWARDSDISTRIBUTION = "RewardsDistribution";
    bytes32 private constant CONTRACT_LIQUIDATORREWARDS = "LiquidatorRewards";
    bytes32 private constant CONTRACT_LIQUIDATOR = "Liquidator";

    // ========== CONSTRUCTOR ==========

    constructor(
        address payable _proxy,
        TokenState _tokenState,
        address _owner,
        uint _totalSupply,
        address _resolver
    )
        public
        ExternStateToken(_proxy, _tokenState, TOKEN_NAME, TOKEN_SYMBOL, _totalSupply, DECIMALS, _owner)
        MixinResolver(_resolver)
    {}

    // ========== VIEWS ==========

    // Note: use public visibility so that it can be invoked in a subclass
    function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {
        addresses = new bytes32[](6);
        addresses[0] = CONTRACT_SYSTEMSTATUS;
        addresses[1] = CONTRACT_EXCHANGER;
        addresses[2] = CONTRACT_ISSUER;
        addresses[3] = CONTRACT_REWARDSDISTRIBUTION;
        addresses[4] = CONTRACT_LIQUIDATORREWARDS;
        addresses[5] = CONTRACT_LIQUIDATOR;
    }

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

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

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

    function rewardsDistribution() internal view returns (IRewardsDistribution) {
        return IRewardsDistribution(requireAndGetAddress(CONTRACT_REWARDSDISTRIBUTION));
    }

    function liquidatorRewards() internal view returns (ILiquidatorRewards) {
        return ILiquidatorRewards(requireAndGetAddress(CONTRACT_LIQUIDATORREWARDS));
    }

    function liquidator() internal view returns (ILiquidator) {
        return ILiquidator(requireAndGetAddress(CONTRACT_LIQUIDATOR));
    }

    function debtBalanceOf(address account, bytes32 currencyKey) external view returns (uint) {
        return issuer().debtBalanceOf(account, currencyKey);
    }

    function totalIssuedSynths(bytes32 currencyKey) external view returns (uint) {
        return issuer().totalIssuedSynths(currencyKey, false);
    }

    function totalIssuedSynthsExcludeOtherCollateral(bytes32 currencyKey) external view returns (uint) {
        return issuer().totalIssuedSynths(currencyKey, true);
    }

    function availableCurrencyKeys() external view returns (bytes32[] memory) {
        return issuer().availableCurrencyKeys();
    }

    function availableSynthCount() external view returns (uint) {
        return issuer().availableSynthCount();
    }

    function availableSynths(uint index) external view returns (ISynth) {
        return issuer().availableSynths(index);
    }

    function synths(bytes32 currencyKey) external view returns (ISynth) {
        return issuer().synths(currencyKey);
    }

    function synthsByAddress(address synthAddress) external view returns (bytes32) {
        return issuer().synthsByAddress(synthAddress);
    }

    function isWaitingPeriod(bytes32 currencyKey) external view returns (bool) {
        return exchanger().maxSecsLeftInWaitingPeriod(messageSender, currencyKey) > 0;
    }

    function anySynthOrSNXRateIsInvalid() external view returns (bool anyRateInvalid) {
        return issuer().anySynthOrSNXRateIsInvalid();
    }

    function maxIssuableSynths(address account) external view returns (uint maxIssuable) {
        return issuer().maxIssuableSynths(account);
    }

    function remainingIssuableSynths(address account)
        external
        view
        returns (
            uint maxIssuable,
            uint alreadyIssued,
            uint totalSystemDebt
        )
    {
        return issuer().remainingIssuableSynths(account);
    }

    function collateralisationRatio(address _issuer) external view returns (uint) {
        return issuer().collateralisationRatio(_issuer);
    }

    function collateral(address account) external view returns (uint) {
        return issuer().collateral(account);
    }

    function transferableSynthetix(address account) external view returns (uint transferable) {
        (transferable, ) = issuer().transferableSynthetixAndAnyRateIsInvalid(account, tokenState.balanceOf(account));
    }

    function _canTransfer(address account, uint value) internal view returns (bool) {
        if (issuer().debtBalanceOf(account, sUSD) > 0) {
            (uint transferable, bool anyRateIsInvalid) =
                issuer().transferableSynthetixAndAnyRateIsInvalid(account, tokenState.balanceOf(account));
            require(value <= transferable, "Cannot transfer staked or escrowed SNX");
            require(!anyRateIsInvalid, "A synth or SNX rate is invalid");
        }

        return true;
    }

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

    function exchange(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey
    ) external exchangeActive(sourceCurrencyKey, destinationCurrencyKey) optionalProxy returns (uint amountReceived) {
        (amountReceived, ) = exchanger().exchange(
            messageSender,
            messageSender,
            sourceCurrencyKey,
            sourceAmount,
            destinationCurrencyKey,
            messageSender,
            false,
            messageSender,
            bytes32(0)
        );
    }

    function exchangeOnBehalf(
        address exchangeForAddress,
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey
    ) external exchangeActive(sourceCurrencyKey, destinationCurrencyKey) optionalProxy returns (uint amountReceived) {
        (amountReceived, ) = exchanger().exchange(
            exchangeForAddress,
            messageSender,
            sourceCurrencyKey,
            sourceAmount,
            destinationCurrencyKey,
            exchangeForAddress,
            false,
            exchangeForAddress,
            bytes32(0)
        );
    }

    function settle(bytes32 currencyKey)
        external
        optionalProxy
        returns (
            uint reclaimed,
            uint refunded,
            uint numEntriesSettled
        )
    {
        return exchanger().settle(messageSender, currencyKey);
    }

    function exchangeWithTracking(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        address rewardAddress,
        bytes32 trackingCode
    ) external exchangeActive(sourceCurrencyKey, destinationCurrencyKey) optionalProxy returns (uint amountReceived) {
        (amountReceived, ) = exchanger().exchange(
            messageSender,
            messageSender,
            sourceCurrencyKey,
            sourceAmount,
            destinationCurrencyKey,
            messageSender,
            false,
            rewardAddress,
            trackingCode
        );
    }

    function exchangeOnBehalfWithTracking(
        address exchangeForAddress,
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        address rewardAddress,
        bytes32 trackingCode
    ) external exchangeActive(sourceCurrencyKey, destinationCurrencyKey) optionalProxy returns (uint amountReceived) {
        (amountReceived, ) = exchanger().exchange(
            exchangeForAddress,
            messageSender,
            sourceCurrencyKey,
            sourceAmount,
            destinationCurrencyKey,
            exchangeForAddress,
            false,
            rewardAddress,
            trackingCode
        );
    }

    function transfer(address to, uint value) external optionalProxy systemActive returns (bool) {
        // Ensure they're not trying to exceed their locked amount -- only if they have debt.
        _canTransfer(messageSender, value);

        // Perform the transfer: if there is a problem an exception will be thrown in this call.
        _transferByProxy(messageSender, to, value);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint value
    ) external optionalProxy systemActive returns (bool) {
        // Ensure they're not trying to exceed their locked amount -- only if they have debt.
        _canTransfer(from, value);

        // Perform the transfer: if there is a problem,
        // an exception will be thrown in this call.
        return _transferFromByProxy(messageSender, from, to, value);
    }

    function issueSynths(uint amount) external issuanceActive optionalProxy {
        return issuer().issueSynths(messageSender, amount);
    }

    function issueSynthsOnBehalf(address issueForAddress, uint amount) external issuanceActive optionalProxy {
        return issuer().issueSynthsOnBehalf(issueForAddress, messageSender, amount);
    }

    function issueMaxSynths() external issuanceActive optionalProxy {
        return issuer().issueMaxSynths(messageSender);
    }

    function issueMaxSynthsOnBehalf(address issueForAddress) external issuanceActive optionalProxy {
        return issuer().issueMaxSynthsOnBehalf(issueForAddress, messageSender);
    }

    function burnSynths(uint amount) external issuanceActive optionalProxy {
        return issuer().burnSynths(messageSender, amount);
    }

    function burnSynthsOnBehalf(address burnForAddress, uint amount) external issuanceActive optionalProxy {
        return issuer().burnSynthsOnBehalf(burnForAddress, messageSender, amount);
    }

    function burnSynthsToTarget() external issuanceActive optionalProxy {
        return issuer().burnSynthsToTarget(messageSender);
    }

    function burnSynthsToTargetOnBehalf(address burnForAddress) external issuanceActive optionalProxy {
        return issuer().burnSynthsToTargetOnBehalf(burnForAddress, messageSender);
    }

    /// @notice Force liquidate a delinquent account and distribute the redeemed SNX rewards amongst the appropriate recipients.
    /// @dev The SNX transfers will revert if the amount to send is more than balanceOf account (i.e. due to escrowed balance).
    function liquidateDelinquentAccount(address account) external systemActive optionalProxy returns (bool) {
        (uint totalRedeemed, uint amountLiquidated) = issuer().liquidateAccount(account, false);

        emitAccountLiquidated(account, totalRedeemed, amountLiquidated, messageSender);

        if (totalRedeemed > 0) {
            uint stakerRewards; // The amount of rewards to be sent to the LiquidatorRewards contract.
            uint flagReward = liquidator().flagReward();
            uint liquidateReward = liquidator().liquidateReward();
            // Check if the total amount of redeemed SNX is enough to payout the liquidation rewards.
            if (totalRedeemed > flagReward.add(liquidateReward)) {
                // Transfer the flagReward to the account who flagged this account for liquidation.
                address flagger = liquidator().getLiquidationCallerForAccount(account);
                bool flagRewardTransferSucceeded = _transferByProxy(account, flagger, flagReward);
                require(flagRewardTransferSucceeded, "Flag reward transfer did not succeed");

                // Transfer the liquidateReward to liquidator (the account who invoked this liquidation).
                bool liquidateRewardTransferSucceeded = _transferByProxy(account, messageSender, liquidateReward);
                require(liquidateRewardTransferSucceeded, "Liquidate reward transfer did not succeed");

                // The remaining SNX to be sent to the LiquidatorRewards contract.
                stakerRewards = totalRedeemed.sub(flagReward.add(liquidateReward));
            } else {
                /* If the total amount of redeemed SNX is greater than zero 
                but is less than the sum of the flag & liquidate rewards,
                then just send all of the SNX to the LiquidatorRewards contract. */
                stakerRewards = totalRedeemed;
            }

            bool liquidatorRewardTransferSucceeded = _transferByProxy(account, address(liquidatorRewards()), stakerRewards);
            require(liquidatorRewardTransferSucceeded, "Transfer to LiquidatorRewards failed");

            // Inform the LiquidatorRewards contract about the incoming SNX rewards.
            liquidatorRewards().notifyRewardAmount(stakerRewards);

            return true;
        } else {
            // In this unlikely case, the total redeemed SNX is not greater than zero so don't perform any transfers.
            return false;
        }
    }

    /// @notice Allows an account to self-liquidate anytime its c-ratio is below the target issuance ratio.
    function liquidateSelf() external systemActive optionalProxy returns (bool) {
        // Self liquidate the account (`isSelfLiquidation` flag must be set to `true`).
        (uint totalRedeemed, uint amountLiquidated) = issuer().liquidateAccount(messageSender, true);

        emitAccountLiquidated(messageSender, totalRedeemed, amountLiquidated, messageSender);

        // Transfer the redeemed SNX to the LiquidatorRewards contract.
        // Reverts if amount to redeem is more than balanceOf account (i.e. due to escrowed balance).
        bool success = _transferByProxy(messageSender, address(liquidatorRewards()), totalRedeemed);
        require(success, "Transfer to LiquidatorRewards failed");

        // Inform the LiquidatorRewards contract about the incoming SNX rewards.
        liquidatorRewards().notifyRewardAmount(totalRedeemed);

        return success;
    }

    function exchangeWithTrackingForInitiator(
        bytes32,
        uint,
        bytes32,
        address,
        bytes32
    ) external returns (uint) {
        _notImplemented();
    }

    function exchangeWithVirtual(
        bytes32,
        uint,
        bytes32,
        bytes32
    ) external returns (uint, IVirtualSynth) {
        _notImplemented();
    }

    function exchangeAtomically(
        bytes32,
        uint,
        bytes32,
        bytes32,
        uint
    ) external returns (uint) {
        _notImplemented();
    }

    function mint() external returns (bool) {
        _notImplemented();
    }

    function mintSecondary(address, uint) external {
        _notImplemented();
    }

    function mintSecondaryRewards(uint) external {
        _notImplemented();
    }

    function burnSecondary(address, uint) external {
        _notImplemented();
    }

    function _notImplemented() internal pure {
        revert("Cannot be run on this layer");
    }

    // ========== MODIFIERS ==========

    modifier systemActive() {
        _systemActive();
        _;
    }

    function _systemActive() private view {
        systemStatus().requireSystemActive();
    }

    modifier issuanceActive() {
        _issuanceActive();
        _;
    }

    function _issuanceActive() private view {
        systemStatus().requireIssuanceActive();
    }

    modifier exchangeActive(bytes32 src, bytes32 dest) {
        _exchangeActive(src, dest);
        _;
    }

    function _exchangeActive(bytes32 src, bytes32 dest) private view {
        systemStatus().requireExchangeBetweenSynthsAllowed(src, dest);
    }

    modifier onlyExchanger() {
        _onlyExchanger();
        _;
    }

    function _onlyExchanger() private view {
        require(msg.sender == address(exchanger()), "Only Exchanger can invoke this");
    }

    // ========== EVENTS ==========
    event AccountLiquidated(address indexed account, uint snxRedeemed, uint amountLiquidated, address liquidator);
    bytes32 internal constant ACCOUNTLIQUIDATED_SIG = keccak256("AccountLiquidated(address,uint256,uint256,address)");

    function emitAccountLiquidated(
        address account,
        uint256 snxRedeemed,
        uint256 amountLiquidated,
        address liquidator
    ) internal {
        proxy._emit(
            abi.encode(snxRedeemed, amountLiquidated, liquidator),
            2,
            ACCOUNTLIQUIDATED_SIG,
            addressToBytes32(account),
            0,
            0
        );
    }

    event SynthExchange(
        address indexed account,
        bytes32 fromCurrencyKey,
        uint256 fromAmount,
        bytes32 toCurrencyKey,
        uint256 toAmount,
        address toAddress
    );
    bytes32 internal constant SYNTH_EXCHANGE_SIG =
        keccak256("SynthExchange(address,bytes32,uint256,bytes32,uint256,address)");

    function emitSynthExchange(
        address account,
        bytes32 fromCurrencyKey,
        uint256 fromAmount,
        bytes32 toCurrencyKey,
        uint256 toAmount,
        address toAddress
    ) external onlyExchanger {
        proxy._emit(
            abi.encode(fromCurrencyKey, fromAmount, toCurrencyKey, toAmount, toAddress),
            2,
            SYNTH_EXCHANGE_SIG,
            addressToBytes32(account),
            0,
            0
        );
    }

    event ExchangeTracking(bytes32 indexed trackingCode, bytes32 toCurrencyKey, uint256 toAmount, uint256 fee);
    bytes32 internal constant EXCHANGE_TRACKING_SIG = keccak256("ExchangeTracking(bytes32,bytes32,uint256,uint256)");

    function emitExchangeTracking(
        bytes32 trackingCode,
        bytes32 toCurrencyKey,
        uint256 toAmount,
        uint256 fee
    ) external onlyExchanger {
        proxy._emit(abi.encode(toCurrencyKey, toAmount, fee), 2, EXCHANGE_TRACKING_SIG, trackingCode, 0, 0);
    }

    event ExchangeReclaim(address indexed account, bytes32 currencyKey, uint amount);
    bytes32 internal constant EXCHANGERECLAIM_SIG = keccak256("ExchangeReclaim(address,bytes32,uint256)");

    function emitExchangeReclaim(
        address account,
        bytes32 currencyKey,
        uint256 amount
    ) external onlyExchanger {
        proxy._emit(abi.encode(currencyKey, amount), 2, EXCHANGERECLAIM_SIG, addressToBytes32(account), 0, 0);
    }

    event ExchangeRebate(address indexed account, bytes32 currencyKey, uint amount);
    bytes32 internal constant EXCHANGEREBATE_SIG = keccak256("ExchangeRebate(address,bytes32,uint256)");

    function emitExchangeRebate(
        address account,
        bytes32 currencyKey,
        uint256 amount
    ) external onlyExchanger {
        proxy._emit(abi.encode(currencyKey, amount), 2, EXCHANGEREBATE_SIG, addressToBytes32(account), 0, 0);
    }
}


// https://docs.synthetix.io/contracts/source/interfaces/irewardescrow
interface IRewardEscrow {
    // Views
    function balanceOf(address account) external view returns (uint);

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

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

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

    function getVestingScheduleEntry(address account, uint index) external view returns (uint[2] memory);

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

    // Mutative functions
    function appendVestingEntry(address account, uint quantity) external;

    function vest() external;
}


pragma experimental ABIEncoderV2;

library VestingEntries {
    struct VestingEntry {
        uint64 endTime;
        uint256 escrowAmount;
    }
    struct VestingEntryWithID {
        uint64 endTime;
        uint256 escrowAmount;
        uint256 entryID;
    }
}

interface IRewardEscrowV2 {
    // Views
    function balanceOf(address account) external view returns (uint);

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

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

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

    function getVestingQuantity(address account, uint256[] calldata entryIDs) external view returns (uint);

    function getVestingSchedules(
        address account,
        uint256 index,
        uint256 pageSize
    ) external view returns (VestingEntries.VestingEntryWithID[] memory);

    function getAccountVestingEntryIDs(
        address account,
        uint256 index,
        uint256 pageSize
    ) external view returns (uint256[] memory);

    function getVestingEntryClaimable(address account, uint256 entryID) external view returns (uint);

    function getVestingEntry(address account, uint256 entryID) external view returns (uint64, uint256);

    // Mutative functions
    function vest(uint256[] calldata entryIDs) external;

    function createEscrowEntry(
        address beneficiary,
        uint256 deposit,
        uint256 duration
    ) external;

    function appendVestingEntry(
        address account,
        uint256 quantity,
        uint256 duration
    ) external;

    function migrateVestingSchedule(address _addressToMigrate) external;

    function migrateAccountEscrowBalances(
        address[] calldata accounts,
        uint256[] calldata escrowBalances,
        uint256[] calldata vestedBalances
    ) external;

    // Account Merging
    function startMergingWindow() external;

    function mergeAccount(address accountToMerge, uint256[] calldata entryIDs) external;

    function nominateAccountToMerge(address account) external;

    function accountMergingIsOpen() external view returns (bool);

    // L2 Migration
    function importVestingEntries(
        address account,
        uint256 escrowedAmount,
        VestingEntries.VestingEntry[] calldata vestingEntries
    ) external;

    // Return amount of SNX transfered to SynthetixBridgeToOptimism deposit contract
    function burnForMigration(address account, uint256[] calldata entryIDs)
        external
        returns (uint256 escrowedAccountBalance, VestingEntries.VestingEntry[] memory vestingEntries);
}


// https://docs.synthetix.io/contracts/source/interfaces/isupplyschedule
interface ISupplySchedule {
    // Views
    function mintableSupply() external view returns (uint);

    function isMintable() external view returns (bool);

    function minterReward() external view returns (uint);

    // Mutative functions
    function recordMintEvent(uint supplyMinted) external returns (uint);
}


// Inheritance


// Internal references


// https://docs.synthetix.io/contracts/source/contracts/synthetix
contract Synthetix is BaseSynthetix {
    bytes32 public constant CONTRACT_NAME = "Synthetix";

    // ========== ADDRESS RESOLVER CONFIGURATION ==========
    bytes32 private constant CONTRACT_REWARD_ESCROW = "RewardEscrow";
    bytes32 private constant CONTRACT_REWARDESCROW_V2 = "RewardEscrowV2";
    bytes32 private constant CONTRACT_SUPPLYSCHEDULE = "SupplySchedule";

    // ========== CONSTRUCTOR ==========

    constructor(
        address payable _proxy,
        TokenState _tokenState,
        address _owner,
        uint _totalSupply,
        address _resolver
    ) public BaseSynthetix(_proxy, _tokenState, _owner, _totalSupply, _resolver) {}

    function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {
        bytes32[] memory existingAddresses = BaseSynthetix.resolverAddressesRequired();
        bytes32[] memory newAddresses = new bytes32[](3);
        newAddresses[0] = CONTRACT_REWARD_ESCROW;
        newAddresses[1] = CONTRACT_REWARDESCROW_V2;
        newAddresses[2] = CONTRACT_SUPPLYSCHEDULE;
        return combineArrays(existingAddresses, newAddresses);
    }

    // ========== VIEWS ==========

    function rewardEscrow() internal view returns (IRewardEscrow) {
        return IRewardEscrow(requireAndGetAddress(CONTRACT_REWARD_ESCROW));
    }

    function rewardEscrowV2() internal view returns (IRewardEscrowV2) {
        return IRewardEscrowV2(requireAndGetAddress(CONTRACT_REWARDESCROW_V2));
    }

    function supplySchedule() internal view returns (ISupplySchedule) {
        return ISupplySchedule(requireAndGetAddress(CONTRACT_SUPPLYSCHEDULE));
    }

    // ========== OVERRIDDEN FUNCTIONS ==========

    function exchangeWithVirtual(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        bytes32 trackingCode
    )
        external
        exchangeActive(sourceCurrencyKey, destinationCurrencyKey)
        optionalProxy
        returns (uint amountReceived, IVirtualSynth vSynth)
    {
        return
            exchanger().exchange(
                messageSender,
                messageSender,
                sourceCurrencyKey,
                sourceAmount,
                destinationCurrencyKey,
                messageSender,
                true,
                messageSender,
                trackingCode
            );
    }

    // SIP-140 The initiating user of this exchange will receive the proceeds of the exchange
    // Note: this function may have unintended consequences if not understood correctly. Please
    // read SIP-140 for more information on the use-case
    function exchangeWithTrackingForInitiator(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        address rewardAddress,
        bytes32 trackingCode
    ) external exchangeActive(sourceCurrencyKey, destinationCurrencyKey) optionalProxy returns (uint amountReceived) {
        (amountReceived, ) = exchanger().exchange(
            messageSender,
            messageSender,
            sourceCurrencyKey,
            sourceAmount,
            destinationCurrencyKey,
            // solhint-disable avoid-tx-origin
            tx.origin,
            false,
            rewardAddress,
            trackingCode
        );
    }

    function exchangeAtomically(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        bytes32 trackingCode,
        uint minAmount
    ) external exchangeActive(sourceCurrencyKey, destinationCurrencyKey) optionalProxy returns (uint amountReceived) {
        return
            exchanger().exchangeAtomically(
                messageSender,
                sourceCurrencyKey,
                sourceAmount,
                destinationCurrencyKey,
                messageSender,
                trackingCode,
                minAmount
            );
    }

    function settle(bytes32 currencyKey)
        external
        optionalProxy
        returns (
            uint reclaimed,
            uint refunded,
            uint numEntriesSettled
        )
    {
        return exchanger().settle(messageSender, currencyKey);
    }

    function mint() external issuanceActive returns (bool) {
        require(address(rewardsDistribution()) != address(0), "RewardsDistribution not set");

        ISupplySchedule _supplySchedule = supplySchedule();
        IRewardsDistribution _rewardsDistribution = rewardsDistribution();

        uint supplyToMint = _supplySchedule.mintableSupply();
        require(supplyToMint > 0, "No supply is mintable");

        emitTransfer(address(0), address(this), supplyToMint);

        // record minting event before mutation to token supply
        uint minterReward = _supplySchedule.recordMintEvent(supplyToMint);

        // Set minted SNX balance to RewardEscrow's balance
        // Minus the minterReward and set balance of minter to add reward
        uint amountToDistribute = supplyToMint.sub(minterReward);

        // Set the token balance to the RewardsDistribution contract
        tokenState.setBalanceOf(
            address(_rewardsDistribution),
            tokenState.balanceOf(address(_rewardsDistribution)).add(amountToDistribute)
        );
        emitTransfer(address(this), address(_rewardsDistribution), amountToDistribute);

        // Kick off the distribution of rewards
        _rewardsDistribution.distributeRewards(amountToDistribute);

        // Assign the minters reward.
        tokenState.setBalanceOf(msg.sender, tokenState.balanceOf(msg.sender).add(minterReward));
        emitTransfer(address(this), msg.sender, minterReward);

        // Increase total supply by minted amount
        totalSupply = totalSupply.add(supplyToMint);

        return true;
    }

    /* Once off function for SIP-60 to migrate SNX balances in the RewardEscrow contract
     * To the new RewardEscrowV2 contract
     */
    function migrateEscrowBalanceToRewardEscrowV2() external onlyOwner {
        // Record balanceOf(RewardEscrow) contract
        uint rewardEscrowBalance = tokenState.balanceOf(address(rewardEscrow()));

        // transfer all of RewardEscrow's balance to RewardEscrowV2
        // _internalTransfer emits the transfer event
        _internalTransfer(address(rewardEscrow()), address(rewardEscrowV2()), rewardEscrowBalance);
    }

    // ========== EVENTS ==========

    event AtomicSynthExchange(
        address indexed account,
        bytes32 fromCurrencyKey,
        uint256 fromAmount,
        bytes32 toCurrencyKey,
        uint256 toAmount,
        address toAddress
    );
    bytes32 internal constant ATOMIC_SYNTH_EXCHANGE_SIG =
        keccak256("AtomicSynthExchange(address,bytes32,uint256,bytes32,uint256,address)");

    function emitAtomicSynthExchange(
        address account,
        bytes32 fromCurrencyKey,
        uint256 fromAmount,
        bytes32 toCurrencyKey,
        uint256 toAmount,
        address toAddress
    ) external onlyExchanger {
        proxy._emit(
            abi.encode(fromCurrencyKey, fromAmount, toCurrencyKey, toAmount, toAddress),
            2,
            ATOMIC_SYNTH_EXCHANGE_SIG,
            addressToBytes32(account),
            0,
            0
        );
    }
}

Contract ABI

[{"inputs":[{"internalType":"address payable","name":"_proxy","type":"address"},{"internalType":"contract TokenState","name":"_tokenState","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_totalSupply","type":"uint256"},{"internalType":"address","name":"_resolver","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"snxRedeemed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountLiquidated","type":"uint256"},{"indexed":false,"internalType":"address","name":"liquidator","type":"address"}],"name":"AccountLiquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bytes32","name":"fromCurrencyKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"fromAmount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"toCurrencyKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"toAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"toAddress","type":"address"}],"name":"AtomicSynthExchange","type":"event"},{"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":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bytes32","name":"currencyKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ExchangeRebate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bytes32","name":"currencyKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ExchangeReclaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"trackingCode","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"toCurrencyKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"toAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"ExchangeTracking","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"proxyAddress","type":"address"}],"name":"ProxyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bytes32","name":"fromCurrencyKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"fromAmount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"toCurrencyKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"toAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"toAddress","type":"address"}],"name":"SynthExchange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newTokenState","type":"address"}],"name":"TokenStateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[],"name":"CONTRACT_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DECIMALS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"TOKEN_NAME","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"TOKEN_SYMBOL","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"anySynthOrSNXRateIsInvalid","outputs":[{"internalType":"bool","name":"anyRateInvalid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"availableCurrencyKeys","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"availableSynthCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"availableSynths","outputs":[{"internalType":"contract ISynth","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"burnSecondary","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnSynths","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"burnForAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnSynthsOnBehalf","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"burnSynthsToTarget","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"burnForAddress","type":"address"}],"name":"burnSynthsToTargetOnBehalf","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"collateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_issuer","type":"address"}],"name":"collateralisationRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"currencyKey","type":"bytes32"}],"name":"debtBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"fromCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"fromAmount","type":"uint256"},{"internalType":"bytes32","name":"toCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"toAmount","type":"uint256"},{"internalType":"address","name":"toAddress","type":"address"}],"name":"emitAtomicSynthExchange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"currencyKey","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emitExchangeRebate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"currencyKey","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emitExchangeReclaim","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"trackingCode","type":"bytes32"},{"internalType":"bytes32","name":"toCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"toAmount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"emitExchangeTracking","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"fromCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"fromAmount","type":"uint256"},{"internalType":"bytes32","name":"toCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"toAmount","type":"uint256"},{"internalType":"address","name":"toAddress","type":"address"}],"name":"emitSynthExchange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"sourceCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"sourceAmount","type":"uint256"},{"internalType":"bytes32","name":"destinationCurrencyKey","type":"bytes32"}],"name":"exchange","outputs":[{"internalType":"uint256","name":"amountReceived","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"sourceCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"sourceAmount","type":"uint256"},{"internalType":"bytes32","name":"destinationCurrencyKey","type":"bytes32"},{"internalType":"bytes32","name":"trackingCode","type":"bytes32"},{"internalType":"uint256","name":"minAmount","type":"uint256"}],"name":"exchangeAtomically","outputs":[{"internalType":"uint256","name":"amountReceived","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"exchangeForAddress","type":"address"},{"internalType":"bytes32","name":"sourceCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"sourceAmount","type":"uint256"},{"internalType":"bytes32","name":"destinationCurrencyKey","type":"bytes32"}],"name":"exchangeOnBehalf","outputs":[{"internalType":"uint256","name":"amountReceived","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"exchangeForAddress","type":"address"},{"internalType":"bytes32","name":"sourceCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"sourceAmount","type":"uint256"},{"internalType":"bytes32","name":"destinationCurrencyKey","type":"bytes32"},{"internalType":"address","name":"rewardAddress","type":"address"},{"internalType":"bytes32","name":"trackingCode","type":"bytes32"}],"name":"exchangeOnBehalfWithTracking","outputs":[{"internalType":"uint256","name":"amountReceived","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"sourceCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"sourceAmount","type":"uint256"},{"internalType":"bytes32","name":"destinationCurrencyKey","type":"bytes32"},{"internalType":"address","name":"rewardAddress","type":"address"},{"internalType":"bytes32","name":"trackingCode","type":"bytes32"}],"name":"exchangeWithTracking","outputs":[{"internalType":"uint256","name":"amountReceived","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"sourceCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"sourceAmount","type":"uint256"},{"internalType":"bytes32","name":"destinationCurrencyKey","type":"bytes32"},{"internalType":"address","name":"rewardAddress","type":"address"},{"internalType":"bytes32","name":"trackingCode","type":"bytes32"}],"name":"exchangeWithTrackingForInitiator","outputs":[{"internalType":"uint256","name":"amountReceived","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"sourceCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"sourceAmount","type":"uint256"},{"internalType":"bytes32","name":"destinationCurrencyKey","type":"bytes32"},{"internalType":"bytes32","name":"trackingCode","type":"bytes32"}],"name":"exchangeWithVirtual","outputs":[{"internalType":"uint256","name":"amountReceived","type":"uint256"},{"internalType":"contract IVirtualSynth","name":"vSynth","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isResolverCached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"}],"name":"isWaitingPeriod","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"issueMaxSynths","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"issueForAddress","type":"address"}],"name":"issueMaxSynthsOnBehalf","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"issueSynths","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"issueForAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"issueSynthsOnBehalf","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"liquidateDelinquentAccount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"liquidateSelf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"maxIssuableSynths","outputs":[{"internalType":"uint256","name":"maxIssuable","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"messageSender","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"migrateEscrowBalanceToRewardEscrowV2","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"mintSecondary","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mintSecondaryRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":true,"inputs":[],"name":"proxy","outputs":[{"internalType":"contract Proxy","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"rebuildCache","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"remainingIssuableSynths","outputs":[{"internalType":"uint256","name":"maxIssuable","type":"uint256"},{"internalType":"uint256","name":"alreadyIssued","type":"uint256"},{"internalType":"uint256","name":"totalSystemDebt","type":"uint256"}],"payable":false,"stateMutability":"view","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":true,"inputs":[],"name":"sUSD","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"setMessageSender","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address payable","name":"_proxy","type":"address"}],"name":"setProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract TokenState","name":"_tokenState","type":"address"}],"name":"setTokenState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"}],"name":"settle","outputs":[{"internalType":"uint256","name":"reclaimed","type":"uint256"},{"internalType":"uint256","name":"refunded","type":"uint256"},{"internalType":"uint256","name":"numEntriesSettled","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"}],"name":"synths","outputs":[{"internalType":"contract ISynth","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"synthAddress","type":"address"}],"name":"synthsByAddress","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenState","outputs":[{"internalType":"contract TokenState","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"}],"name":"totalIssuedSynths","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"}],"name":"totalIssuedSynthsExcludeOtherCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"transferableSynthetix","outputs":[{"internalType":"uint256","name":"transferable","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b506040516200520f3803806200520f833981016040819052620000349162000315565b84848484848085856040518060400160405280601781526020017f53796e746865746978204e6574776f726b20546f6b656e000000000000000000815250604051806040016040528060038152602001620a69cb60eb1b81525086601289868160006001600160a01b0316816001600160a01b03161415620000d35760405162461bcd60e51b8152600401620000ca9062000463565b60405180910390fd5b600080546001600160a01b0319166001600160a01b0383161781556040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91620001209184906200042b565b60405180910390a1506000546001600160a01b0316620001545760405162461bcd60e51b8152600401620000ca9062000451565b600280546001600160a01b0319166001600160a01b0383161790556040517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e90620001a19083906200041b565b60405180910390a150600480546001600160a01b0319166001600160a01b0388161790558451620001da90600590602088019062000243565b508351620001f090600690602087019062000243565b50506007919091556008805460ff191660ff90921691909117610100600160a81b0319166101006001600160a01b0397909716969096029590951790945550620004e19c50505050505050505050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200028657805160ff1916838001178555620002b6565b82800160010185558215620002b6579182015b82811115620002b657825182559160200191906001019062000299565b50620002c4929150620002c8565b5090565b620002e591905b80821115620002c45760008155600101620002cf565b90565b8051620002f581620004b1565b92915050565b8051620002f581620004cb565b8051620002f581620004d6565b600080600080600060a086880312156200032e57600080fd5b60006200033c8888620002e8565b95505060206200034f88828901620002fb565b94505060406200036288828901620002e8565b9350506060620003758882890162000308565b92505060806200038888828901620002e8565b9150509295509295909350565b620003a081620004a4565b82525050565b620003a0816200047e565b6000620003c060118362000475565b7013dddb995c881b5d5cdd081899481cd95d607a1b815260200192915050565b6000620003ef60198362000475565b7f4f776e657220616464726573732063616e6e6f74206265203000000000000000815260200192915050565b60208101620002f5828462000395565b604081016200043b828562000395565b6200044a6020830184620003a6565b9392505050565b60208082528101620002f581620003b1565b60208082528101620002f581620003e0565b90815260200190565b6000620002f58262000498565b6000620002f5826200047e565b6001600160a01b031690565b6000620002f5826200048b565b620004bc816200047e565b8114620004c857600080fd5b50565b620004bc816200048b565b620004bc81620002e5565b614d1e80620004f16000396000f3fe608060405234801561001057600080fd5b506004361061041d5760003560e01c80636c00f3101161022b578063a311c7c211610130578063d67bdd25116100b8578063e8e09b8b11610087578063e8e09b8b14610878578063e90dd9e21461088b578063ec55688914610893578063edef719a14610669578063ee52a2f31461089b5761041d565b8063d67bdd2514610842578063d8a1f76f1461084a578063dbf633401461085d578063dd62ed3e146108655761041d565b8063af086c7e116100ff578063af086c7e146107ee578063bc67f832146107f6578063c2bf388014610809578063c836fa0a1461081c578063d37c4d8b1461082f5761041d565b8063a311c7c2146107a2578063a5fdc5de146107b5578063a9059cbb146107c8578063ace88afd146107db5761041d565b80638a290014116101b357806395d89b411161018257806395d89b411461075957806397107d6d146107615780639741fb2214610774578063987757dd1461077c5780639f7698071461078f5761041d565b80638a290014146107235780638da5cb5b1461073657806391e56b681461073e5780639324cac7146107515761041d565b806374185360116101fa57806374185360146106e557806379ba5097146106ed578063835e119c146106f557806383d625d414610708578063899ffef41461071b5761041d565b80636c00f310146106975780636f01a986146106aa57806370a08231146106bd57806372cb051f146106d05761041d565b80632d3169eb116103315780634e99bda9116102b95780635e22846a116102885780635e22846a1461064e578063614d08f814610661578063666ed4f1146106695780636ac0bf9c1461067c5780636b76222f1461068f5761041d565b80634e99bda914610616578063528c7efb1461061e57806353a47bb7146106265780635af090ef1461063b5761041d565b8063313ce56711610300578063313ce567146105c2578063320223db146105ca57806332608039146105dd5780633e89b9e5146105f057806344b3e923146106035761041d565b80632d3169eb146105745780632e0f2625146105875780632f7206ce1461059c57806330ead760146105af5761041d565b806316b2213f116103b457806323b872dd1161038357806323b872dd1461052b578063295da87d1461053e5780632a905318146105515780632af64bd3146105595780632c955fa7146105615761041d565b806316b2213f146104f557806318160ddd1461050857806318821400146105105780631fce304d146105185761041d565b80630e30963c116103f05780630e30963c146104955780631137aedf146104b65780631249c58b146104d85780631627540c146104e05761041d565b806304f3bcec1461042257806305b3c1c91461044057806306fdde0314610460578063095ea7b314610475575b600080fd5b61042a6108ae565b6040516104379190614a66565b60405180910390f35b61045361044e3660046138f4565b6108c2565b60405161043791906148c7565b61046861094f565b6040516104379190614a74565b6104886104833660046139b7565b6109dd565b60405161043791906148b9565b6104a86104a3366004613c0a565b610a6a565b604051610437929190614b85565b6104c96104c43660046138f4565b610b79565b6040516104379392919061496b565b610488610c0e565b6104f36104ee3660046138f4565b610fd1565b005b6104536105033660046138f4565b61102f565b610453611064565b61046861106a565b610488610526366004613bce565b6110a3565b61048861053936600461396a565b611138565b6104f361054c366004613bce565b611177565b6104686111f8565b610488611217565b6104f361056f3660046138f4565b611333565b6104f3610582366004613c0a565b61137f565b61058f611435565b6040516104379190614bc8565b6104f36105aa366004613b01565b61143a565b6104536105bd366004613c4d565b6114fc565b61058f6115ba565b6104f36105d83660046138f4565b6115c3565b61042a6105eb366004613bce565b61160f565b6104536105fe366004613bce565b611694565b610453610611366004613cc2565b6116cc565b610488611784565b610488611803565b61062e61196f565b60405161043791906146d3565b610453610649366004613c4d565b61197e565b61048861065c3660046138f4565b6119de565b610453611d7d565b6104f36106773660046139b7565b611d8d565b61045361068a3660046138f4565b611d99565b6104f3611ea1565b6104f36106a5366004613b01565b611f4c565b6104f36106b83660046139e7565b611f9f565b6104536106cb3660046138f4565b612058565b6106d861208a565b60405161043791906148a8565b6104f3612108565b6104f361225a565b61042a610703366004613bce565b6122f6565b610453610716366004613bce565b61232b565b6106d8612363565b6104f3610731366004613bce565b612424565b61062e61246e565b61045361074c366004613a7a565b61247d565b61045361253d565b610468612548565b6104f361076f3660046138f4565b6125a3565b6104f36125f6565b6104c961078a366004613bce565b612674565b6104f361079d366004613d37565b6126ea565b6104536107b03660046138f4565b612716565b6104536107c33660046138f4565b61274b565b6104886107d63660046139b7565b612780565b6104f36107e93660046139e7565b6127ca565b6104f3612817565b6104f36108043660046138f4565b612860565b6104f36108173660046139b7565b61288a565b61045361082a366004613a19565b61290e565b61045361083d3660046139b7565b6129cc565b61062e612a53565b6104f3610858366004613bce565b612a62565b610453612a6a565b610453610873366004613930565b612ae4565b6104f36108863660046139b7565b612b18565b61042a612b66565b61042a612b75565b6104536108a9366004613c2c565b612b84565b60085461010090046001600160a01b031681565b60006108cc612c40565b6001600160a01b03166305b3c1c9836040518263ffffffff1660e01b81526004016108f791906146d3565b60206040518083038186803b15801561090f57600080fd5b505afa158015610923573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109479190810190613bec565b90505b919050565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109d55780601f106109aa576101008083540402835291602001916109d5565b820191906000526020600020905b8154815290600101906020018083116109b857829003601f168201915b505050505081565b60006109e7612c54565b60035460048054604051633691826360e21b81526001600160a01b03938416939091169163da46098c91610a2191859189918991016147fb565b600060405180830381600087803b158015610a3b57600080fd5b505af1158015610a4f573d6000803e3d6000fd5b50505050610a5e818585612c93565b60019150505b92915050565b6000808584610a798282612d13565b610a81612c54565b610a89612d74565b6001600160a01b0316634f8633d2600360009054906101000a90046001600160a01b0316600360009054906101000a90046001600160a01b03168b8b8b600360009054906101000a90046001600160a01b03166001600360009054906101000a90046001600160a01b03168e6040518a63ffffffff1660e01b8152600401610b19999897969594939291906147ab565b6040805180830381600087803b158015610b3257600080fd5b505af1158015610b46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b6a9190810190613d85565b93509350505094509492505050565b6000806000610b86612c40565b6001600160a01b0316631137aedf856040518263ffffffff1660e01b8152600401610bb191906146d3565b60606040518083038186803b158015610bc957600080fd5b505afa158015610bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c019190810190613de5565b9250925092509193909250565b6000610c18612d8b565b6000610c22612ddf565b6001600160a01b03161415610c525760405162461bcd60e51b8152600401610c4990614b25565b60405180910390fd5b6000610c5c612e00565b90506000610c68612ddf565b90506000826001600160a01b031663cc5c095c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ca557600080fd5b505afa158015610cb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610cdd9190810190613bec565b905060008111610cff5760405162461bcd60e51b8152600401610c4990614b65565b610d0b60003083612e1c565b604051637e7961d760e01b81526000906001600160a01b03851690637e7961d790610d3a9085906004016148c7565b602060405180830381600087803b158015610d5457600080fd5b505af1158015610d68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d8c9190810190613bec565b90506000610da0838363ffffffff612e5f16565b600480546040516370a0823160e01b81529293506001600160a01b03169163b46310f6918791610e3c91869186916370a0823191610de0918791016146d3565b60206040518083038186803b158015610df857600080fd5b505afa158015610e0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e309190810190613bec565b9063ffffffff612e8716565b6040518363ffffffff1660e01b8152600401610e5992919061483e565b600060405180830381600087803b158015610e7357600080fd5b505af1158015610e87573d6000803e3d6000fd5b50505050610e96308583612e1c565b604051630b32e9c760e31b81526001600160a01b038516906359974e3890610ec29084906004016148c7565b602060405180830381600087803b158015610edc57600080fd5b505af1158015610ef0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f149190810190613bb0565b50600480546040516370a0823160e01b81526001600160a01b039091169163b46310f6913391610f5491879186916370a0823191610de0918791016146e1565b6040518363ffffffff1660e01b8152600401610f719291906146ef565b600060405180830381600087803b158015610f8b57600080fd5b505af1158015610f9f573d6000803e3d6000fd5b50505050610fae303384612e1c565b600754610fc1908463ffffffff612e8716565b6007555060019450505050505b90565b610fd9612eac565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906110249083906146d3565b60405180910390a150565b6000611039612c40565b6001600160a01b03166316b2213f836040518263ffffffff1660e01b81526004016108f791906146d3565b60075481565b6040518060400160405280601781526020017f53796e746865746978204e6574776f726b20546f6b656e00000000000000000081525081565b6000806110ae612d74565b6003546040516301670a7b60e21b81526001600160a01b039283169263059c29ec926110e192911690879060040161483e565b60206040518083038186803b1580156110f957600080fd5b505afa15801561110d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111319190810190613bec565b1192915050565b6000611142612c54565b61114a612ed6565b6111548483612f16565b5060035461116d906001600160a01b03168585856130fb565b90505b9392505050565b61117f612d8b565b611187612c54565b61118f612c40565b60035460405163b06e8c6560e01b81526001600160a01b039283169263b06e8c65926111c292911690859060040161483e565b600060405180830381600087803b1580156111dc57600080fd5b505af11580156111f0573d6000803e3d6000fd5b505050505b50565b604051806040016040528060038152602001620a69cb60eb1b81525081565b60006060611223612363565b905060005b815181101561132a57600082828151811061123f57fe5b602090810291909101810151600081815260099092526040918290205460085492516321f8a72160e01b81529193506001600160a01b0390811692610100900416906321f8a721906112959085906004016148c7565b60206040518083038186803b1580156112ad57600080fd5b505afa1580156112c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112e59190810190613912565b6001600160a01b031614158061131057506000818152600960205260409020546001600160a01b0316155b156113215760009350505050610fce565b50600101611228565b50600191505090565b61133b612d8b565b611343612c54565b61134b612c40565b60035460405163159fa0d560e11b81526001600160a01b0392831692632b3f41aa926111c29286929091169060040161470a565b611387613203565b6002546040516001600160a01b039091169063907dff97906113b19086908690869060200161496b565b60405160208183030381529060405260026040516113ce9061465b565b6040519081900381206001600160e01b031960e086901b1682526113fd9392918a9060009081906004016149e5565b600060405180830381600087803b15801561141757600080fd5b505af115801561142b573d6000803e3d6000fd5b5050505050505050565b601281565b611442613203565b6002546040516001600160a01b039091169063907dff9790611470908890889088908890889060200161491f565b604051602081830303815290604052600260405161148d90614645565b604051809103902061149e8b61323b565b6000806040518763ffffffff1660e01b81526004016114c2969594939291906149e5565b600060405180830381600087803b1580156114dc57600080fd5b505af11580156114f0573d6000803e3d6000fd5b50505050505050505050565b6000858461150a8282612d13565b611512612c54565b61151a612d74565b6003546040516327c319e960e11b81526001600160a01b0392831692634f8633d29261155c9291169081908d908d908d9084906000908f908f906004016147ab565b6040805180830381600087803b15801561157557600080fd5b505af1158015611589573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115ad9190810190613d85565b5098975050505050505050565b60085460ff1681565b6115cb612d8b565b6115d3612c54565b6115db612c40565b60035460405163fd864ccf60e01b81526001600160a01b039283169263fd864ccf926111c29286929091169060040161470a565b6000611619612c40565b6001600160a01b03166332608039836040518263ffffffff1660e01b815260040161164491906148c7565b60206040518083038186803b15801561165c57600080fd5b505afa158015611670573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109479190810190613d19565b600061169e612c40565b6001600160a01b0316637b1001b78360016040518363ffffffff1660e01b81526004016108f79291906148e3565b600085846116da8282612d13565b6116e2612c54565b6116ea612d74565b60035460405162674ed160e71b81526001600160a01b03928316926333a7688092611726929116908c908c908c9084908d908d9060040161484c565b602060405180830381600087803b15801561174057600080fd5b505af1158015611754573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117789190810190613bec565b98975050505050505050565b600061178e612c40565b6001600160a01b0316634e99bda96040518163ffffffff1660e01b815260040160206040518083038186803b1580156117c657600080fd5b505afa1580156117da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117fe9190810190613bb0565b905090565b600061180d612ed6565b611815612c54565b600080611820612c40565b6003546040516339632c0b60e11b81526001600160a01b03928316926372c658169261185492911690600190600401614823565b6040805180830381600087803b15801561186d57600080fd5b505af1158015611881573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118a59190810190613db5565b60035491935091506118c2906001600160a01b0316838382613247565b6003546000906118e3906001600160a01b03166118dd6132c3565b856132e2565b9050806119025760405162461bcd60e51b8152600401610c4990614b45565b61190a6132c3565b6001600160a01b0316633c6b16ab846040518263ffffffff1660e01b815260040161193591906148c7565b600060405180830381600087803b15801561194f57600080fd5b505af1158015611963573d6000803e3d6000fd5b50929550505050505090565b6001546001600160a01b031681565b6000858461198c8282612d13565b611994612c54565b61199c612d74565b6003546040516327c319e960e11b81526001600160a01b0392831692634f8633d29261155c9291169081908d908d908d9032906000908f908f90600401614725565b60006119e8612ed6565b6119f0612c54565b6000806119fb612c40565b6001600160a01b03166372c658168560006040518363ffffffff1660e01b8152600401611a29929190614823565b6040805180830381600087803b158015611a4257600080fd5b505af1158015611a56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a7a9190810190613db5565b6003549193509150611a9a908590849084906001600160a01b0316613247565b8115611d7257600080611aab6132ef565b6001600160a01b0316638074b3726040518163ffffffff1660e01b815260040160206040518083038186803b158015611ae357600080fd5b505afa158015611af7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b1b9190810190613bec565b90506000611b276132ef565b6001600160a01b03166331e4e0306040518163ffffffff1660e01b815260040160206040518083038186803b158015611b5f57600080fd5b505afa158015611b73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b979190810190613bec565b9050611ba9828263ffffffff612e8716565b851115611cc7576000611bba6132ef565b6001600160a01b0316635616c957896040518263ffffffff1660e01b8152600401611be591906146d3565b60206040518083038186803b158015611bfd57600080fd5b505afa158015611c11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c359190810190613912565b90506000611c448983866132e2565b905080611c635760405162461bcd60e51b8152600401610c4990614ad5565b600354600090611c7e908b906001600160a01b0316866132e2565b905080611c9d5760405162461bcd60e51b8152600401610c4990614b55565b611cbd611cb0868663ffffffff612e8716565b899063ffffffff612e5f16565b9550505050611ccb565b8492505b6000611cdf88611cd96132c3565b866132e2565b905080611cfe5760405162461bcd60e51b8152600401610c4990614b45565b611d066132c3565b6001600160a01b0316633c6b16ab856040518263ffffffff1660e01b8152600401611d3191906148c7565b600060405180830381600087803b158015611d4b57600080fd5b505af1158015611d5f573d6000803e3d6000fd5b505050506001965050505050505061094a565b60009250505061094a565b680a6f2dce8d0cae8d2f60bb1b81565b611d95613307565b5050565b6000611da3612c40565b600480546040516370a0823160e01b81526001600160a01b0393841693636bed0415938793909116916370a0823191611dde918591016146d3565b60206040518083038186803b158015611df657600080fd5b505afa158015611e0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e2e9190810190613bec565b6040518363ffffffff1660e01b8152600401611e4b92919061483e565b604080518083038186803b158015611e6257600080fd5b505afa158015611e76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e9a9190810190613d55565b5092915050565b611ea9612eac565b6004546000906001600160a01b03166370a08231611ec561331f565b6040518263ffffffff1660e01b8152600401611ee191906146d3565b60206040518083038186803b158015611ef957600080fd5b505afa158015611f0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611f319190810190613bec565b9050611d95611f3e61331f565b611f46613339565b83613355565b611f54613203565b6002546040516001600160a01b039091169063907dff9790611f82908890889088908890889060200161491f565b604051602081830303815290604052600260405161148d90614686565b611fa7613203565b6002546040516001600160a01b039091169063907dff9790611fcf90859085906020016148f1565b6040516020818303038152906040526002604051611fec9061469c565b6040518091039020611ffd8861323b565b6000806040518763ffffffff1660e01b8152600401612021969594939291906149e5565b600060405180830381600087803b15801561203b57600080fd5b505af115801561204f573d6000803e3d6000fd5b50505050505050565b600480546040516370a0823160e01b81526000926001600160a01b03909216916370a08231916108f7918691016146d3565b6060612094612c40565b6001600160a01b03166372cb051f6040518163ffffffff1660e01b815260040160006040518083038186803b1580156120cc57600080fd5b505afa1580156120e0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526117fe9190810190613b7b565b6060612112612363565b905060005b8151811015611d9557600082828151811061212e57fe5b602002602001015190506000600860019054906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200161217091906146bd565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161219c9291906148ff565b60206040518083038186803b1580156121b457600080fd5b505afa1580156121c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121ec9190810190613912565b6000838152600960205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa689061224890849084906148d5565b60405180910390a15050600101612117565b6001546001600160a01b031633146122845760405162461bcd60e51b8152600401610c4990614a95565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c926122c7926001600160a01b039182169291169061470a565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6000612300612c40565b6001600160a01b031663835e119c836040518263ffffffff1660e01b815260040161164491906148c7565b6000612335612c40565b6001600160a01b0316637b1001b78360006040518363ffffffff1660e01b81526004016108f79291906148e3565b60608061236e6134d5565b60408051600380825260808201909252919250606091906020820183803883390190505090506b526577617264457363726f7760a01b816000815181106123b157fe5b6020026020010181815250506d2932bbb0b93222b9b1b937bbab1960911b816001815181106123dc57fe5b6020026020010181815250506d537570706c795363686564756c6560901b8160028151811061240757fe5b60200260200101818152505061241d82826135f2565b9250505090565b61242c612d8b565b612434612c54565b61243c612c40565b6003546040516285c0d160e31b81526001600160a01b039283169263042e0688926111c292911690859060040161483e565b6000546001600160a01b031681565b6000858461248b8282612d13565b612493612c54565b61249b612d74565b6003546040516327c319e960e11b81526001600160a01b0392831692634f8633d2926124de928e92909116908d908d908d9085906000908f908f906004016147ab565b6040805180830381600087803b1580156124f757600080fd5b505af115801561250b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061252f9190810190613d85565b509998505050505050505050565b631cd554d160e21b81565b6006805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109d55780601f106109aa576101008083540402835291602001916109d5565b6125ab612eac565b600280546001600160a01b0319166001600160a01b0383161790556040517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e906110249083906146e1565b6125fe612d8b565b612606612c54565b61260e612c40565b6003546040516324beb82560e11b81526001600160a01b039283169263497d704a9261263f929116906004016146d3565b600060405180830381600087803b15801561265957600080fd5b505af115801561266d573d6000803e3d6000fd5b505050505b565b6000806000612681612c54565b612689612d74565b6003546040516306c5a00b60e21b81526001600160a01b0392831692631b16802c926126bc92911690889060040161483e565b606060405180830381600087803b1580156126d657600080fd5b505af1158015610bdd573d6000803e3d6000fd5b6126f26136a7565b600480546001600160a01b0319166001600160a01b0383161790556111f581613715565b6000612720612c40565b6001600160a01b031663a311c7c2836040518263ffffffff1660e01b81526004016108f791906146d3565b6000612755612c40565b6001600160a01b031663a5fdc5de836040518263ffffffff1660e01b81526004016108f791906146d3565b600061278a612c54565b612792612ed6565b6003546127a8906001600160a01b031683612f16565b506003546127c0906001600160a01b031684846132e2565b5060019392505050565b6127d2613203565b6002546040516001600160a01b039091169063907dff97906127fa90859085906020016148f1565b6040516020818303038152906040526002604051611fec90614650565b61281f612d8b565b612827612c54565b61282f612c40565b60035460405163644bb89960e11b81526001600160a01b039283169263c89771329261263f929116906004016146d3565b612868613787565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b612892612d8b565b61289a612c54565b6128a2612c40565b600354604051632694552d60e21b81526001600160a01b0392831692639a5154b4926128d89287929091169086906004016147fb565b600060405180830381600087803b1580156128f257600080fd5b505af1158015612906573d6000803e3d6000fd5b505050505050565b6000838261291c8282612d13565b612924612c54565b61292c612d74565b6003546040516327c319e960e11b81526001600160a01b0392831692634f8633d29261296f928c92909116908b908b908b908590600090829082906004016147ab565b6040805180830381600087803b15801561298857600080fd5b505af115801561299c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506129c09190810190613d85565b50979650505050505050565b60006129d6612c40565b6001600160a01b031663d37c4d8b84846040518363ffffffff1660e01b8152600401612a0392919061483e565b60206040518083038186803b158015612a1b57600080fd5b505afa158015612a2f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111709190810190613bec565b6003546001600160a01b031681565b6111f5613307565b6000612a74612c40565b6001600160a01b031663dbf633406040518163ffffffff1660e01b815260040160206040518083038186803b158015612aac57600080fd5b505afa158015612ac0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117fe9190810190613bec565b60048054604051636eb1769f60e11b81526000926001600160a01b039092169163dd62ed3e91612a0391879187910161470a565b612b20612d8b565b612b28612c54565b612b30612c40565b60035460405163227635b160e11b81526001600160a01b03928316926344ec6b62926128d89287929091169086906004016147fb565b6004546001600160a01b031681565b6002546001600160a01b031681565b60008382612b928282612d13565b612b9a612c54565b612ba2612d74565b6003546040516327c319e960e11b81526001600160a01b0392831692634f8633d292612be49291169081908b908b908b908490600090829082906004016147ab565b6040805180830381600087803b158015612bfd57600080fd5b505af1158015612c11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612c359190810190613d85565b509695505050505050565b60006117fe6524b9b9bab2b960d11b6137b1565b6002546001600160a01b03163314801590612c7a57506003546001600160a01b03163314155b1561267257600380546001600160a01b03191633179055565b6002546040516001600160a01b039091169063907dff9790612cb99084906020016148c7565b6040516020818303038152906040526003604051612cd690614691565b6040518091039020612ce78861323b565b612cf08861323b565b60006040518763ffffffff1660e01b815260040161202196959493929190614a1f565b612d1b61380e565b6001600160a01b0316631ce00ba283836040518363ffffffff1660e01b8152600401612d489291906148f1565b60006040518083038186803b158015612d6057600080fd5b505afa158015612906573d6000803e3d6000fd5b60006117fe6822bc31b430b733b2b960b91b6137b1565b612d9361380e565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015612dcb57600080fd5b505afa15801561266d573d6000803e3d6000fd5b60006117fe722932bbb0b93239a234b9ba3934b13aba34b7b760691b6137b1565b60006117fe6d537570706c795363686564756c6560901b6137b1565b6002546040516001600160a01b039091169063907dff9790612e429084906020016148c7565b6040516020818303038152906040526003604051612cd6906146c8565b600082821115612e815760405162461bcd60e51b8152600401610c4990614ae5565b50900390565b6000828201838110156111705760405162461bcd60e51b8152600401610c4990614ac5565b6000546001600160a01b031633146126725760405162461bcd60e51b8152600401610c4990614b35565b612ede61380e565b6001600160a01b031663086dabd16040518163ffffffff1660e01b815260040160006040518083038186803b158015612dcb57600080fd5b600080612f21612c40565b6001600160a01b031663d37c4d8b85631cd554d160e21b6040518363ffffffff1660e01b8152600401612f5592919061483e565b60206040518083038186803b158015612f6d57600080fd5b505afa158015612f81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612fa59190810190613bec565b11156130f257600080612fb6612c40565b600480546040516370a0823160e01b81526001600160a01b0393841693636bed0415938a93909116916370a0823191612ff1918591016146d3565b60206040518083038186803b15801561300957600080fd5b505afa15801561301d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506130419190810190613bec565b6040518363ffffffff1660e01b815260040161305e92919061483e565b604080518083038186803b15801561307557600080fd5b505afa158015613089573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506130ad9190810190613d55565b91509150818411156130d15760405162461bcd60e51b8152600401610c4990614b05565b80156130ef5760405162461bcd60e51b8152600401610c4990614b15565b50505b50600192915050565b60048054604051636eb1769f60e11b81526000926001600160a01b039092169163da46098c918791899161319d918891879163dd62ed3e9161314191889188910161470a565b60206040518083038186803b15801561315957600080fd5b505afa15801561316d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506131919190810190613bec565b9063ffffffff612e5f16565b6040518463ffffffff1660e01b81526004016131bb939291906147fb565b600060405180830381600087803b1580156131d557600080fd5b505af11580156131e9573d6000803e3d6000fd5b505050506131f8848484613355565b90505b949350505050565b61320b612d74565b6001600160a01b0316336001600160a01b0316146126725760405162461bcd60e51b8152600401610c4990614ab5565b6001600160a01b031690565b6002546040516001600160a01b039091169063907dff979061327190869086908690602001614ba0565b604051602081830303815290604052600260405161328e906146b2565b604051809103902061329f8961323b565b6000806040518763ffffffff1660e01b81526004016113fd969594939291906149e5565b60006117fe704c697175696461746f725265776172647360781b6137b1565b600061116d848484613355565b60006117fe692634b8bab4b230ba37b960b11b6137b1565b60405162461bcd60e51b8152600401610c4990614af5565b60006117fe6b526577617264457363726f7760a01b6137b1565b60006117fe6d2932bbb0b93222b9b1b937bbab1960911b6137b1565b60006001600160a01b0383161580159061337857506001600160a01b0383163014155b801561339257506002546001600160a01b03848116911614155b6133ae5760405162461bcd60e51b8152600401610c4990614a85565b600480546040516370a0823160e01b81526001600160a01b039091169163b46310f69187916133ed91879186916370a0823191613141918791016146d3565b6040518363ffffffff1660e01b815260040161340a92919061483e565b600060405180830381600087803b15801561342457600080fd5b505af1158015613438573d6000803e3d6000fd5b5050600480546040516370a0823160e01b81526001600160a01b03909116935063b46310f69250869161347b91879186916370a0823191610de0918791016146d3565b6040518363ffffffff1660e01b815260040161349892919061483e565b600060405180830381600087803b1580156134b257600080fd5b505af11580156134c6573d6000803e3d6000fd5b505050506127c0848484612e1c565b60408051600680825260e082019092526060916020820160c0803883390190505090506b53797374656d53746174757360a01b8160008151811061351557fe5b6020026020010181815250506822bc31b430b733b2b960b91b8160018151811061353b57fe5b6020026020010181815250506524b9b9bab2b960d11b8160028151811061355e57fe5b602002602001018181525050722932bbb0b93239a234b9ba3934b13aba34b7b760691b8160038151811061358e57fe5b602002602001018181525050704c697175696461746f725265776172647360781b816004815181106135bc57fe5b602002602001018181525050692634b8bab4b230ba37b960b11b816005815181106135e357fe5b60200260200101818152505090565b60608151835101604051908082528060200260200182016040528015613622578160200160208202803883390190505b50905060005b83518110156136645783818151811061363d57fe5b602002602001015182828151811061365157fe5b6020908102919091010152600101613628565b5060005b8251811015611e9a5782818151811061367d57fe5b602002602001015182828651018151811061369457fe5b6020908102919091010152600101613668565b6002546001600160a01b031633148015906136cd57506003546001600160a01b03163314155b156136e557600380546001600160a01b031916331790555b6000546003546001600160a01b039081169116146126725760405162461bcd60e51b8152600401610c4990614aa5565b6002546040516001600160a01b039091169063907dff979061373b9084906020016146d3565b6040516020818303038152906040526001604051613758906146a7565b6040519081900381206001600160e01b031960e086901b1682526111c293929160009081908190600401614986565b6002546001600160a01b031633146126725760405162461bcd60e51b8152600401610c4990614b75565b60008181526009602090815260408083205490516001600160a01b0390911691821515916137e191869101614666565b60405160208183030381529060405290611e9a5760405162461bcd60e51b8152600401610c499190614a74565b60006117fe6b53797374656d53746174757360a01b6137b1565b8035610a6481614cac565b8051610a6481614cac565b600082601f83011261384f57600080fd5b815161386261385d82614bfd565b614bd6565b9150818183526020840193506020810190508385602084028201111561388757600080fd5b60005b838110156138b3578161389d88826138d3565b845250602092830192919091019060010161388a565b5050505092915050565b8051610a6481614cc0565b8035610a6481614cc9565b8051610a6481614cc9565b8051610a6481614cd2565b8035610a6481614cd2565b60006020828403121561390657600080fd5b60006131fb8484613828565b60006020828403121561392457600080fd5b60006131fb8484613833565b6000806040838503121561394357600080fd5b600061394f8585613828565b925050602061396085828601613828565b9150509250929050565b60008060006060848603121561397f57600080fd5b600061398b8686613828565b935050602061399c86828701613828565b92505060406139ad868287016138c8565b9150509250925092565b600080604083850312156139ca57600080fd5b60006139d68585613828565b9250506020613960858286016138c8565b6000806000606084860312156139fc57600080fd5b6000613a088686613828565b935050602061399c868287016138c8565b60008060008060808587031215613a2f57600080fd5b6000613a3b8787613828565b9450506020613a4c878288016138c8565b9350506040613a5d878288016138c8565b9250506060613a6e878288016138c8565b91505092959194509250565b60008060008060008060c08789031215613a9357600080fd5b6000613a9f8989613828565b9650506020613ab089828a016138c8565b9550506040613ac189828a016138c8565b9450506060613ad289828a016138c8565b9350506080613ae389828a01613828565b92505060a0613af489828a016138c8565b9150509295509295509295565b60008060008060008060c08789031215613b1a57600080fd5b6000613b268989613828565b9650506020613b3789828a016138c8565b9550506040613b4889828a016138c8565b9450506060613b5989828a016138c8565b9350506080613b6a89828a016138c8565b92505060a0613af489828a01613828565b600060208284031215613b8d57600080fd5b815167ffffffffffffffff811115613ba457600080fd5b6131fb8482850161383e565b600060208284031215613bc257600080fd5b60006131fb84846138bd565b600060208284031215613be057600080fd5b60006131fb84846138c8565b600060208284031215613bfe57600080fd5b60006131fb84846138d3565b60008060008060808587031215613c2057600080fd5b6000613a3b87876138c8565b600080600060608486031215613c4157600080fd5b6000613a0886866138c8565b600080600080600060a08688031215613c6557600080fd5b6000613c7188886138c8565b9550506020613c82888289016138c8565b9450506040613c93888289016138c8565b9350506060613ca488828901613828565b9250506080613cb5888289016138c8565b9150509295509295909350565b600080600080600060a08688031215613cda57600080fd5b6000613ce688886138c8565b9550506020613cf7888289016138c8565b9450506040613d08888289016138c8565b9350506060613ca4888289016138c8565b600060208284031215613d2b57600080fd5b60006131fb84846138de565b600060208284031215613d4957600080fd5b60006131fb84846138e9565b60008060408385031215613d6857600080fd5b6000613d7485856138d3565b9250506020613960858286016138bd565b60008060408385031215613d9857600080fd5b6000613da485856138d3565b9250506020613960858286016138de565b60008060408385031215613dc857600080fd5b6000613dd485856138d3565b9250506020613960858286016138d3565b600080600060608486031215613dfa57600080fd5b6000613e0686866138d3565b9350506020613e17868287016138d3565b92505060406139ad868287016138d3565b6000613e348383613eb6565b505060200190565b613e4581614c52565b82525050565b613e4581614c31565b6000613e5f82614c24565b613e698185614c28565b9350613e7483614c1e565b8060005b83811015613ea2578151613e8c8882613e28565b9750613e9783614c1e565b925050600101613e78565b509495945050505050565b613e4581614c3c565b613e4581610fce565b613e45613ecb82610fce565b610fce565b6000613edb82614c24565b613ee58185614c28565b9350613ef5818560208601614c76565b613efe81614ca2565b9093019392505050565b613e4581614c41565b613e4581614c5d565b613e4581614c6b565b6000613f30601f83614c28565b7f43616e6e6f74207472616e7366657220746f2074686973206164647265737300815260200192915050565b6000613f69603583614c28565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527402063616e20616363657074206f776e65727368697605c1b602082015260400192915050565b6000613fc0601383614c28565b7227bbb732b91037b7363c90333ab731ba34b7b760691b815260200192915050565b6000613fef601e83614c28565b7f4f6e6c792045786368616e6765722063616e20696e766f6b6520746869730000815260200192915050565b600061402860448361094a565b7f41746f6d696353796e746845786368616e676528616464726573732c6279746581527f7333322c75696e743235362c627974657333322c75696e743235362c616464726020820152636573732960e01b604082015260440192915050565b6000614094601b83614c28565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b60006140cd602483614c28565b7f466c616720726577617264207472616e7366657220646964206e6f742073756381526318d9595960e21b602082015260400192915050565b600061411360288361094a565b7f45786368616e67655265636c61696d28616464726573732c627974657333322c81526775696e743235362960c01b602082015260280192915050565b600061415d601e83614c28565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b6000614196601b83614c28565b7f43616e6e6f742062652072756e206f6e2074686973206c617965720000000000815260200192915050565b60006141cf60318361094a565b7f45786368616e6765547261636b696e6728627974657333322c627974657333328152702c75696e743235362c75696e743235362960781b602082015260310192915050565b600061422260118361094a565b70026b4b9b9b4b7339030b2323932b9b99d1607d1b815260110192915050565b600061424f603e8361094a565b7f53796e746845786368616e676528616464726573732c627974657333322c756981527f6e743235362c627974657333322c75696e743235362c616464726573732900006020820152603e0192915050565b60006142ae602683614c28565b7f43616e6e6f74207472616e73666572207374616b6564206f7220657363726f778152650cac840a69cb60d31b602082015260400192915050565b60006142f6601e83614c28565b7f412073796e7468206f7220534e58207261746520697320696e76616c69640000815260200192915050565b600061432f601b83614c28565b7f52657761726473446973747269627574696f6e206e6f74207365740000000000815260200192915050565b6000614368602f83614c28565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681526e37b936903a3434b99030b1ba34b7b760891b602082015260400192915050565b60006143b9602483614c28565b7f5472616e7366657220746f204c697175696461746f72526577617264732066618152631a5b195960e21b602082015260400192915050565b60006143ff60218361094a565b7f417070726f76616c28616464726573732c616464726573732c75696e743235368152602960f81b602082015260210192915050565b600061444260278361094a565b7f45786368616e676552656261746528616464726573732c627974657333322c75815266696e743235362960c81b602082015260270192915050565b600061448b601a8361094a565b7f546f6b656e5374617465557064617465642861646472657373290000000000008152601a0192915050565b60006144c460328361094a565b7f4163636f756e744c69717569646174656428616464726573732c75696e743235815271362c75696e743235362c616464726573732960701b602082015260320192915050565b600061451860198361094a565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b6000614551602983614c28565b7f4c697175696461746520726577617264207472616e7366657220646964206e6f8152681d081cdd58d8d9595960ba1b602082015260400192915050565b600061459c601583614c28565b744e6f20737570706c79206973206d696e7461626c6560581b815260200192915050565b60006145cd60218361094a565b7f5472616e7366657228616464726573732c616464726573732c75696e743235368152602960f81b602082015260210192915050565b6000614610601783614c28565b7f4f6e6c79207468652070726f78792063616e2063616c6c000000000000000000815260200192915050565b613e4581614c4c565b6000610a648261401b565b6000610a6482614106565b6000610a64826141c2565b600061467182614215565b915061467d8284613ebf565b50602001919050565b6000610a6482614242565b6000610a64826143f2565b6000610a6482614435565b6000610a648261447e565b6000610a64826144b7565b60006146718261450b565b6000610a64826145c0565b60208101610a648284613e4b565b60208101610a648284613e3c565b604081016146fd8285613e3c565b6111706020830184613eb6565b604081016147188285613e4b565b6111706020830184613e4b565b6101208101614734828c613e4b565b614741602083018b613e4b565b61474e604083018a613eb6565b61475b6060830189613eb6565b6147686080830188613eb6565b61477560a0830187613e3c565b61478260c0830186613ead565b61478f60e0830185613e4b565b61479d610100830184613eb6565b9a9950505050505050505050565b61012081016147ba828c613e4b565b6147c7602083018b613e4b565b6147d4604083018a613eb6565b6147e16060830189613eb6565b6147ee6080830188613eb6565b61477560a0830187613e4b565b606081016148098286613e4b565b6148166020830185613e4b565b6131fb6040830184613eb6565b604081016148318285613e4b565b6111706020830184613ead565b604081016146fd8285613e4b565b60e0810161485a828a613e4b565b6148676020830189613eb6565b6148746040830188613eb6565b6148816060830187613eb6565b61488e6080830186613e4b565b61489b60a0830185613eb6565b61177860c0830184613eb6565b602080825281016111708184613e54565b60208101610a648284613ead565b60208101610a648284613eb6565b604081016147188285613eb6565b604081016148318285613eb6565b604081016146fd8285613eb6565b6040810161490d8285613eb6565b818103602083015261116d8184613ed0565b60a0810161492d8288613eb6565b61493a6020830187613eb6565b6149476040830186613eb6565b6149546060830185613eb6565b6149616080830184613e4b565b9695505050505050565b606081016149798286613eb6565b6148166020830185613eb6565b60c080825281016149978189613ed0565b90506149a66020830188613f1a565b6149b36040830187613eb6565b6149c06060830186613f11565b6149cd6080830185613f11565b6149da60a0830184613f11565b979650505050505050565b60c080825281016149f68189613ed0565b9050614a056020830188613f1a565b614a126040830187613eb6565b6149c06060830186613eb6565b60c08082528101614a308189613ed0565b9050614a3f6020830188613f1a565b614a4c6040830187613eb6565b614a596060830186613eb6565b6149cd6080830185613eb6565b60208101610a648284613f08565b602080825281016111708184613ed0565b6020808252810161094781613f23565b6020808252810161094781613f5c565b6020808252810161094781613fb3565b6020808252810161094781613fe2565b6020808252810161094781614087565b60208082528101610947816140c0565b6020808252810161094781614150565b6020808252810161094781614189565b60208082528101610947816142a1565b60208082528101610947816142e9565b6020808252810161094781614322565b602080825281016109478161435b565b60208082528101610947816143ac565b6020808252810161094781614544565b602080825281016109478161458f565b6020808252810161094781614603565b60408101614b938285613eb6565b6111706020830184613f08565b60608101614bae8286613eb6565b614bbb6020830185613eb6565b6131fb6040830184613e4b565b60208101610a64828461463c565b60405181810167ffffffffffffffff81118282101715614bf557600080fd5b604052919050565b600067ffffffffffffffff821115614c1457600080fd5b5060209081020190565b60200190565b5190565b90815260200190565b60006109478261323b565b151590565b600061094782614c31565b60ff1690565b600061094782614c41565b6000610947613ecb83610fce565b600061094782610fce565b60005b83811015614c91578181015183820152602001614c79565b8381111561266d5750506000910152565b601f01601f191690565b614cb581614c31565b81146111f557600080fd5b614cb581614c3c565b614cb581610fce565b614cb581614c4156fea365627a7a72315820ea46f549018146cd45078a24736f27e8aba94eca06f4e3845c9f655feb67d1a36c6578706572696d656e74616cf564736f6c63430005100040000000000000000000000000c011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f00000000000000000000000046824bfaafd049fb0af9a45159a88e595bbbb9f700000000000000000000000073570075092502472e4b61a7058df1a4a1db12f2000000000000000000000000000000000000000000d51f6559b1f1b4d0a9dff0000000000000000000000000242a3df52c375bee81b1c668741d7c63af68fdd2

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

000000000000000000000000c011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f00000000000000000000000046824bfaafd049fb0af9a45159a88e595bbbb9f700000000000000000000000073570075092502472e4b61a7058df1a4a1db12f2000000000000000000000000000000000000000000d51f6559b1f1b4d0a9dff0000000000000000000000000242a3df52c375bee81b1c668741d7c63af68fdd2

-----Decoded View---------------
Arg [0] : _proxy (address): 0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f
Arg [1] : _tokenState (address): 0x46824bfaafd049fb0af9a45159a88e595bbbb9f7
Arg [2] : _owner (address): 0x73570075092502472e4b61a7058df1a4a1db12f2
Arg [3] : _totalSupply (uint256): 257649462523249117029326832
Arg [4] : _resolver (address): 0x242a3df52c375bee81b1c668741d7c63af68fdd2

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000c011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f
Arg [1] : 00000000000000000000000046824bfaafd049fb0af9a45159a88e595bbbb9f7
Arg [2] : 00000000000000000000000073570075092502472e4b61a7058df1a4a1db12f2
Arg [3] : 000000000000000000000000000000000000000000d51f6559b1f1b4d0a9dff0
Arg [4] : 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.