Contract
0xc66a263f2C7C1Af0bD70c6cA4Bff5936F3D6Ef9F
1
Contract Overview
Balance:
0 Ether
EtherValue:
$0.00
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
MintableSynthetix
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 optimistic.etherscan.io on 2022-05-14 */ /* ⚠⚠⚠ 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//ovmProxySynthetix *//* ____ __ __ __ _ / __/__ __ ___ / /_ / / ___ / /_ (_)__ __ _\ \ / // // _ \/ __// _ \/ -_)/ __// / \ \ / /___/ \_, //_//_/\__//_//_/\__/ \__//_/ /_\_\ /___/ * Synthetix: MintableSynthetix.sol * * Latest source (may be newer): https://github.com/Synthetixio/synthetix/blob/master/contracts/MintableSynthetix.sol * Docs: https://docs.synthetix.io/contracts/MintableSynthetix * * Contract Dependencies: * - BaseSynthetix * - ExternStateToken * - IAddressResolver * - IERC20 * - ISynthetix * - MixinResolver * - Owned * - Proxyable * - State * Libraries: * - SafeDecimalMath * - SafeMath * * MIT License * =========== * * Copyright (c) 2022 Synthetix * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity >=0.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); } } // Inheritance // https://docs.synthetix.io/contracts/source/contracts/mintablesynthetix contract MintableSynthetix is BaseSynthetix { bytes32 private constant CONTRACT_SYNTHETIX_BRIDGE = "SynthetixBridgeToBase"; constructor( address payable _proxy, TokenState _tokenState, address _owner, uint _totalSupply, address _resolver ) public BaseSynthetix(_proxy, _tokenState, _owner, _totalSupply, _resolver) {} /* ========== INTERNALS =================== */ function _mintSecondary(address account, uint amount) internal { tokenState.setBalanceOf(account, tokenState.balanceOf(account).add(amount)); emitTransfer(address(this), account, amount); totalSupply = totalSupply.add(amount); } function onlyAllowFromBridge() internal view { require(msg.sender == synthetixBridge(), "Can only be invoked by bridge"); } /* ========== MODIFIERS =================== */ modifier onlyBridge() { onlyAllowFromBridge(); _; } /* ========== VIEWS ======================= */ function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { bytes32[] memory existingAddresses = BaseSynthetix.resolverAddressesRequired(); bytes32[] memory newAddresses = new bytes32[](1); newAddresses[0] = CONTRACT_SYNTHETIX_BRIDGE; addresses = combineArrays(existingAddresses, newAddresses); } function synthetixBridge() internal view returns (address) { return requireAndGetAddress(CONTRACT_SYNTHETIX_BRIDGE); } /* ========== RESTRICTED FUNCTIONS ========== */ function mintSecondary(address account, uint amount) external onlyBridge { _mintSecondary(account, amount); } function mintSecondaryRewards(uint amount) external onlyBridge { IRewardsDistribution _rewardsDistribution = rewardsDistribution(); _mintSecondary(address(_rewardsDistribution), amount); _rewardsDistribution.distributeRewards(amount); } function burnSecondary(address account, uint amount) external onlyBridge systemActive { tokenState.setBalanceOf(account, tokenState.balanceOf(account).sub(amount)); emitTransfer(account, address(0), amount); totalSupply = totalSupply.sub(amount); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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":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":"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":"account","type":"address"},{"internalType":"uint256","name":"amount","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":"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":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"exchangeAtomically","outputs":[{"internalType":"uint256","name":"","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":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"exchangeWithTrackingForInitiator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"exchangeWithVirtual","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"contract IVirtualSynth","name":"","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":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintSecondary","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","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"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040516200487638038062004876833981810160405260a08110156200003757600080fd5b508051602080830151604080850151606086015160809096015182518084018452601781527f53796e746865746978204e6574776f726b20546f6b656e00000000000000000081870152835180850190945260038452620a69cb60eb1b958401959095529495929490939091869186918691869186918291879187918660128986816001600160a01b03811662000115576040805162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b038316908117825560408051928352602083019190915280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a1506000546001600160a01b0316620001c0576040805162461bcd60e51b815260206004820152601160248201527013dddb995c881b5d5cdd081899481cd95d607a1b604482015290519081900360640190fd5b600280546001600160a01b0383166001600160a01b0319909116811790915560408051918252517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e9181900360200190a150600480546001600160a01b0319166001600160a01b038816179055845162000242906005906020880190620002ab565b50835162000258906006906020870190620002ab565b50506007919091556008805460ff191660ff90921691909117610100600160a81b0319166101006001600160a01b0397909716969096029590951790945550620003509c50505050505050505050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620002ee57805160ff19168380011785556200031e565b828001600101855582156200031e579182015b828111156200031e57825182559160200191906001019062000301565b506200032c92915062000330565b5090565b6200034d91905b808211156200032c576000815560010162000337565b90565b61451680620003606000396000f3fe608060405234801561001057600080fd5b50600436106103fc5760003560e01c806370a0823111610215578063a5fdc5de11610125578063d67bdd25116100b8578063e8e09b8b11610087578063e8e09b8b14610ca7578063e90dd9e214610cd3578063ec55688914610cdb578063edef719a14610ce3578063ee52a2f314610d0f576103fc565b8063d67bdd2514610c4c578063d8a1f76f14610c54578063dbf6334014610c71578063dd62ed3e14610c79576103fc565b8063bc67f832116100f4578063bc67f83214610b96578063c2bf388014610bbc578063c836fa0a14610be8578063d37c4d8b14610c20576103fc565b8063a5fdc5de14610b0a578063a9059cbb14610b30578063ace88afd14610b5c578063af086c7e14610b8e576103fc565b80638da5cb5b116101a857806397107d6d1161017757806397107d6d14610a735780639741fb2214610a99578063987757dd14610aa15780639f76980714610abe578063a311c7c214610ae4576103fc565b80638da5cb5b14610a1557806391e56b6814610a1d5780639324cac714610a6357806395d89b4114610a6b576103fc565b8063835e119c116101e4578063835e119c146109b657806383d625d4146109d3578063899ffef4146109f05780638a290014146109f8576103fc565b806370a082311461092857806372cb051f1461094e57806374185360146109a657806379ba5097146109ae576103fc565b80632d3169eb116103105780634e99bda9116102a35780635e22846a116102725780635e22846a14610838578063666ed4f11461085e5780636ac0bf9c1461088a5780636c00f310146108b05780636f01a986146108f6576103fc565b80634e99bda9146107e2578063528c7efb146107ea57806353a47bb7146107f25780635af090ef146107fa576103fc565b8063320223db116102df578063320223db1461074d57806332608039146107735780633e89b9e51461079057806344b3e923146107ad576103fc565b80632d3169eb146106ba5780632e0f2625146106e957806330ead76014610707578063313ce56714610745576103fc565b806316b2213f1161039357806323b872dd1161036257806323b872dd14610631578063295da87d146106675780632a905318146106845780632af64bd31461068c5780632c955fa714610694576103fc565b806316b2213f146105de57806318160ddd14610604578063188214001461060c5780631fce304d14610614576103fc565b80630e30963c116103cf5780630e30963c1461051a5780631137aedf1461056a5780631249c58b146105ae5780631627540c146105b6576103fc565b806304f3bcec1461040157806305b3c1c91461042557806306fdde031461045d578063095ea7b3146104da575b600080fd5b610409610d38565b604080516001600160a01b039092168252519081900360200190f35b61044b6004803603602081101561043b57600080fd5b50356001600160a01b0316610d4c565b60408051918252519081900360200190f35b610465610ddf565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561049f578181015183820152602001610487565b50505050905090810190601f1680156104cc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610506600480360360408110156104f057600080fd5b506001600160a01b038135169060200135610e6d565b604080519115158252519081900360200190f35b6105496004803603608081101561053057600080fd5b5080359060208101359060408101359060600135610f08565b604080519283526001600160a01b0390911660208301528051918290030190f35b6105906004803603602081101561058057600080fd5b50356001600160a01b0316610f1c565b60408051938452602084019290925282820152519081900360600190f35b610506610fc2565b6105dc600480360360208110156105cc57600080fd5b50356001600160a01b0316610fcf565b005b61044b600480360360208110156105f457600080fd5b50356001600160a01b031661102b565b61044b61108a565b610465611090565b6105066004803603602081101561062a57600080fd5b50356110c9565b6105066004803603606081101561064757600080fd5b506001600160a01b0381358116916020810135909116906040013561115c565b6105dc6004803603602081101561067d57600080fd5b5035611199565b610465611223565b610506611242565b6105dc600480360360208110156106aa57600080fd5b50356001600160a01b0316611353565b6105dc600480360360808110156106d057600080fd5b50803590602081013590604081013590606001356113c2565b6106f1611505565b6040805160ff9092168252519081900360200190f35b61044b600480360360a081101561071d57600080fd5b508035906020810135906040810135906001600160a01b03606082013516906080013561150a565b6106f16115e8565b6105dc6004803603602081101561076357600080fd5b50356001600160a01b03166115f1565b6104096004803603602081101561078957600080fd5b5035611660565b61044b600480360360208110156107a657600080fd5b50356116ad565b61044b600480360360a08110156107c357600080fd5b5080359060208101359060408101359060608101359060800135611707565b61050661171a565b61050661178d565b610409611919565b61044b600480360360a081101561081057600080fd5b508035906020810135906040810135906001600160a01b036060820135169060800135611707565b6105066004803603602081101561084e57600080fd5b50356001600160a01b0316611928565b6105dc6004803603604081101561087457600080fd5b506001600160a01b038135169060200135611d19565b61044b600480360360208110156108a057600080fd5b50356001600160a01b0316611d2f565b6105dc600480360360c08110156108c657600080fd5b506001600160a01b03813581169160208101359160408201359160608101359160808201359160a0013516611e39565b6105dc6004803603606081101561090c57600080fd5b506001600160a01b038135169060208101359060400135611f98565b61044b6004803603602081101561093e57600080fd5b50356001600160a01b03166120d9565b61095661212c565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561099257818101518382015260200161097a565b505050509050019250505060405180910390f35b6105dc61223c565b6105dc612415565b610409600480360360208110156109cc57600080fd5b50356124d1565b61044b600480360360208110156109e957600080fd5b503561251e565b610956612578565b6105dc60048036036020811015610a0e57600080fd5b50356125ec565b610409612659565b61044b600480360360c0811015610a3357600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135612668565b61044b61274b565b610465612756565b6105dc60048036036020811015610a8957600080fd5b50356001600160a01b03166127b1565b6105dc61280d565b61059060048036036020811015610ab757600080fd5b503561288f565b6105dc60048036036020811015610ad457600080fd5b50356001600160a01b031661290f565b61044b60048036036020811015610afa57600080fd5b50356001600160a01b031661293b565b61044b60048036036020811015610b2057600080fd5b50356001600160a01b031661299a565b61050660048036036040811015610b4657600080fd5b506001600160a01b0381351690602001356129f9565b6105dc60048036036060811015610b7257600080fd5b506001600160a01b038135169060208101359060400135612a39565b6105dc612a99565b6105dc60048036036020811015610bac57600080fd5b50356001600160a01b0316612b00565b6105dc60048036036040811015610bd257600080fd5b506001600160a01b038135169060200135612b2a565b61044b60048036036080811015610bfe57600080fd5b506001600160a01b038135169060208101359060408101359060600135612bbc565b61044b60048036036040811015610c3657600080fd5b506001600160a01b038135169060200135612c9a565b610409612d34565b6105dc60048036036020811015610c6a57600080fd5b5035612d43565b61044b612dd1565b61044b60048036036040811015610c8f57600080fd5b506001600160a01b0381358116916020013516612e13565b6105dc60048036036040811015610cbd57600080fd5b506001600160a01b038135169060200135612e6e565b610409612ee4565b610409612ef3565b6105dc60048036036040811015610cf957600080fd5b506001600160a01b038135169060200135612f02565b61044b60048036036060811015610d2557600080fd5b5080359060208101359060400135613037565b60085461010090046001600160a01b031681565b6000610d56613115565b6001600160a01b03166305b3c1c9836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610dab57600080fd5b505afa158015610dbf573d6000803e3d6000fd5b505050506040513d6020811015610dd557600080fd5b505190505b919050565b6005805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610e655780601f10610e3a57610100808354040283529160200191610e65565b820191906000526020600020905b815481529060010190602001808311610e4857829003601f168201915b505050505081565b6000610e7761312e565b6003546004805460408051633691826360e21b81526001600160a01b03948516938101849052878516602482015260448101879052905192939091169163da46098c9160648082019260009290919082900301818387803b158015610edb57600080fd5b505af1158015610eef573d6000803e3d6000fd5b50505050610efe81858561316d565b5060019392505050565b600080610f13613237565b94509492505050565b6000806000610f29613115565b6001600160a01b0316631137aedf856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060606040518083038186803b158015610f7e57600080fd5b505afa158015610f92573d6000803e3d6000fd5b505050506040513d6060811015610fa857600080fd5b508051602082015160409092015190969195509350915050565b6000610fcc613237565b90565b610fd7613284565b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229181900360200190a150565b6000611035613115565b6001600160a01b03166316b2213f836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610dab57600080fd5b60075481565b6040518060400160405280601781526020017f53796e746865746978204e6574776f726b20546f6b656e00000000000000000081525081565b6000806110d46132cd565b600354604080516301670a7b60e21b81526001600160a01b039283166004820152602481018790529051929091169163059c29ec91604480820192602092909190829003018186803b15801561112957600080fd5b505afa15801561113d573d6000803e3d6000fd5b505050506040513d602081101561115357600080fd5b50511192915050565b600061116661312e565b61116e6132e4565b6111788483613338565b50600354611191906001600160a01b0316858585613588565b949350505050565b6111a1613680565b6111a961312e565b6111b1613115565b6003546040805163b06e8c6560e01b81526001600160a01b039283166004820152602481018590529051929091169163b06e8c659160448082019260009290919082900301818387803b15801561120757600080fd5b505af115801561121b573d6000803e3d6000fd5b505050505b50565b604051806040016040528060038152602001620a69cb60eb1b81525081565b6000606061124e612578565b905060005b815181101561134a57600082828151811061126a57fe5b6020908102919091018101516000818152600983526040908190205460085482516321f8a72160e01b81526004810185905292519395506001600160a01b0391821694610100909104909116926321f8a721926024808201939291829003018186803b1580156112d957600080fd5b505afa1580156112ed573d6000803e3d6000fd5b505050506040513d602081101561130357600080fd5b50516001600160a01b031614158061133057506000818152600960205260409020546001600160a01b0316155b156113415760009350505050610fcc565b50600101611253565b50600191505090565b61135b613680565b61136361312e565b61136b613115565b6003546040805163159fa0d560e11b81526001600160a01b038581166004830152928316602482015290519290911691632b3f41aa9160448082019260009290919082900301818387803b15801561120757600080fd5b6113ca6136c0565b6002805460408051602081018790528082018690526060808201869052825180830390910181526080909101918290526001600160a01b039092169263907dff979291806031614336823960310190506040518091039020886000806040518763ffffffff1660e01b815260040180806020018781526020018681526020018581526020018460001b81526020018360001b8152602001828103825288818151815260200191508051906020019080838360005b8381101561149657818101518382015260200161147e565b50505050905090810190601f1680156114c35780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b1580156114e757600080fd5b505af11580156114fb573d6000803e3d6000fd5b5050505050505050565b601281565b60008584611518828261372d565b61152061312e565b6115286132cd565b600354604080516327c319e960e11b81526001600160a01b039283166004820181905260248201819052604482018d9052606482018c9052608482018b905260a4820152600060c4820181905289841660e4830152610104820189905282519490931693634f8633d29361012480840194938390030190829087803b1580156115b057600080fd5b505af11580156115c4573d6000803e3d6000fd5b505050506040513d60408110156115da57600080fd5b505198975050505050505050565b60085460ff1681565b6115f9613680565b61160161312e565b611609613115565b6003546040805163fd864ccf60e01b81526001600160a01b03858116600483015292831660248201529051929091169163fd864ccf9160448082019260009290919082900301818387803b15801561120757600080fd5b600061166a613115565b6001600160a01b03166332608039836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610dab57600080fd5b60006116b7613115565b6001600160a01b0316637b1001b78360016040518363ffffffff1660e01b815260040180838152602001821515151581526020019250505060206040518083038186803b158015610dab57600080fd5b6000611711613237565b95945050505050565b6000611724613115565b6001600160a01b0316634e99bda96040518163ffffffff1660e01b815260040160206040518083038186803b15801561175c57600080fd5b505afa158015611770573d6000803e3d6000fd5b505050506040513d602081101561178657600080fd5b5051905090565b60006117976132e4565b61179f61312e565b6000806117aa613115565b600354604080516339632c0b60e11b81526001600160a01b03928316600482015260016024820152815193909216926372c658169260448082019392918290030181600087803b1580156117fd57600080fd5b505af1158015611811573d6000803e3d6000fd5b505050506040513d604081101561182757600080fd5b508051602090910151600354919350915061184d906001600160a01b0316838382613794565b60035460009061186e906001600160a01b031661186861386b565b8561388a565b9050806118ac5760405162461bcd60e51b81526004018080602001828103825260248152602001806143fa6024913960400191505060405180910390fd5b6118b461386b565b6001600160a01b0316633c6b16ab846040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156118f957600080fd5b505af115801561190d573d6000803e3d6000fd5b50929550505050505090565b6001546001600160a01b031681565b60006119326132e4565b61193a61312e565b600080611945613115565b604080516339632c0b60e11b81526001600160a01b038781166004830152600060248301819052835194909116936372c65816936044808501949193918390030190829087803b15801561199857600080fd5b505af11580156119ac573d6000803e3d6000fd5b505050506040513d60408110156119c257600080fd5b50805160209091015160035491935091506119eb908590849084906001600160a01b0316613794565b8115611d0e576000806119fc613897565b6001600160a01b0316638074b3726040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3457600080fd5b505afa158015611a48573d6000803e3d6000fd5b505050506040513d6020811015611a5e57600080fd5b505190506000611a6c613897565b6001600160a01b03166331e4e0306040518163ffffffff1660e01b815260040160206040518083038186803b158015611aa457600080fd5b505afa158015611ab8573d6000803e3d6000fd5b505050506040513d6020811015611ace57600080fd5b50519050611ae2828263ffffffff6138af16565b851115611c44576000611af3613897565b6001600160a01b0316635616c957896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611b4857600080fd5b505afa158015611b5c573d6000803e3d6000fd5b505050506040513d6020811015611b7257600080fd5b505190506000611b8389838661388a565b905080611bc15760405162461bcd60e51b81526004018080602001828103825260248152602001806142ea6024913960400191505060405180910390fd5b600354600090611bdc908b906001600160a01b03168661388a565b905080611c1a5760405162461bcd60e51b81526004018080602001828103825260298152602001806144986029913960400191505060405180910390fd5b611c3a611c2d868663ffffffff6138af16565b899063ffffffff61391016565b9550505050611c48565b8492505b6000611c5c88611c5661386b565b8661388a565b905080611c9a5760405162461bcd60e51b81526004018080602001828103825260248152602001806143fa6024913960400191505060405180910390fd5b611ca261386b565b6001600160a01b0316633c6b16ab856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611ce757600080fd5b505af1158015611cfb573d6000803e3d6000fd5b5050505060019650505050505050610dda565b600092505050610dda565b611d2161396d565b611d2b82826139da565b5050565b6000611d39613115565b60048054604080516370a0823160e01b81526001600160a01b0387811694820194909452905193831693636bed041593879316916370a08231916024808301926020929190829003018186803b158015611d9257600080fd5b505afa158015611da6573d6000803e3d6000fd5b505050506040513d6020811015611dbc57600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091528051604480840193829003018186803b158015611e0757600080fd5b505afa158015611e1b573d6000803e3d6000fd5b505050506040513d6040811015611e3157600080fd5b505192915050565b611e416136c0565b60028054604080516020810189905280820188905260608101879052608081018690526001600160a01b0385811660a0808401919091528351808403909101815260c0909201928390529092169263907dff97929180603e6143678239603e0190506040518091039020611eb48b613af7565b6000806040518763ffffffff1660e01b815260040180806020018781526020018681526020018581526020018460001b81526020018360001b8152602001828103825288818151815260200191508051906020019080838360005b83811015611f27578181015183820152602001611f0f565b50505050905090810190601f168015611f545780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b158015611f7857600080fd5b505af1158015611f8c573d6000803e3d6000fd5b50505050505050505050565b611fa06136c0565b6002805460408051602081018690528082018590528151808203830181526060909101918290526001600160a01b039092169263907dff97929180602761443f823960270190506040518091039020611ff888613af7565b6000806040518763ffffffff1660e01b815260040180806020018781526020018681526020018581526020018460001b81526020018360001b8152602001828103825288818151815260200191508051906020019080838360005b8381101561206b578181015183820152602001612053565b50505050905090810190601f1680156120985780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b1580156120bc57600080fd5b505af11580156120d0573d6000803e3d6000fd5b50505050505050565b60048054604080516370a0823160e01b81526001600160a01b03858116948201949094529051600093909216916370a0823191602480820192602092909190829003018186803b158015610dab57600080fd5b6060612136613115565b6001600160a01b03166372cb051f6040518163ffffffff1660e01b815260040160006040518083038186803b15801561216e57600080fd5b505afa158015612182573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156121ab57600080fd5b81019080805160405193929190846401000000008211156121cb57600080fd5b9083019060208201858111156121e057600080fd5b82518660208202830111640100000000821117156121fd57600080fd5b82525081516020918201928201910280838360005b8381101561222a578181015183820152602001612212565b50505050905001604052505050905090565b6060612246612578565b905060005b8151811015611d2b57600082828151811061226257fe5b602002602001015190506000600860019054906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200180807f5265736f6c766572206d697373696e67207461726765743a20000000000000008152506019018281526020019150506040516020818303038152906040526040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561232d578181015183820152602001612315565b50505050905090810190601f16801561235a5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561237857600080fd5b505afa15801561238c573d6000803e3d6000fd5b505050506040513d60208110156123a257600080fd5b505160008381526009602090815260409182902080546001600160a01b0319166001600160a01b03851690811790915582518681529182015281519293507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68929081900390910190a1505060010161224b565b6001546001600160a01b0316331461245e5760405162461bcd60e51b81526004018080602001828103825260358152602001806142b56035913960400191505060405180910390fd5b600054600154604080516001600160a01b03938416815292909116602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b60006124db613115565b6001600160a01b031663835e119c836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610dab57600080fd5b6000612528613115565b6001600160a01b0316637b1001b78360006040518363ffffffff1660e01b815260040180838152602001821515151581526020019250505060206040518083038186803b158015610dab57600080fd5b606080612583613b03565b60408051600180825281830190925291925060609190602080830190803883390190505090507453796e746865746978427269646765546f4261736560581b816000815181106125cf57fe5b6020026020010181815250506125e58282613c20565b9250505090565b6125f4613680565b6125fc61312e565b612604613115565b600354604080516285c0d160e31b81526001600160a01b039283166004820152602481018590529051929091169163042e06889160448082019260009290919082900301818387803b15801561120757600080fd5b6000546001600160a01b031681565b60008584612676828261372d565b61267e61312e565b6126866132cd565b600354604080516327c319e960e11b81526001600160a01b038d8116600483018190529381166024830152604482018d9052606482018c9052608482018b905260a4820193909352600060c4820181905289841660e4830152610104820189905282519490931693634f8633d29361012480840194938390030190829087803b15801561271257600080fd5b505af1158015612726573d6000803e3d6000fd5b505050506040513d604081101561273c57600080fd5b50519998505050505050505050565b631cd554d160e21b81565b6006805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610e655780601f10610e3a57610100808354040283529160200191610e65565b6127b9613284565b600280546001600160a01b0383166001600160a01b0319909116811790915560408051918252517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e9181900360200190a150565b612815613680565b61281d61312e565b612825613115565b600354604080516324beb82560e11b81526001600160a01b0392831660048201529051929091169163497d704a9160248082019260009290919082900301818387803b15801561287457600080fd5b505af1158015612888573d6000803e3d6000fd5b505050505b565b600080600061289c61312e565b6128a46132cd565b600354604080516306c5a00b60e21b81526001600160a01b0392831660048201526024810188905290519290911691631b16802c916044808201926060929091908290030181600087803b1580156128fb57600080fd5b505af1158015610f92573d6000803e3d6000fd5b612917613cdc565b600480546001600160a01b0319166001600160a01b03831617905561122081613d75565b6000612945613115565b6001600160a01b031663a311c7c2836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610dab57600080fd5b60006129a4613115565b6001600160a01b031663a5fdc5de836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610dab57600080fd5b6000612a0361312e565b612a0b6132e4565b600354612a21906001600160a01b031683613338565b50600354610efe906001600160a01b0316848461388a565b612a416136c0565b6002805460408051602081018690528082018590528151808203830181526060909101918290526001600160a01b039092169263907dff97929180602861430e823960280190506040518091039020611ff888613af7565b612aa1613680565b612aa961312e565b612ab1613115565b6003546040805163644bb89960e11b81526001600160a01b0392831660048201529051929091169163c89771329160248082019260009290919082900301818387803b15801561287457600080fd5b612b08613ea0565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b612b32613680565b612b3a61312e565b612b42613115565b60035460408051632694552d60e21b81526001600160a01b03868116600483015292831660248201526044810185905290519290911691639a5154b49160648082019260009290919082900301818387803b158015612ba057600080fd5b505af1158015612bb4573d6000803e3d6000fd5b505050505050565b60008382612bca828261372d565b612bd261312e565b612bda6132cd565b600354604080516327c319e960e11b81526001600160a01b038b8116600483018190529381166024830152604482018b9052606482018a90526084820189905260a48201849052600060c4830181905260e483019490945261010482018490528251941693634f8633d29361012480840194938390030190829087803b158015612c6357600080fd5b505af1158015612c77573d6000803e3d6000fd5b505050506040513d6040811015612c8d57600080fd5b5051979650505050505050565b6000612ca4613115565b6001600160a01b031663d37c4d8b84846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b031681526020018281526020019250505060206040518083038186803b158015612d0157600080fd5b505afa158015612d15573d6000803e3d6000fd5b505050506040513d6020811015612d2b57600080fd5b50519392505050565b6003546001600160a01b031681565b612d4b61396d565b6000612d55613eff565b9050612d6181836139da565b806001600160a01b03166359974e38836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612da757600080fd5b505af1158015612dbb573d6000803e3d6000fd5b505050506040513d602081101561288857600080fd5b6000612ddb613115565b6001600160a01b031663dbf633406040518163ffffffff1660e01b815260040160206040518083038186803b15801561175c57600080fd5b6004805460408051636eb1769f60e11b81526001600160a01b0386811694820194909452848416602482015290516000939092169163dd62ed3e91604480820192602092909190829003018186803b158015612d0157600080fd5b612e76613680565b612e7e61312e565b612e86613115565b6003546040805163227635b160e11b81526001600160a01b038681166004830152928316602482015260448101859052905192909116916344ec6b629160648082019260009290919082900301818387803b158015612ba057600080fd5b6004546001600160a01b031681565b6002546001600160a01b031681565b612f0a61396d565b612f126132e4565b60048054604080516370a0823160e01b81526001600160a01b03868116948201949094529051929091169163b46310f6918591612faa91869186916370a08231916024808301926020929190829003018186803b158015612f7257600080fd5b505afa158015612f86573d6000803e3d6000fd5b505050506040513d6020811015612f9c57600080fd5b50519063ffffffff61391016565b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015612ff957600080fd5b505af115801561300d573d6000803e3d6000fd5b5050505061301d82600083613f20565b600754613030908263ffffffff61391016565b6007555050565b60008382613045828261372d565b61304d61312e565b6130556132cd565b600354604080516327c319e960e11b81526001600160a01b039283166004820181905260248201819052604482018b9052606482018a90526084820189905260a48201819052600060c4830181905260e4830191909152610104820181905282519490931693634f8633d29361012480840194938390030190829087803b1580156130df57600080fd5b505af11580156130f3573d6000803e3d6000fd5b505050506040513d604081101561310957600080fd5b50519695505050505050565b60006131296524b9b9bab2b960d11b613f73565b905090565b6002546001600160a01b0316331480159061315457506003546001600160a01b03163314155b1561288d57600380546001600160a01b03191633179055565b60025460408051602080820185905282518083039091018152908201918290526001600160a01b039092169163907dff979160039080602161441e8239602101905060405180910390206131c088613af7565b6131c988613af7565b60006040518763ffffffff1660e01b815260040180806020018781526020018681526020018581526020018481526020018360001b8152602001828103825288818151815260200191508051906020019080838360008381101561206b578181015183820152602001612053565b6040805162461bcd60e51b815260206004820152601b60248201527f43616e6e6f742062652072756e206f6e2074686973206c617965720000000000604482015290519081900360640190fd5b6000546001600160a01b0316331461288d5760405162461bcd60e51b815260040180806020018281038252602f8152602001806143cb602f913960400191505060405180910390fd5b60006131296822bc31b430b733b2b960b91b613f73565b6132ec614050565b6001600160a01b031663086dabd16040518163ffffffff1660e01b815260040160006040518083038186803b15801561332457600080fd5b505afa158015612888573d6000803e3d6000fd5b600080613343613115565b6001600160a01b031663d37c4d8b85631cd554d160e21b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b031681526020018281526020019250505060206040518083038186803b1580156133a757600080fd5b505afa1580156133bb573d6000803e3d6000fd5b505050506040513d60208110156133d157600080fd5b5051111561357f576000806133e4613115565b60048054604080516370a0823160e01b81526001600160a01b038a811694820194909452905193831693636bed0415938a9316916370a08231916024808301926020929190829003018186803b15801561343d57600080fd5b505afa158015613451573d6000803e3d6000fd5b505050506040513d602081101561346757600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091528051604480840193829003018186803b1580156134b257600080fd5b505afa1580156134c6573d6000803e3d6000fd5b505050506040513d60408110156134dc57600080fd5b5080516020909101519092509050818411156135295760405162461bcd60e51b81526004018080602001828103825260268152602001806143a56026913960400191505060405180910390fd5b801561357c576040805162461bcd60e51b815260206004820152601e60248201527f412073796e7468206f7220534e58207261746520697320696e76616c69640000604482015290519081900360640190fd5b50505b50600192915050565b6004805460408051636eb1769f60e11b81526001600160a01b0387811694820194909452878416602482015290516000939092169163da46098c91879189916135f5918891879163dd62ed3e91604480820192602092909190829003018186803b158015612f7257600080fd5b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561365d57600080fd5b505af1158015613671573d6000803e3d6000fd5b5050505061171184848461406a565b613688614050565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b15801561332457600080fd5b6136c86132cd565b6001600160a01b0316336001600160a01b03161461288d576040805162461bcd60e51b815260206004820152601e60248201527f4f6e6c792045786368616e6765722063616e20696e766f6b6520746869730000604482015290519081900360640190fd5b613735614050565b6001600160a01b0316631ce00ba283836040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b15801561378057600080fd5b505afa158015612bb4573d6000803e3d6000fd5b6002805460408051602081018790528082018690526001600160a01b03858116606080840191909152835180840390910181526080909201928390529092169263907dff9792918060326144668239603201905060405180910390206137f989613af7565b6000806040518763ffffffff1660e01b815260040180806020018781526020018681526020018581526020018460001b81526020018360001b8152602001828103825288818151815260200191508051906020019080838360008381101561149657818101518382015260200161147e565b6000613129704c697175696461746f725265776172647360781b613f73565b600061119184848461406a565b6000613129692634b8bab4b230ba37b960b11b613f73565b600082820183811015613909576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600082821115613967576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b613975614291565b6001600160a01b0316336001600160a01b03161461288d576040805162461bcd60e51b815260206004820152601d60248201527f43616e206f6e6c7920626520696e766f6b656420627920627269646765000000604482015290519081900360640190fd5b60048054604080516370a0823160e01b81526001600160a01b03868116948201949094529051929091169163b46310f6918591613a7291869186916370a08231916024808301926020929190829003018186803b158015613a3a57600080fd5b505afa158015613a4e573d6000803e3d6000fd5b505050506040513d6020811015613a6457600080fd5b50519063ffffffff6138af16565b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015613ac157600080fd5b505af1158015613ad5573d6000803e3d6000fd5b50505050613ae4308383613f20565b600754613030908263ffffffff6138af16565b6001600160a01b031690565b60408051600680825260e082019092526060916020820160c0803883390190505090506b53797374656d53746174757360a01b81600081518110613b4357fe5b6020026020010181815250506822bc31b430b733b2b960b91b81600181518110613b6957fe5b6020026020010181815250506524b9b9bab2b960d11b81600281518110613b8c57fe5b602002602001018181525050722932bbb0b93239a234b9ba3934b13aba34b7b760691b81600381518110613bbc57fe5b602002602001018181525050704c697175696461746f725265776172647360781b81600481518110613bea57fe5b602002602001018181525050692634b8bab4b230ba37b960b11b81600581518110613c1157fe5b60200260200101818152505090565b60608151835101604051908082528060200260200182016040528015613c50578160200160208202803883390190505b50905060005b8351811015613c9257838181518110613c6b57fe5b6020026020010151828281518110613c7f57fe5b6020908102919091010152600101613c56565b5060005b8251811015613cd557828181518110613cab57fe5b6020026020010151828286510181518110613cc257fe5b6020908102919091010152600101613c96565b5092915050565b6002546001600160a01b03163314801590613d0257506003546001600160a01b03163314155b15613d1a57600380546001600160a01b031916331790555b6000546003546001600160a01b0390811691161461288d576040805162461bcd60e51b815260206004820152601360248201527227bbb732b91037b7363c90333ab731ba34b7b760691b604482015290519081900360640190fd5b600254604080516001600160a01b038481166020808401919091528351808403820181528385018086527f546f6b656e5374617465557064617465642861646472657373290000000000009052935192839003605a01832063907dff9760e01b8452600160248501819052604485018290526000606486018190526084860181905260a4860181905260c060048701908152875160c48801528751959098169763907dff97979692959394919384938493839260e490920191908a0190808383885b83811015613e4f578181015183820152602001613e37565b50505050905090810190601f168015613e7c5780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b15801561120757600080fd5b6002546001600160a01b0316331461288d576040805162461bcd60e51b815260206004820152601760248201527f4f6e6c79207468652070726f78792063616e2063616c6c000000000000000000604482015290519081900360640190fd5b6000613129722932bbb0b93239a234b9ba3934b13aba34b7b760691b613f73565b60025460408051602080820185905282518083039091018152908201918290526001600160a01b039092169163907dff97916003908060216144c18239602101905060405180910390206131c088613af7565b600081815260096020908152604080832054815170026b4b9b9b4b7339030b2323932b9b99d1607d1b9381019390935260318084018690528251808503909101815260519093019091526001600160a01b03169081613cd55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614015578181015183820152602001613ffd565b50505050905090810190601f1680156140425780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60006131296b53797374656d53746174757360a01b613f73565b60006001600160a01b0383161580159061408d57506001600160a01b0383163014155b80156140a757506002546001600160a01b03848116911614155b6140f8576040805162461bcd60e51b815260206004820152601f60248201527f43616e6e6f74207472616e7366657220746f2074686973206164647265737300604482015290519081900360640190fd5b60048054604080516370a0823160e01b81526001600160a01b03888116948201949094529051929091169163b46310f691879161415891879186916370a08231916024808301926020929190829003018186803b158015612f7257600080fd5b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156141a757600080fd5b505af11580156141bb573d6000803e3d6000fd5b505060048054604080516370a0823160e01b81526001600160a01b0389811694820194909452905192909116935063b46310f69250869161421f91879186916370a08231916024808301926020929190829003018186803b158015613a3a57600080fd5b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561426e57600080fd5b505af1158015614282573d6000803e3d6000fd5b50505050610efe848484613f20565b60006131297453796e746865746978427269646765546f4261736560581b613f7356fe596f75206d757374206265206e6f6d696e61746564206265666f726520796f752063616e20616363657074206f776e657273686970466c616720726577617264207472616e7366657220646964206e6f74207375636365656445786368616e67655265636c61696d28616464726573732c627974657333322c75696e743235362945786368616e6765547261636b696e6728627974657333322c627974657333322c75696e743235362c75696e743235362953796e746845786368616e676528616464726573732c627974657333322c75696e743235362c627974657333322c75696e743235362c616464726573732943616e6e6f74207472616e73666572207374616b6564206f7220657363726f77656420534e584f6e6c792074686520636f6e7472616374206f776e6572206d617920706572666f726d207468697320616374696f6e5472616e7366657220746f204c697175696461746f7252657761726473206661696c6564417070726f76616c28616464726573732c616464726573732c75696e743235362945786368616e676552656261746528616464726573732c627974657333322c75696e74323536294163636f756e744c69717569646174656428616464726573732c75696e743235362c75696e743235362c61646472657373294c697175696461746520726577617264207472616e7366657220646964206e6f7420737563636565645472616e7366657228616464726573732c616464726573732c75696e7432353629a265627a7a7231582056bfde9cb144938cf3d4c65a3bfe81e2e2ee76bd69553bcb369bd8b3b20acb5b64736f6c634300051000320000000000000000000000008700daec35af8ff88c16bdf0418774cb3d7599b4000000000000000000000000b9c6ca25452e7f6d0d3340ce1e9b573421afc2ee000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe0000000000000000000000000000000000000000002cb8e740f2ea7913a9d1860000000000000000000000001cb059b7e74fd21665968c908806143e744d5f30
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000008700daec35af8ff88c16bdf0418774cb3d7599b4000000000000000000000000b9c6ca25452e7f6d0d3340ce1e9b573421afc2ee000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe0000000000000000000000000000000000000000002cb8e740f2ea7913a9d1860000000000000000000000001cb059b7e74fd21665968c908806143e744d5f30
-----Decoded View---------------
Arg [0] : _proxy (address): 0x8700daec35af8ff88c16bdf0418774cb3d7599b4
Arg [1] : _tokenState (address): 0xb9c6ca25452e7f6d0d3340ce1e9b573421afc2ee
Arg [2] : _owner (address): 0xde910777c787903f78c89e7a0bf7f4c435cbb1fe
Arg [3] : _totalSupply (uint256): 54065917373833493846020486
Arg [4] : _resolver (address): 0x1cb059b7e74fd21665968c908806143e744d5f30
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000008700daec35af8ff88c16bdf0418774cb3d7599b4
Arg [1] : 000000000000000000000000b9c6ca25452e7f6d0d3340ce1e9b573421afc2ee
Arg [2] : 000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe
Arg [3] : 0000000000000000000000000000000000000000002cb8e740f2ea7913a9d186
Arg [4] : 0000000000000000000000001cb059b7e74fd21665968c908806143e744d5f30
Library Used
SafeDecimalMath : 0x0142f40c25ce1f1177ed131101fa19217396cb88
SystemSettingsLib : 0xc818f3a73f0f4a9afdc9835be2682e627a04a4ff
SignedSafeDecimalMath : 0x253914cf059f4c3e277c28060c404acfc38fb6e2
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.