Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 568 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Update Cached Sy... | 12425644 | 1331 days ago | IN | 0 ETH | 0.04094181 | ||||
Update Cached Sy... | 12425581 | 1331 days ago | IN | 0 ETH | 0.03293997 | ||||
Update Cached Sy... | 12425421 | 1331 days ago | IN | 0 ETH | 0.03430001 | ||||
Update Cached Sy... | 12425347 | 1331 days ago | IN | 0 ETH | 0.0422393 | ||||
Take Debt Snapsh... | 12425300 | 1331 days ago | IN | 0 ETH | 0.71456262 | ||||
Update Cached Sy... | 12425258 | 1331 days ago | IN | 0 ETH | 0.03648166 | ||||
Update Cached Sy... | 12425100 | 1331 days ago | IN | 0 ETH | 0.03187294 | ||||
Update Cached Sy... | 12424942 | 1331 days ago | IN | 0 ETH | 0.02535018 | ||||
Update Cached Sy... | 12424152 | 1331 days ago | IN | 0 ETH | 0.0921795 | ||||
Update Cached Sy... | 12423755 | 1331 days ago | IN | 0 ETH | 0.05155997 | ||||
Update Cached Sy... | 12423647 | 1331 days ago | IN | 0 ETH | 0.03108493 | ||||
Update Cached Sy... | 12423253 | 1331 days ago | IN | 0 ETH | 0.0520043 | ||||
Update Cached Sy... | 12422815 | 1331 days ago | IN | 0 ETH | 0.080355 | ||||
Update Cached Sy... | 12422663 | 1332 days ago | IN | 0 ETH | 0.072282 | ||||
Update Cached Sy... | 12422580 | 1332 days ago | IN | 0 ETH | 0.06207959 | ||||
Update Cached Sy... | 12422543 | 1332 days ago | IN | 0 ETH | 0.05820888 | ||||
Update Cached Sy... | 12422507 | 1332 days ago | IN | 0 ETH | 0.03782904 | ||||
Update Cached Sy... | 12422368 | 1332 days ago | IN | 0 ETH | 0.04148379 | ||||
Update Cached Sy... | 12422254 | 1332 days ago | IN | 0 ETH | 0.03808348 | ||||
Update Cached Sy... | 12422195 | 1332 days ago | IN | 0 ETH | 0.05892568 | ||||
Take Debt Snapsh... | 12422033 | 1332 days ago | IN | 0 ETH | 0.75322377 | ||||
Update Cached Sy... | 12421559 | 1332 days ago | IN | 0 ETH | 0.0623796 | ||||
Update Cached Sy... | 12421461 | 1332 days ago | IN | 0 ETH | 0.0459927 | ||||
Update Cached Sy... | 12420783 | 1332 days ago | IN | 0 ETH | 0.0639654 | ||||
Update Cached Sy... | 12420451 | 1332 days ago | IN | 0 ETH | 0.0459927 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
DebtCache
Compiler Version
v0.5.16+commit.9c3226ce
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-12-24 */ /* ____ __ __ __ _ / __/__ __ ___ / /_ / / ___ / /_ (_)__ __ _\ \ / // // _ \/ __// _ \/ -_)/ __// / \ \ / /___/ \_, //_//_/\__//_//_/\__/ \__//_/ /_\_\ /___/ * Synthetix: DebtCache.sol * * Latest source (may be newer): https://github.com/Synthetixio/synthetix/blob/master/contracts/DebtCache.sol * Docs: https://docs.synthetix.io/contracts/DebtCache * * Contract Dependencies: * - IAddressResolver * - IDebtCache * - MixinResolver * - MixinSystemSettings * - Owned * Libraries: * - SafeDecimalMath * - SafeMath * * MIT License * =========== * * Copyright (c) 2020 Synthetix * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity ^0.5.16; // https://docs.synthetix.io/contracts/source/contracts/owned contract Owned { address public owner; address public nominatedOwner; constructor(address _owner) public { require(_owner != address(0), "Owner address cannot be 0"); owner = _owner; emit OwnerChanged(address(0), _owner); } function nominateNewOwner(address _owner) external onlyOwner { nominatedOwner = _owner; emit OwnerNominated(_owner); } function acceptOwnership() external { require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership"); emit OwnerChanged(owner, nominatedOwner); owner = nominatedOwner; nominatedOwner = address(0); } modifier onlyOwner { _onlyOwner(); _; } function _onlyOwner() private view { require(msg.sender == owner, "Only the contract owner may perform this action"); } event OwnerNominated(address newOwner); event OwnerChanged(address oldOwner, address newOwner); } // https://docs.synthetix.io/contracts/source/interfaces/iaddressresolver interface IAddressResolver { function getAddress(bytes32 name) external view returns (address); function getSynth(bytes32 key) external view returns (address); function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address); } // https://docs.synthetix.io/contracts/source/interfaces/isynth interface ISynth { // Views function currencyKey() external view returns (bytes32); function transferableSynths(address account) external view returns (uint); // Mutative functions function transferAndSettle(address to, uint value) external returns (bool); function transferFromAndSettle( address from, address to, uint value ) external returns (bool); // Restricted: used internally to Synthetix function burn(address account, uint amount) external; function issue(address account, uint amount) external; } // https://docs.synthetix.io/contracts/source/interfaces/iissuer interface IIssuer { // Views function anySynthOrSNXRateIsInvalid() external view returns (bool anyRateInvalid); function availableCurrencyKeys() external view returns (bytes32[] memory); function availableSynthCount() external view returns (uint); function availableSynths(uint index) external view returns (ISynth); function canBurnSynths(address account) external view returns (bool); function collateral(address account) external view returns (uint); function collateralisationRatio(address issuer) external view returns (uint); function collateralisationRatioAndAnyRatesInvalid(address _issuer) external view returns (uint cratio, bool anyRateIsInvalid); function debtBalanceOf(address issuer, bytes32 currencyKey) external view returns (uint debtBalance); function issuanceRatio() external view returns (uint); function lastIssueEvent(address account) external view returns (uint); function maxIssuableSynths(address issuer) external view returns (uint maxIssuable); function minimumStakeTime() external view returns (uint); function remainingIssuableSynths(address issuer) external view returns ( uint maxIssuable, uint alreadyIssued, uint totalSystemDebt ); function synths(bytes32 currencyKey) external view returns (ISynth); function getSynths(bytes32[] calldata currencyKeys) external view returns (ISynth[] memory); function synthsByAddress(address synthAddress) external view returns (bytes32); function totalIssuedSynths(bytes32 currencyKey, bool excludeEtherCollateral) 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 liquidateDelinquentAccount( address account, uint susdAmount, address liquidator ) external returns (uint totalRedeemed, uint amountToLiquidate); } // 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); } // solhint-disable payable-fallback // https://docs.synthetix.io/contracts/source/contracts/readproxy contract ReadProxy is Owned { address public target; constructor(address _owner) public Owned(_owner) {} function setTarget(address _target) external onlyOwner { target = _target; emit TargetUpdated(target); } function() external { // The basics of a proxy read call // Note that msg.sender in the underlying will always be the address of this contract. assembly { calldatacopy(0, 0, calldatasize) // Use of staticcall - this will revert if the underlying function mutates state let result := staticcall(gas, sload(target_slot), 0, calldatasize, 0, 0) returndatacopy(0, 0, returndatasize) if iszero(result) { revert(0, returndatasize) } return(0, returndatasize) } } event TargetUpdated(address newTarget); } // Inheritance // Internal references // https://docs.synthetix.io/contracts/source/contracts/mixinresolver contract MixinResolver { AddressResolver public resolver; mapping(bytes32 => address) private addressCache; constructor(address _resolver) internal { resolver = AddressResolver(_resolver); } /* ========== INTERNAL FUNCTIONS ========== */ function combineArrays(bytes32[] memory first, bytes32[] memory second) internal pure returns (bytes32[] memory combination) { combination = new bytes32[](first.length + second.length); for (uint i = 0; i < first.length; i++) { combination[i] = first[i]; } for (uint j = 0; j < second.length; j++) { combination[first.length + j] = second[j]; } } /* ========== PUBLIC FUNCTIONS ========== */ // Note: this function is public not external in order for it to be overridden and invoked via super in subclasses function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {} function rebuildCache() public { bytes32[] memory requiredAddresses = resolverAddressesRequired(); // The resolver must call this function whenver it updates its state for (uint i = 0; i < requiredAddresses.length; i++) { bytes32 name = requiredAddresses[i]; // Note: can only be invoked once the resolver has all the targets needed added address destination = resolver.requireAndGetAddress( name, string(abi.encodePacked("Resolver missing target: ", name)) ); addressCache[name] = destination; emit CacheUpdated(name, destination); } } /* ========== VIEWS ========== */ function isResolverCached() external view returns (bool) { bytes32[] memory requiredAddresses = resolverAddressesRequired(); for (uint i = 0; i < requiredAddresses.length; i++) { bytes32 name = requiredAddresses[i]; // false if our cache is invalid or if the resolver doesn't have the required address if (resolver.getAddress(name) != addressCache[name] || addressCache[name] == address(0)) { return false; } } return true; } /* ========== INTERNAL FUNCTIONS ========== */ function requireAndGetAddress(bytes32 name) internal view returns (address) { address _foundAddress = addressCache[name]; require(_foundAddress != address(0), string(abi.encodePacked("Missing address: ", name))); return _foundAddress; } /* ========== EVENTS ========== */ event CacheUpdated(bytes32 name, address destination); } // https://docs.synthetix.io/contracts/source/interfaces/iflexiblestorage interface IFlexibleStorage { // Views function getUIntValue(bytes32 contractName, bytes32 record) external view returns (uint); function getUIntValues(bytes32 contractName, bytes32[] calldata records) external view returns (uint[] memory); function getIntValue(bytes32 contractName, bytes32 record) external view returns (int); function getIntValues(bytes32 contractName, bytes32[] calldata records) external view returns (int[] memory); function getAddressValue(bytes32 contractName, bytes32 record) external view returns (address); function getAddressValues(bytes32 contractName, bytes32[] calldata records) external view returns (address[] memory); function getBoolValue(bytes32 contractName, bytes32 record) external view returns (bool); function getBoolValues(bytes32 contractName, bytes32[] calldata records) external view returns (bool[] memory); function getBytes32Value(bytes32 contractName, bytes32 record) external view returns (bytes32); function getBytes32Values(bytes32 contractName, bytes32[] calldata records) external view returns (bytes32[] memory); // Mutative functions function deleteUIntValue(bytes32 contractName, bytes32 record) external; function deleteIntValue(bytes32 contractName, bytes32 record) external; function deleteAddressValue(bytes32 contractName, bytes32 record) external; function deleteBoolValue(bytes32 contractName, bytes32 record) external; function deleteBytes32Value(bytes32 contractName, bytes32 record) external; function setUIntValue( bytes32 contractName, bytes32 record, uint value ) external; function setUIntValues( bytes32 contractName, bytes32[] calldata records, uint[] calldata values ) external; function setIntValue( bytes32 contractName, bytes32 record, int value ) external; function setIntValues( bytes32 contractName, bytes32[] calldata records, int[] calldata values ) external; function setAddressValue( bytes32 contractName, bytes32 record, address value ) external; function setAddressValues( bytes32 contractName, bytes32[] calldata records, address[] calldata values ) external; function setBoolValue( bytes32 contractName, bytes32 record, bool value ) external; function setBoolValues( bytes32 contractName, bytes32[] calldata records, bool[] calldata values ) external; function setBytes32Value( bytes32 contractName, bytes32 record, bytes32 value ) external; function setBytes32Values( bytes32 contractName, bytes32[] calldata records, bytes32[] calldata values ) external; } // Internal references // https://docs.synthetix.io/contracts/source/contracts/mixinsystemsettings contract MixinSystemSettings is MixinResolver { bytes32 internal constant SETTING_CONTRACT_NAME = "SystemSettings"; bytes32 internal constant SETTING_WAITING_PERIOD_SECS = "waitingPeriodSecs"; bytes32 internal constant SETTING_PRICE_DEVIATION_THRESHOLD_FACTOR = "priceDeviationThresholdFactor"; bytes32 internal constant SETTING_ISSUANCE_RATIO = "issuanceRatio"; bytes32 internal constant SETTING_FEE_PERIOD_DURATION = "feePeriodDuration"; bytes32 internal constant SETTING_TARGET_THRESHOLD = "targetThreshold"; bytes32 internal constant SETTING_LIQUIDATION_DELAY = "liquidationDelay"; bytes32 internal constant SETTING_LIQUIDATION_RATIO = "liquidationRatio"; bytes32 internal constant SETTING_LIQUIDATION_PENALTY = "liquidationPenalty"; bytes32 internal constant SETTING_RATE_STALE_PERIOD = "rateStalePeriod"; bytes32 internal constant SETTING_EXCHANGE_FEE_RATE = "exchangeFeeRate"; bytes32 internal constant SETTING_MINIMUM_STAKE_TIME = "minimumStakeTime"; bytes32 internal constant SETTING_AGGREGATOR_WARNING_FLAGS = "aggregatorWarningFlags"; bytes32 internal constant SETTING_TRADING_REWARDS_ENABLED = "tradingRewardsEnabled"; bytes32 internal constant SETTING_DEBT_SNAPSHOT_STALE_TIME = "debtSnapshotStaleTime"; bytes32 internal constant SETTING_CROSS_DOMAIN_MESSAGE_GAS_LIMIT = "crossDomainMessageGasLimit"; bytes32 internal constant CONTRACT_FLEXIBLESTORAGE = "FlexibleStorage"; constructor(address _resolver) internal MixinResolver(_resolver) {} function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { addresses = new bytes32[](1); addresses[0] = CONTRACT_FLEXIBLESTORAGE; } function flexibleStorage() internal view returns (IFlexibleStorage) { return IFlexibleStorage(requireAndGetAddress(CONTRACT_FLEXIBLESTORAGE)); } function getCrossDomainMessageGasLimit() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_CROSS_DOMAIN_MESSAGE_GAS_LIMIT); } function getTradingRewardsEnabled() internal view returns (bool) { return flexibleStorage().getBoolValue(SETTING_CONTRACT_NAME, SETTING_TRADING_REWARDS_ENABLED); } function getWaitingPeriodSecs() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_WAITING_PERIOD_SECS); } function getPriceDeviationThresholdFactor() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_PRICE_DEVIATION_THRESHOLD_FACTOR); } function getIssuanceRatio() internal view returns (uint) { // lookup on flexible storage directly for gas savings (rather than via SystemSettings) return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ISSUANCE_RATIO); } function getFeePeriodDuration() internal view returns (uint) { // lookup on flexible storage directly for gas savings (rather than via SystemSettings) return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_FEE_PERIOD_DURATION); } function getTargetThreshold() internal view returns (uint) { // lookup on flexible storage directly for gas savings (rather than via SystemSettings) return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_TARGET_THRESHOLD); } function getLiquidationDelay() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_DELAY); } function getLiquidationRatio() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_RATIO); } function getLiquidationPenalty() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_PENALTY); } function getRateStalePeriod() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_RATE_STALE_PERIOD); } function getExchangeFeeRate(bytes32 currencyKey) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_EXCHANGE_FEE_RATE, currencyKey)) ); } function getMinimumStakeTime() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_MINIMUM_STAKE_TIME); } function getAggregatorWarningFlags() internal view returns (address) { return flexibleStorage().getAddressValue(SETTING_CONTRACT_NAME, SETTING_AGGREGATOR_WARNING_FLAGS); } function getDebtSnapshotStaleTime() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_DEBT_SNAPSHOT_STALE_TIME); } } // https://docs.synthetix.io/contracts/source/interfaces/idebtcache interface IDebtCache { // Views function cachedDebt() external view returns (uint); function cachedSynthDebt(bytes32 currencyKey) external view returns (uint); function cacheTimestamp() external view returns (uint); function cacheInvalid() external view returns (bool); function cacheStale() external view returns (bool); function currentSynthDebts(bytes32[] calldata currencyKeys) external view returns (uint[] memory debtValues, bool anyRateIsInvalid); function cachedSynthDebts(bytes32[] calldata currencyKeys) external view returns (uint[] memory debtValues); function currentDebt() external view returns (uint debt, bool anyRateIsInvalid); function cacheInfo() external view returns ( uint debt, uint timestamp, bool isInvalid, bool isStale ); // Mutative functions function takeDebtSnapshot() external; function updateCachedSynthDebts(bytes32[] calldata currencyKeys) external; } /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // Libraries // https://docs.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; } } interface IVirtualSynth { // Views function balanceOfUnderlying(address account) external view returns (uint); function rate() external view returns (uint); function readyToSettle() external view returns (bool); function secsLeftInWaitingPeriod() external view returns (uint); function settled() external view returns (bool); function synth() external view returns (ISynth); // Mutative functions function settle(address account) external; } // https://docs.synthetix.io/contracts/source/interfaces/iexchanger interface IExchanger { // 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 exchangeFeeRate); function getAmountsForExchange( uint sourceAmount, bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey ) external view returns ( uint amountReceived, uint fee, uint exchangeFeeRate ); function priceDeviationThresholdFactor() external view returns (uint); function waitingPeriodSecs() external view returns (uint); // Mutative functions function exchange( address from, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address destinationAddress ) external returns (uint amountReceived); function exchangeOnBehalf( address exchangeForAddress, address from, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external returns (uint amountReceived); function exchangeWithTracking( address from, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address destinationAddress, address originator, bytes32 trackingCode ) external returns (uint amountReceived); function exchangeOnBehalfWithTracking( address exchangeForAddress, address from, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address originator, bytes32 trackingCode ) external returns (uint amountReceived); function exchangeWithVirtual( address from, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address destinationAddress, bytes32 trackingCode ) external returns (uint amountReceived, IVirtualSynth vSynth); function settle(address from, bytes32 currencyKey) external returns ( uint reclaimed, uint refunded, uint numEntries ); function setLastExchangeRateForSynth(bytes32 currencyKey, uint rate) external; function suspendSynthWithInvalidRate(bytes32 currencyKey) external; } // https://docs.synthetix.io/contracts/source/interfaces/iexchangerates interface IExchangeRates { // Structs struct RateAndUpdatedTime { uint216 rate; uint40 time; } struct InversePricing { uint entryPoint; uint upperLimit; uint lowerLimit; bool frozenAtUpperLimit; bool frozenAtLowerLimit; } // Views function aggregators(bytes32 currencyKey) external view returns (address); function aggregatorWarningFlags() external view returns (address); function anyRateIsInvalid(bytes32[] calldata currencyKeys) external view returns (bool); function canFreezeRate(bytes32 currencyKey) external view returns (bool); function currentRoundForRate(bytes32 currencyKey) external view returns (uint); function currenciesUsingAggregator(address aggregator) external view returns (bytes32[] memory); function effectiveValue( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external view returns (uint value); function effectiveValueAndRates( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external view returns ( uint value, uint sourceRate, uint destinationRate ); function effectiveValueAtRound( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, uint roundIdForSrc, uint roundIdForDest ) external view returns (uint value); function getCurrentRoundId(bytes32 currencyKey) external view returns (uint); function getLastRoundIdBeforeElapsedSecs( bytes32 currencyKey, uint startingRoundId, uint startingTimestamp, uint timediff ) external view returns (uint); function inversePricing(bytes32 currencyKey) external view returns ( uint entryPoint, uint upperLimit, uint lowerLimit, bool frozenAtUpperLimit, bool frozenAtLowerLimit ); function lastRateUpdateTimes(bytes32 currencyKey) external view returns (uint256); function oracle() external view returns (address); function rateAndTimestampAtRound(bytes32 currencyKey, uint roundId) external view returns (uint rate, uint time); function rateAndUpdatedTime(bytes32 currencyKey) external view returns (uint rate, uint time); function rateAndInvalid(bytes32 currencyKey) external view returns (uint rate, bool isInvalid); function rateForCurrency(bytes32 currencyKey) external view returns (uint); function rateIsFlagged(bytes32 currencyKey) external view returns (bool); function rateIsFrozen(bytes32 currencyKey) external view returns (bool); function rateIsInvalid(bytes32 currencyKey) external view returns (bool); function rateIsStale(bytes32 currencyKey) external view returns (bool); function rateStalePeriod() external view returns (uint); function ratesAndUpdatedTimeForCurrencyLastNRounds(bytes32 currencyKey, uint numRounds) external view returns (uint[] memory rates, uint[] memory times); function ratesAndInvalidForCurrencies(bytes32[] calldata currencyKeys) external view returns (uint[] memory rates, bool anyRateInvalid); function ratesForCurrencies(bytes32[] calldata currencyKeys) external view returns (uint[] memory); // Mutative functions function freezeRate(bytes32 currencyKey) external; } // https://docs.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 requireIssuanceActive() external view; function requireExchangeActive() external view; function requireSynthActive(bytes32 currencyKey) external view; function requireSynthsActive(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) external view; function synthSuspension(bytes32 currencyKey) external view returns (bool suspended, uint248 reason); // Restricted functions function suspendSynth(bytes32 currencyKey, uint256 reason) external; function updateAccessControl( bytes32 section, address account, bool canSuspend, bool canResume ) external; } // https://docs.synthetix.io/contracts/source/interfaces/iethercollateral interface IEtherCollateral { // Views function totalIssuedSynths() external view returns (uint256); function totalLoansCreated() external view returns (uint256); function totalOpenLoanCount() external view returns (uint256); // Mutative functions function openLoan() external payable returns (uint256 loanID); function closeLoan(uint256 loanID) external; function liquidateUnclosedLoan(address _loanCreatorsAddress, uint256 _loanID) external; } // https://docs.synthetix.io/contracts/source/interfaces/iethercollateralsusd interface IEtherCollateralsUSD { // Views function totalIssuedSynths() external view returns (uint256); function totalLoansCreated() external view returns (uint256); function totalOpenLoanCount() external view returns (uint256); // Mutative functions function openLoan(uint256 _loanAmount) external payable returns (uint256 loanID); function closeLoan(uint256 loanID) external; function liquidateUnclosedLoan(address _loanCreatorsAddress, uint256 _loanID) external; function depositCollateral(address account, uint256 loanID) external payable; function withdrawCollateral(uint256 loanID, uint256 withdrawAmount) external; function repayLoan( address _loanCreatorsAddress, uint256 _loanID, uint256 _repayAmount ) external; } // https://docs.synthetix.io/contracts/source/interfaces/ierc20 interface IERC20 { // ERC20 Optional Views function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); // Views function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); // Mutative functions function transfer(address to, uint value) external returns (bool); function approve(address spender, uint value) external returns (bool); function transferFrom( address from, address to, uint value ) external returns (bool); // Events event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); } interface ICollateralManager { // Manager information function hasCollateral(address collateral) external view returns (bool); function isSynthManaged(bytes32 currencyKey) external view returns (bool); // State information function long(bytes32 synth) external view returns (uint amount); function short(bytes32 synth) external view returns (uint amount); function totalLong() external view returns (uint susdValue, bool anyRateIsInvalid); function totalShort() external view returns (uint susdValue, bool anyRateIsInvalid); function getBorrowRate() external view returns (uint borrowRate, bool anyRateIsInvalid); function getShortRate(bytes32 synth) external view returns (uint shortRate, bool rateIsInvalid); function getRatesAndTime(uint index) external view returns ( uint entryRate, uint lastRate, uint lastUpdated, uint newIndex ); function getShortRatesAndTime(bytes32 currency, uint index) external view returns ( uint entryRate, uint lastRate, uint lastUpdated, uint newIndex ); function exceedsDebtLimit(uint amount, bytes32 currency) external view returns (bool canIssue, bool anyRateIsInvalid); function areSynthsAndCurrenciesSet(bytes32[] calldata requiredSynthNamesInResolver, bytes32[] calldata synthKeys) external view returns (bool); function areShortableSynthsSet(bytes32[] calldata requiredSynthNamesInResolver, bytes32[] calldata synthKeys) external view returns (bool); // Loans function getNewLoanId() external returns (uint id); // Manager mutative function addCollaterals(address[] calldata collaterals) external; function removeCollaterals(address[] calldata collaterals) external; function addSynths(bytes32[] calldata synthNamesInResolver, bytes32[] calldata synthKeys) external; function removeSynths(bytes32[] calldata synths, bytes32[] calldata synthKeys) external; function addShortableSynths(bytes32[2][] calldata requiredSynthAndInverseNamesInResolver, bytes32[] calldata synthKeys) external; function removeShortableSynths(bytes32[] calldata synths) external; // State mutative function updateBorrowRates(uint rate) external; function updateShortRates(bytes32 currency, uint rate) external; function incrementLongs(bytes32 synth, uint amount) external; function decrementLongs(bytes32 synth, uint amount) external; function incrementShorts(bytes32 synth, uint amount) external; function decrementShorts(bytes32 synth, uint amount) external; } // Inheritance // Libraries // Internal references // https://docs.synthetix.io/contracts/source/contracts/debtcache contract DebtCache is Owned, MixinSystemSettings, IDebtCache { using SafeMath for uint; using SafeDecimalMath for uint; uint internal _cachedDebt; mapping(bytes32 => uint) internal _cachedSynthDebt; uint internal _cacheTimestamp; bool internal _cacheInvalid = true; /* ========== ENCODED NAMES ========== */ bytes32 internal constant sUSD = "sUSD"; bytes32 internal constant sETH = "sETH"; /* ========== ADDRESS RESOLVER CONFIGURATION ========== */ bytes32 private constant CONTRACT_ISSUER = "Issuer"; bytes32 private constant CONTRACT_EXCHANGER = "Exchanger"; bytes32 private constant CONTRACT_EXRATES = "ExchangeRates"; bytes32 private constant CONTRACT_SYSTEMSTATUS = "SystemStatus"; bytes32 private constant CONTRACT_ETHERCOLLATERAL = "EtherCollateral"; bytes32 private constant CONTRACT_ETHERCOLLATERAL_SUSD = "EtherCollateralsUSD"; bytes32 private constant CONTRACT_COLLATERALMANAGER = "CollateralManager"; constructor(address _owner, address _resolver) public Owned(_owner) MixinSystemSettings(_resolver) {} /* ========== VIEWS ========== */ function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { bytes32[] memory existingAddresses = MixinSystemSettings.resolverAddressesRequired(); bytes32[] memory newAddresses = new bytes32[](7); newAddresses[0] = CONTRACT_ISSUER; newAddresses[1] = CONTRACT_EXCHANGER; newAddresses[2] = CONTRACT_EXRATES; newAddresses[3] = CONTRACT_SYSTEMSTATUS; newAddresses[4] = CONTRACT_ETHERCOLLATERAL; newAddresses[5] = CONTRACT_ETHERCOLLATERAL_SUSD; newAddresses[6] = CONTRACT_COLLATERALMANAGER; addresses = combineArrays(existingAddresses, newAddresses); } function issuer() internal view returns (IIssuer) { return IIssuer(requireAndGetAddress(CONTRACT_ISSUER)); } function exchanger() internal view returns (IExchanger) { return IExchanger(requireAndGetAddress(CONTRACT_EXCHANGER)); } function exchangeRates() internal view returns (IExchangeRates) { return IExchangeRates(requireAndGetAddress(CONTRACT_EXRATES)); } function systemStatus() internal view returns (ISystemStatus) { return ISystemStatus(requireAndGetAddress(CONTRACT_SYSTEMSTATUS)); } function etherCollateral() internal view returns (IEtherCollateral) { return IEtherCollateral(requireAndGetAddress(CONTRACT_ETHERCOLLATERAL)); } function etherCollateralsUSD() internal view returns (IEtherCollateralsUSD) { return IEtherCollateralsUSD(requireAndGetAddress(CONTRACT_ETHERCOLLATERAL_SUSD)); } function collateralManager() internal view returns (ICollateralManager) { return ICollateralManager(requireAndGetAddress(CONTRACT_COLLATERALMANAGER)); } function debtSnapshotStaleTime() external view returns (uint) { return getDebtSnapshotStaleTime(); } function cachedDebt() external view returns (uint) { return _cachedDebt; } function cachedSynthDebt(bytes32 currencyKey) external view returns (uint) { return _cachedSynthDebt[currencyKey]; } function cacheTimestamp() external view returns (uint) { return _cacheTimestamp; } function cacheInvalid() external view returns (bool) { return _cacheInvalid; } function _cacheStale(uint timestamp) internal view returns (bool) { // Note a 0 timestamp means that the cache is uninitialised. // We'll keep the check explicitly in case the stale time is // ever set to something higher than the current unix time (e.g. to turn off staleness). return getDebtSnapshotStaleTime() < block.timestamp - timestamp || timestamp == 0; } function cacheStale() external view returns (bool) { return _cacheStale(_cacheTimestamp); } function _issuedSynthValues(bytes32[] memory currencyKeys, uint[] memory rates) internal view returns (uint[] memory) { uint numValues = currencyKeys.length; uint[] memory values = new uint[](numValues); ISynth[] memory synths = issuer().getSynths(currencyKeys); for (uint i = 0; i < numValues; i++) { bytes32 key = currencyKeys[i]; address synthAddress = address(synths[i]); require(synthAddress != address(0), "Synth does not exist"); uint supply = IERC20(synthAddress).totalSupply(); if (collateralManager().isSynthManaged(key)) { uint collateralIssued = collateralManager().long(key); // this is an edge case -- // if a synth other than sUSD is only issued by non SNX collateral // the long value will exceed the supply if there was a minting fee, // so we check explicitly and 0 it out to prevent // a safesub overflow. if (collateralIssued > supply) { supply = 0; } else { supply = supply.sub(collateralIssued); } } bool isSUSD = key == sUSD; if (isSUSD || key == sETH) { IEtherCollateral etherCollateralContract = isSUSD ? IEtherCollateral(address(etherCollateralsUSD())) : etherCollateral(); uint etherCollateralSupply = etherCollateralContract.totalIssuedSynths(); supply = supply.sub(etherCollateralSupply); } values[i] = supply.multiplyDecimalRound(rates[i]); } return values; } function _currentSynthDebts(bytes32[] memory currencyKeys) internal view returns (uint[] memory snxIssuedDebts, bool anyRateIsInvalid) { (uint[] memory rates, bool isInvalid) = exchangeRates().ratesAndInvalidForCurrencies(currencyKeys); return (_issuedSynthValues(currencyKeys, rates), isInvalid); } function currentSynthDebts(bytes32[] calldata currencyKeys) external view returns (uint[] memory debtValues, bool anyRateIsInvalid) { return _currentSynthDebts(currencyKeys); } function _cachedSynthDebts(bytes32[] memory currencyKeys) internal view returns (uint[] memory) { uint numKeys = currencyKeys.length; uint[] memory debts = new uint[](numKeys); for (uint i = 0; i < numKeys; i++) { debts[i] = _cachedSynthDebt[currencyKeys[i]]; } return debts; } function cachedSynthDebts(bytes32[] calldata currencyKeys) external view returns (uint[] memory snxIssuedDebts) { return _cachedSynthDebts(currencyKeys); } function _currentDebt() internal view returns (uint debt, bool anyRateIsInvalid) { (uint[] memory values, bool isInvalid) = _currentSynthDebts(issuer().availableCurrencyKeys()); uint numValues = values.length; uint total; for (uint i; i < numValues; i++) { total = total.add(values[i]); } // subtract the USD value of all shorts. (uint susdValue, bool shortInvalid) = collateralManager().totalShort(); total = total.sub(susdValue); isInvalid = isInvalid || shortInvalid; return (total, isInvalid); } function currentDebt() external view returns (uint debt, bool anyRateIsInvalid) { return _currentDebt(); } function cacheInfo() external view returns ( uint debt, uint timestamp, bool isInvalid, bool isStale ) { uint time = _cacheTimestamp; return (_cachedDebt, time, _cacheInvalid, _cacheStale(time)); } /* ========== MUTATIVE FUNCTIONS ========== */ // This function exists in case a synth is ever somehow removed without its snapshot being updated. function purgeCachedSynthDebt(bytes32 currencyKey) external onlyOwner { require(issuer().synths(currencyKey) == ISynth(0), "Synth exists"); delete _cachedSynthDebt[currencyKey]; } function takeDebtSnapshot() external requireSystemActiveIfNotOwner { bytes32[] memory currencyKeys = issuer().availableCurrencyKeys(); (uint[] memory values, bool isInvalid) = _currentSynthDebts(currencyKeys); // Subtract the USD value of all shorts. (uint shortValue, ) = collateralManager().totalShort(); uint numValues = values.length; uint snxCollateralDebt; for (uint i; i < numValues; i++) { uint value = values[i]; snxCollateralDebt = snxCollateralDebt.add(value); _cachedSynthDebt[currencyKeys[i]] = value; } _cachedDebt = snxCollateralDebt.sub(shortValue); _cacheTimestamp = block.timestamp; emit DebtCacheUpdated(snxCollateralDebt); emit DebtCacheSnapshotTaken(block.timestamp); // (in)validate the cache if necessary _updateDebtCacheValidity(isInvalid); } function updateCachedSynthDebts(bytes32[] calldata currencyKeys) external requireSystemActiveIfNotOwner { (uint[] memory rates, bool anyRateInvalid) = exchangeRates().ratesAndInvalidForCurrencies(currencyKeys); _updateCachedSynthDebtsWithRates(currencyKeys, rates, anyRateInvalid); } function updateCachedSynthDebtWithRate(bytes32 currencyKey, uint currencyRate) external onlyIssuer { bytes32[] memory synthKeyArray = new bytes32[](1); synthKeyArray[0] = currencyKey; uint[] memory synthRateArray = new uint[](1); synthRateArray[0] = currencyRate; _updateCachedSynthDebtsWithRates(synthKeyArray, synthRateArray, false); } function updateCachedSynthDebtsWithRates(bytes32[] calldata currencyKeys, uint[] calldata currencyRates) external onlyIssuerOrExchanger { _updateCachedSynthDebtsWithRates(currencyKeys, currencyRates, false); } function updateDebtCacheValidity(bool currentlyInvalid) external onlyIssuer { _updateDebtCacheValidity(currentlyInvalid); } /* ========== INTERNAL FUNCTIONS ========== */ function _updateDebtCacheValidity(bool currentlyInvalid) internal { if (_cacheInvalid != currentlyInvalid) { _cacheInvalid = currentlyInvalid; emit DebtCacheValidityChanged(currentlyInvalid); } } function _updateCachedSynthDebtsWithRates( bytes32[] memory currencyKeys, uint[] memory currentRates, bool anyRateIsInvalid ) internal { uint numKeys = currencyKeys.length; require(numKeys == currentRates.length, "Input array lengths differ"); // Update the cached values for each synth, saving the sums as we go. uint cachedSum; uint currentSum; uint[] memory currentValues = _issuedSynthValues(currencyKeys, currentRates); for (uint i = 0; i < numKeys; i++) { bytes32 key = currencyKeys[i]; uint currentSynthDebt = currentValues[i]; cachedSum = cachedSum.add(_cachedSynthDebt[key]); currentSum = currentSum.add(currentSynthDebt); _cachedSynthDebt[key] = currentSynthDebt; } // Compute the difference and apply it to the snapshot if (cachedSum != currentSum) { uint debt = _cachedDebt; // This requirement should never fail, as the total debt snapshot is the sum of the individual synth // debt snapshots. require(cachedSum <= debt, "Cached synth sum exceeds total debt"); debt = debt.sub(cachedSum).add(currentSum); _cachedDebt = debt; emit DebtCacheUpdated(debt); } // A partial update can invalidate the debt cache, but a full snapshot must be performed in order // to re-validate it. if (anyRateIsInvalid) { _updateDebtCacheValidity(anyRateIsInvalid); } } /* ========== MODIFIERS ========== */ function _requireSystemActiveIfNotOwner() internal view { if (msg.sender != owner) { systemStatus().requireSystemActive(); } } modifier requireSystemActiveIfNotOwner() { _requireSystemActiveIfNotOwner(); _; } function _onlyIssuer() internal view { require(msg.sender == address(issuer()), "Sender is not Issuer"); } modifier onlyIssuer() { _onlyIssuer(); _; } function _onlyIssuerOrExchanger() internal view { require(msg.sender == address(issuer()) || msg.sender == address(exchanger()), "Sender is not Issuer or Exchanger"); } modifier onlyIssuerOrExchanger() { _onlyIssuerOrExchanger(); _; } /* ========== EVENTS ========== */ event DebtCacheUpdated(uint cachedDebt); event DebtCacheSnapshotTaken(uint timestamp); event DebtCacheValidityChanged(bool indexed isInvalid); }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_resolver","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"name","type":"bytes32"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"CacheUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"DebtCacheSnapshotTaken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cachedDebt","type":"uint256"}],"name":"DebtCacheUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"isInvalid","type":"bool"}],"name":"DebtCacheValidityChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cacheInfo","outputs":[{"internalType":"uint256","name":"debt","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bool","name":"isInvalid","type":"bool"},{"internalType":"bool","name":"isStale","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cacheInvalid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cacheStale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cacheTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cachedDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"}],"name":"cachedSynthDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32[]","name":"currencyKeys","type":"bytes32[]"}],"name":"cachedSynthDebts","outputs":[{"internalType":"uint256[]","name":"snxIssuedDebts","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentDebt","outputs":[{"internalType":"uint256","name":"debt","type":"uint256"},{"internalType":"bool","name":"anyRateIsInvalid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32[]","name":"currencyKeys","type":"bytes32[]"}],"name":"currentSynthDebts","outputs":[{"internalType":"uint256[]","name":"debtValues","type":"uint256[]"},{"internalType":"bool","name":"anyRateIsInvalid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"debtSnapshotStaleTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isResolverCached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"}],"name":"purgeCachedSynthDebt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"rebuildCache","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"resolver","outputs":[{"internalType":"contract AddressResolver","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"resolverAddressesRequired","outputs":[{"internalType":"bytes32[]","name":"addresses","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"takeDebtSnapshot","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"},{"internalType":"uint256","name":"currencyRate","type":"uint256"}],"name":"updateCachedSynthDebtWithRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32[]","name":"currencyKeys","type":"bytes32[]"}],"name":"updateCachedSynthDebts","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32[]","name":"currencyKeys","type":"bytes32[]"},{"internalType":"uint256[]","name":"currencyRates","type":"uint256[]"}],"name":"updateCachedSynthDebtsWithRates","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"currentlyInvalid","type":"bool"}],"name":"updateDebtCacheValidity","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526007805460ff1916600117905534801561001d57600080fd5b506040516125e03803806125e08339818101604052604081101561004057600080fd5b5080516020909101518080836001600160a01b0381166100a7576040805162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b038316908117825560408051928352602083019190915280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a150600280546001600160a01b039092166001600160a01b03199092169190911790555050506124ad806101336000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c806379ba5097116100c3578063b13cd7851161007c578063b13cd7851461049c578063cda218c71461050a578063d0fffafd14610578578063d685743a14610580578063e3476cd4146105a3578063fc524773146105ab57610158565b806379ba509714610407578063899ffef41461040f5780638da5cb5b146104675780638dd5bfbc1461046f578063a5f27edb1461048c578063af5355d81461049457610158565b80632af64bd3116101155780632af64bd3146102bd5780633a900a2e146102d957806353a47bb7146103095780636bf7c4351461031157806374185360146103de578063759076e5146103e657610158565b806304bd11e51461015d57806304f3bcec1461017e57806305393262146101a25780630fb38465146101bc5780631627540c146101d957806317b38db4146101ff575b600080fd5b61017c6004803603602081101561017357600080fd5b503515156105b3565b005b6101866105c7565b604080516001600160a01b039092168252519081900360200190f35b6101aa6105d6565b60408051918252519081900360200190f35b6101aa600480360360208110156101d257600080fd5b50356105dd565b61017c600480360360208110156101ef57600080fd5b50356001600160a01b03166105ef565b61017c6004803603604081101561021557600080fd5b810190602081018135600160201b81111561022f57600080fd5b82018360208201111561024157600080fd5b803590602001918460208302840111600160201b8311171561026257600080fd5b919390929091602081019035600160201b81111561027f57600080fd5b82018360208201111561029157600080fd5b803590602001918460208302840111600160201b831117156102b257600080fd5b50909250905061064b565b6102c56106c6565b604080519115158252519081900360200190f35b6102e16107d0565b6040805194855260208501939093529015158383015215156060830152519081900360800190f35b610186610801565b61037f6004803603602081101561032757600080fd5b810190602081018135600160201b81111561034157600080fd5b82018360208201111561035357600080fd5b803590602001918460208302840111600160201b8311171561037457600080fd5b509092509050610810565b604051808060200183151515158152602001828103825284818151815260200191508051906020019060200280838360005b838110156103c95781810151838201526020016103b1565b50505050905001935050505060405180910390f35b61017c61085b565b6103ee610a23565b6040805192835290151560208301528051918290030190f35b61017c610a36565b610417610af2565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561045357818101518382015260200161043b565b505050509050019250505060405180910390f35b610186610c5c565b61017c6004803603602081101561048557600080fd5b5035610c6b565b6102c5610d47565b6101aa610d50565b610417600480360360208110156104b257600080fd5b810190602081018135600160201b8111156104cc57600080fd5b8201836020820111156104de57600080fd5b803590602001918460208302840111600160201b831117156104ff57600080fd5b509092509050610d5f565b61017c6004803603602081101561052057600080fd5b810190602081018135600160201b81111561053a57600080fd5b82018360208201111561054c57600080fd5b803590602001918460208302840111600160201b8311171561056d57600080fd5b509092509050610da6565b6101aa610f3b565b61017c6004803603604081101561059657600080fd5b5080359060200135610f41565b61017c610fce565b6102c5611261565b6105bb61126e565b6105c4816112d4565b50565b6002546001600160a01b031681565b6004545b90565b60009081526005602052604090205490565b6105f7611321565b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229181900360200190a150565b61065361136a565b6106c084848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092018290525092506113e4915050565b50505050565b600060606106d2610af2565b905060005b81518110156107c75760008282815181106106ee57fe5b6020908102919091018101516000818152600383526040908190205460025482516321f8a72160e01b81526004810185905292519395506001600160a01b03918216949116926321f8a721926024808201939291829003018186803b15801561075657600080fd5b505afa15801561076a573d6000803e3d6000fd5b505050506040513d602081101561078057600080fd5b50516001600160a01b03161415806107ad57506000818152600360205260409020546001600160a01b0316155b156107be57600093505050506105da565b506001016106d7565b50600191505090565b6006546004546007546000928392839283929190829060ff166107f282611599565b94509450945094505090919293565b6001546001600160a01b031681565b606060006108508484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b292505050565b915091509250929050565b6060610865610af2565b905060005b8151811015610a1f57600082828151811061088157fe5b602090810291909101810151600254604080517f5265736f6c766572206d697373696e67207461726765743a2000000000000000818601526039808201859052825180830390910181526059820180845263dacb2d0160e01b9052605d8201858152607d83019384528151609d84015281519597506000966001600160a01b039095169563dacb2d01958995939492939260bd0191908501908083838c5b8381101561093757818101518382015260200161091f565b50505050905090810190601f1680156109645780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561098257600080fd5b505afa158015610996573d6000803e3d6000fd5b505050506040513d60208110156109ac57600080fd5b505160008381526003602090815260409182902080546001600160a01b0319166001600160a01b03851690811790915582518681529182015281519293507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68929081900390910190a1505060010161086a565b5050565b600080610a2e61172b565b915091509091565b6001546001600160a01b03163314610a7f5760405162461bcd60e51b81526004018080602001828103825260358152602001806123b06035913960400191505060405180910390fd5b600054600154604080516001600160a01b03938416815292909116602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b606080610afd611929565b6040805160078082526101008201909252919250606091906020820160e0803883390190505090506524b9b9bab2b960d11b81600081518110610b3c57fe5b6020026020010181815250506822bc31b430b733b2b960b91b81600181518110610b6257fe5b6020026020010181815250506c45786368616e6765526174657360981b81600281518110610b8c57fe5b6020026020010181815250506b53797374656d53746174757360a01b81600381518110610bb557fe5b6020026020010181815250506e115d1a195c90dbdb1b185d195c985b608a1b81600481518110610be157fe5b60200260200101818152505072115d1a195c90dbdb1b185d195c985b1cd554d1606a1b81600581518110610c1157fe5b6020026020010181815250507021b7b63630ba32b930b626b0b730b3b2b960791b81600681518110610c3f57fe5b602002602001018181525050610c55828261197a565b9250505090565b6000546001600160a01b031681565b610c73611321565b6000610c7d611a36565b6001600160a01b03166332608039836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610cc057600080fd5b505afa158015610cd4573d6000803e3d6000fd5b505050506040513d6020811015610cea57600080fd5b50516001600160a01b031614610d36576040805162461bcd60e51b815260206004820152600c60248201526b53796e74682065786973747360a01b604482015290519081900360640190fd5b600090815260056020526040812055565b60075460ff1690565b6000610d5a611a4a565b905090565b6060610d9d838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611af992505050565b90505b92915050565b610dae611b89565b60606000610dba611bef565b6001600160a01b031663c8e5bbd585856040518363ffffffff1660e01b815260040180806020018281038252848482818152602001925060200280828437600081840152601f19601f820116905080830192505050935050505060006040518083038186803b158015610e2c57600080fd5b505afa158015610e40573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040908152811015610e6957600080fd5b8101908080516040519392919084600160201b821115610e8857600080fd5b908301906020820185811115610e9d57600080fd5b82518660208202830111600160201b82111715610eb957600080fd5b82525081516020918201928201910280838360005b83811015610ee6578181015183820152602001610ece565b505050509190910160408181526020938401518a850280840186019092528a83529698509596506106c09590945089935088928392508501908490808284376000920191909152508692508591506113e49050565b60065490565b610f4961126e565b604080516001808252818301909252606091602080830190803883390190505090508281600081518110610f7957fe5b60209081029190910101526040805160018082528183019092526060918160200160208202803883390190505090508281600081518110610fb657fe5b6020026020010181815250506106c0828260006113e4565b610fd6611b89565b6060610fe0611a36565b6001600160a01b03166372cb051f6040518163ffffffff1660e01b815260040160006040518083038186803b15801561101857600080fd5b505afa15801561102c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561105557600080fd5b8101908080516040519392919084600160201b82111561107457600080fd5b90830190602082018581111561108957600080fd5b82518660208202830111600160201b821117156110a557600080fd5b82525081516020918201928201910280838360005b838110156110d25781810151838201526020016110ba565b505050509050016040525050509050606060006110ee836115b2565b9150915060006110fc611c0a565b6001600160a01b031663ad79a8586040518163ffffffff1660e01b8152600401604080518083038186803b15801561113357600080fd5b505afa158015611147573d6000803e3d6000fd5b505050506040513d604081101561115d57600080fd5b505183519091506000805b828110156111d257600086828151811061117e57fe5b6020026020010151905061119b8184611c2990919063ffffffff16565b925080600560008a85815181106111ae57fe5b60209081029190910181015182528101919091526040016000205550600101611168565b506111e3818463ffffffff611c8316565b600455426006556040805182815290517f294a7c394e53042c7d754779562747d93b41db019dd4b970dd9b531db71be5999181900360200190a16040805142815290517fc481e742c89630d4b1a5ed3a0fc624c1c41ed463bd00ac26a7e93c71e932126f9181900360200190a1611259846112d4565b505050505050565b6000610d5a600654611599565b611276611a36565b6001600160a01b0316336001600160a01b0316146112d2576040805162461bcd60e51b815260206004820152601460248201527329b2b73232b91034b9903737ba1024b9b9bab2b960611b604482015290519081900360640190fd5b565b60075460ff161515811515146105c4576007805460ff19168215159081179091556040517f8eebec690c34bbf0fe0d5b93e442beaf16bdaf99052569581de2dcb3e31a53a790600090a250565b6000546001600160a01b031633146112d25760405162461bcd60e51b815260040180806020018281038252602f815260200180612406602f913960400191505060405180910390fd5b611372611a36565b6001600160a01b0316336001600160a01b031614806113a95750611394611ce0565b6001600160a01b0316336001600160a01b0316145b6112d25760405162461bcd60e51b81526004018080602001828103825260218152602001806123e56021913960400191505060405180910390fd5b82518251811461143b576040805162461bcd60e51b815260206004820152601a60248201527f496e707574206172726179206c656e6774687320646966666572000000000000604482015290519081900360640190fd5b600080606061144a8787611cf7565b905060005b848110156114d957600088828151811061146557fe5b60200260200101519050600083838151811061147d57fe5b602002602001015190506114ad600560008481526020019081526020016000205487611c2990919063ffffffff16565b95506114bf858263ffffffff611c2916565b60009283526005602052604090922055925060010161144f565b5081831461158157600454808411156115235760405162461bcd60e51b81526004018080602001828103825260238152602001806124566023913960400191505060405180910390fd5b61154383611537838763ffffffff611c8316565b9063ffffffff611c2916565b60048190556040805182815290519192507f294a7c394e53042c7d754779562747d93b41db019dd4b970dd9b531db71be599919081900360200190a1505b841561159057611590856112d4565b50505050505050565b60008142036115a6611a4a565b1080610da05750501590565b60606000606060006115c2611bef565b6001600160a01b031663c8e5bbd5866040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b83811015611620578181015183820152602001611608565b505050509050019250505060006040518083038186803b15801561164357600080fd5b505afa158015611657573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604090815281101561168057600080fd5b8101908080516040519392919084600160201b82111561169f57600080fd5b9083019060208201858111156116b457600080fd5b82518660208202830111600160201b821117156116d057600080fd5b82525081516020918201928201910280838360005b838110156116fd5781810151838201526020016116e5565b50505050919091016040525060200151929450919250611721915086905083611cf7565b9350915050915091565b6000806060600061184161173d611a36565b6001600160a01b03166372cb051f6040518163ffffffff1660e01b815260040160006040518083038186803b15801561177557600080fd5b505afa158015611789573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156117b257600080fd5b8101908080516040519392919084600160201b8211156117d157600080fd5b9083019060208201858111156117e657600080fd5b82518660208202830111600160201b8211171561180257600080fd5b82525081516020918201928201910280838360005b8381101561182f578181015183820152602001611817565b505050509050016040525050506115b2565b815191935091506000805b828110156118845761187a85828151811061186357fe5b602002602001015183611c2990919063ffffffff16565b915060010161184c565b50600080611890611c0a565b6001600160a01b031663ad79a8586040518163ffffffff1660e01b8152600401604080518083038186803b1580156118c757600080fd5b505afa1580156118db573d6000803e3d6000fd5b505050506040513d60408110156118f157600080fd5b508051602090910151909250905061190f838363ffffffff611c8316565b9250848061191a5750805b92975091955050505050509091565b604080516001808252818301909252606091602080830190803883390190505090506e466c657869626c6553746f7261676560881b8160008151811061196b57fe5b60200260200101818152505090565b606081518351016040519080825280602002602001820160405280156119aa578160200160208202803883390190505b50905060005b83518110156119ec578381815181106119c557fe5b60200260200101518282815181106119d957fe5b60209081029190910101526001016119b0565b5060005b8251811015611a2f57828181518110611a0557fe5b6020026020010151828286510181518110611a1c57fe5b60209081029190910101526001016119f0565b5092915050565b6000610d5a6524b9b9bab2b960d11b6121ba565b6000611a54612297565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b7464656274536e617073686f745374616c6554696d6560581b6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b158015611ac857600080fd5b505afa158015611adc573d6000803e3d6000fd5b505050506040513d6020811015611af257600080fd5b5051905090565b6060600082519050606081604051908082528060200260200182016040528015611b2d578160200160208202803883390190505b50905060005b82811015611b815760056000868381518110611b4b57fe5b6020026020010151815260200190815260200160002054828281518110611b6e57fe5b6020908102919091010152600101611b33565b509392505050565b6000546001600160a01b031633146112d257611ba36122b4565b6001600160a01b031663086dabd16040518163ffffffff1660e01b815260040160006040518083038186803b158015611bdb57600080fd5b505afa1580156106c0573d6000803e3d6000fd5b6000610d5a6c45786368616e6765526174657360981b6121ba565b6000610d5a7021b7b63630ba32b930b626b0b730b3b2b960791b6121ba565b600082820183811015610d9d576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082821115611cda576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000610d5a6822bc31b430b733b2b960b91b6121ba565b6060600083519050606081604051908082528060200260200182016040528015611d2b578160200160208202803883390190505b5090506060611d38611a36565b6001600160a01b0316633b6afe40876040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b83811015611d96578181015183820152602001611d7e565b505050509050019250505060006040518083038186803b158015611db957600080fd5b505afa158015611dcd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611df657600080fd5b8101908080516040519392919084600160201b821115611e1557600080fd5b908301906020820185811115611e2a57600080fd5b82518660208202830111600160201b82111715611e4657600080fd5b82525081516020918201928201910280838360005b83811015611e73578181015183820152602001611e5b565b50505050905001604052505050905060008090505b838110156121af576000878281518110611e9e57fe5b602002602001015190506000838381518110611eb657fe5b6020026020010151905060006001600160a01b0316816001600160a01b03161415611f1f576040805162461bcd60e51b815260206004820152601460248201527314de5b9d1a08191bd95cc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b6000816001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f5a57600080fd5b505afa158015611f6e573d6000803e3d6000fd5b505050506040513d6020811015611f8457600080fd5b50519050611f90611c0a565b6001600160a01b0316638471db13846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611fd357600080fd5b505afa158015611fe7573d6000803e3d6000fd5b505050506040513d6020811015611ffd57600080fd5b5051156120a557600061200e611c0a565b6001600160a01b031663d2f00475856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561205157600080fd5b505afa158015612065573d6000803e3d6000fd5b505050506040513d602081101561207b57600080fd5b505190508181111561209057600091506120a3565b6120a0828263ffffffff611c8316565b91505b505b631cd554d160e21b831480806120c15750630e68aa8960e31b84145b15612162576000816120da576120d56122ce565b6120e2565b6120e26122eb565b90506000816001600160a01b031663ee5f3f5c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561211f57600080fd5b505afa158015612133573d6000803e3d6000fd5b505050506040513d602081101561214957600080fd5b5051905061215d848263ffffffff611c8316565b935050505b6121888a868151811061217157fe5b60200260200101518361230c90919063ffffffff16565b87868151811061219457fe5b6020908102919091010152505060019092019150611e889050565b509095945050505050565b600081815260036020908152604080832054815170026b4b9b9b4b7339030b2323932b9b99d1607d1b9381019390935260318084018690528251808503909101815260519093019091526001600160a01b03169081611a2f5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561225c578181015183820152602001612244565b50505050905090810190601f1680156122895780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6000610d5a6e466c657869626c6553746f7261676560881b6121ba565b6000610d5a6b53797374656d53746174757360a01b6121ba565b6000610d5a6e115d1a195c90dbdb1b185d195c985b608a1b6121ba565b6000610d5a72115d1a195c90dbdb1b185d195c985b1cd554d1606a1b6121ba565b6000610d9d8383670de0b6b3a7640000848067016345785d8a00006123318686612356565b8161233857fe5b0490506005600a82061061234a57600a015b600a9004949350505050565b60008261236557506000610da0565b8282028284828161237257fe5b0414610d9d5760405162461bcd60e51b81526004018080602001828103825260218152602001806124356021913960400191505060405180910390fdfe596f75206d757374206265206e6f6d696e61746564206265666f726520796f752063616e20616363657074206f776e65727368697053656e646572206973206e6f7420497373756572206f722045786368616e6765724f6e6c792074686520636f6e7472616374206f776e6572206d617920706572666f726d207468697320616374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774361636865642073796e74682073756d206578636565647320746f74616c2064656274a265627a7a72315820804273d96350b998c6306cfd16daf7e63fbcd5259c40ca19183b5364881a2f0a64736f6c63430005100032000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe0000000000000000000000004e3b31eb0e5cb73641ee1e65e7dcefe520ba3ef2
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101585760003560e01c806379ba5097116100c3578063b13cd7851161007c578063b13cd7851461049c578063cda218c71461050a578063d0fffafd14610578578063d685743a14610580578063e3476cd4146105a3578063fc524773146105ab57610158565b806379ba509714610407578063899ffef41461040f5780638da5cb5b146104675780638dd5bfbc1461046f578063a5f27edb1461048c578063af5355d81461049457610158565b80632af64bd3116101155780632af64bd3146102bd5780633a900a2e146102d957806353a47bb7146103095780636bf7c4351461031157806374185360146103de578063759076e5146103e657610158565b806304bd11e51461015d57806304f3bcec1461017e57806305393262146101a25780630fb38465146101bc5780631627540c146101d957806317b38db4146101ff575b600080fd5b61017c6004803603602081101561017357600080fd5b503515156105b3565b005b6101866105c7565b604080516001600160a01b039092168252519081900360200190f35b6101aa6105d6565b60408051918252519081900360200190f35b6101aa600480360360208110156101d257600080fd5b50356105dd565b61017c600480360360208110156101ef57600080fd5b50356001600160a01b03166105ef565b61017c6004803603604081101561021557600080fd5b810190602081018135600160201b81111561022f57600080fd5b82018360208201111561024157600080fd5b803590602001918460208302840111600160201b8311171561026257600080fd5b919390929091602081019035600160201b81111561027f57600080fd5b82018360208201111561029157600080fd5b803590602001918460208302840111600160201b831117156102b257600080fd5b50909250905061064b565b6102c56106c6565b604080519115158252519081900360200190f35b6102e16107d0565b6040805194855260208501939093529015158383015215156060830152519081900360800190f35b610186610801565b61037f6004803603602081101561032757600080fd5b810190602081018135600160201b81111561034157600080fd5b82018360208201111561035357600080fd5b803590602001918460208302840111600160201b8311171561037457600080fd5b509092509050610810565b604051808060200183151515158152602001828103825284818151815260200191508051906020019060200280838360005b838110156103c95781810151838201526020016103b1565b50505050905001935050505060405180910390f35b61017c61085b565b6103ee610a23565b6040805192835290151560208301528051918290030190f35b61017c610a36565b610417610af2565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561045357818101518382015260200161043b565b505050509050019250505060405180910390f35b610186610c5c565b61017c6004803603602081101561048557600080fd5b5035610c6b565b6102c5610d47565b6101aa610d50565b610417600480360360208110156104b257600080fd5b810190602081018135600160201b8111156104cc57600080fd5b8201836020820111156104de57600080fd5b803590602001918460208302840111600160201b831117156104ff57600080fd5b509092509050610d5f565b61017c6004803603602081101561052057600080fd5b810190602081018135600160201b81111561053a57600080fd5b82018360208201111561054c57600080fd5b803590602001918460208302840111600160201b8311171561056d57600080fd5b509092509050610da6565b6101aa610f3b565b61017c6004803603604081101561059657600080fd5b5080359060200135610f41565b61017c610fce565b6102c5611261565b6105bb61126e565b6105c4816112d4565b50565b6002546001600160a01b031681565b6004545b90565b60009081526005602052604090205490565b6105f7611321565b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229181900360200190a150565b61065361136a565b6106c084848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092018290525092506113e4915050565b50505050565b600060606106d2610af2565b905060005b81518110156107c75760008282815181106106ee57fe5b6020908102919091018101516000818152600383526040908190205460025482516321f8a72160e01b81526004810185905292519395506001600160a01b03918216949116926321f8a721926024808201939291829003018186803b15801561075657600080fd5b505afa15801561076a573d6000803e3d6000fd5b505050506040513d602081101561078057600080fd5b50516001600160a01b03161415806107ad57506000818152600360205260409020546001600160a01b0316155b156107be57600093505050506105da565b506001016106d7565b50600191505090565b6006546004546007546000928392839283929190829060ff166107f282611599565b94509450945094505090919293565b6001546001600160a01b031681565b606060006108508484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b292505050565b915091509250929050565b6060610865610af2565b905060005b8151811015610a1f57600082828151811061088157fe5b602090810291909101810151600254604080517f5265736f6c766572206d697373696e67207461726765743a2000000000000000818601526039808201859052825180830390910181526059820180845263dacb2d0160e01b9052605d8201858152607d83019384528151609d84015281519597506000966001600160a01b039095169563dacb2d01958995939492939260bd0191908501908083838c5b8381101561093757818101518382015260200161091f565b50505050905090810190601f1680156109645780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561098257600080fd5b505afa158015610996573d6000803e3d6000fd5b505050506040513d60208110156109ac57600080fd5b505160008381526003602090815260409182902080546001600160a01b0319166001600160a01b03851690811790915582518681529182015281519293507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68929081900390910190a1505060010161086a565b5050565b600080610a2e61172b565b915091509091565b6001546001600160a01b03163314610a7f5760405162461bcd60e51b81526004018080602001828103825260358152602001806123b06035913960400191505060405180910390fd5b600054600154604080516001600160a01b03938416815292909116602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b606080610afd611929565b6040805160078082526101008201909252919250606091906020820160e0803883390190505090506524b9b9bab2b960d11b81600081518110610b3c57fe5b6020026020010181815250506822bc31b430b733b2b960b91b81600181518110610b6257fe5b6020026020010181815250506c45786368616e6765526174657360981b81600281518110610b8c57fe5b6020026020010181815250506b53797374656d53746174757360a01b81600381518110610bb557fe5b6020026020010181815250506e115d1a195c90dbdb1b185d195c985b608a1b81600481518110610be157fe5b60200260200101818152505072115d1a195c90dbdb1b185d195c985b1cd554d1606a1b81600581518110610c1157fe5b6020026020010181815250507021b7b63630ba32b930b626b0b730b3b2b960791b81600681518110610c3f57fe5b602002602001018181525050610c55828261197a565b9250505090565b6000546001600160a01b031681565b610c73611321565b6000610c7d611a36565b6001600160a01b03166332608039836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610cc057600080fd5b505afa158015610cd4573d6000803e3d6000fd5b505050506040513d6020811015610cea57600080fd5b50516001600160a01b031614610d36576040805162461bcd60e51b815260206004820152600c60248201526b53796e74682065786973747360a01b604482015290519081900360640190fd5b600090815260056020526040812055565b60075460ff1690565b6000610d5a611a4a565b905090565b6060610d9d838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611af992505050565b90505b92915050565b610dae611b89565b60606000610dba611bef565b6001600160a01b031663c8e5bbd585856040518363ffffffff1660e01b815260040180806020018281038252848482818152602001925060200280828437600081840152601f19601f820116905080830192505050935050505060006040518083038186803b158015610e2c57600080fd5b505afa158015610e40573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040908152811015610e6957600080fd5b8101908080516040519392919084600160201b821115610e8857600080fd5b908301906020820185811115610e9d57600080fd5b82518660208202830111600160201b82111715610eb957600080fd5b82525081516020918201928201910280838360005b83811015610ee6578181015183820152602001610ece565b505050509190910160408181526020938401518a850280840186019092528a83529698509596506106c09590945089935088928392508501908490808284376000920191909152508692508591506113e49050565b60065490565b610f4961126e565b604080516001808252818301909252606091602080830190803883390190505090508281600081518110610f7957fe5b60209081029190910101526040805160018082528183019092526060918160200160208202803883390190505090508281600081518110610fb657fe5b6020026020010181815250506106c0828260006113e4565b610fd6611b89565b6060610fe0611a36565b6001600160a01b03166372cb051f6040518163ffffffff1660e01b815260040160006040518083038186803b15801561101857600080fd5b505afa15801561102c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561105557600080fd5b8101908080516040519392919084600160201b82111561107457600080fd5b90830190602082018581111561108957600080fd5b82518660208202830111600160201b821117156110a557600080fd5b82525081516020918201928201910280838360005b838110156110d25781810151838201526020016110ba565b505050509050016040525050509050606060006110ee836115b2565b9150915060006110fc611c0a565b6001600160a01b031663ad79a8586040518163ffffffff1660e01b8152600401604080518083038186803b15801561113357600080fd5b505afa158015611147573d6000803e3d6000fd5b505050506040513d604081101561115d57600080fd5b505183519091506000805b828110156111d257600086828151811061117e57fe5b6020026020010151905061119b8184611c2990919063ffffffff16565b925080600560008a85815181106111ae57fe5b60209081029190910181015182528101919091526040016000205550600101611168565b506111e3818463ffffffff611c8316565b600455426006556040805182815290517f294a7c394e53042c7d754779562747d93b41db019dd4b970dd9b531db71be5999181900360200190a16040805142815290517fc481e742c89630d4b1a5ed3a0fc624c1c41ed463bd00ac26a7e93c71e932126f9181900360200190a1611259846112d4565b505050505050565b6000610d5a600654611599565b611276611a36565b6001600160a01b0316336001600160a01b0316146112d2576040805162461bcd60e51b815260206004820152601460248201527329b2b73232b91034b9903737ba1024b9b9bab2b960611b604482015290519081900360640190fd5b565b60075460ff161515811515146105c4576007805460ff19168215159081179091556040517f8eebec690c34bbf0fe0d5b93e442beaf16bdaf99052569581de2dcb3e31a53a790600090a250565b6000546001600160a01b031633146112d25760405162461bcd60e51b815260040180806020018281038252602f815260200180612406602f913960400191505060405180910390fd5b611372611a36565b6001600160a01b0316336001600160a01b031614806113a95750611394611ce0565b6001600160a01b0316336001600160a01b0316145b6112d25760405162461bcd60e51b81526004018080602001828103825260218152602001806123e56021913960400191505060405180910390fd5b82518251811461143b576040805162461bcd60e51b815260206004820152601a60248201527f496e707574206172726179206c656e6774687320646966666572000000000000604482015290519081900360640190fd5b600080606061144a8787611cf7565b905060005b848110156114d957600088828151811061146557fe5b60200260200101519050600083838151811061147d57fe5b602002602001015190506114ad600560008481526020019081526020016000205487611c2990919063ffffffff16565b95506114bf858263ffffffff611c2916565b60009283526005602052604090922055925060010161144f565b5081831461158157600454808411156115235760405162461bcd60e51b81526004018080602001828103825260238152602001806124566023913960400191505060405180910390fd5b61154383611537838763ffffffff611c8316565b9063ffffffff611c2916565b60048190556040805182815290519192507f294a7c394e53042c7d754779562747d93b41db019dd4b970dd9b531db71be599919081900360200190a1505b841561159057611590856112d4565b50505050505050565b60008142036115a6611a4a565b1080610da05750501590565b60606000606060006115c2611bef565b6001600160a01b031663c8e5bbd5866040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b83811015611620578181015183820152602001611608565b505050509050019250505060006040518083038186803b15801561164357600080fd5b505afa158015611657573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604090815281101561168057600080fd5b8101908080516040519392919084600160201b82111561169f57600080fd5b9083019060208201858111156116b457600080fd5b82518660208202830111600160201b821117156116d057600080fd5b82525081516020918201928201910280838360005b838110156116fd5781810151838201526020016116e5565b50505050919091016040525060200151929450919250611721915086905083611cf7565b9350915050915091565b6000806060600061184161173d611a36565b6001600160a01b03166372cb051f6040518163ffffffff1660e01b815260040160006040518083038186803b15801561177557600080fd5b505afa158015611789573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156117b257600080fd5b8101908080516040519392919084600160201b8211156117d157600080fd5b9083019060208201858111156117e657600080fd5b82518660208202830111600160201b8211171561180257600080fd5b82525081516020918201928201910280838360005b8381101561182f578181015183820152602001611817565b505050509050016040525050506115b2565b815191935091506000805b828110156118845761187a85828151811061186357fe5b602002602001015183611c2990919063ffffffff16565b915060010161184c565b50600080611890611c0a565b6001600160a01b031663ad79a8586040518163ffffffff1660e01b8152600401604080518083038186803b1580156118c757600080fd5b505afa1580156118db573d6000803e3d6000fd5b505050506040513d60408110156118f157600080fd5b508051602090910151909250905061190f838363ffffffff611c8316565b9250848061191a5750805b92975091955050505050509091565b604080516001808252818301909252606091602080830190803883390190505090506e466c657869626c6553746f7261676560881b8160008151811061196b57fe5b60200260200101818152505090565b606081518351016040519080825280602002602001820160405280156119aa578160200160208202803883390190505b50905060005b83518110156119ec578381815181106119c557fe5b60200260200101518282815181106119d957fe5b60209081029190910101526001016119b0565b5060005b8251811015611a2f57828181518110611a0557fe5b6020026020010151828286510181518110611a1c57fe5b60209081029190910101526001016119f0565b5092915050565b6000610d5a6524b9b9bab2b960d11b6121ba565b6000611a54612297565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b7464656274536e617073686f745374616c6554696d6560581b6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b158015611ac857600080fd5b505afa158015611adc573d6000803e3d6000fd5b505050506040513d6020811015611af257600080fd5b5051905090565b6060600082519050606081604051908082528060200260200182016040528015611b2d578160200160208202803883390190505b50905060005b82811015611b815760056000868381518110611b4b57fe5b6020026020010151815260200190815260200160002054828281518110611b6e57fe5b6020908102919091010152600101611b33565b509392505050565b6000546001600160a01b031633146112d257611ba36122b4565b6001600160a01b031663086dabd16040518163ffffffff1660e01b815260040160006040518083038186803b158015611bdb57600080fd5b505afa1580156106c0573d6000803e3d6000fd5b6000610d5a6c45786368616e6765526174657360981b6121ba565b6000610d5a7021b7b63630ba32b930b626b0b730b3b2b960791b6121ba565b600082820183811015610d9d576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082821115611cda576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000610d5a6822bc31b430b733b2b960b91b6121ba565b6060600083519050606081604051908082528060200260200182016040528015611d2b578160200160208202803883390190505b5090506060611d38611a36565b6001600160a01b0316633b6afe40876040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b83811015611d96578181015183820152602001611d7e565b505050509050019250505060006040518083038186803b158015611db957600080fd5b505afa158015611dcd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611df657600080fd5b8101908080516040519392919084600160201b821115611e1557600080fd5b908301906020820185811115611e2a57600080fd5b82518660208202830111600160201b82111715611e4657600080fd5b82525081516020918201928201910280838360005b83811015611e73578181015183820152602001611e5b565b50505050905001604052505050905060008090505b838110156121af576000878281518110611e9e57fe5b602002602001015190506000838381518110611eb657fe5b6020026020010151905060006001600160a01b0316816001600160a01b03161415611f1f576040805162461bcd60e51b815260206004820152601460248201527314de5b9d1a08191bd95cc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b6000816001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f5a57600080fd5b505afa158015611f6e573d6000803e3d6000fd5b505050506040513d6020811015611f8457600080fd5b50519050611f90611c0a565b6001600160a01b0316638471db13846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611fd357600080fd5b505afa158015611fe7573d6000803e3d6000fd5b505050506040513d6020811015611ffd57600080fd5b5051156120a557600061200e611c0a565b6001600160a01b031663d2f00475856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561205157600080fd5b505afa158015612065573d6000803e3d6000fd5b505050506040513d602081101561207b57600080fd5b505190508181111561209057600091506120a3565b6120a0828263ffffffff611c8316565b91505b505b631cd554d160e21b831480806120c15750630e68aa8960e31b84145b15612162576000816120da576120d56122ce565b6120e2565b6120e26122eb565b90506000816001600160a01b031663ee5f3f5c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561211f57600080fd5b505afa158015612133573d6000803e3d6000fd5b505050506040513d602081101561214957600080fd5b5051905061215d848263ffffffff611c8316565b935050505b6121888a868151811061217157fe5b60200260200101518361230c90919063ffffffff16565b87868151811061219457fe5b6020908102919091010152505060019092019150611e889050565b509095945050505050565b600081815260036020908152604080832054815170026b4b9b9b4b7339030b2323932b9b99d1607d1b9381019390935260318084018690528251808503909101815260519093019091526001600160a01b03169081611a2f5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561225c578181015183820152602001612244565b50505050905090810190601f1680156122895780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6000610d5a6e466c657869626c6553746f7261676560881b6121ba565b6000610d5a6b53797374656d53746174757360a01b6121ba565b6000610d5a6e115d1a195c90dbdb1b185d195c985b608a1b6121ba565b6000610d5a72115d1a195c90dbdb1b185d195c985b1cd554d1606a1b6121ba565b6000610d9d8383670de0b6b3a7640000848067016345785d8a00006123318686612356565b8161233857fe5b0490506005600a82061061234a57600a015b600a9004949350505050565b60008261236557506000610da0565b8282028284828161237257fe5b0414610d9d5760405162461bcd60e51b81526004018080602001828103825260218152602001806124356021913960400191505060405180910390fdfe596f75206d757374206265206e6f6d696e61746564206265666f726520796f752063616e20616363657074206f776e65727368697053656e646572206973206e6f7420497373756572206f722045786368616e6765724f6e6c792074686520636f6e7472616374206f776e6572206d617920706572666f726d207468697320616374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774361636865642073796e74682073756d206578636565647320746f74616c2064656274a265627a7a72315820804273d96350b998c6306cfd16daf7e63fbcd5259c40ca19183b5364881a2f0a64736f6c63430005100032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe0000000000000000000000004e3b31eb0e5cb73641ee1e65e7dcefe520ba3ef2
-----Decoded View---------------
Arg [0] : _owner (address): 0xDe910777C787903F78C89e7a0bf7F4C435cBB1Fe
Arg [1] : _resolver (address): 0x4E3b31eB0E5CB73641EE1E65E7dCEFe520bA3ef2
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe
Arg [1] : 0000000000000000000000004e3b31eb0e5cb73641ee1e65e7dcefe520ba3ef2
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.