Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
ExchangeSettlementLib
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 sepolia-optimism.etherscan.io on 2023-12-11
*/
/*
____ __ __ __ _
/ __/__ __ ___ / /_ / / ___ / /_ (_)__ __
_\ \ / // // _ \/ __// _ \/ -_)/ __// / \ \ /
/___/ \_, //_//_/\__//_//_/\__/ \__//_/ /_\_\
/___/
* Synthetix: ExchangeSettlementLib.sol
*
* Latest source (may be newer): https://github.com/Synthetixio/synthetix/blob/master/contracts/ExchangeSettlementLib.sol
* Docs: https://docs.synthetix.io/contracts/ExchangeSettlementLib
*
* Contract Dependencies: (none)
* Libraries:
* - ExchangeSettlementLib
* - SafeDecimalMath
* - SafeMath
*
* MIT License
* ===========
*
* Copyright (c) 2023 Synthetix
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*/
pragma solidity >=0.4.24;
// https://docs.synthetix.io/contracts/source/interfaces/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;
}
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;
}
pragma experimental ABIEncoderV2;
// https://docs.synthetix.io/contracts/source/interfaces/iexchanger
interface IExchanger {
struct ExchangeEntrySettlement {
bytes32 src;
uint amount;
bytes32 dest;
uint reclaim;
uint rebate;
uint srcRoundIdAtPeriodEnd;
uint destRoundIdAtPeriodEnd;
uint timestamp;
}
struct ExchangeEntry {
uint sourceRate;
uint destinationRate;
uint destinationAmount;
uint exchangeFeeRate;
uint exchangeDynamicFeeRate;
uint roundIdForSrc;
uint roundIdForDest;
uint sourceAmountAfterSettlement;
}
// Views
function calculateAmountAfterSettlement(
address from,
bytes32 currencyKey,
uint amount,
uint refunded
) external view returns (uint amountAfterSettlement);
function isSynthRateInvalid(bytes32 currencyKey) external view returns (bool);
function maxSecsLeftInWaitingPeriod(address account, bytes32 currencyKey) external view returns (uint);
function settlementOwing(address account, bytes32 currencyKey)
external
view
returns (
uint reclaimAmount,
uint rebateAmount,
uint numEntries
);
function hasWaitingPeriodOrSettlementOwing(address account, bytes32 currencyKey) external view returns (bool);
function feeRateForExchange(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) external view returns (uint);
function dynamicFeeRateForExchange(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey)
external
view
returns (uint feeRate, bool tooVolatile);
function getAmountsForExchange(
uint sourceAmount,
bytes32 sourceCurrencyKey,
bytes32 destinationCurrencyKey
)
external
view
returns (
uint amountReceived,
uint fee,
uint exchangeFeeRate
);
function priceDeviationThresholdFactor() external view returns (uint);
function waitingPeriodSecs() external view returns (uint);
function lastExchangeRate(bytes32 currencyKey) external view returns (uint);
// Mutative functions
function exchange(
address exchangeForAddress,
address from,
bytes32 sourceCurrencyKey,
uint sourceAmount,
bytes32 destinationCurrencyKey,
address destinationAddress,
bool virtualSynth,
address rewardAddress,
bytes32 trackingCode
) external returns (uint amountReceived, IVirtualSynth vSynth);
function exchangeAtomically(
address from,
bytes32 sourceCurrencyKey,
uint sourceAmount,
bytes32 destinationCurrencyKey,
address destinationAddress,
bytes32 trackingCode,
uint minAmount
) external returns (uint amountReceived);
function settle(address from, bytes32 currencyKey)
external
returns (
uint reclaimed,
uint refunded,
uint numEntries
);
}
// Used to have strongly-typed access to internal mutative functions in Synthetix
interface ISynthetixInternal {
function emitExchangeTracking(
bytes32 trackingCode,
bytes32 toCurrencyKey,
uint256 toAmount,
uint256 fee
) external;
function emitSynthExchange(
address account,
bytes32 fromCurrencyKey,
uint fromAmount,
bytes32 toCurrencyKey,
uint toAmount,
address toAddress
) external;
function emitAtomicSynthExchange(
address account,
bytes32 fromCurrencyKey,
uint fromAmount,
bytes32 toCurrencyKey,
uint toAmount,
address toAddress
) external;
function emitExchangeReclaim(
address account,
bytes32 currencyKey,
uint amount
) external;
function emitExchangeRebate(
address account,
bytes32 currencyKey,
uint amount
) external;
}
interface IExchangerInternalDebtCache {
function updateCachedSynthDebtsWithRates(bytes32[] calldata currencyKeys, uint[] calldata currencyRates) external;
function updateCachedSynthDebts(bytes32[] calldata currencyKeys) external;
}
// https://docs.synthetix.io/contracts/source/interfaces/ICircuitBreaker
interface ICircuitBreaker {
// Views
function isInvalid(address oracleAddress, uint value) external view returns (bool);
function priceDeviationThresholdFactor() external view returns (uint);
function isDeviationAboveThreshold(uint base, uint comparison) external view returns (bool);
function lastValue(address oracleAddress) external view returns (uint);
function circuitBroken(address oracleAddress) external view returns (bool);
// Mutative functions
function resetLastValue(address[] calldata oracleAddresses, uint[] calldata values) external;
function probeCircuitBreaker(address oracleAddress, uint value) external returns (bool circuitBroken);
}
// https://docs.synthetix.io/contracts/source/interfaces/IDirectIntegration
interface IDirectIntegrationManager {
struct ParameterIntegrationSettings {
bytes32 currencyKey;
address dexPriceAggregator;
address atomicEquivalentForDexPricing;
uint atomicExchangeFeeRate;
uint atomicTwapWindow;
uint atomicMaxVolumePerBlock;
uint atomicVolatilityConsiderationWindow;
uint atomicVolatilityUpdateThreshold;
uint exchangeFeeRate;
uint exchangeMaxDynamicFee;
uint exchangeDynamicFeeRounds;
uint exchangeDynamicFeeThreshold;
uint exchangeDynamicFeeWeightDecay;
}
function getExchangeParameters(address integration, bytes32 key)
external
view
returns (ParameterIntegrationSettings memory settings);
function setExchangeParameters(
address integration,
bytes32[] calldata currencyKeys,
ParameterIntegrationSettings calldata params
) external;
}
// https://docs.synthetix.io/contracts/source/interfaces/iexchangerates
interface IExchangeRates {
// Structs
struct RateAndUpdatedTime {
uint216 rate;
uint40 time;
}
// Views
function aggregators(bytes32 currencyKey) external view returns (address);
function aggregatorWarningFlags() external view returns (address);
function anyRateIsInvalid(bytes32[] calldata currencyKeys) external view returns (bool);
function anyRateIsInvalidAtRound(bytes32[] calldata currencyKeys, uint[] calldata roundIds) external view returns (bool);
function currenciesUsingAggregator(address aggregator) external view returns (bytes32[] memory);
function effectiveValue(
bytes32 sourceCurrencyKey,
uint sourceAmount,
bytes32 destinationCurrencyKey
) external view returns (uint value);
function effectiveValueAndRates(
bytes32 sourceCurrencyKey,
uint sourceAmount,
bytes32 destinationCurrencyKey
)
external
view
returns (
uint value,
uint sourceRate,
uint destinationRate
);
function effectiveValueAndRatesAtRound(
bytes32 sourceCurrencyKey,
uint sourceAmount,
bytes32 destinationCurrencyKey,
uint roundIdForSrc,
uint roundIdForDest
)
external
view
returns (
uint value,
uint sourceRate,
uint destinationRate
);
function effectiveAtomicValueAndRates(
bytes32 sourceCurrencyKey,
uint sourceAmount,
bytes32 destinationCurrencyKey
)
external
view
returns (
uint value,
uint systemValue,
uint systemSourceRate,
uint systemDestinationRate
);
function effectiveAtomicValueAndRates(
IDirectIntegrationManager.ParameterIntegrationSettings calldata sourceSettings,
uint sourceAmount,
IDirectIntegrationManager.ParameterIntegrationSettings calldata destinationSettings,
IDirectIntegrationManager.ParameterIntegrationSettings calldata usdSettings
)
external
view
returns (
uint value,
uint systemValue,
uint systemSourceRate,
uint systemDestinationRate
);
function getCurrentRoundId(bytes32 currencyKey) external view returns (uint);
function getLastRoundIdBeforeElapsedSecs(
bytes32 currencyKey,
uint startingRoundId,
uint startingTimestamp,
uint timediff
) external view returns (uint);
function lastRateUpdateTimes(bytes32 currencyKey) external view returns (uint256);
function rateAndTimestampAtRound(bytes32 currencyKey, uint roundId) external view returns (uint rate, uint time);
function rateAndUpdatedTime(bytes32 currencyKey) external view returns (uint rate, uint time);
function rateAndInvalid(bytes32 currencyKey) external view returns (uint rate, bool isInvalid);
function rateForCurrency(bytes32 currencyKey) external view returns (uint);
function rateIsFlagged(bytes32 currencyKey) external view returns (bool);
function rateIsInvalid(bytes32 currencyKey) external view returns (bool);
function rateIsStale(bytes32 currencyKey) external view returns (bool);
function rateStalePeriod() external view returns (uint);
function ratesAndUpdatedTimeForCurrencyLastNRounds(
bytes32 currencyKey,
uint numRounds,
uint roundId
) external view returns (uint[] memory rates, uint[] memory times);
function ratesAndInvalidForCurrencies(bytes32[] calldata currencyKeys)
external
view
returns (uint[] memory rates, bool anyRateInvalid);
function ratesForCurrencies(bytes32[] calldata currencyKeys) external view returns (uint[] memory);
function synthTooVolatileForAtomicExchange(bytes32 currencyKey) external view returns (bool);
function synthTooVolatileForAtomicExchange(IDirectIntegrationManager.ParameterIntegrationSettings calldata settings)
external
view
returns (bool);
function rateWithSafetyChecks(bytes32 currencyKey)
external
returns (
uint rate,
bool broken,
bool invalid
);
}
// https://docs.synthetix.io/contracts/source/interfaces/iexchangestate
interface IExchangeState {
// Views
struct ExchangeEntry {
bytes32 src;
uint amount;
bytes32 dest;
uint amountReceived;
uint exchangeFeeRate;
uint timestamp;
uint roundIdForSrc;
uint roundIdForDest;
}
function getLengthOfEntries(address account, bytes32 currencyKey) external view returns (uint);
function getEntryAt(
address account,
bytes32 currencyKey,
uint index
)
external
view
returns (
bytes32 src,
uint amount,
bytes32 dest,
uint amountReceived,
uint exchangeFeeRate,
uint timestamp,
uint roundIdForSrc,
uint roundIdForDest
);
function getMaxTimestamp(address account, bytes32 currencyKey) external view returns (uint);
// Mutative functions
function appendExchangeEntry(
address account,
bytes32 src,
uint amount,
bytes32 dest,
uint amountReceived,
uint exchangeFeeRate,
uint timestamp,
uint roundIdForSrc,
uint roundIdForDest
) external;
function removeEntries(address account, bytes32 currencyKey) external;
}
// https://docs.synthetix.io/contracts/source/interfaces/iissuer
interface IIssuer {
// Views
function allNetworksDebtInfo()
external
view
returns (
uint256 debt,
uint256 sharesSupply,
bool isStale
);
function anySynthOrSNXRateIsInvalid() external view returns (bool anyRateInvalid);
function availableCurrencyKeys() external view returns (bytes32[] memory);
function availableSynthCount() external view returns (uint);
function availableSynths(uint index) external view returns (ISynth);
function canBurnSynths(address account) external view returns (bool);
function collateral(address account) external view returns (uint);
function collateralisationRatio(address issuer) external view returns (uint);
function collateralisationRatioAndAnyRatesInvalid(address _issuer)
external
view
returns (uint cratio, bool anyRateIsInvalid);
function debtBalanceOf(address issuer, bytes32 currencyKey) external view returns (uint debtBalance);
function issuanceRatio() external view returns (uint);
function lastIssueEvent(address account) external view returns (uint);
function maxIssuableSynths(address issuer) external view returns (uint maxIssuable);
function minimumStakeTime() external view returns (uint);
function remainingIssuableSynths(address issuer)
external
view
returns (
uint maxIssuable,
uint alreadyIssued,
uint totalSystemDebt
);
function synths(bytes32 currencyKey) external view returns (ISynth);
function getSynths(bytes32[] calldata currencyKeys) external view returns (ISynth[] memory);
function synthsByAddress(address synthAddress) external view returns (bytes32);
function totalIssuedSynths(bytes32 currencyKey, bool excludeOtherCollateral) external view returns (uint);
function transferableSynthetixAndAnyRateIsInvalid(address account, uint balance)
external
view
returns (uint transferable, bool anyRateIsInvalid);
function liquidationAmounts(address account, bool isSelfLiquidation)
external
view
returns (
uint totalRedeemed,
uint debtToRemove,
uint escrowToLiquidate,
uint initialDebtBalance
);
// Restricted: used internally to Synthetix
function addSynths(ISynth[] calldata synthsToAdd) external;
function issueSynths(address from, uint amount) external;
function issueSynthsOnBehalf(
address issueFor,
address from,
uint amount
) external;
function issueMaxSynths(address from) external;
function issueMaxSynthsOnBehalf(address issueFor, address from) external;
function burnSynths(address from, uint amount) external;
function burnSynthsOnBehalf(
address burnForAddress,
address from,
uint amount
) external;
function burnSynthsToTarget(address from) external;
function burnSynthsToTargetOnBehalf(address burnForAddress, address from) external;
function burnForRedemption(
address deprecatedSynthProxy,
address account,
uint balance
) external;
function setCurrentPeriodId(uint128 periodId) external;
function liquidateAccount(address account, bool isSelfLiquidation)
external
returns (
uint totalRedeemed,
uint debtRemoved,
uint escrowToLiquidate
);
function issueSynthsWithoutDebt(
bytes32 currencyKey,
address to,
uint amount
) external returns (bool rateInvalid);
function burnSynthsWithoutDebt(
bytes32 currencyKey,
address to,
uint amount
) external returns (bool rateInvalid);
function modifyDebtSharesForMigration(address account, uint amount) external;
}
interface IDebtCache {
// Views
function cachedDebt() external view returns (uint);
function cachedSynthDebt(bytes32 currencyKey) external view returns (uint);
function cacheTimestamp() external view returns (uint);
function cacheInvalid() external view returns (bool);
function cacheStale() external view returns (bool);
function isInitialized() external view returns (bool);
function currentSynthDebts(bytes32[] calldata currencyKeys)
external
view
returns (
uint[] memory debtValues,
uint futuresDebt,
uint excludedDebt,
bool anyRateIsInvalid
);
function cachedSynthDebts(bytes32[] calldata currencyKeys) external view returns (uint[] memory debtValues);
function totalNonSnxBackedDebt() external view returns (uint excludedDebt, bool isInvalid);
function currentDebt() external view returns (uint debt, bool anyRateIsInvalid);
function cacheInfo()
external
view
returns (
uint debt,
uint timestamp,
bool isInvalid,
bool isStale
);
function excludedIssuedDebts(bytes32[] calldata currencyKeys) external view returns (uint[] memory excludedDebts);
// Mutative functions
function updateCachedSynthDebts(bytes32[] calldata currencyKeys) external;
function updateCachedSynthDebtWithRate(bytes32 currencyKey, uint currencyRate) external;
function updateCachedSynthDebtsWithRates(bytes32[] calldata currencyKeys, uint[] calldata currencyRates) external;
function updateDebtCacheValidity(bool currentlyInvalid) external;
function purgeCachedSynthDebt(bytes32 currencyKey) external;
function takeDebtSnapshot() external;
function recordExcludedDebtChange(bytes32 currencyKey, int256 delta) external;
function updateCachedsUSDDebt(int amount) external;
function importExcludedIssuedDebts(IDebtCache prevDebtCache, IIssuer prevIssuer) external;
}
// https://docs.synthetix.io/contracts/source/interfaces/isynthetix
interface ISynthetix {
// Views
function anySynthOrSNXRateIsInvalid() external view returns (bool anyRateInvalid);
function availableCurrencyKeys() external view returns (bytes32[] memory);
function availableSynthCount() external view returns (uint);
function availableSynths(uint index) external view returns (ISynth);
function collateral(address account) external view returns (uint);
function collateralisationRatio(address issuer) external view returns (uint);
function debtBalanceOf(address issuer, bytes32 currencyKey) external view returns (uint);
function isWaitingPeriod(bytes32 currencyKey) external view returns (bool);
function maxIssuableSynths(address issuer) external view returns (uint maxIssuable);
function remainingIssuableSynths(address issuer)
external
view
returns (
uint maxIssuable,
uint alreadyIssued,
uint totalSystemDebt
);
function synths(bytes32 currencyKey) external view returns (ISynth);
function synthsByAddress(address synthAddress) external view returns (bytes32);
function totalIssuedSynths(bytes32 currencyKey) external view returns (uint);
function totalIssuedSynthsExcludeOtherCollateral(bytes32 currencyKey) external view returns (uint);
function transferableSynthetix(address account) external view returns (uint transferable);
function getFirstNonZeroEscrowIndex(address account) external view returns (uint);
// Mutative Functions
function burnSynths(uint amount) external;
function burnSynthsOnBehalf(address burnForAddress, uint amount) external;
function burnSynthsToTarget() external;
function burnSynthsToTargetOnBehalf(address burnForAddress) external;
function exchange(
bytes32 sourceCurrencyKey,
uint sourceAmount,
bytes32 destinationCurrencyKey
) external returns (uint amountReceived);
function exchangeOnBehalf(
address exchangeForAddress,
bytes32 sourceCurrencyKey,
uint sourceAmount,
bytes32 destinationCurrencyKey
) external returns (uint amountReceived);
function exchangeWithTracking(
bytes32 sourceCurrencyKey,
uint sourceAmount,
bytes32 destinationCurrencyKey,
address rewardAddress,
bytes32 trackingCode
) external returns (uint amountReceived);
function exchangeWithTrackingForInitiator(
bytes32 sourceCurrencyKey,
uint sourceAmount,
bytes32 destinationCurrencyKey,
address rewardAddress,
bytes32 trackingCode
) external returns (uint amountReceived);
function exchangeOnBehalfWithTracking(
address exchangeForAddress,
bytes32 sourceCurrencyKey,
uint sourceAmount,
bytes32 destinationCurrencyKey,
address rewardAddress,
bytes32 trackingCode
) external returns (uint amountReceived);
function exchangeWithVirtual(
bytes32 sourceCurrencyKey,
uint sourceAmount,
bytes32 destinationCurrencyKey,
bytes32 trackingCode
) external returns (uint amountReceived, IVirtualSynth vSynth);
function exchangeAtomically(
bytes32 sourceCurrencyKey,
uint sourceAmount,
bytes32 destinationCurrencyKey,
bytes32 trackingCode,
uint minAmount
) external returns (uint amountReceived);
function issueMaxSynths() external;
function issueMaxSynthsOnBehalf(address issueForAddress) external;
function issueSynths(uint amount) external;
function issueSynthsOnBehalf(address issueForAddress, uint amount) external;
function mint() external returns (bool);
function settle(bytes32 currencyKey)
external
returns (
uint reclaimed,
uint refunded,
uint numEntries
);
// Liquidations
function liquidateDelinquentAccount(address account) external returns (bool);
function liquidateDelinquentAccountEscrowIndex(address account, uint escrowStartIndex) external returns (bool);
function liquidateSelf() external returns (bool);
// Restricted Functions
function mintSecondary(address account, uint amount) external;
function mintSecondaryRewards(uint amount) external;
function burnSecondary(address account, uint amount) external;
function revokeAllEscrow(address account) external;
function migrateAccountBalances(address account) external returns (uint totalEscrowRevoked, uint totalLiquidBalance);
}
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, "SafeMath: division by zero");
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0, "SafeMath: modulo by zero");
return a % b;
}
}
// Libraries
// https://docs.synthetix.io/contracts/source/libraries/safedecimalmath
library SafeDecimalMath {
using SafeMath for uint;
/* Number of decimal places in the representations. */
uint8 public constant decimals = 18;
uint8 public constant highPrecisionDecimals = 27;
/* The number representing 1.0. */
uint public constant UNIT = 10**uint(decimals);
/* The number representing 1.0 for higher fidelity numbers. */
uint public constant PRECISE_UNIT = 10**uint(highPrecisionDecimals);
uint private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR = 10**uint(highPrecisionDecimals - decimals);
/**
* @return Provides an interface to UNIT.
*/
function unit() external pure returns (uint) {
return UNIT;
}
/**
* @return Provides an interface to PRECISE_UNIT.
*/
function preciseUnit() external pure returns (uint) {
return PRECISE_UNIT;
}
/**
* @return The result of multiplying x and y, interpreting the operands as fixed-point
* decimals.
*
* @dev A unit factor is divided out after the product of x and y is evaluated,
* so that product must be less than 2**256. As this is an integer division,
* the internal division always rounds down. This helps save on gas. Rounding
* is more expensive on gas.
*/
function multiplyDecimal(uint x, uint y) internal pure returns (uint) {
/* Divide by UNIT to remove the extra factor introduced by the product. */
return x.mul(y) / UNIT;
}
/**
* @return The result of safely multiplying x and y, interpreting the operands
* as fixed-point decimals of the specified precision unit.
*
* @dev The operands should be in the form of a the specified unit factor which will be
* divided out after the product of x and y is evaluated, so that product must be
* less than 2**256.
*
* Unlike multiplyDecimal, this function rounds the result to the nearest increment.
* Rounding is useful when you need to retain fidelity for small decimal numbers
* (eg. small fractions or percentages).
*/
function _multiplyDecimalRound(
uint x,
uint y,
uint precisionUnit
) private pure returns (uint) {
/* Divide by UNIT to remove the extra factor introduced by the product. */
uint quotientTimesTen = x.mul(y) / (precisionUnit / 10);
if (quotientTimesTen % 10 >= 5) {
quotientTimesTen += 10;
}
return quotientTimesTen / 10;
}
/**
* @return The result of safely multiplying x and y, interpreting the operands
* as fixed-point decimals of a precise unit.
*
* @dev The operands should be in the precise unit factor which will be
* divided out after the product of x and y is evaluated, so that product must be
* less than 2**256.
*
* Unlike multiplyDecimal, this function rounds the result to the nearest increment.
* Rounding is useful when you need to retain fidelity for small decimal numbers
* (eg. small fractions or percentages).
*/
function multiplyDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) {
return _multiplyDecimalRound(x, y, PRECISE_UNIT);
}
/**
* @return The result of safely multiplying x and y, interpreting the operands
* as fixed-point decimals of a standard unit.
*
* @dev The operands should be in the standard unit factor which will be
* divided out after the product of x and y is evaluated, so that product must be
* less than 2**256.
*
* Unlike multiplyDecimal, this function rounds the result to the nearest increment.
* Rounding is useful when you need to retain fidelity for small decimal numbers
* (eg. small fractions or percentages).
*/
function multiplyDecimalRound(uint x, uint y) internal pure returns (uint) {
return _multiplyDecimalRound(x, y, UNIT);
}
/**
* @return The result of safely dividing x and y. The return value is a high
* precision decimal.
*
* @dev y is divided after the product of x and the standard precision unit
* is evaluated, so the product of x and UNIT must be less than 2**256. As
* this is an integer division, the result is always rounded down.
* This helps save on gas. Rounding is more expensive on gas.
*/
function divideDecimal(uint x, uint y) internal pure returns (uint) {
/* Reintroduce the UNIT factor that will be divided out by y. */
return x.mul(UNIT).div(y);
}
/**
* @return The result of safely dividing x and y. The return value is as a rounded
* decimal in the precision unit specified in the parameter.
*
* @dev y is divided after the product of x and the specified precision unit
* is evaluated, so the product of x and the specified precision unit must
* be less than 2**256. The result is rounded to the nearest increment.
*/
function _divideDecimalRound(
uint x,
uint y,
uint precisionUnit
) private pure returns (uint) {
uint resultTimesTen = x.mul(precisionUnit * 10).div(y);
if (resultTimesTen % 10 >= 5) {
resultTimesTen += 10;
}
return resultTimesTen / 10;
}
/**
* @return The result of safely dividing x and y. The return value is as a rounded
* standard precision decimal.
*
* @dev y is divided after the product of x and the standard precision unit
* is evaluated, so the product of x and the standard precision unit must
* be less than 2**256. The result is rounded to the nearest increment.
*/
function divideDecimalRound(uint x, uint y) internal pure returns (uint) {
return _divideDecimalRound(x, y, UNIT);
}
/**
* @return The result of safely dividing x and y. The return value is as a rounded
* high precision decimal.
*
* @dev y is divided after the product of x and the high precision unit
* is evaluated, so the product of x and the high precision unit must
* be less than 2**256. The result is rounded to the nearest increment.
*/
function divideDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) {
return _divideDecimalRound(x, y, PRECISE_UNIT);
}
/**
* @dev Convert a standard decimal representation to a high precision one.
*/
function decimalToPreciseDecimal(uint i) internal pure returns (uint) {
return i.mul(UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR);
}
/**
* @dev Convert a high precision decimal to a standard decimal representation.
*/
function preciseDecimalToDecimal(uint i) internal pure returns (uint) {
uint quotientTimesTen = i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10);
if (quotientTimesTen % 10 >= 5) {
quotientTimesTen += 10;
}
return quotientTimesTen / 10;
}
// Computes `a - b`, setting the value to 0 if b > a.
function floorsub(uint a, uint b) internal pure returns (uint) {
return b >= a ? 0 : a - b;
}
/* ---------- Utilities ---------- */
/*
* Absolute value of the input, returned as a signed number.
*/
function signedAbs(int x) internal pure returns (int) {
return x < 0 ? -x : x;
}
/*
* Absolute value of the input, returned as an unsigned number.
*/
function abs(int x) internal pure returns (uint) {
return uint(signedAbs(x));
}
}
library ExchangeSettlementLib {
using SafeMath for uint256;
using SafeDecimalMath for uint256;
struct ResolvedAddresses {
IExchangeState exchangeState;
IExchangeRates exchangeRates;
ICircuitBreaker circuitBreaker;
IExchangerInternalDebtCache debtCache;
IIssuer issuer;
ISynthetix synthetix;
}
bytes32 internal constant sUSD = "sUSD";
function internalSettle(
ResolvedAddresses calldata resolvedAddresses,
address from,
bytes32 currencyKey,
bool updateCache,
uint waitingPeriod
)
external
returns (
uint reclaimed,
uint refunded,
uint numEntriesSettled
)
{
require(
maxSecsLeftInWaitingPeriod(resolvedAddresses.exchangeState, from, currencyKey, waitingPeriod) == 0,
"Cannot settle during waiting period"
);
(uint reclaimAmount, uint rebateAmount, uint entries, IExchanger.ExchangeEntrySettlement[] memory settlements) =
_settlementOwing(resolvedAddresses, from, currencyKey, waitingPeriod);
if (reclaimAmount > rebateAmount) {
reclaimed = reclaimAmount.sub(rebateAmount);
_reclaim(resolvedAddresses, from, currencyKey, reclaimed);
} else if (rebateAmount > reclaimAmount) {
refunded = rebateAmount.sub(reclaimAmount);
_refund(resolvedAddresses, from, currencyKey, refunded);
}
// by checking a reclaim or refund we also check that the currency key is still a valid synth,
// as the deviation check will return 0 if the synth has been removed.
if (updateCache && (reclaimed > 0 || refunded > 0)) {
bytes32[] memory key = new bytes32[](1);
key[0] = currencyKey;
resolvedAddresses.debtCache.updateCachedSynthDebts(key);
}
// emit settlement event for each settled exchange entry
for (uint i = 0; i < settlements.length; i++) {
emit ExchangeEntrySettled(
from,
settlements[i].src,
settlements[i].amount,
settlements[i].dest,
settlements[i].reclaim,
settlements[i].rebate,
settlements[i].srcRoundIdAtPeriodEnd,
settlements[i].destRoundIdAtPeriodEnd,
settlements[i].timestamp
);
}
numEntriesSettled = entries;
// Now remove all entries, even if no reclaim and no rebate
resolvedAddresses.exchangeState.removeEntries(from, currencyKey);
}
function maxSecsLeftInWaitingPeriod(
IExchangeState exchangeState,
address account,
bytes32 currencyKey,
uint waitingPeriod
) public view returns (uint) {
return _secsLeftInWaitingPeriodForExchange(exchangeState.getMaxTimestamp(account, currencyKey), waitingPeriod);
}
function _secsLeftInWaitingPeriodForExchange(uint timestamp, uint waitingPeriod) internal view returns (uint) {
if (timestamp == 0 || now >= timestamp.add(waitingPeriod)) {
return 0;
}
return timestamp.add(waitingPeriod).sub(now);
}
function _reclaim(
ResolvedAddresses memory resolvedAddresses,
address from,
bytes32 currencyKey,
uint amount
) internal {
// burn amount from user
resolvedAddresses.issuer.synths(currencyKey).burn(from, amount);
ISynthetixInternal(address(resolvedAddresses.synthetix)).emitExchangeReclaim(from, currencyKey, amount);
}
function _refund(
ResolvedAddresses memory resolvedAddresses,
address from,
bytes32 currencyKey,
uint amount
) internal {
// issue amount to user
resolvedAddresses.issuer.synths(currencyKey).issue(from, amount);
ISynthetixInternal(address(resolvedAddresses.synthetix)).emitExchangeRebate(from, currencyKey, amount);
}
function hasWaitingPeriodOrSettlementOwing(
ResolvedAddresses calldata resolvedAddresses,
address account,
bytes32 currencyKey,
uint waitingPeriod
) external view returns (bool) {
if (maxSecsLeftInWaitingPeriod(resolvedAddresses.exchangeState, account, currencyKey, waitingPeriod) != 0) {
return true;
}
(uint reclaimAmount, , , ) = _settlementOwing(resolvedAddresses, account, currencyKey, waitingPeriod);
return reclaimAmount > 0;
}
function settlementOwing(
ResolvedAddresses calldata resolvedAddresses,
address account,
bytes32 currencyKey,
uint waitingPeriod
)
external
view
returns (
uint reclaimAmount,
uint rebateAmount,
uint numEntries,
IExchanger.ExchangeEntrySettlement[] memory
)
{
return _settlementOwing(resolvedAddresses, account, currencyKey, waitingPeriod);
}
// Internal function to aggregate each individual rebate and reclaim entry for a synth
function _settlementOwing(
ResolvedAddresses memory resolvedAddresses,
address account,
bytes32 currencyKey,
uint waitingPeriod
)
internal
view
returns (
uint reclaimAmount,
uint rebateAmount,
uint numEntries,
IExchanger.ExchangeEntrySettlement[] memory
)
{
// Need to sum up all reclaim and rebate amounts for the user and the currency key
numEntries = resolvedAddresses.exchangeState.getLengthOfEntries(account, currencyKey);
// For each unsettled exchange
IExchanger.ExchangeEntrySettlement[] memory settlements = new IExchanger.ExchangeEntrySettlement[](numEntries);
for (uint i = 0; i < numEntries; i++) {
// fetch the entry from storage
IExchangeState.ExchangeEntry memory exchangeEntry =
_getExchangeEntry(resolvedAddresses.exchangeState, account, currencyKey, i);
// determine the last round ids for src and dest pairs when period ended or latest if not over
(uint srcRoundIdAtPeriodEnd, uint destRoundIdAtPeriodEnd) =
_getRoundIdsAtPeriodEnd(resolvedAddresses.exchangeRates, exchangeEntry, waitingPeriod);
// given these round ids, determine what effective value they should have received
uint amountShouldHaveReceived;
{
(uint destinationAmount, , ) =
resolvedAddresses.exchangeRates.effectiveValueAndRatesAtRound(
exchangeEntry.src,
exchangeEntry.amount,
exchangeEntry.dest,
srcRoundIdAtPeriodEnd,
destRoundIdAtPeriodEnd
);
// and deduct the fee from this amount using the exchangeFeeRate from storage
amountShouldHaveReceived = _deductFeesFromAmount(destinationAmount, exchangeEntry.exchangeFeeRate);
}
// SIP-65 settlements where the amount at end of waiting period is beyond the threshold, then
// settle with no reclaim or rebate
bool sip65condition =
resolvedAddresses.circuitBreaker.isDeviationAboveThreshold(
exchangeEntry.amountReceived,
amountShouldHaveReceived
);
uint reclaim;
uint rebate;
if (!sip65condition) {
if (exchangeEntry.amountReceived > amountShouldHaveReceived) {
// if they received more than they should have, add to the reclaim tally
reclaim = exchangeEntry.amountReceived.sub(amountShouldHaveReceived);
reclaimAmount = reclaimAmount.add(reclaim);
} else if (amountShouldHaveReceived > exchangeEntry.amountReceived) {
// if less, add to the rebate tally
rebate = amountShouldHaveReceived.sub(exchangeEntry.amountReceived);
rebateAmount = rebateAmount.add(rebate);
}
}
settlements[i] = IExchanger.ExchangeEntrySettlement({
src: exchangeEntry.src,
amount: exchangeEntry.amount,
dest: exchangeEntry.dest,
reclaim: reclaim,
rebate: rebate,
srcRoundIdAtPeriodEnd: srcRoundIdAtPeriodEnd,
destRoundIdAtPeriodEnd: destRoundIdAtPeriodEnd,
timestamp: exchangeEntry.timestamp
});
}
return (reclaimAmount, rebateAmount, numEntries, settlements);
}
function _getExchangeEntry(
IExchangeState exchangeState,
address account,
bytes32 currencyKey,
uint index
) internal view returns (IExchangeState.ExchangeEntry memory) {
(
bytes32 src,
uint amount,
bytes32 dest,
uint amountReceived,
uint exchangeFeeRate,
uint timestamp,
uint roundIdForSrc,
uint roundIdForDest
) = exchangeState.getEntryAt(account, currencyKey, index);
return
IExchangeState.ExchangeEntry({
src: src,
amount: amount,
dest: dest,
amountReceived: amountReceived,
exchangeFeeRate: exchangeFeeRate,
timestamp: timestamp,
roundIdForSrc: roundIdForSrc,
roundIdForDest: roundIdForDest
});
}
function _getRoundIdsAtPeriodEnd(
IExchangeRates exRates,
IExchangeState.ExchangeEntry memory exchangeEntry,
uint waitingPeriod
) internal view returns (uint srcRoundIdAtPeriodEnd, uint destRoundIdAtPeriodEnd) {
srcRoundIdAtPeriodEnd = exRates.getLastRoundIdBeforeElapsedSecs(
exchangeEntry.src,
exchangeEntry.roundIdForSrc,
exchangeEntry.timestamp,
waitingPeriod
);
destRoundIdAtPeriodEnd = exRates.getLastRoundIdBeforeElapsedSecs(
exchangeEntry.dest,
exchangeEntry.roundIdForDest,
exchangeEntry.timestamp,
waitingPeriod
);
}
function _deductFeesFromAmount(uint destinationAmount, uint exchangeFeeRate)
internal
pure
returns (uint amountReceived)
{
amountReceived = destinationAmount.multiplyDecimal(SafeDecimalMath.unit().sub(exchangeFeeRate));
}
function appendExchange(
ResolvedAddresses calldata resolvedAddresses,
address account,
bytes32 src,
uint amount,
bytes32 dest,
uint amountReceived,
uint exchangeFeeRate
) external {
uint roundIdForSrc = resolvedAddresses.exchangeRates.getCurrentRoundId(src);
uint roundIdForDest = resolvedAddresses.exchangeRates.getCurrentRoundId(dest);
resolvedAddresses.exchangeState.appendExchangeEntry(
account,
src,
amount,
dest,
amountReceived,
exchangeFeeRate,
now,
roundIdForSrc,
roundIdForDest
);
emit ExchangeEntryAppended(
account,
src,
amount,
dest,
amountReceived,
exchangeFeeRate,
roundIdForSrc,
roundIdForDest
);
}
// ========== EVENTS ==========
event ExchangeEntryAppended(
address indexed account,
bytes32 src,
uint256 amount,
bytes32 dest,
uint256 amountReceived,
uint256 exchangeFeeRate,
uint256 roundIdForSrc,
uint256 roundIdForDest
);
event ExchangeEntrySettled(
address indexed from,
bytes32 src,
uint256 amount,
bytes32 dest,
uint256 reclaim,
uint256 rebate,
uint256 srcRoundIdAtPeriodEnd,
uint256 destRoundIdAtPeriodEnd,
uint256 exchangeTimestamp
);
}Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bytes32","name":"src","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"dest","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amountReceived","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"exchangeFeeRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"roundIdForSrc","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"roundIdForDest","type":"uint256"}],"name":"ExchangeEntryAppended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"bytes32","name":"src","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"dest","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"reclaim","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rebate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"srcRoundIdAtPeriodEnd","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"destRoundIdAtPeriodEnd","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"exchangeTimestamp","type":"uint256"}],"name":"ExchangeEntrySettled","type":"event"},{"constant":true,"inputs":[{"components":[{"internalType":"contract IExchangeState","name":"exchangeState","type":"IExchangeState"},{"internalType":"contract IExchangeRates","name":"exchangeRates","type":"IExchangeRates"},{"internalType":"contract ICircuitBreaker","name":"circuitBreaker","type":"ICircuitBreaker"},{"internalType":"contract IExchangerInternalDebtCache","name":"debtCache","type":"IExchangerInternalDebtCache"},{"internalType":"contract IIssuer","name":"issuer","type":"IIssuer"},{"internalType":"contract ISynthetix","name":"synthetix","type":"ISynthetix"}],"internalType":"struct ExchangeSettlementLib.ResolvedAddresses","name":"resolvedAddresses","type":"tuple"},{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"currencyKey","type":"bytes32"},{"internalType":"uint256","name":"waitingPeriod","type":"uint256"}],"name":"hasWaitingPeriodOrSettlementOwing","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IExchangeState","name":"exchangeState","type":"IExchangeState"},{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"currencyKey","type":"bytes32"},{"internalType":"uint256","name":"waitingPeriod","type":"uint256"}],"name":"maxSecsLeftInWaitingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"contract IExchangeState","name":"exchangeState","type":"IExchangeState"},{"internalType":"contract IExchangeRates","name":"exchangeRates","type":"IExchangeRates"},{"internalType":"contract ICircuitBreaker","name":"circuitBreaker","type":"ICircuitBreaker"},{"internalType":"contract IExchangerInternalDebtCache","name":"debtCache","type":"IExchangerInternalDebtCache"},{"internalType":"contract IIssuer","name":"issuer","type":"IIssuer"},{"internalType":"contract ISynthetix","name":"synthetix","type":"ISynthetix"}],"internalType":"struct ExchangeSettlementLib.ResolvedAddresses","name":"resolvedAddresses","type":"tuple"},{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"currencyKey","type":"bytes32"},{"internalType":"uint256","name":"waitingPeriod","type":"uint256"}],"name":"settlementOwing","outputs":[{"internalType":"uint256","name":"reclaimAmount","type":"uint256"},{"internalType":"uint256","name":"rebateAmount","type":"uint256"},{"internalType":"uint256","name":"numEntries","type":"uint256"},{"components":[{"internalType":"bytes32","name":"src","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"dest","type":"bytes32"},{"internalType":"uint256","name":"reclaim","type":"uint256"},{"internalType":"uint256","name":"rebate","type":"uint256"},{"internalType":"uint256","name":"srcRoundIdAtPeriodEnd","type":"uint256"},{"internalType":"uint256","name":"destRoundIdAtPeriodEnd","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"internalType":"struct IExchanger.ExchangeEntrySettlement[]","name":"","type":"tuple[]"}],"payable":false,"stateMutability":"view","type":"function"}]Contract Creation Code
611b9f610026600b82828239805160001a60731461001957fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100615760003560e01c80630a0ecd1b14610066578063291be93d146100925780632f2de902146100b257806377cd29a5146100d45780638317e96b14610103575b600080fd5b6100796100743660046113c1565b610123565b6040516100899493929190611a8c565b60405180910390f35b6100a56100a03660046112ca565b610155565b60405161008991906118b9565b8180156100be57600080fd5b506100d26100cd366004611418565b6101e9565b005b8180156100e057600080fd5b506100f46100ef366004611349565b6103d9565b60405161008993929190611a7e565b6101166101113660046113c1565b610712565b60405161008991906118ab565b60008080606061014361013b368a90038a018a6114b9565b888888610764565b929b919a509850909650945050505050565b60006101de856001600160a01b031663f1406dc886866040518363ffffffff1660e01b81526004016101889291906117ca565b60206040518083038186803b1580156101a057600080fd5b505afa1580156101b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506101d891908101906114d7565b83610a99565b90505b949350505050565b60006101fb6040890160208a016112ac565b6001600160a01b0316637a018a1e876040518263ffffffff1660e01b815260040161022691906118b9565b60206040518083038186803b15801561023e57600080fd5b505afa158015610252573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061027691908101906114d7565b9050600061028a60408a0160208b016112ac565b6001600160a01b0316637a018a1e866040518263ffffffff1660e01b81526004016102b591906118b9565b60206040518083038186803b1580156102cd57600080fd5b505afa1580156102e1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061030591908101906114d7565b905061031460208a018a6112ac565b6001600160a01b0316633ca9d85c898989898989428a8a6040518a63ffffffff1660e01b815260040161034f99989796959493929190611814565b600060405180830381600087803b15801561036957600080fd5b505af115801561037d573d6000803e3d6000fd5b50505050876001600160a01b03167f62e40d554c7abcdd31074960d8347a2225daeb04d93bc748f049ba2ce9462398888888888888886040516103c69796959493929190611913565b60405180910390a2505050505050505050565b600080806103f56103ed60208a018a6112ac565b888887610155565b1561041b5760405162461bcd60e51b815260040161041290611a60565b60405180910390fd5b60008080606061043b610433368e90038e018e6114b9565b8c8c8b610764565b93509350935093508284111561047c5761045b848463ffffffff610aed16565b965061047761046f368e90038e018e6114b9565b8c8c8a610b15565b6104b0565b838311156104b057610494838563ffffffff610aed16565b95506104b06104a8368e90038e018e6114b9565b8c8c89610c60565b8880156104c7575060008711806104c75750600086115b1561057657604080516001808252818301909252606091602080830190803883390190505090508a816000815181106104fc57fe5b602090810291909101015261051760808e0160608f016112ac565b6001600160a01b031663cda218c7826040518263ffffffff1660e01b8152600401610542919061189a565b600060405180830381600087803b15801561055c57600080fd5b505af1158015610570573d6000803e3d6000fd5b50505050505b60005b8151811015610691578b6001600160a01b03167f8e3ad1f68bec55de3b6fa12ae2674a2a683a17c918a4cbf5157ac5d9ddc6e9408383815181106105b957fe5b6020026020010151600001518484815181106105d157fe5b6020026020010151602001518585815181106105e957fe5b60200260200101516040015186868151811061060157fe5b60200260200101516060015187878151811061061957fe5b60200260200101516080015188888151811061063157fe5b602002602001015160a0015189898151811061064957fe5b602002602001015160c001518a8a8151811061066157fe5b602002602001015160e0015160405161068198979695949392919061197b565b60405180910390a2600101610579565b5090935083906106a460208d018d6112ac565b6001600160a01b031663d0d3d62a8c8c6040518363ffffffff1660e01b81526004016106d19291906117ca565b600060405180830381600087803b1580156106eb57600080fd5b505af11580156106ff573d6000803e3d6000fd5b5050505050505050955095509592505050565b600061072c61072460208701876112ac565b858585610155565b15610739575060016101e1565b600061075561074d368890038801886114b9565b868686610764565b50505015159695505050505050565b6000806000606087600001516001600160a01b031663b44e975388886040518363ffffffff1660e01b815260040161079d9291906117ca565b60206040518083038186803b1580156107b557600080fd5b505afa1580156107c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107ed91908101906114d7565b915060608260405190808252806020026020018201604052801561082b57816020015b610818611097565b8152602001906001900390816108105790505b50905060005b83811015610a8b57610841611097565b8a5161084f908b8b85610d73565b90506000806108638d60200151848c610e52565b915091506000808e602001516001600160a01b0316636ce66c8086600001518760200151886040015188886040518663ffffffff1660e01b81526004016108ae9594939291906118c7565b60606040518083038186803b1580156108c657600080fd5b505afa1580156108da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108fe91908101906114f5565b50509050610910818660800151610f7c565b91505060008e604001516001600160a01b03166378cb51cb8660600151846040518363ffffffff1660e01b815260040161094b929190611a70565b60206040518083038186803b15801561096357600080fd5b505afa158015610977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061099b91908101906111de565b905060008082610a165783876060015111156109df5760608701516109c6908563ffffffff610aed16565b91506109d88d8363ffffffff61100e16565b9c50610a16565b8660600151841115610a16576060870151610a0190859063ffffffff610aed16565b9050610a138c8263ffffffff61100e16565b9b505b6040518061010001604052808860000151815260200188602001518152602001886040015181526020018381526020018281526020018781526020018681526020018860a00151815250898981518110610a6c57fe5b6020026020010181905250505050505050508080600101915050610831565b509050945094509450949050565b6000821580610ab75750610ab3838363ffffffff61100e16565b4210155b15610ac457506000610ae7565b610ae442610ad8858563ffffffff61100e16565b9063ffffffff610aed16565b90505b92915050565b600082821115610b0f5760405162461bcd60e51b815260040161041290611a40565b50900390565b83608001516001600160a01b03166332608039836040518263ffffffff1660e01b8152600401610b4591906118b9565b60206040518083038186803b158015610b5d57600080fd5b505afa158015610b71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b95919081019061132b565b6001600160a01b0316639dc29fac84836040518363ffffffff1660e01b8152600401610bc29291906117ca565b600060405180830381600087803b158015610bdc57600080fd5b505af1158015610bf0573d6000803e3d6000fd5b505050508360a001516001600160a01b031663ace88afd8484846040518463ffffffff1660e01b8152600401610c28939291906117ec565b600060405180830381600087803b158015610c4257600080fd5b505af1158015610c56573d6000803e3d6000fd5b5050505050505050565b83608001516001600160a01b03166332608039836040518263ffffffff1660e01b8152600401610c9091906118b9565b60206040518083038186803b158015610ca857600080fd5b505afa158015610cbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ce0919081019061132b565b6001600160a01b031663867904b484836040518363ffffffff1660e01b8152600401610d0d9291906117ca565b600060405180830381600087803b158015610d2757600080fd5b505af1158015610d3b573d6000803e3d6000fd5b505050508360a001516001600160a01b0316636f01a9868484846040518463ffffffff1660e01b8152600401610c28939291906117ec565b610d7b611097565b6000806000806000806000808c6001600160a01b03166315987eb68d8d8d6040518463ffffffff1660e01b8152600401610db7939291906117ec565b6101006040518083038186803b158015610dd057600080fd5b505afa158015610de4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e0891908101906111fc565b60408051610100810182529889526020890197909752958701949094526060860192909252608085015260a084015260c083015260e08201529d9c50505050505050505050505050565b815160c083015160a084015160405163084f235160e11b815260009384936001600160a01b0389169363109e46a293610e929392919089906004016119f2565b60206040518083038186803b158015610eaa57600080fd5b505afa158015610ebe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ee291908101906114d7565b60408086015160e087015160a0880151925163084f235160e11b81529395506001600160a01b0389169363109e46a293610f2293929189906004016119f2565b60206040518083038186803b158015610f3a57600080fd5b505afa158015610f4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f7291908101906114d7565b9050935093915050565b6000610ae461100183732ad7ccaac0eeb396c3a5fc2b73a885435688c0d563907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015610fc957600080fd5b505af4158015610fdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ad891908101906114d7565b849063ffffffff61103316565b600082820183811015610ae45760405162461bcd60e51b815260040161041290611a30565b6000670de0b6b3a764000061104e848463ffffffff61105d16565b8161105557fe5b049392505050565b60008261106c57506000610ae7565b8282028284828161107957fe5b0414610ae45760405162461bcd60e51b815260040161041290611a50565b60405180610100016040528060008019168152602001600081526020016000801916815260200160008152602001600081526020016000815260200160008152602001600081525090565b8035610ae781611b2a565b8035610ae781611b41565b8051610ae781611b41565b8035610ae781611b4a565b8051610ae781611b4a565b8035610ae781611b53565b8051610ae781611b53565b600060c0828403121561114157600080fd5b50919050565b600060c0828403121561115957600080fd5b61116360c0611ac6565b905060006111718484611119565b825250602061118284848301611119565b602083015250604061119684828501611119565b60408301525060606111aa84828501611119565b60608301525060806111be84828501611119565b60808301525060a06111d284828501611119565b60a08301525092915050565b6000602082840312156111f057600080fd5b60006101e184846110f8565b600080600080600080600080610100898b03121561121957600080fd5b60006112258b8b61110e565b98505060206112368b828c0161110e565b97505060406112478b828c0161110e565b96505060606112588b828c0161110e565b95505060806112698b828c0161110e565b94505060a061127a8b828c0161110e565b93505060c061128b8b828c0161110e565b92505060e061129c8b828c0161110e565b9150509295985092959890939650565b6000602082840312156112be57600080fd5b60006101e18484611119565b600080600080608085870312156112e057600080fd5b60006112ec8787611119565b94505060206112fd878288016110e2565b935050604061130e87828801611103565b925050606061131f87828801611103565b91505092959194509250565b60006020828403121561133d57600080fd5b60006101e18484611124565b6000806000806000610140868803121561136257600080fd5b600061136e888861112f565b95505060c061137f888289016110e2565b94505060e061139088828901611103565b9350506101006113a2888289016110ed565b9250506101206113b488828901611103565b9150509295509295909350565b60008060008061012085870312156113d857600080fd5b60006113e4878761112f565b94505060c06113f5878288016110e2565b93505060e061140687828801611103565b92505061010061131f87828801611103565b6000806000806000806000610180888a03121561143457600080fd5b60006114408a8a61112f565b97505060c06114518a828b016110e2565b96505060e06114628a828b01611103565b9550506101006114748a828b01611103565b9450506101206114868a828b01611103565b9350506101406114988a828b01611103565b9250506101606114aa8a828b01611103565b91505092959891949750929550565b600060c082840312156114cb57600080fd5b60006101e18484611147565b6000602082840312156114e957600080fd5b60006101e1848461110e565b60008060006060848603121561150a57600080fd5b6000611516868661110e565b93505060206115278682870161110e565b92505060406115388682870161110e565b9150509250925092565b600061154e838361162a565b505060200190565b6000611562838361172d565b50506101000190565b61157481611b00565b82525050565b600061158582611af3565b61158f8185611af7565b935061159a83611aed565b8060005b838110156115c85781516115b28882611542565b97506115bd83611aed565b92505060010161159e565b509495945050505050565b60006115de82611af3565b6115e88185611af7565b93506115f383611aed565b8060005b838110156115c857815161160b8882611556565b975061161683611aed565b9250506001016115f7565b61157481611b0b565b61157481611b10565b6000611640601b83611af7565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000611679601e83611af7565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b60006116b2602183611af7565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b60006116f5602383611af7565b7f43616e6e6f7420736574746c6520647572696e672077616974696e67207065728152621a5bd960ea1b602082015260400192915050565b805161010083019061173f848261162a565b506020820151611752602085018261162a565b506040820151611765604085018261162a565b506060820151611778606085018261162a565b50608082015161178b608085018261162a565b5060a082015161179e60a085018261162a565b5060c08201516117b160c085018261162a565b5060e08201516117c460e085018261162a565b50505050565b604081016117d8828561156b565b6117e5602083018461162a565b9392505050565b606081016117fa828661156b565b611807602083018561162a565b6101e1604083018461162a565b6101208101611823828c61156b565b611830602083018b61162a565b61183d604083018a61162a565b61184a606083018961162a565b611857608083018861162a565b61186460a083018761162a565b61187160c083018661162a565b61187e60e083018561162a565b61188c61010083018461162a565b9a9950505050505050505050565b60208082528101610ae4818461157a565b60208101610ae78284611621565b60208101610ae7828461162a565b60a081016118d5828861162a565b6118e2602083018761162a565b6118ef604083018661162a565b6118fc606083018561162a565b611909608083018461162a565b9695505050505050565b60e08101611921828a61162a565b61192e602083018961162a565b61193b604083018861162a565b611948606083018761162a565b611955608083018661162a565b61196260a083018561162a565b61196f60c083018461162a565b98975050505050505050565b610100810161198a828b61162a565b611997602083018a61162a565b6119a4604083018961162a565b6119b1606083018861162a565b6119be608083018761162a565b6119cb60a083018661162a565b6119d860c083018561162a565b6119e560e083018461162a565b9998505050505050505050565b60808101611a00828761162a565b611a0d602083018661162a565b611a1a604083018561162a565b611a27606083018461162a565b95945050505050565b60208082528101610ae781611633565b60208082528101610ae78161166c565b60208082528101610ae7816116a5565b60208082528101610ae7816116e8565b604081016117d8828561162a565b606081016117fa828661162a565b60808101611a9a828761162a565b611aa7602083018661162a565b611ab4604083018561162a565b818103606083015261190981846115d3565b60405181810167ffffffffffffffff81118282101715611ae557600080fd5b604052919050565b60200190565b5190565b90815260200190565b6000610ae782611b1e565b151590565b90565b6000610ae782611b00565b6001600160a01b031690565b611b3381611b00565b8114611b3e57600080fd5b50565b611b3381611b0b565b611b3381611b10565b611b3381611b1356fea365627a7a7231582017d7c7bc315fbd2b924ce48c9a9309a773e584250f7eb0dc4fa27bc7f6487e7d6c6578706572696d656e74616cf564736f6c63430005100040
Deployed Bytecode
0x733f60ffaef1ebd84e3c2d0c9c0e12388365d5df1230146080604052600436106100615760003560e01c80630a0ecd1b14610066578063291be93d146100925780632f2de902146100b257806377cd29a5146100d45780638317e96b14610103575b600080fd5b6100796100743660046113c1565b610123565b6040516100899493929190611a8c565b60405180910390f35b6100a56100a03660046112ca565b610155565b60405161008991906118b9565b8180156100be57600080fd5b506100d26100cd366004611418565b6101e9565b005b8180156100e057600080fd5b506100f46100ef366004611349565b6103d9565b60405161008993929190611a7e565b6101166101113660046113c1565b610712565b60405161008991906118ab565b60008080606061014361013b368a90038a018a6114b9565b888888610764565b929b919a509850909650945050505050565b60006101de856001600160a01b031663f1406dc886866040518363ffffffff1660e01b81526004016101889291906117ca565b60206040518083038186803b1580156101a057600080fd5b505afa1580156101b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506101d891908101906114d7565b83610a99565b90505b949350505050565b60006101fb6040890160208a016112ac565b6001600160a01b0316637a018a1e876040518263ffffffff1660e01b815260040161022691906118b9565b60206040518083038186803b15801561023e57600080fd5b505afa158015610252573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061027691908101906114d7565b9050600061028a60408a0160208b016112ac565b6001600160a01b0316637a018a1e866040518263ffffffff1660e01b81526004016102b591906118b9565b60206040518083038186803b1580156102cd57600080fd5b505afa1580156102e1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061030591908101906114d7565b905061031460208a018a6112ac565b6001600160a01b0316633ca9d85c898989898989428a8a6040518a63ffffffff1660e01b815260040161034f99989796959493929190611814565b600060405180830381600087803b15801561036957600080fd5b505af115801561037d573d6000803e3d6000fd5b50505050876001600160a01b03167f62e40d554c7abcdd31074960d8347a2225daeb04d93bc748f049ba2ce9462398888888888888886040516103c69796959493929190611913565b60405180910390a2505050505050505050565b600080806103f56103ed60208a018a6112ac565b888887610155565b1561041b5760405162461bcd60e51b815260040161041290611a60565b60405180910390fd5b60008080606061043b610433368e90038e018e6114b9565b8c8c8b610764565b93509350935093508284111561047c5761045b848463ffffffff610aed16565b965061047761046f368e90038e018e6114b9565b8c8c8a610b15565b6104b0565b838311156104b057610494838563ffffffff610aed16565b95506104b06104a8368e90038e018e6114b9565b8c8c89610c60565b8880156104c7575060008711806104c75750600086115b1561057657604080516001808252818301909252606091602080830190803883390190505090508a816000815181106104fc57fe5b602090810291909101015261051760808e0160608f016112ac565b6001600160a01b031663cda218c7826040518263ffffffff1660e01b8152600401610542919061189a565b600060405180830381600087803b15801561055c57600080fd5b505af1158015610570573d6000803e3d6000fd5b50505050505b60005b8151811015610691578b6001600160a01b03167f8e3ad1f68bec55de3b6fa12ae2674a2a683a17c918a4cbf5157ac5d9ddc6e9408383815181106105b957fe5b6020026020010151600001518484815181106105d157fe5b6020026020010151602001518585815181106105e957fe5b60200260200101516040015186868151811061060157fe5b60200260200101516060015187878151811061061957fe5b60200260200101516080015188888151811061063157fe5b602002602001015160a0015189898151811061064957fe5b602002602001015160c001518a8a8151811061066157fe5b602002602001015160e0015160405161068198979695949392919061197b565b60405180910390a2600101610579565b5090935083906106a460208d018d6112ac565b6001600160a01b031663d0d3d62a8c8c6040518363ffffffff1660e01b81526004016106d19291906117ca565b600060405180830381600087803b1580156106eb57600080fd5b505af11580156106ff573d6000803e3d6000fd5b5050505050505050955095509592505050565b600061072c61072460208701876112ac565b858585610155565b15610739575060016101e1565b600061075561074d368890038801886114b9565b868686610764565b50505015159695505050505050565b6000806000606087600001516001600160a01b031663b44e975388886040518363ffffffff1660e01b815260040161079d9291906117ca565b60206040518083038186803b1580156107b557600080fd5b505afa1580156107c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107ed91908101906114d7565b915060608260405190808252806020026020018201604052801561082b57816020015b610818611097565b8152602001906001900390816108105790505b50905060005b83811015610a8b57610841611097565b8a5161084f908b8b85610d73565b90506000806108638d60200151848c610e52565b915091506000808e602001516001600160a01b0316636ce66c8086600001518760200151886040015188886040518663ffffffff1660e01b81526004016108ae9594939291906118c7565b60606040518083038186803b1580156108c657600080fd5b505afa1580156108da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108fe91908101906114f5565b50509050610910818660800151610f7c565b91505060008e604001516001600160a01b03166378cb51cb8660600151846040518363ffffffff1660e01b815260040161094b929190611a70565b60206040518083038186803b15801561096357600080fd5b505afa158015610977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061099b91908101906111de565b905060008082610a165783876060015111156109df5760608701516109c6908563ffffffff610aed16565b91506109d88d8363ffffffff61100e16565b9c50610a16565b8660600151841115610a16576060870151610a0190859063ffffffff610aed16565b9050610a138c8263ffffffff61100e16565b9b505b6040518061010001604052808860000151815260200188602001518152602001886040015181526020018381526020018281526020018781526020018681526020018860a00151815250898981518110610a6c57fe5b6020026020010181905250505050505050508080600101915050610831565b509050945094509450949050565b6000821580610ab75750610ab3838363ffffffff61100e16565b4210155b15610ac457506000610ae7565b610ae442610ad8858563ffffffff61100e16565b9063ffffffff610aed16565b90505b92915050565b600082821115610b0f5760405162461bcd60e51b815260040161041290611a40565b50900390565b83608001516001600160a01b03166332608039836040518263ffffffff1660e01b8152600401610b4591906118b9565b60206040518083038186803b158015610b5d57600080fd5b505afa158015610b71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b95919081019061132b565b6001600160a01b0316639dc29fac84836040518363ffffffff1660e01b8152600401610bc29291906117ca565b600060405180830381600087803b158015610bdc57600080fd5b505af1158015610bf0573d6000803e3d6000fd5b505050508360a001516001600160a01b031663ace88afd8484846040518463ffffffff1660e01b8152600401610c28939291906117ec565b600060405180830381600087803b158015610c4257600080fd5b505af1158015610c56573d6000803e3d6000fd5b5050505050505050565b83608001516001600160a01b03166332608039836040518263ffffffff1660e01b8152600401610c9091906118b9565b60206040518083038186803b158015610ca857600080fd5b505afa158015610cbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ce0919081019061132b565b6001600160a01b031663867904b484836040518363ffffffff1660e01b8152600401610d0d9291906117ca565b600060405180830381600087803b158015610d2757600080fd5b505af1158015610d3b573d6000803e3d6000fd5b505050508360a001516001600160a01b0316636f01a9868484846040518463ffffffff1660e01b8152600401610c28939291906117ec565b610d7b611097565b6000806000806000806000808c6001600160a01b03166315987eb68d8d8d6040518463ffffffff1660e01b8152600401610db7939291906117ec565b6101006040518083038186803b158015610dd057600080fd5b505afa158015610de4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e0891908101906111fc565b60408051610100810182529889526020890197909752958701949094526060860192909252608085015260a084015260c083015260e08201529d9c50505050505050505050505050565b815160c083015160a084015160405163084f235160e11b815260009384936001600160a01b0389169363109e46a293610e929392919089906004016119f2565b60206040518083038186803b158015610eaa57600080fd5b505afa158015610ebe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ee291908101906114d7565b60408086015160e087015160a0880151925163084f235160e11b81529395506001600160a01b0389169363109e46a293610f2293929189906004016119f2565b60206040518083038186803b158015610f3a57600080fd5b505afa158015610f4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f7291908101906114d7565b9050935093915050565b6000610ae461100183732ad7ccaac0eeb396c3a5fc2b73a885435688c0d563907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015610fc957600080fd5b505af4158015610fdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ad891908101906114d7565b849063ffffffff61103316565b600082820183811015610ae45760405162461bcd60e51b815260040161041290611a30565b6000670de0b6b3a764000061104e848463ffffffff61105d16565b8161105557fe5b049392505050565b60008261106c57506000610ae7565b8282028284828161107957fe5b0414610ae45760405162461bcd60e51b815260040161041290611a50565b60405180610100016040528060008019168152602001600081526020016000801916815260200160008152602001600081526020016000815260200160008152602001600081525090565b8035610ae781611b2a565b8035610ae781611b41565b8051610ae781611b41565b8035610ae781611b4a565b8051610ae781611b4a565b8035610ae781611b53565b8051610ae781611b53565b600060c0828403121561114157600080fd5b50919050565b600060c0828403121561115957600080fd5b61116360c0611ac6565b905060006111718484611119565b825250602061118284848301611119565b602083015250604061119684828501611119565b60408301525060606111aa84828501611119565b60608301525060806111be84828501611119565b60808301525060a06111d284828501611119565b60a08301525092915050565b6000602082840312156111f057600080fd5b60006101e184846110f8565b600080600080600080600080610100898b03121561121957600080fd5b60006112258b8b61110e565b98505060206112368b828c0161110e565b97505060406112478b828c0161110e565b96505060606112588b828c0161110e565b95505060806112698b828c0161110e565b94505060a061127a8b828c0161110e565b93505060c061128b8b828c0161110e565b92505060e061129c8b828c0161110e565b9150509295985092959890939650565b6000602082840312156112be57600080fd5b60006101e18484611119565b600080600080608085870312156112e057600080fd5b60006112ec8787611119565b94505060206112fd878288016110e2565b935050604061130e87828801611103565b925050606061131f87828801611103565b91505092959194509250565b60006020828403121561133d57600080fd5b60006101e18484611124565b6000806000806000610140868803121561136257600080fd5b600061136e888861112f565b95505060c061137f888289016110e2565b94505060e061139088828901611103565b9350506101006113a2888289016110ed565b9250506101206113b488828901611103565b9150509295509295909350565b60008060008061012085870312156113d857600080fd5b60006113e4878761112f565b94505060c06113f5878288016110e2565b93505060e061140687828801611103565b92505061010061131f87828801611103565b6000806000806000806000610180888a03121561143457600080fd5b60006114408a8a61112f565b97505060c06114518a828b016110e2565b96505060e06114628a828b01611103565b9550506101006114748a828b01611103565b9450506101206114868a828b01611103565b9350506101406114988a828b01611103565b9250506101606114aa8a828b01611103565b91505092959891949750929550565b600060c082840312156114cb57600080fd5b60006101e18484611147565b6000602082840312156114e957600080fd5b60006101e1848461110e565b60008060006060848603121561150a57600080fd5b6000611516868661110e565b93505060206115278682870161110e565b92505060406115388682870161110e565b9150509250925092565b600061154e838361162a565b505060200190565b6000611562838361172d565b50506101000190565b61157481611b00565b82525050565b600061158582611af3565b61158f8185611af7565b935061159a83611aed565b8060005b838110156115c85781516115b28882611542565b97506115bd83611aed565b92505060010161159e565b509495945050505050565b60006115de82611af3565b6115e88185611af7565b93506115f383611aed565b8060005b838110156115c857815161160b8882611556565b975061161683611aed565b9250506001016115f7565b61157481611b0b565b61157481611b10565b6000611640601b83611af7565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000611679601e83611af7565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b60006116b2602183611af7565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b60006116f5602383611af7565b7f43616e6e6f7420736574746c6520647572696e672077616974696e67207065728152621a5bd960ea1b602082015260400192915050565b805161010083019061173f848261162a565b506020820151611752602085018261162a565b506040820151611765604085018261162a565b506060820151611778606085018261162a565b50608082015161178b608085018261162a565b5060a082015161179e60a085018261162a565b5060c08201516117b160c085018261162a565b5060e08201516117c460e085018261162a565b50505050565b604081016117d8828561156b565b6117e5602083018461162a565b9392505050565b606081016117fa828661156b565b611807602083018561162a565b6101e1604083018461162a565b6101208101611823828c61156b565b611830602083018b61162a565b61183d604083018a61162a565b61184a606083018961162a565b611857608083018861162a565b61186460a083018761162a565b61187160c083018661162a565b61187e60e083018561162a565b61188c61010083018461162a565b9a9950505050505050505050565b60208082528101610ae4818461157a565b60208101610ae78284611621565b60208101610ae7828461162a565b60a081016118d5828861162a565b6118e2602083018761162a565b6118ef604083018661162a565b6118fc606083018561162a565b611909608083018461162a565b9695505050505050565b60e08101611921828a61162a565b61192e602083018961162a565b61193b604083018861162a565b611948606083018761162a565b611955608083018661162a565b61196260a083018561162a565b61196f60c083018461162a565b98975050505050505050565b610100810161198a828b61162a565b611997602083018a61162a565b6119a4604083018961162a565b6119b1606083018861162a565b6119be608083018761162a565b6119cb60a083018661162a565b6119d860c083018561162a565b6119e560e083018461162a565b9998505050505050505050565b60808101611a00828761162a565b611a0d602083018661162a565b611a1a604083018561162a565b611a27606083018461162a565b95945050505050565b60208082528101610ae781611633565b60208082528101610ae78161166c565b60208082528101610ae7816116a5565b60208082528101610ae7816116e8565b604081016117d8828561162a565b606081016117fa828661162a565b60808101611a9a828761162a565b611aa7602083018661162a565b611ab4604083018561162a565b818103606083015261190981846115d3565b60405181810167ffffffffffffffff81118282101715611ae557600080fd5b604052919050565b60200190565b5190565b90815260200190565b6000610ae782611b1e565b151590565b90565b6000610ae782611b00565b6001600160a01b031690565b611b3381611b00565b8114611b3e57600080fd5b50565b611b3381611b0b565b611b3381611b10565b611b3381611b1356fea365627a7a7231582017d7c7bc315fbd2b924ce48c9a9309a773e584250f7eb0dc4fa27bc7f6487e7d6c6578706572696d656e74616cf564736f6c63430005100040
Library Used
SafeDecimalMath : 0x2ad7ccaac0eeb396c3a5fc2b73a885435688c0d5SystemSettingsLib : 0x343b5efcbf331957d3f4236eb16c338d7256f62dSignedSafeDecimalMath : 0xc7dcc0929881530d3386de51d9ffdd35b8009c6eExchangeSettlementLib : 0x3f60ffaef1ebd84e3c2d0c9c0e12388365d5df12
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.