More Info
Private Name Tags
ContractCreator
GENESIS at txn GENESIS_ad32aa4bff8b61b4ae07e3ba437cf81100af0cd7
Latest 25 from a total of 632 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Burn | 70149072 | 681 days ago | IN | 0 ETH | 0.000320904464 | ||||
Burn | 67929661 | 689 days ago | IN | 0 ETH | 0.00006517682 | ||||
Burn | 58539285 | 705 days ago | IN | 0 ETH | 0.000056088927 | ||||
Burn | 58536947 | 705 days ago | IN | 0 ETH | 0.000054417442 | ||||
Burn | 56091931 | 709 days ago | IN | 0 ETH | 0.000044286407 | ||||
Mint | 53038058 | 715 days ago | IN | 0 ETH | 0.000051748627 | ||||
Mint | 53036863 | 715 days ago | IN | 0 ETH | 0.000052202064 | ||||
Mint | 52998562 | 715 days ago | IN | 0 ETH | 0.000078709449 | ||||
Mint | 52998252 | 715 days ago | IN | 0 ETH | 0.000075308638 | ||||
Mint | 52996280 | 715 days ago | IN | 0 ETH | 0.000061382029 | ||||
Mint | 52994737 | 715 days ago | IN | 0 ETH | 0.000076194422 | ||||
Burn | 52991961 | 715 days ago | IN | 0 ETH | 0.000058439386 | ||||
Mint | 52723755 | 716 days ago | IN | 0 ETH | 0.000062592059 | ||||
Accept Ownership | 52723443 | 716 days ago | IN | 0 ETH | 0.000059033692 | ||||
Mint | 52707675 | 716 days ago | IN | 0 ETH | 0.000054688943 | ||||
Mint | 52691871 | 716 days ago | IN | 0 ETH | 0.00005503796 | ||||
Mint | 52612785 | 716 days ago | IN | 0 ETH | 0.000044134046 | ||||
Nominate New Own... | 1197859 | 1087 days ago | IN | 0 ETH | 0.000349422887 | ||||
Burn | 886627 | 1094 days ago | IN | 0 ETH | 0.0003854598 | ||||
Burn | 867796 | 1095 days ago | IN | 0 ETH | 0.000644224126 | ||||
Burn | 852704 | 1095 days ago | IN | 0 ETH | 0.000705692131 | ||||
Burn | 852440 | 1095 days ago | IN | 0 ETH | 0.000608452815 | ||||
Mint | 555001 | 1103 days ago | IN | 0 ETH | 0.000449182244 | ||||
Mint | 490003 | 1105 days ago | IN | 0 ETH | 0.000676583634 | ||||
Mint | 489976 | 1105 days ago | IN | 0 ETH | 0.000608770264 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
107538710 | 495 days ago | 0 ETH | ||||
107538710 | 495 days ago | 0 ETH | ||||
107538710 | 495 days ago | 0 ETH | ||||
107538710 | 495 days ago | 0 ETH | ||||
107538710 | 495 days ago | 0 ETH | ||||
107538710 | 495 days ago | 0 ETH | ||||
107538710 | 495 days ago | 0 ETH | ||||
107538710 | 495 days ago | 0 ETH | ||||
107538710 | 495 days ago | 0 ETH | ||||
107538710 | 495 days ago | 0 ETH | ||||
107538710 | 495 days ago | 0 ETH | ||||
107538710 | 495 days ago | 0 ETH | ||||
107538710 | 495 days ago | 0 ETH | ||||
107538710 | 495 days ago | 0 ETH | ||||
107451323 | 497 days ago | 0 ETH | ||||
107451323 | 497 days ago | 0 ETH | ||||
107451323 | 497 days ago | 0 ETH | ||||
107451323 | 497 days ago | 0 ETH | ||||
107451323 | 497 days ago | 0 ETH | ||||
107451323 | 497 days ago | 0 ETH | ||||
107451323 | 497 days ago | 0 ETH | ||||
107451323 | 497 days ago | 0 ETH | ||||
107451323 | 497 days ago | 0 ETH | ||||
107451323 | 497 days ago | 0 ETH | ||||
107451323 | 497 days ago | 0 ETH |
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:
Wrapper
Compiler Version
v0.5.16+commit.9c3226ce
Contract Source Code (Solidity)
/** *Submitted for verification at optimistic.etherscan.io on 2021-11-15 */ /** *Submitted for verification at optimistic.etherscan.io on 2021-10-28 */ /* ____ __ __ __ _ / __/__ __ ___ / /_ / / ___ / /_ (_)__ __ _\ \ / // // _ \/ __// _ \/ -_)/ __// / \ \ / /___/ \_, //_//_/\__//_//_/\__/ \__//_/ /_\_\ /___/ * Synthetix: Wrapper.sol * * Latest source (may be newer): https://github.com/Synthetixio/synthetix/blob/master/contracts/Wrapper.sol * Docs: https://docs.synthetix.io/contracts/Wrapper * * Contract Dependencies: * - IAddressResolver * - IWrapper * - MixinResolver * - MixinSystemSettings * - Owned * - Pausable * Libraries: * - SafeDecimalMath * - SafeMath * * MIT License * =========== * * Copyright (c) 2021 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/ierc20 interface IERC20 { // ERC20 Optional Views function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); // Views function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); // Mutative functions function transfer(address to, uint value) external returns (bool); function approve(address spender, uint value) external returns (bool); function transferFrom( address from, address to, uint value ) external returns (bool); // Events event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); } // https://docs.synthetix.io/contracts/source/interfaces/iwrapper interface IWrapper { function mint(uint amount) external; function burn(uint amount) external; function capacity() external view returns (uint); function totalIssuedSynths() external view returns (uint); function calculateMintFee(uint amount) external view returns (uint, bool); function calculateBurnFee(uint amount) external view returns (uint, bool); function maxTokenAmount() external view returns (uint256); function mintFeeRate() external view returns (int256); function burnFeeRate() external view returns (int256); } // 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; } // Inheritance // https://docs.synthetix.io/contracts/source/contracts/pausable contract Pausable is Owned { uint public lastPauseTime; bool public paused; constructor() internal { // This contract is abstract, and thus cannot be instantiated directly require(owner != address(0), "Owner must be set"); // Paused will be false, and lastPauseTime will be 0 upon initialisation } /** * @notice Change the paused state of the contract * @dev Only the contract owner may call this. */ function setPaused(bool _paused) external onlyOwner { // Ensure we're actually changing the state before we do anything if (_paused == paused) { return; } // Set our paused state. paused = _paused; // If applicable, set the last pause time. if (paused) { lastPauseTime = now; } // Let everyone know that our pause state has changed. emit PauseChanged(paused); } event PauseChanged(bool isPaused); modifier notPaused { require(!paused, "This action cannot be performed while the contract is paused"); _; } } // 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; } 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, 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 ); // 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; } // 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 requireExchangeBetweenSynthsAllowed(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) external view; function requireSynthActive(bytes32 currencyKey) external view; function requireSynthsActive(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) external view; function systemSuspension() external view returns (bool suspended, uint248 reason); function issuanceSuspension() external view returns (bool suspended, uint248 reason); function exchangeSuspension() external view returns (bool suspended, uint248 reason); function synthExchangeSuspension(bytes32 currencyKey) external view returns (bool suspended, uint248 reason); function synthSuspension(bytes32 currencyKey) external view returns (bool suspended, uint248 reason); function getSynthExchangeSuspensions(bytes32[] calldata synths) external view returns (bool[] memory exchangeSuspensions, uint256[] memory reasons); function getSynthSuspensions(bytes32[] calldata synths) external view returns (bool[] memory suspensions, uint256[] memory reasons); // 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/iwrapperfactory interface IWrapperFactory { function isWrapper(address possibleWrapper) external view returns (bool); function createWrapper( IERC20 token, bytes32 currencyKey, bytes32 synthContractName ) external returns (address); function distributeFees() external; } // https://docs.synthetix.io/contracts/source/interfaces/iissuer interface IIssuer { // Views function anySynthOrSNXRateIsInvalid() external view returns (bool anyRateInvalid); function availableCurrencyKeys() external view returns (bytes32[] memory); function availableSynthCount() external view returns (uint); function availableSynths(uint index) external view returns (ISynth); function canBurnSynths(address account) external view returns (bool); function collateral(address account) external view returns (uint); function collateralisationRatio(address issuer) external view returns (uint); function collateralisationRatioAndAnyRatesInvalid(address _issuer) external view returns (uint cratio, bool anyRateIsInvalid); function debtBalanceOf(address issuer, bytes32 currencyKey) external view returns (uint debtBalance); function issuanceRatio() external view returns (uint); function lastIssueEvent(address account) external view returns (uint); function maxIssuableSynths(address issuer) external view returns (uint maxIssuable); function minimumStakeTime() external view returns (uint); function remainingIssuableSynths(address issuer) external view returns ( uint maxIssuable, uint alreadyIssued, uint totalSystemDebt ); function synths(bytes32 currencyKey) external view returns (ISynth); function getSynths(bytes32[] calldata currencyKeys) external view returns (ISynth[] memory); function synthsByAddress(address synthAddress) external view returns (bytes32); function totalIssuedSynths(bytes32 currencyKey, bool excludeOtherCollateral) external view returns (uint); function transferableSynthetixAndAnyRateIsInvalid(address account, uint balance) external view returns (uint transferable, bool anyRateIsInvalid); // Restricted: used internally to Synthetix function issueSynths(address from, uint amount) external; function issueSynthsOnBehalf( address issueFor, address from, uint amount ) external; function issueMaxSynths(address from) external; function issueMaxSynthsOnBehalf(address issueFor, address from) external; function burnSynths(address from, uint amount) external; function burnSynthsOnBehalf( address burnForAddress, address from, uint amount ) external; function burnSynthsToTarget(address from) external; function burnSynthsToTargetOnBehalf(address burnForAddress, address from) external; function burnForRedemption( address deprecatedSynthProxy, address account, uint balance ) external; function liquidateDelinquentAccount( address account, uint susdAmount, address liquidator ) external returns (uint totalRedeemed, uint amountToLiquidate); } // Inheritance // Internal references // https://docs.synthetix.io/contracts/source/contracts/addressresolver contract AddressResolver is Owned, IAddressResolver { mapping(bytes32 => address) public repository; constructor(address _owner) public Owned(_owner) {} /* ========== RESTRICTED FUNCTIONS ========== */ function importAddresses(bytes32[] calldata names, address[] calldata destinations) external onlyOwner { require(names.length == destinations.length, "Input lengths must match"); for (uint i = 0; i < names.length; i++) { bytes32 name = names[i]; address destination = destinations[i]; repository[name] = destination; emit AddressImported(name, destination); } } /* ========= PUBLIC FUNCTIONS ========== */ function rebuildCaches(MixinResolver[] calldata destinations) external { for (uint i = 0; i < destinations.length; i++) { destinations[i].rebuildCache(); } } /* ========== VIEWS ========== */ function areAddressesImported(bytes32[] calldata names, address[] calldata destinations) external view returns (bool) { for (uint i = 0; i < names.length; i++) { if (repository[names[i]] != destinations[i]) { return false; } } return true; } function getAddress(bytes32 name) external view returns (address) { return repository[name]; } function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address) { address _foundAddress = repository[name]; require(_foundAddress != address(0), reason); return _foundAddress; } function getSynth(bytes32 key) external view returns (address) { IIssuer issuer = IIssuer(repository["Issuer"]); require(address(issuer) != address(0), "Cannot find Issuer address"); return address(issuer.synths(key)); } /* ========== EVENTS ========== */ event AddressImported(bytes32 name, address destination); } // Internal references // https://docs.synthetix.io/contracts/source/contracts/mixinresolver contract MixinResolver { AddressResolver public resolver; mapping(bytes32 => address) private addressCache; constructor(address _resolver) internal { resolver = AddressResolver(_resolver); } /* ========== INTERNAL FUNCTIONS ========== */ function combineArrays(bytes32[] memory first, bytes32[] memory second) internal pure returns (bytes32[] memory combination) { combination = new bytes32[](first.length + second.length); for (uint i = 0; i < first.length; i++) { combination[i] = first[i]; } for (uint j = 0; j < second.length; j++) { combination[first.length + j] = second[j]; } } /* ========== PUBLIC FUNCTIONS ========== */ // Note: this function is public not external in order for it to be overridden and invoked via super in subclasses function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {} function rebuildCache() public { bytes32[] memory requiredAddresses = resolverAddressesRequired(); // The resolver must call this function whenver it updates its state for (uint i = 0; i < requiredAddresses.length; i++) { bytes32 name = requiredAddresses[i]; // Note: can only be invoked once the resolver has all the targets needed added address destination = resolver.requireAndGetAddress(name, string(abi.encodePacked("Resolver missing target: ", name))); addressCache[name] = destination; emit CacheUpdated(name, destination); } } /* ========== VIEWS ========== */ function isResolverCached() external view returns (bool) { bytes32[] memory requiredAddresses = resolverAddressesRequired(); for (uint i = 0; i < requiredAddresses.length; i++) { bytes32 name = requiredAddresses[i]; // false if our cache is invalid or if the resolver doesn't have the required address if (resolver.getAddress(name) != addressCache[name] || addressCache[name] == address(0)) { return false; } } return true; } /* ========== INTERNAL FUNCTIONS ========== */ function requireAndGetAddress(bytes32 name) internal view returns (address) { address _foundAddress = addressCache[name]; require(_foundAddress != address(0), string(abi.encodePacked("Missing address: ", name))); return _foundAddress; } /* ========== EVENTS ========== */ event CacheUpdated(bytes32 name, address destination); } // https://docs.synthetix.io/contracts/source/interfaces/iflexiblestorage interface IFlexibleStorage { // Views function getUIntValue(bytes32 contractName, bytes32 record) external view returns (uint); function getUIntValues(bytes32 contractName, bytes32[] calldata records) external view returns (uint[] memory); function getIntValue(bytes32 contractName, bytes32 record) external view returns (int); function getIntValues(bytes32 contractName, bytes32[] calldata records) external view returns (int[] memory); function getAddressValue(bytes32 contractName, bytes32 record) external view returns (address); function getAddressValues(bytes32 contractName, bytes32[] calldata records) external view returns (address[] memory); function getBoolValue(bytes32 contractName, bytes32 record) external view returns (bool); function getBoolValues(bytes32 contractName, bytes32[] calldata records) external view returns (bool[] memory); function getBytes32Value(bytes32 contractName, bytes32 record) external view returns (bytes32); function getBytes32Values(bytes32 contractName, bytes32[] calldata records) external view returns (bytes32[] memory); // Mutative functions function deleteUIntValue(bytes32 contractName, bytes32 record) external; function deleteIntValue(bytes32 contractName, bytes32 record) external; function deleteAddressValue(bytes32 contractName, bytes32 record) external; function deleteBoolValue(bytes32 contractName, bytes32 record) external; function deleteBytes32Value(bytes32 contractName, bytes32 record) external; function setUIntValue( bytes32 contractName, bytes32 record, uint value ) external; function setUIntValues( bytes32 contractName, bytes32[] calldata records, uint[] calldata values ) external; function setIntValue( bytes32 contractName, bytes32 record, int value ) external; function setIntValues( bytes32 contractName, bytes32[] calldata records, int[] calldata values ) external; function setAddressValue( bytes32 contractName, bytes32 record, address value ) external; function setAddressValues( bytes32 contractName, bytes32[] calldata records, address[] calldata values ) external; function setBoolValue( bytes32 contractName, bytes32 record, bool value ) external; function setBoolValues( bytes32 contractName, bytes32[] calldata records, bool[] calldata values ) external; function setBytes32Value( bytes32 contractName, bytes32 record, bytes32 value ) external; function setBytes32Values( bytes32 contractName, bytes32[] calldata records, bytes32[] calldata values ) external; } // Internal references // https://docs.synthetix.io/contracts/source/contracts/mixinsystemsettings contract MixinSystemSettings is MixinResolver { 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_DEPOSIT_GAS_LIMIT = "crossDomainDepositGasLimit"; bytes32 internal constant SETTING_CROSS_DOMAIN_ESCROW_GAS_LIMIT = "crossDomainEscrowGasLimit"; bytes32 internal constant SETTING_CROSS_DOMAIN_REWARD_GAS_LIMIT = "crossDomainRewardGasLimit"; bytes32 internal constant SETTING_CROSS_DOMAIN_WITHDRAWAL_GAS_LIMIT = "crossDomainWithdrawalGasLimit"; bytes32 internal constant SETTING_ETHER_WRAPPER_MAX_ETH = "etherWrapperMaxETH"; bytes32 internal constant SETTING_ETHER_WRAPPER_MINT_FEE_RATE = "etherWrapperMintFeeRate"; bytes32 internal constant SETTING_ETHER_WRAPPER_BURN_FEE_RATE = "etherWrapperBurnFeeRate"; bytes32 internal constant SETTING_WRAPPER_MAX_TOKEN_AMOUNT = "wrapperMaxTokens"; bytes32 internal constant SETTING_WRAPPER_MINT_FEE_RATE = "wrapperMintFeeRate"; bytes32 internal constant SETTING_WRAPPER_BURN_FEE_RATE = "wrapperBurnFeeRate"; bytes32 internal constant SETTING_MIN_CRATIO = "minCratio"; bytes32 internal constant SETTING_NEW_COLLATERAL_MANAGER = "newCollateralManager"; bytes32 internal constant SETTING_INTERACTION_DELAY = "interactionDelay"; bytes32 internal constant SETTING_COLLAPSE_FEE_RATE = "collapseFeeRate"; bytes32 internal constant CONTRACT_FLEXIBLESTORAGE = "FlexibleStorage"; enum CrossDomainMessageGasLimits {Deposit, Escrow, Reward, Withdrawal} constructor(address _resolver) internal MixinResolver(_resolver) {} function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { addresses = new bytes32[](1); addresses[0] = CONTRACT_FLEXIBLESTORAGE; } function flexibleStorage() internal view returns (IFlexibleStorage) { return IFlexibleStorage(requireAndGetAddress(CONTRACT_FLEXIBLESTORAGE)); } function _getGasLimitSetting(CrossDomainMessageGasLimits gasLimitType) internal pure returns (bytes32) { if (gasLimitType == CrossDomainMessageGasLimits.Deposit) { return SETTING_CROSS_DOMAIN_DEPOSIT_GAS_LIMIT; } else if (gasLimitType == CrossDomainMessageGasLimits.Escrow) { return SETTING_CROSS_DOMAIN_ESCROW_GAS_LIMIT; } else if (gasLimitType == CrossDomainMessageGasLimits.Reward) { return SETTING_CROSS_DOMAIN_REWARD_GAS_LIMIT; } else if (gasLimitType == CrossDomainMessageGasLimits.Withdrawal) { return SETTING_CROSS_DOMAIN_WITHDRAWAL_GAS_LIMIT; } else { revert("Unknown gas limit type"); } } function getCrossDomainMessageGasLimit(CrossDomainMessageGasLimits gasLimitType) internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, _getGasLimitSetting(gasLimitType)); } function getTradingRewardsEnabled() internal view returns (bool) { return flexibleStorage().getBoolValue(SETTING_CONTRACT_NAME, SETTING_TRADING_REWARDS_ENABLED); } function getWaitingPeriodSecs() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_WAITING_PERIOD_SECS); } function getPriceDeviationThresholdFactor() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_PRICE_DEVIATION_THRESHOLD_FACTOR); } function getIssuanceRatio() internal view returns (uint) { // lookup on flexible storage directly for gas savings (rather than via SystemSettings) return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ISSUANCE_RATIO); } function getFeePeriodDuration() internal view returns (uint) { // lookup on flexible storage directly for gas savings (rather than via SystemSettings) return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_FEE_PERIOD_DURATION); } function getTargetThreshold() internal view returns (uint) { // lookup on flexible storage directly for gas savings (rather than via SystemSettings) return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_TARGET_THRESHOLD); } function getLiquidationDelay() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_DELAY); } function getLiquidationRatio() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_RATIO); } function getLiquidationPenalty() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_PENALTY); } function getRateStalePeriod() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_RATE_STALE_PERIOD); } 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); } function getEtherWrapperMaxETH() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ETHER_WRAPPER_MAX_ETH); } function getEtherWrapperMintFeeRate() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ETHER_WRAPPER_MINT_FEE_RATE); } function getEtherWrapperBurnFeeRate() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ETHER_WRAPPER_BURN_FEE_RATE); } function getWrapperMaxTokenAmount(address wrapper) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_WRAPPER_MAX_TOKEN_AMOUNT, wrapper)) ); } function getWrapperMintFeeRate(address wrapper) internal view returns (int) { return flexibleStorage().getIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_WRAPPER_MINT_FEE_RATE, wrapper)) ); } function getWrapperBurnFeeRate(address wrapper) internal view returns (int) { return flexibleStorage().getIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_WRAPPER_BURN_FEE_RATE, wrapper)) ); } function getMinCratio(address collateral) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_MIN_CRATIO, collateral)) ); } function getNewCollateralManager(address collateral) internal view returns (address) { return flexibleStorage().getAddressValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_NEW_COLLATERAL_MANAGER, collateral)) ); } function getInteractionDelay(address collateral) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_INTERACTION_DELAY, collateral)) ); } function getCollapseFeeRate(address collateral) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_COLLAPSE_FEE_RATE, collateral)) ); } } /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // Libraries // https://docs.synthetix.io/contracts/source/libraries/safedecimalmath library SafeDecimalMath { using SafeMath for uint; /* Number of decimal places in the representations. */ uint8 public constant decimals = 18; uint8 public constant highPrecisionDecimals = 27; /* The number representing 1.0. */ uint public constant UNIT = 10**uint(decimals); /* The number representing 1.0 for higher fidelity numbers. */ uint public constant PRECISE_UNIT = 10**uint(highPrecisionDecimals); uint private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR = 10**uint(highPrecisionDecimals - decimals); /** * @return Provides an interface to UNIT. */ function unit() external pure returns (uint) { return UNIT; } /** * @return Provides an interface to PRECISE_UNIT. */ function preciseUnit() external pure returns (uint) { return PRECISE_UNIT; } /** * @return The result of multiplying x and y, interpreting the operands as fixed-point * decimals. * * @dev A unit factor is divided out after the product of x and y is evaluated, * so that product must be less than 2**256. As this is an integer division, * the internal division always rounds down. This helps save on gas. Rounding * is more expensive on gas. */ function multiplyDecimal(uint x, uint y) internal pure returns (uint) { /* Divide by UNIT to remove the extra factor introduced by the product. */ return x.mul(y) / UNIT; } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of the specified precision unit. * * @dev The operands should be in the form of a the specified unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function _multiplyDecimalRound( uint x, uint y, uint precisionUnit ) private pure returns (uint) { /* Divide by UNIT to remove the extra factor introduced by the product. */ uint quotientTimesTen = x.mul(y) / (precisionUnit / 10); if (quotientTimesTen % 10 >= 5) { quotientTimesTen += 10; } return quotientTimesTen / 10; } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of a precise unit. * * @dev The operands should be in the precise unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function multiplyDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) { return _multiplyDecimalRound(x, y, PRECISE_UNIT); } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of a standard unit. * * @dev The operands should be in the standard unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function multiplyDecimalRound(uint x, uint y) internal pure returns (uint) { return _multiplyDecimalRound(x, y, UNIT); } /** * @return The result of safely dividing x and y. The return value is a high * precision decimal. * * @dev y is divided after the product of x and the standard precision unit * is evaluated, so the product of x and UNIT must be less than 2**256. As * this is an integer division, the result is always rounded down. * This helps save on gas. Rounding is more expensive on gas. */ function divideDecimal(uint x, uint y) internal pure returns (uint) { /* Reintroduce the UNIT factor that will be divided out by y. */ return x.mul(UNIT).div(y); } /** * @return The result of safely dividing x and y. The return value is as a rounded * decimal in the precision unit specified in the parameter. * * @dev y is divided after the product of x and the specified precision unit * is evaluated, so the product of x and the specified precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function _divideDecimalRound( uint x, uint y, uint precisionUnit ) private pure returns (uint) { uint resultTimesTen = x.mul(precisionUnit * 10).div(y); if (resultTimesTen % 10 >= 5) { resultTimesTen += 10; } return resultTimesTen / 10; } /** * @return The result of safely dividing x and y. The return value is as a rounded * standard precision decimal. * * @dev y is divided after the product of x and the standard precision unit * is evaluated, so the product of x and the standard precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function divideDecimalRound(uint x, uint y) internal pure returns (uint) { return _divideDecimalRound(x, y, UNIT); } /** * @return The result of safely dividing x and y. The return value is as a rounded * high precision decimal. * * @dev y is divided after the product of x and the high precision unit * is evaluated, so the product of x and the high precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function divideDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) { return _divideDecimalRound(x, y, PRECISE_UNIT); } /** * @dev Convert a standard decimal representation to a high precision one. */ function decimalToPreciseDecimal(uint i) internal pure returns (uint) { return i.mul(UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR); } /** * @dev Convert a high precision decimal to a standard decimal representation. */ function preciseDecimalToDecimal(uint i) internal pure returns (uint) { uint quotientTimesTen = i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10); if (quotientTimesTen % 10 >= 5) { quotientTimesTen += 10; } return quotientTimesTen / 10; } // Computes `a - b`, setting the value to 0 if b > a. function floorsub(uint a, uint b) internal pure returns (uint) { return b >= a ? 0 : a - b; } /* ---------- Utilities ---------- */ /* * Absolute value of the input, returned as a signed number. */ function signedAbs(int x) internal pure returns (int) { return x < 0 ? -x : x; } /* * Absolute value of the input, returned as an unsigned number. */ function abs(int x) internal pure returns (uint) { return uint(signedAbs(x)); } } // Inheritance // Internal references // Libraries // https://docs.synthetix.io/contracts/source/contracts/wrapper contract Wrapper is Owned, Pausable, MixinResolver, MixinSystemSettings, IWrapper { using SafeMath for uint; using SafeDecimalMath for uint; /* ========== ENCODED NAMES ========== */ bytes32 internal constant sUSD = "sUSD"; /* ========== ADDRESS RESOLVER CONFIGURATION ========== */ bytes32 private constant CONTRACT_SYNTH_SUSD = "SynthsUSD"; bytes32 private constant CONTRACT_EXRATES = "ExchangeRates"; bytes32 private constant CONTRACT_DEBTCACHE = "DebtCache"; bytes32 private constant CONTRACT_SYSTEMSTATUS = "SystemStatus"; bytes32 private constant CONTRACT_WRAPPERFACTORY = "WrapperFactory"; // ========== STATE VARIABLES ========== // NOTE: these values should ideally be `immutable` instead of public IERC20 public token; bytes32 public currencyKey; bytes32 public synthContractName; uint public targetSynthIssued; constructor( address _owner, address _resolver, IERC20 _token, bytes32 _currencyKey, bytes32 _synthContractName ) public Owned(_owner) MixinSystemSettings(_resolver) { token = _token; currencyKey = _currencyKey; synthContractName = _synthContractName; targetSynthIssued = 0; token.approve(address(this), uint256(-1)); } /* ========== VIEWS ========== */ function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { bytes32[] memory existingAddresses = MixinSystemSettings.resolverAddressesRequired(); bytes32[] memory newAddresses = new bytes32[](6); newAddresses[0] = CONTRACT_SYNTH_SUSD; newAddresses[1] = synthContractName; newAddresses[2] = CONTRACT_EXRATES; newAddresses[3] = CONTRACT_DEBTCACHE; newAddresses[4] = CONTRACT_SYSTEMSTATUS; newAddresses[5] = CONTRACT_WRAPPERFACTORY; addresses = combineArrays(existingAddresses, newAddresses); return addresses; } /* ========== INTERNAL VIEWS ========== */ function synthsUSD() internal view returns (ISynth) { return ISynth(requireAndGetAddress(CONTRACT_SYNTH_SUSD)); } function synth() internal view returns (ISynth) { return ISynth(requireAndGetAddress(synthContractName)); } function exchangeRates() internal view returns (IExchangeRates) { return IExchangeRates(requireAndGetAddress(CONTRACT_EXRATES)); } function debtCache() internal view returns (IDebtCache) { return IDebtCache(requireAndGetAddress(CONTRACT_DEBTCACHE)); } function systemStatus() internal view returns (ISystemStatus) { return ISystemStatus(requireAndGetAddress(CONTRACT_SYSTEMSTATUS)); } function wrapperFactory() internal view returns (IWrapperFactory) { return IWrapperFactory(requireAndGetAddress(CONTRACT_WRAPPERFACTORY)); } /* ========== PUBLIC FUNCTIONS ========== */ // ========== VIEWS ========== function capacity() public view returns (uint _capacity) { // capacity = max(maxETH - balance, 0) uint balance = getReserves(); uint maxToken = maxTokenAmount(); if (balance >= maxToken) { return 0; } return maxToken.sub(balance); } function totalIssuedSynths() public view returns (uint) { // synths issued by this contract is always exactly equal to the balance of reserves return exchangeRates().effectiveValue(currencyKey, targetSynthIssued, sUSD); } function getReserves() public view returns (uint) { return token.balanceOf(address(this)); } function calculateMintFee(uint amount) public view returns (uint, bool) { int r = mintFeeRate(); if (r < 0) { return (amount.multiplyDecimalRound(uint(-r)), true); } else { return (amount.multiplyDecimalRound(uint(r)), false); } } function calculateBurnFee(uint amount) public view returns (uint, bool) { int r = burnFeeRate(); if (r < 0) { return (amount.multiplyDecimalRound(uint(-r)), true); } else { return (amount.multiplyDecimalRound(uint(r)), false); } } function maxTokenAmount() public view returns (uint256) { return getWrapperMaxTokenAmount(address(this)); } function mintFeeRate() public view returns (int256) { return getWrapperMintFeeRate(address(this)); } function burnFeeRate() public view returns (int256) { return getWrapperBurnFeeRate(address(this)); } /* ========== MUTATIVE FUNCTIONS ========== */ // Transfers `amountIn` token to mint `amountIn - fees` of currencyKey. // `amountIn` is inclusive of fees, calculable via `calculateMintFee`. function mint(uint amountIn) external notPaused issuanceActive { require(amountIn <= token.allowance(msg.sender, address(this)), "Allowance not high enough"); require(amountIn <= token.balanceOf(msg.sender), "Balance is too low"); require(!exchangeRates().rateIsInvalid(currencyKey), "Currency rate is invalid"); uint currentCapacity = capacity(); require(currentCapacity > 0, "Contract has no spare capacity to mint"); uint actualAmountIn = currentCapacity < amountIn ? currentCapacity : amountIn; (uint feeAmountTarget, bool negative) = calculateMintFee(actualAmountIn); uint mintAmount = negative ? actualAmountIn.add(feeAmountTarget) : actualAmountIn.sub(feeAmountTarget); // Transfer token from user. bool success = _safeTransferFrom(address(token), msg.sender, address(this), actualAmountIn); require(success, "Transfer did not succeed"); // Mint tokens to user _mint(mintAmount); emit Minted(msg.sender, mintAmount, negative ? 0 : feeAmountTarget, actualAmountIn); } // Burns `amountIn` synth for `amountIn - fees` amount of token. // `amountIn` is inclusive of fees, calculable via `calculateBurnFee`. function burn(uint amountIn) external notPaused issuanceActive { require(amountIn <= IERC20(address(synth())).balanceOf(msg.sender), "Balance is too low"); require(!exchangeRates().rateIsInvalid(currencyKey), "Currency rate is invalid"); require(totalIssuedSynths() > 0, "Contract cannot burn for token, token balance is zero"); (uint burnFee, bool negative) = calculateBurnFee(targetSynthIssued); uint burnAmount; uint amountOut; if (negative) { burnAmount = targetSynthIssued < amountIn ? targetSynthIssued.sub(burnFee) : amountIn; amountOut = burnAmount.multiplyDecimal( // -1e18 <= burnFeeRate <= 1e18 so this operation is safe uint(int(SafeDecimalMath.unit()) - burnFeeRate()) ); } else { burnAmount = targetSynthIssued.add(burnFee) < amountIn ? targetSynthIssued.add(burnFee) : amountIn; amountOut = burnAmount.divideDecimal( // -1e18 <= burnFeeRate <= 1e18 so this operation is safe uint(int(SafeDecimalMath.unit()) + burnFeeRate()) ); } uint feeAmountTarget = negative ? 0 : burnAmount.sub(amountOut); // Transfer token to user. bool success = _safeTransferFrom(address(token), address(this), msg.sender, amountOut); require(success, "Transfer did not succeed"); // Burn _burn(burnAmount); emit Burned(msg.sender, amountOut, feeAmountTarget, burnAmount); } // ========== RESTRICTED ========== /** * @notice Fallback function */ function() external payable { revert("Fallback disabled, use mint()"); } /* ========== INTERNAL FUNCTIONS ========== */ function _mint(uint amount) internal { uint reserves = getReserves(); uint excessAmount = reserves > targetSynthIssued.add(amount) ? reserves.sub(targetSynthIssued.add(amount)) : 0; uint excessAmountUsd = exchangeRates().effectiveValue(currencyKey, excessAmount, sUSD); // Mint `amount` to user. synth().issue(msg.sender, amount); // Escrow fee. if (excessAmountUsd > 0) { synthsUSD().issue(address(wrapperFactory()), excessAmountUsd); } // in the case of a negative fee extra synths will be issued, billed to the snx stakers _setTargetSynthIssued(reserves); } function _burn(uint amount) internal { uint reserves = getReserves(); // this is logically equivalent to getReserves() - (targetSynthIssued - amount), without going negative uint excessAmount = reserves.add(amount) > targetSynthIssued ? reserves.add(amount).sub(targetSynthIssued) : 0; uint excessAmountUsd = exchangeRates().effectiveValue(currencyKey, excessAmount, sUSD); // Burn `amount` of currencyKey from user. synth().burn(msg.sender, amount); // We use burn/issue instead of burning the principal and transferring the fee. // This saves an approval and is cheaper. // Escrow fee. if (excessAmountUsd > 0) { synthsUSD().issue(address(wrapperFactory()), excessAmountUsd); } // in the case of a negative fee fewer synths will be burned, billed to the snx stakers _setTargetSynthIssued(reserves); } function _setTargetSynthIssued(uint _targetSynthIssued) internal { debtCache().recordExcludedDebtChange(currencyKey, int256(_targetSynthIssued) - int256(targetSynthIssued)); targetSynthIssued = _targetSynthIssued; } function _safeTransferFrom( address _tokenAddress, address _from, address _to, uint256 _value ) internal returns (bool success) { // note: both of these could be replaced with manual mstore's to reduce cost if desired bytes memory msgData = abi.encodeWithSignature("transferFrom(address,address,uint256)", _from, _to, _value); uint msgSize = msgData.length; assembly { // pre-set scratch space to all bits set mstore(0x00, 0xff) // note: this requires tangerine whistle compatible EVM if iszero(call(gas(), _tokenAddress, 0, add(msgData, 0x20), msgSize, 0x00, 0x20)) { revert(0, 0) } switch mload(0x00) case 0xff { // token is not fully ERC20 compatible, didn't return anything, assume it was successful success := 1 } case 0x01 { success := 1 } case 0x00 { success := 0 } default { // unexpected value, what could this be? revert(0, 0) } } } modifier issuanceActive { systemStatus().requireIssuanceActive(); _; } /* ========== EVENTS ========== */ event Minted(address indexed account, uint principal, uint fee, uint amountIn); event Burned(address indexed account, uint principal, uint fee, uint amountIn); }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_resolver","type":"address"},{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"bytes32","name":"_currencyKey","type":"bytes32"},{"internalType":"bytes32","name":"_synthContractName","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"principal","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"Burned","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"name","type":"bytes32"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"CacheUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"principal","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"PauseChanged","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"burnFeeRate","outputs":[{"internalType":"int256","name":"","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calculateBurnFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calculateMintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"capacity","outputs":[{"internalType":"uint256","name":"_capacity","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currencyKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getReserves","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":true,"inputs":[],"name":"lastPauseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxTokenAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"mintFeeRate","outputs":[{"internalType":"int256","name":"","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","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":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"synthContractName","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"targetSynthIssued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalIssuedSynths","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052600436106101665760003560e01c80635c975abb116100d15780638a926d0f1161008a578063a0712d6811610064578063a0712d681461048d578063dbd06c85146104b7578063ee5f3f5c146104cc578063fc0c546a146104e157610166565b80638a926d0f1461044e5780638da5cb5b1461046357806391b4ded91461047857610166565b80635c975abb1461036b5780635cfc1a51146103805780636ad882691461039557806374185360146103bf57806379ba5097146103d4578063899ffef4146103e957610166565b80631f23a352116101235780631f23a352146102965780632af64bd3146102ab57806342966c68146102d4578063509bf42a146102fe57806353a47bb7146103135780635c095e541461032857610166565b806304f3bcec146101b35780630902f1ac146101e45780631627540c1461020b57806316c38b3c1461024057806317c943bc1461026c57806318819a3114610281575b6040805162461bcd60e51b815260206004820152601d60248201527f46616c6c6261636b2064697361626c65642c20757365206d696e742829000000604482015290519081900360640190fd5b3480156101bf57600080fd5b506101c86104f6565b604080516001600160a01b039092168252519081900360200190f35b3480156101f057600080fd5b506101f961050a565b60408051918252519081900360200190f35b34801561021757600080fd5b5061023e6004803603602081101561022e57600080fd5b50356001600160a01b0316610587565b005b34801561024c57600080fd5b5061023e6004803603602081101561026357600080fd5b503515156105e3565b34801561027857600080fd5b506101f961065d565b34801561028d57600080fd5b506101f9610663565b3480156102a257600080fd5b506101f9610673565b3480156102b757600080fd5b506102c0610679565b604080519115158252519081900360200190f35b3480156102e057600080fd5b5061023e600480360360208110156102f757600080fd5b5035610789565b34801561030a57600080fd5b506101f9610c73565b34801561031f57600080fd5b506101c8610c7e565b34801561033457600080fd5b506103526004803603602081101561034b57600080fd5b5035610c8d565b6040805192835290151560208301528051918290030190f35b34801561037757600080fd5b506102c0610ce2565b34801561038c57600080fd5b506101f9610ceb565b3480156103a157600080fd5b50610352600480360360208110156103b857600080fd5b5035610d2d565b3480156103cb57600080fd5b5061023e610d3a565b3480156103e057600080fd5b5061023e610f17565b3480156103f557600080fd5b506103fe610fd3565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561043a578181015183820152602001610422565b505050509050019250505060405180910390f35b34801561045a57600080fd5b506101f96110f5565b34801561046f57600080fd5b506101c8611100565b34801561048457600080fd5b506101f961110f565b34801561049957600080fd5b5061023e600480360360208110156104b057600080fd5b5035611115565b3480156104c357600080fd5b506101f961156f565b3480156104d857600080fd5b506101f9611575565b3480156104ed57600080fd5b506101c86115dd565b60035461010090046001600160a01b031681565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561055557600080fd5b505afa158015610569573d6000803e3d6000fd5b505050506040513d602081101561057f57600080fd5b505190505b90565b61058f6115ec565b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229181900360200190a150565b6105eb6115ec565b60035460ff16151581151514156106015761065a565b6003805460ff1916821515179081905560ff161561061e57426002555b6003546040805160ff90921615158252517f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec59181900360200190a15b50565b60085481565b600061066e30611637565b905090565b60075481565b60006060610685610fd3565b905060005b81518110156107805760008282815181106106a157fe5b602090810291909101810151600081815260048084526040918290205460035483516321f8a72160e01b815292830185905292519395506001600160a01b039081169461010090930416926321f8a72192602480840193919291829003018186803b15801561070f57600080fd5b505afa158015610723573d6000803e3d6000fd5b505050506040513d602081101561073957600080fd5b50516001600160a01b031614158061076657506000818152600460205260409020546001600160a01b0316155b156107775760009350505050610584565b5060010161068a565b50600191505090565b60035460ff16156107cb5760405162461bcd60e51b815260040180806020018281038252603c815260200180612258603c913960400191505060405180910390fd5b6107d3611727565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b15801561080b57600080fd5b505afa15801561081f573d6000803e3d6000fd5b5050505061082b611741565b6001600160a01b03166370a08231336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561088057600080fd5b505afa158015610894573d6000803e3d6000fd5b505050506040513d60208110156108aa57600080fd5b50518111156108f5576040805162461bcd60e51b815260206004820152601260248201527142616c616e636520697320746f6f206c6f7760701b604482015290519081900360640190fd5b6108fd61174e565b6001600160a01b0316632528f0fe6006546040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561094257600080fd5b505afa158015610956573d6000803e3d6000fd5b505050506040513d602081101561096c57600080fd5b5051156109bb576040805162461bcd60e51b815260206004820152601860248201527710dd5c9c995b98de481c985d19481a5cc81a5b9d985b1a5960421b604482015290519081900360640190fd5b60006109c5611575565b11610a015760405162461bcd60e51b81526004018080602001828103825260358152602001806122ba6035913960400191505060405180910390fd5b600080610a0f600854610d2d565b915091506000808215610ad1578460085410610a2b5784610a3e565b600854610a3e908563ffffffff61176916565b9150610aca610a4b610c73565b730142f40c25ce1f1177ed131101fa19217396cb8863907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8f57600080fd5b505af4158015610aa3573d6000803e3d6000fd5b505050506040513d6020811015610ab957600080fd5b50518491900363ffffffff6117cb16565b9050610b92565b6008548590610ae6908663ffffffff6117f516565b10610af15784610b04565b600854610b04908563ffffffff6117f516565b9150610b8f610b11610c73565b730142f40c25ce1f1177ed131101fa19217396cb8863907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5557600080fd5b505af4158015610b69573d6000803e3d6000fd5b505050506040513d6020811015610b7f57600080fd5b505184910163ffffffff61185616565b90505b600083610bae57610ba9838363ffffffff61176916565b610bb1565b60005b600554909150600090610bcf906001600160a01b0316303386611880565b905080610c1e576040805162461bcd60e51b8152602060048201526018602482015277151c985b9cd9995c88191a59081b9bdd081cdd58d8d9595960421b604482015290519081900360640190fd5b610c2784611925565b6040805184815260208101849052808201869052905133917f4c60206a5c1de41f3376d1d60f0949d96cb682033c90b1c2d9d9a62d4c4120c0919081900360600190a250505050505050565b600061066e30611b2b565b6001546001600160a01b031681565b6000806000610c9a610663565b90506000811215610cc557610cb984600083900363ffffffff611be916565b60019250925050610cdd565b610cd5848263ffffffff611be916565b600092509250505b915091565b60035460ff1681565b600080610cf661050a565b90506000610d026110f5565b9050808210610d1657600092505050610584565b610d26818363ffffffff61176916565b9250505090565b6000806000610c9a610c73565b6060610d44610fd3565b905060005b8151811015610f13576000828281518110610d6057fe5b602002602001015190506000600360019054906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200180807f5265736f6c766572206d697373696e67207461726765743a20000000000000008152506019018281526020019150506040516020818303038152906040526040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610e2b578181015183820152602001610e13565b50505050905090810190601f168015610e585780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015610e7657600080fd5b505afa158015610e8a573d6000803e3d6000fd5b505050506040513d6020811015610ea057600080fd5b505160008381526004602090815260409182902080546001600160a01b0319166001600160a01b03851690811790915582518681529182015281519293507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68929081900390910190a15050600101610d49565b5050565b6001546001600160a01b03163314610f605760405162461bcd60e51b81526004018080602001828103825260358152602001806121d36035913960400191505060405180910390fd5b600054600154604080516001600160a01b03938416815292909116602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b606080610fde611bfe565b60408051600680825260e08201909252919250606091906020820160c0803883390190505090506814de5b9d1a1cd554d160ba1b8160008151811061101f57fe5b6020026020010181815250506007548160018151811061103b57fe5b6020026020010181815250506c45786368616e6765526174657360981b8160028151811061106557fe5b6020026020010181815250506844656274436163686560b81b8160038151811061108b57fe5b6020026020010181815250506b53797374656d53746174757360a01b816004815181106110b457fe5b6020026020010181815250506d57726170706572466163746f727960901b816005815181106110df57fe5b602002602001018181525050610d268282611c4f565b600061066e30611d0b565b6000546001600160a01b031681565b60025481565b60035460ff16156111575760405162461bcd60e51b815260040180806020018281038252603c815260200180612258603c913960400191505060405180910390fd5b61115f611727565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b15801561119757600080fd5b505afa1580156111ab573d6000803e3d6000fd5b505060055460408051636eb1769f60e11b815233600482015230602482015290516001600160a01b03909216935063dd62ed3e9250604480820192602092909190829003018186803b15801561120057600080fd5b505afa158015611214573d6000803e3d6000fd5b505050506040513d602081101561122a57600080fd5b5051811115611280576040805162461bcd60e51b815260206004820152601960248201527f416c6c6f77616e6365206e6f74206869676820656e6f75676800000000000000604482015290519081900360640190fd5b600554604080516370a0823160e01b815233600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b1580156112cb57600080fd5b505afa1580156112df573d6000803e3d6000fd5b505050506040513d60208110156112f557600080fd5b5051811115611340576040805162461bcd60e51b815260206004820152601260248201527142616c616e636520697320746f6f206c6f7760701b604482015290519081900360640190fd5b61134861174e565b6001600160a01b0316632528f0fe6006546040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561138d57600080fd5b505afa1580156113a1573d6000803e3d6000fd5b505050506040513d60208110156113b757600080fd5b505115611406576040805162461bcd60e51b815260206004820152601860248201527710dd5c9c995b98de481c985d19481a5cc81a5b9d985b1a5960421b604482015290519081900360640190fd5b6000611410610ceb565b9050600081116114515760405162461bcd60e51b81526004018080602001828103825260268152602001806122946026913960400191505060405180910390fd5b60008282106114605782611462565b815b905060008061147083610c8d565b915091506000816114905761148b848463ffffffff61176916565b6114a0565b6114a0848463ffffffff6117f516565b6005549091506000906114be906001600160a01b0316333088611880565b90508061150d576040805162461bcd60e51b8152602060048201526018602482015277151c985b9cd9995c88191a59081b9bdd081cdd58d8d9595960421b604482015290519081900360640190fd5b61151682611dc7565b337f5a3358a3d27a5373c0df2604662088d37894d56b7cfd27f315770440f4e0d91983856115445786611547565b60005b604080519283526020830191909152818101899052519081900360600190a250505050505050565b60065481565b600061157f61174e565b6001600160a01b031663654a60ac600654600854631cd554d160e21b6040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b15801561055557600080fd5b6005546001600160a01b031681565b6000546001600160a01b031633146116355760405162461bcd60e51b815260040180806020018281038252602f815260200180612208602f913960400191505060405180910390fd5b565b6000611641611f18565b6001600160a01b031663c4f610ed6d53797374656d53657474696e677360901b71777261707065724d696e744665655261746560701b8560405160200180838152602001826001600160a01b03166001600160a01b031660601b815260140192505050604051602081830303815290604052805190602001206040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156116f557600080fd5b505afa158015611709573d6000803e3d6000fd5b505050506040513d602081101561171f57600080fd5b505192915050565b600061066e6b53797374656d53746174757360a01b611f31565b600061066e600754611f31565b600061066e6c45786368616e6765526174657360981b611f31565b6000828211156117c0576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b6000670de0b6b3a76400006117e6848463ffffffff61200e16565b816117ed57fe5b049392505050565b60008282018381101561184f576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600061184f8261187485670de0b6b3a764000063ffffffff61200e16565b9063ffffffff61206716565b604080516001600160a01b038086166024830152841660448201526064808201849052825180830390910181526084909101909152602081810180516001600160e01b03166323b872dd60e01b178152825160ff60009081529392909184908390828b5af16118ee57600080fd5b60005160ff811461190c576001811461190c57801561191557600080fd5b6001935061191a565b600093505b505050949350505050565b600061192f61050a565b600854909150600090611948838563ffffffff6117f516565b11611954576000611977565b6008546119779061196b848663ffffffff6117f516565b9063ffffffff61176916565b9050600061198361174e565b6001600160a01b031663654a60ac60065484631cd554d160e21b6040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b1580156119df57600080fd5b505afa1580156119f3573d6000803e3d6000fd5b505050506040513d6020811015611a0957600080fd5b50519050611a15611741565b6001600160a01b0316639dc29fac33866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611a7457600080fd5b505af1158015611a88573d6000803e3d6000fd5b505050506000811115611b1c57611a9d6120d1565b6001600160a01b031663867904b4611ab36120e8565b836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611b0357600080fd5b505af1158015611b17573d6000803e3d6000fd5b505050505b611b2583612104565b50505050565b6000611b35611f18565b6001600160a01b031663c4f610ed6d53797374656d53657474696e677360901b71777261707065724275726e4665655261746560701b8560405160200180838152602001826001600160a01b03166001600160a01b031660601b815260140192505050604051602081830303815290604052805190602001206040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156116f557600080fd5b600061184f8383670de0b6b3a764000061217f565b604080516001808252818301909252606091602080830190803883390190505090506e466c657869626c6553746f7261676560881b81600081518110611c4057fe5b60200260200101818152505090565b60608151835101604051908082528060200260200182016040528015611c7f578160200160208202803883390190505b50905060005b8351811015611cc157838181518110611c9a57fe5b6020026020010151828281518110611cae57fe5b6020908102919091010152600101611c85565b5060005b8251811015611d0457828181518110611cda57fe5b6020026020010151828286510181518110611cf157fe5b6020908102919091010152600101611cc5565b5092915050565b6000611d15611f18565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b6f777261707065724d6178546f6b656e7360801b8560405160200180838152602001826001600160a01b03166001600160a01b031660601b815260140192505050604051602081830303815290604052805190602001206040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156116f557600080fd5b6000611dd161050a565b90506000611dea836008546117f590919063ffffffff16565b8211611df7576000611e1b565b600854611e1b90611e0e908563ffffffff6117f516565b839063ffffffff61176916565b90506000611e2761174e565b6001600160a01b031663654a60ac60065484631cd554d160e21b6040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b158015611e8357600080fd5b505afa158015611e97573d6000803e3d6000fd5b505050506040513d6020811015611ead57600080fd5b50519050611eb9611741565b6001600160a01b031663867904b433866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611a7457600080fd5b600061066e6e466c657869626c6553746f7261676560881b5b600081815260046020908152604080832054815170026b4b9b9b4b7339030b2323932b9b99d1607d1b9381019390935260318084018690528251808503909101815260519093019091526001600160a01b03169081611d045760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611fd3578181015183820152602001611fbb565b50505050905090810190601f1680156120005780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60008261201d575060006117c5565b8282028284828161202a57fe5b041461184f5760405162461bcd60e51b81526004018080602001828103825260218152602001806122376021913960400191505060405180910390fd5b60008082116120bd576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b60008284816120c857fe5b04949350505050565b600061066e6814de5b9d1a1cd554d160ba1b611f31565b600061066e6d57726170706572466163746f727960901b611f31565b61210c6121bb565b6001600160a01b0316639e3b92ca60065460085484036040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b15801561215f57600080fd5b505af1158015612173573d6000803e3d6000fd5b50505060089190915550565b600080600a8304612196868663ffffffff61200e16565b8161219d57fe5b0490506005600a8206106121af57600a015b600a9004949350505050565b600061066e6844656274436163686560b81b611f3156fe596f75206d757374206265206e6f6d696e61746564206265666f726520796f752063616e20616363657074206f776e6572736869704f6e6c792074686520636f6e7472616374206f776e6572206d617920706572666f726d207468697320616374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775468697320616374696f6e2063616e6e6f7420626520706572666f726d6564207768696c652074686520636f6e747261637420697320706175736564436f6e747261637420686173206e6f20737061726520636170616369747920746f206d696e74436f6e74726163742063616e6e6f74206275726e20666f7220746f6b656e2c20746f6b656e2062616c616e6365206973207a65726fa265627a7a723158208ec50d2f478726a4ebd76ed5ccd94f51be6f5bcfb30e7fafaa463d9527413ff064736f6c63430005100032
Deployed Bytecode
0x6080604052600436106101665760003560e01c80635c975abb116100d15780638a926d0f1161008a578063a0712d6811610064578063a0712d681461048d578063dbd06c85146104b7578063ee5f3f5c146104cc578063fc0c546a146104e157610166565b80638a926d0f1461044e5780638da5cb5b1461046357806391b4ded91461047857610166565b80635c975abb1461036b5780635cfc1a51146103805780636ad882691461039557806374185360146103bf57806379ba5097146103d4578063899ffef4146103e957610166565b80631f23a352116101235780631f23a352146102965780632af64bd3146102ab57806342966c68146102d4578063509bf42a146102fe57806353a47bb7146103135780635c095e541461032857610166565b806304f3bcec146101b35780630902f1ac146101e45780631627540c1461020b57806316c38b3c1461024057806317c943bc1461026c57806318819a3114610281575b6040805162461bcd60e51b815260206004820152601d60248201527f46616c6c6261636b2064697361626c65642c20757365206d696e742829000000604482015290519081900360640190fd5b3480156101bf57600080fd5b506101c86104f6565b604080516001600160a01b039092168252519081900360200190f35b3480156101f057600080fd5b506101f961050a565b60408051918252519081900360200190f35b34801561021757600080fd5b5061023e6004803603602081101561022e57600080fd5b50356001600160a01b0316610587565b005b34801561024c57600080fd5b5061023e6004803603602081101561026357600080fd5b503515156105e3565b34801561027857600080fd5b506101f961065d565b34801561028d57600080fd5b506101f9610663565b3480156102a257600080fd5b506101f9610673565b3480156102b757600080fd5b506102c0610679565b604080519115158252519081900360200190f35b3480156102e057600080fd5b5061023e600480360360208110156102f757600080fd5b5035610789565b34801561030a57600080fd5b506101f9610c73565b34801561031f57600080fd5b506101c8610c7e565b34801561033457600080fd5b506103526004803603602081101561034b57600080fd5b5035610c8d565b6040805192835290151560208301528051918290030190f35b34801561037757600080fd5b506102c0610ce2565b34801561038c57600080fd5b506101f9610ceb565b3480156103a157600080fd5b50610352600480360360208110156103b857600080fd5b5035610d2d565b3480156103cb57600080fd5b5061023e610d3a565b3480156103e057600080fd5b5061023e610f17565b3480156103f557600080fd5b506103fe610fd3565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561043a578181015183820152602001610422565b505050509050019250505060405180910390f35b34801561045a57600080fd5b506101f96110f5565b34801561046f57600080fd5b506101c8611100565b34801561048457600080fd5b506101f961110f565b34801561049957600080fd5b5061023e600480360360208110156104b057600080fd5b5035611115565b3480156104c357600080fd5b506101f961156f565b3480156104d857600080fd5b506101f9611575565b3480156104ed57600080fd5b506101c86115dd565b60035461010090046001600160a01b031681565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561055557600080fd5b505afa158015610569573d6000803e3d6000fd5b505050506040513d602081101561057f57600080fd5b505190505b90565b61058f6115ec565b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229181900360200190a150565b6105eb6115ec565b60035460ff16151581151514156106015761065a565b6003805460ff1916821515179081905560ff161561061e57426002555b6003546040805160ff90921615158252517f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec59181900360200190a15b50565b60085481565b600061066e30611637565b905090565b60075481565b60006060610685610fd3565b905060005b81518110156107805760008282815181106106a157fe5b602090810291909101810151600081815260048084526040918290205460035483516321f8a72160e01b815292830185905292519395506001600160a01b039081169461010090930416926321f8a72192602480840193919291829003018186803b15801561070f57600080fd5b505afa158015610723573d6000803e3d6000fd5b505050506040513d602081101561073957600080fd5b50516001600160a01b031614158061076657506000818152600460205260409020546001600160a01b0316155b156107775760009350505050610584565b5060010161068a565b50600191505090565b60035460ff16156107cb5760405162461bcd60e51b815260040180806020018281038252603c815260200180612258603c913960400191505060405180910390fd5b6107d3611727565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b15801561080b57600080fd5b505afa15801561081f573d6000803e3d6000fd5b5050505061082b611741565b6001600160a01b03166370a08231336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561088057600080fd5b505afa158015610894573d6000803e3d6000fd5b505050506040513d60208110156108aa57600080fd5b50518111156108f5576040805162461bcd60e51b815260206004820152601260248201527142616c616e636520697320746f6f206c6f7760701b604482015290519081900360640190fd5b6108fd61174e565b6001600160a01b0316632528f0fe6006546040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561094257600080fd5b505afa158015610956573d6000803e3d6000fd5b505050506040513d602081101561096c57600080fd5b5051156109bb576040805162461bcd60e51b815260206004820152601860248201527710dd5c9c995b98de481c985d19481a5cc81a5b9d985b1a5960421b604482015290519081900360640190fd5b60006109c5611575565b11610a015760405162461bcd60e51b81526004018080602001828103825260358152602001806122ba6035913960400191505060405180910390fd5b600080610a0f600854610d2d565b915091506000808215610ad1578460085410610a2b5784610a3e565b600854610a3e908563ffffffff61176916565b9150610aca610a4b610c73565b730142f40c25ce1f1177ed131101fa19217396cb8863907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8f57600080fd5b505af4158015610aa3573d6000803e3d6000fd5b505050506040513d6020811015610ab957600080fd5b50518491900363ffffffff6117cb16565b9050610b92565b6008548590610ae6908663ffffffff6117f516565b10610af15784610b04565b600854610b04908563ffffffff6117f516565b9150610b8f610b11610c73565b730142f40c25ce1f1177ed131101fa19217396cb8863907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5557600080fd5b505af4158015610b69573d6000803e3d6000fd5b505050506040513d6020811015610b7f57600080fd5b505184910163ffffffff61185616565b90505b600083610bae57610ba9838363ffffffff61176916565b610bb1565b60005b600554909150600090610bcf906001600160a01b0316303386611880565b905080610c1e576040805162461bcd60e51b8152602060048201526018602482015277151c985b9cd9995c88191a59081b9bdd081cdd58d8d9595960421b604482015290519081900360640190fd5b610c2784611925565b6040805184815260208101849052808201869052905133917f4c60206a5c1de41f3376d1d60f0949d96cb682033c90b1c2d9d9a62d4c4120c0919081900360600190a250505050505050565b600061066e30611b2b565b6001546001600160a01b031681565b6000806000610c9a610663565b90506000811215610cc557610cb984600083900363ffffffff611be916565b60019250925050610cdd565b610cd5848263ffffffff611be916565b600092509250505b915091565b60035460ff1681565b600080610cf661050a565b90506000610d026110f5565b9050808210610d1657600092505050610584565b610d26818363ffffffff61176916565b9250505090565b6000806000610c9a610c73565b6060610d44610fd3565b905060005b8151811015610f13576000828281518110610d6057fe5b602002602001015190506000600360019054906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200180807f5265736f6c766572206d697373696e67207461726765743a20000000000000008152506019018281526020019150506040516020818303038152906040526040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610e2b578181015183820152602001610e13565b50505050905090810190601f168015610e585780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015610e7657600080fd5b505afa158015610e8a573d6000803e3d6000fd5b505050506040513d6020811015610ea057600080fd5b505160008381526004602090815260409182902080546001600160a01b0319166001600160a01b03851690811790915582518681529182015281519293507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68929081900390910190a15050600101610d49565b5050565b6001546001600160a01b03163314610f605760405162461bcd60e51b81526004018080602001828103825260358152602001806121d36035913960400191505060405180910390fd5b600054600154604080516001600160a01b03938416815292909116602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b606080610fde611bfe565b60408051600680825260e08201909252919250606091906020820160c0803883390190505090506814de5b9d1a1cd554d160ba1b8160008151811061101f57fe5b6020026020010181815250506007548160018151811061103b57fe5b6020026020010181815250506c45786368616e6765526174657360981b8160028151811061106557fe5b6020026020010181815250506844656274436163686560b81b8160038151811061108b57fe5b6020026020010181815250506b53797374656d53746174757360a01b816004815181106110b457fe5b6020026020010181815250506d57726170706572466163746f727960901b816005815181106110df57fe5b602002602001018181525050610d268282611c4f565b600061066e30611d0b565b6000546001600160a01b031681565b60025481565b60035460ff16156111575760405162461bcd60e51b815260040180806020018281038252603c815260200180612258603c913960400191505060405180910390fd5b61115f611727565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b15801561119757600080fd5b505afa1580156111ab573d6000803e3d6000fd5b505060055460408051636eb1769f60e11b815233600482015230602482015290516001600160a01b03909216935063dd62ed3e9250604480820192602092909190829003018186803b15801561120057600080fd5b505afa158015611214573d6000803e3d6000fd5b505050506040513d602081101561122a57600080fd5b5051811115611280576040805162461bcd60e51b815260206004820152601960248201527f416c6c6f77616e6365206e6f74206869676820656e6f75676800000000000000604482015290519081900360640190fd5b600554604080516370a0823160e01b815233600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b1580156112cb57600080fd5b505afa1580156112df573d6000803e3d6000fd5b505050506040513d60208110156112f557600080fd5b5051811115611340576040805162461bcd60e51b815260206004820152601260248201527142616c616e636520697320746f6f206c6f7760701b604482015290519081900360640190fd5b61134861174e565b6001600160a01b0316632528f0fe6006546040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561138d57600080fd5b505afa1580156113a1573d6000803e3d6000fd5b505050506040513d60208110156113b757600080fd5b505115611406576040805162461bcd60e51b815260206004820152601860248201527710dd5c9c995b98de481c985d19481a5cc81a5b9d985b1a5960421b604482015290519081900360640190fd5b6000611410610ceb565b9050600081116114515760405162461bcd60e51b81526004018080602001828103825260268152602001806122946026913960400191505060405180910390fd5b60008282106114605782611462565b815b905060008061147083610c8d565b915091506000816114905761148b848463ffffffff61176916565b6114a0565b6114a0848463ffffffff6117f516565b6005549091506000906114be906001600160a01b0316333088611880565b90508061150d576040805162461bcd60e51b8152602060048201526018602482015277151c985b9cd9995c88191a59081b9bdd081cdd58d8d9595960421b604482015290519081900360640190fd5b61151682611dc7565b337f5a3358a3d27a5373c0df2604662088d37894d56b7cfd27f315770440f4e0d91983856115445786611547565b60005b604080519283526020830191909152818101899052519081900360600190a250505050505050565b60065481565b600061157f61174e565b6001600160a01b031663654a60ac600654600854631cd554d160e21b6040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b15801561055557600080fd5b6005546001600160a01b031681565b6000546001600160a01b031633146116355760405162461bcd60e51b815260040180806020018281038252602f815260200180612208602f913960400191505060405180910390fd5b565b6000611641611f18565b6001600160a01b031663c4f610ed6d53797374656d53657474696e677360901b71777261707065724d696e744665655261746560701b8560405160200180838152602001826001600160a01b03166001600160a01b031660601b815260140192505050604051602081830303815290604052805190602001206040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156116f557600080fd5b505afa158015611709573d6000803e3d6000fd5b505050506040513d602081101561171f57600080fd5b505192915050565b600061066e6b53797374656d53746174757360a01b611f31565b600061066e600754611f31565b600061066e6c45786368616e6765526174657360981b611f31565b6000828211156117c0576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b6000670de0b6b3a76400006117e6848463ffffffff61200e16565b816117ed57fe5b049392505050565b60008282018381101561184f576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600061184f8261187485670de0b6b3a764000063ffffffff61200e16565b9063ffffffff61206716565b604080516001600160a01b038086166024830152841660448201526064808201849052825180830390910181526084909101909152602081810180516001600160e01b03166323b872dd60e01b178152825160ff60009081529392909184908390828b5af16118ee57600080fd5b60005160ff811461190c576001811461190c57801561191557600080fd5b6001935061191a565b600093505b505050949350505050565b600061192f61050a565b600854909150600090611948838563ffffffff6117f516565b11611954576000611977565b6008546119779061196b848663ffffffff6117f516565b9063ffffffff61176916565b9050600061198361174e565b6001600160a01b031663654a60ac60065484631cd554d160e21b6040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b1580156119df57600080fd5b505afa1580156119f3573d6000803e3d6000fd5b505050506040513d6020811015611a0957600080fd5b50519050611a15611741565b6001600160a01b0316639dc29fac33866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611a7457600080fd5b505af1158015611a88573d6000803e3d6000fd5b505050506000811115611b1c57611a9d6120d1565b6001600160a01b031663867904b4611ab36120e8565b836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611b0357600080fd5b505af1158015611b17573d6000803e3d6000fd5b505050505b611b2583612104565b50505050565b6000611b35611f18565b6001600160a01b031663c4f610ed6d53797374656d53657474696e677360901b71777261707065724275726e4665655261746560701b8560405160200180838152602001826001600160a01b03166001600160a01b031660601b815260140192505050604051602081830303815290604052805190602001206040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156116f557600080fd5b600061184f8383670de0b6b3a764000061217f565b604080516001808252818301909252606091602080830190803883390190505090506e466c657869626c6553746f7261676560881b81600081518110611c4057fe5b60200260200101818152505090565b60608151835101604051908082528060200260200182016040528015611c7f578160200160208202803883390190505b50905060005b8351811015611cc157838181518110611c9a57fe5b6020026020010151828281518110611cae57fe5b6020908102919091010152600101611c85565b5060005b8251811015611d0457828181518110611cda57fe5b6020026020010151828286510181518110611cf157fe5b6020908102919091010152600101611cc5565b5092915050565b6000611d15611f18565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b6f777261707065724d6178546f6b656e7360801b8560405160200180838152602001826001600160a01b03166001600160a01b031660601b815260140192505050604051602081830303815290604052805190602001206040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156116f557600080fd5b6000611dd161050a565b90506000611dea836008546117f590919063ffffffff16565b8211611df7576000611e1b565b600854611e1b90611e0e908563ffffffff6117f516565b839063ffffffff61176916565b90506000611e2761174e565b6001600160a01b031663654a60ac60065484631cd554d160e21b6040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b158015611e8357600080fd5b505afa158015611e97573d6000803e3d6000fd5b505050506040513d6020811015611ead57600080fd5b50519050611eb9611741565b6001600160a01b031663867904b433866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611a7457600080fd5b600061066e6e466c657869626c6553746f7261676560881b5b600081815260046020908152604080832054815170026b4b9b9b4b7339030b2323932b9b99d1607d1b9381019390935260318084018690528251808503909101815260519093019091526001600160a01b03169081611d045760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611fd3578181015183820152602001611fbb565b50505050905090810190601f1680156120005780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60008261201d575060006117c5565b8282028284828161202a57fe5b041461184f5760405162461bcd60e51b81526004018080602001828103825260218152602001806122376021913960400191505060405180910390fd5b60008082116120bd576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b60008284816120c857fe5b04949350505050565b600061066e6814de5b9d1a1cd554d160ba1b611f31565b600061066e6d57726170706572466163746f727960901b611f31565b61210c6121bb565b6001600160a01b0316639e3b92ca60065460085484036040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b15801561215f57600080fd5b505af1158015612173573d6000803e3d6000fd5b50505060089190915550565b600080600a8304612196868663ffffffff61200e16565b8161219d57fe5b0490506005600a8206106121af57600a015b600a9004949350505050565b600061066e6844656274436163686560b81b611f3156fe596f75206d757374206265206e6f6d696e61746564206265666f726520796f752063616e20616363657074206f776e6572736869704f6e6c792074686520636f6e7472616374206f776e6572206d617920706572666f726d207468697320616374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775468697320616374696f6e2063616e6e6f7420626520706572666f726d6564207768696c652074686520636f6e747261637420697320706175736564436f6e747261637420686173206e6f20737061726520636170616369747920746f206d696e74436f6e74726163742063616e6e6f74206275726e20666f7220746f6b656e2c20746f6b656e2062616c616e6365206973207a65726fa265627a7a723158208ec50d2f478726a4ebd76ed5ccd94f51be6f5bcfb30e7fafaa463d9527413ff064736f6c63430005100032
Deployed Bytecode Sourcemap
47184:11504:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55080:39;;;-1:-1:-1;;;55080:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;20179:31;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20179:31:0;;;:::i;:::-;;;;-1:-1:-1;;;;;20179:31:0;;;;;;;;;;;;;;50787:106;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50787:106:0;;;:::i;:::-;;;;;;;;;;;;;;;;2171:141;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2171:141:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;2171:141:0;-1:-1:-1;;;;;2171:141:0;;:::i;:::-;;6189:488;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6189:488:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;6189:488:0;;;;:::i;48067:29::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48067:29:0;;;:::i;51644:114::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51644:114:0;;;:::i;48026:32::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48026:32:0;;;:::i;21874:537::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21874:537:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;53365:1573;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53365:1573:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;53365:1573:0;;:::i;51766:114::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51766:114:0;;;:::i;1940:29::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1940:29:0;;;:::i;50901:299::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50901:299:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50901:299:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;5775:18;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5775:18:0;;;:::i;50223:304::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50223:304:0;;;:::i;51208:299::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51208:299:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51208:299:0;;:::i;21168:657::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21168:657:0;;;:::i;2320:271::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2320:271:0;;;:::i;48571:632::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48571:632:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;48571:632:0;;;;;;;;;;;;;;;;;51515:121;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51515:121:0;;;:::i;1913:20::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1913:20:0;;;:::i;5743:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5743:25:0;;;:::i;52095:1116::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52095:1116:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52095:1116:0;;:::i;47993:26::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47993:26:0;;;:::i;50535:244::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50535:244:0;;;:::i;47967:19::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47967:19:0;;;:::i;20179:31::-;;;;;;-1:-1:-1;;;;;20179:31:0;;:::o;50787:106::-;50855:5;;:30;;;-1:-1:-1;;;50855:30:0;;50879:4;50855:30;;;;;;50831:4;;-1:-1:-1;;;;;50855:5:0;;:15;;:30;;;;;;;;;;;;;;:5;:30;;;5:2:-1;;;;30:1;27;20:12;5:2;50855:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50855:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50855:30:0;;-1:-1:-1;50787:106:0;;:::o;2171:141::-;2629:12;:10;:12::i;:::-;2243:14;:23;;-1:-1:-1;;;;;2243:23:0;;-1:-1:-1;;;;;;2243:23:0;;;;;;;;2282:22;;;;;;;;;;;;;;;;2171:141;:::o;6189:488::-;2629:12;:10;:12::i;:::-;6342:6;;;;6331:17;;;;;;6327:56;;;6365:7;;6327:56;6429:6;:16;;-1:-1:-1;;6429:16:0;;;;;;;;;;6514:6;6510:58;;;6553:3;6537:13;:19;6510:58;6662:6;;6649:20;;;6662:6;;;;6649:20;;;;;;;;;;;;;;2652:1;6189:488;:::o;48067:29::-;;;;:::o;51644:114::-;51688:6;51714:36;51744:4;51714:21;:36::i;:::-;51707:43;;51644:114;:::o;48026:32::-;;;;:::o;21874:537::-;21925:4;21942:34;21979:27;:25;:27::i;:::-;21942:64;-1:-1:-1;22022:6:0;22017:363;22038:17;:24;22034:1;:28;22017:363;;;22084:12;22099:17;22117:1;22099:20;;;;;;;;;;;;;;;;;;;22266:18;;;;:12;:18;;;;;;;;;22237:8;;:25;;-1:-1:-1;;;22237:25:0;;;;;;;;;;22099:20;;-1:-1:-1;;;;;;22266:18:0;;;;;22237:8;;;;;:19;;:25;;;;;22099:20;;22237:25;;;;;;:8;:25;;;5:2:-1;;;;30:1;27;20:12;5:2;22237:25:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22237:25:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22237:25:0;-1:-1:-1;;;;;22237:47:0;;;;:83;;-1:-1:-1;22318:1:0;22288:18;;;:12;:18;;;;;;-1:-1:-1;;;;;22288:18:0;:32;22237:83;22233:136;;;22348:5;22341:12;;;;;;;22233:136;-1:-1:-1;22064:3:0;;22017:363;;;;22399:4;22392:11;;;21874:537;:::o;53365:1573::-;6766:6;;;;6765:7;6757:80;;;;-1:-1:-1;;;6757:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58415:14;:12;:14::i;:::-;-1:-1:-1;;;;;58415:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58415:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58415:38:0;;;;53474:7;:5;:7::i;:::-;-1:-1:-1;;;;;53459:34:0;;53494:10;53459:46;;;;;;;;;;;;;-1:-1:-1;;;;;53459:46:0;-1:-1:-1;;;;;53459:46:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53459:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53459:46:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;53459:46:0;53447:58;;;53439:89;;;;;-1:-1:-1;;;53439:89:0;;;;;;;;;;;;-1:-1:-1;;;53439:89:0;;;;;;;;;;;;;;;53548:15;:13;:15::i;:::-;-1:-1:-1;;;;;53548:29:0;;53578:11;;53548:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53548:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53548:42:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;53548:42:0;53547:43;53539:80;;;;;-1:-1:-1;;;53539:80:0;;;;;;;;;;;;-1:-1:-1;;;53539:80:0;;;;;;;;;;;;;;;53660:1;53638:19;:17;:19::i;:::-;:23;53630:89;;;;-1:-1:-1;;;53630:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53733:12;53747:13;53764:35;53781:17;;53764:16;:35::i;:::-;53732:67;;;;53812:15;53838:14;53867:8;53863:679;;;53925:8;53905:17;;:28;:72;;53969:8;53905:72;;;53936:17;;:30;;53958:7;53936:30;:21;:30;:::i;:::-;53892:85;;54006:184;54161:13;:11;:13::i;:::-;54135:15;:20;:22;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54135:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54135:22:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54135:22:0;54006:10;;54131:43;;54006:184;:26;:184;:::i;:::-;53994:196;;53863:679;;;54236:17;;54269:8;;54236:30;;54258:7;54236:30;:21;:30;:::i;:::-;:41;:85;;54313:8;54236:85;;;54280:17;;:30;;54302:7;54280:30;:21;:30;:::i;:::-;54223:98;;54348:182;54501:13;:11;:13::i;:::-;54475:15;:20;:22;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54475:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54475:22:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54475:22:0;54348:10;;54471:43;54348:182;:24;:182;:::i;:::-;54336:194;;53863:679;54554:20;54577:8;:40;;54592:25;:10;54607:9;54592:25;:14;:25;:::i;:::-;54577:40;;;54588:1;54577:40;54707:5;;54554:63;;-1:-1:-1;54666:12:0;;54681:71;;-1:-1:-1;;;;;54707:5:0;54723:4;54730:10;54742:9;54681:17;:71::i;:::-;54666:86;;54771:7;54763:44;;;;;-1:-1:-1;;;54763:44:0;;;;;;;;;;;;-1:-1:-1;;;54763:44:0;;;;;;;;;;;;;;;54837:17;54843:10;54837:5;:17::i;:::-;54872:58;;;;;;;;;;;;;;;;;;;;54879:10;;54872:58;;;;;;;;;;58464:1;;;;;;53365:1573;:::o;51766:114::-;51810:6;51836:36;51866:4;51836:21;:36::i;1940:29::-;;;-1:-1:-1;;;;;1940:29:0;;:::o;50901:299::-;50961:4;50967;50984:5;50992:13;:11;:13::i;:::-;50984:21;;51026:1;51022;:5;51018:175;;;51052:37;:6;51085:2;;;;51052:37;:27;:37;:::i;:::-;51091:4;51044:52;;;;;;;51018:175;51137:36;:6;51170:1;51137:36;:27;:36;:::i;:::-;51175:5;51129:52;;;;;50901:299;;;;:::o;5775:18::-;;;;;;:::o;50223:304::-;50264:14;50339:12;50354:13;:11;:13::i;:::-;50339:28;;50378:13;50394:16;:14;:16::i;:::-;50378:32;;50436:8;50425:7;:19;50421:60;;50468:1;50461:8;;;;;;50421:60;50498:21;:8;50511:7;50498:21;:12;:21;:::i;:::-;50491:28;;;;50223:304;:::o;51208:299::-;51268:4;51274;51291:5;51299:13;:11;:13::i;21168:657::-;21210:34;21247:27;:25;:27::i;:::-;21210:64;-1:-1:-1;21368:6:0;21363:455;21384:17;:24;21380:1;:28;21363:455;;;21430:12;21445:17;21463:1;21445:20;;;;;;;;;;;;;;21430:35;;21573:19;21612:8;;;;;;;;;-1:-1:-1;;;;;21612:8:0;-1:-1:-1;;;;;21612:29:0;;21642:4;21701;21655:51;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;21655:51:0;;;21612:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;21612:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21612:96:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21612:96:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21612:96:0;21723:18;;;;:12;21612:96;21723:18;;;;;;;;:32;;-1:-1:-1;;;;;;21723:32:0;-1:-1:-1;;;;;21723:32:0;;;;;;;;21775:31;;;;;;;;;;;21612:96;;-1:-1:-1;21775:31:0;;;;;;;;;;;-1:-1:-1;;21410:3:0;;21363:455;;;;21168:657;:::o;2320:271::-;2389:14;;-1:-1:-1;;;;;2389:14:0;2375:10;:28;2367:94;;;;-1:-1:-1;;;2367:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2490:5;;;2497:14;2477:35;;;-1:-1:-1;;;;;2490:5:0;;;2477:35;;2497:14;;;;2477:35;;;;;;;;;;;;;;;;2531:14;;;;2523:22;;-1:-1:-1;;;;;;2523:22:0;;;-1:-1:-1;;;;;2531:14:0;;2523:22;;;;2556:27;;;2320:271::o;48571:632::-;48629:26;48668:34;48705:47;:45;:47::i;:::-;48795:16;;;48809:1;48795:16;;;;;;;;;48668:84;;-1:-1:-1;48763:29:0;;48795:16;;;;17:15:-1;;105:10;48795:16:0;88:34:-1;136:17;;-1:-1;48795:16:0;48763:48;;-1:-1:-1;;;48822:12:0;48835:1;48822:15;;;;;;;;;;;;;:37;;;;;48888:17;;48870:12;48883:1;48870:15;;;;;;;;;;;;;:35;;;;;-1:-1:-1;;;48916:12:0;48929:1;48916:15;;;;;;;;;;;;;:34;;;;;-1:-1:-1;;;48961:12:0;48974:1;48961:15;;;;;;;;;;;;;:36;;;;;-1:-1:-1;;;49008:12:0;49021:1;49008:15;;;;;;;;;;;;;:39;;;;;-1:-1:-1;;;49058:12:0;49071:1;49058:15;;;;;;;;;;;;;:41;;;;;49122:46;49136:17;49155:12;49122:13;:46::i;51515:121::-;51562:7;51589:39;51622:4;51589:24;:39::i;1913:20::-;;;-1:-1:-1;;;;;1913:20:0;;:::o;5743:25::-;;;;:::o;52095:1116::-;6766:6;;;;6765:7;6757:80;;;;-1:-1:-1;;;6757:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58415:14;:12;:14::i;:::-;-1:-1:-1;;;;;58415:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58415:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;52189:5:0;;:42;;;-1:-1:-1;;;52189:42:0;;52205:10;52189:42;;;;52225:4;52189:42;;;;;;-1:-1:-1;;;;;52189:5:0;;;;-1:-1:-1;52189:15:0;;-1:-1:-1;52189:42:0;;;;;;;;;;;;;;;:5;:42;;;5:2:-1;;;;30:1;27;20:12;5:2;52189:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52189:42:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52189:42:0;52177:54;;;52169:92;;;;;-1:-1:-1;;;52169:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52292:5;;:27;;;-1:-1:-1;;;52292:27:0;;52308:10;52292:27;;;;;;-1:-1:-1;;;;;52292:5:0;;;;:15;;:27;;;;;;;;;;;;;;;:5;:27;;;5:2:-1;;;;30:1;27;20:12;5:2;52292:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52292:27:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52292:27:0;52280:39;;;52272:70;;;;;-1:-1:-1;;;52272:70:0;;;;;;;;;;;;-1:-1:-1;;;52272:70:0;;;;;;;;;;;;;;;52362:15;:13;:15::i;:::-;-1:-1:-1;;;;;52362:29:0;;52392:11;;52362:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52362:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52362:42:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52362:42:0;52361:43;52353:80;;;;;-1:-1:-1;;;52353:80:0;;;;;;;;;;;;-1:-1:-1;;;52353:80:0;;;;;;;;;;;;;;;52446:20;52469:10;:8;:10::i;:::-;52446:33;;52516:1;52498:15;:19;52490:70;;;;-1:-1:-1;;;52490:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52573:19;52613:8;52595:15;:26;:55;;52642:8;52595:55;;;52624:15;52595:55;52573:77;;52664:20;52686:13;52703:32;52720:14;52703:16;:32::i;:::-;52663:72;;;;52746:15;52764:8;:84;;52813:35;:14;52832:15;52813:35;:18;:35;:::i;:::-;52764:84;;;52775:35;:14;52794:15;52775:35;:18;:35;:::i;:::-;52940:5;;52746:102;;-1:-1:-1;52899:12:0;;52914:76;;-1:-1:-1;;;;;52940:5:0;52948:10;52968:4;52975:14;52914:17;:76::i;:::-;52899:91;;53009:7;53001:44;;;;;-1:-1:-1;;;53001:44:0;;;;;;;;;;;;-1:-1:-1;;;53001:44:0;;;;;;;;;;;;;;;53090:17;53096:10;53090:5;:17::i;:::-;53132:10;53125:78;53144:10;53156:8;:30;;53171:15;53156:30;;;53167:1;53156:30;53125:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;58464:1;;;;;;52095:1116;:::o;47993:26::-;;;;:::o;50535:244::-;50585:4;50703:15;:13;:15::i;:::-;-1:-1:-1;;;;;50703:30:0;;50734:11;;50747:17;;-1:-1:-1;;;50703:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;47967:19:0;;;-1:-1:-1;;;;;47967:19:0;;:::o;2669:133::-;2737:5;;-1:-1:-1;;;;;2737:5:0;2723:10;:19;2715:79;;;;-1:-1:-1;;;2715:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2669:133::o;33879:285::-;33950:3;33986:17;:15;:17::i;:::-;-1:-1:-1;;;;;33986:29:0;;-1:-1:-1;;;;;;34132:7:0;34084:56;;;;;;;;;;;-1:-1:-1;;;;;34084:56:0;-1:-1:-1;;;;;34084:56:0;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;34084:56:0;;;34074:67;;;;;;33986:170;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33986:170:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33986:170:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33986:170:0;;33879:285;-1:-1:-1;;33879:285:0:o;49817:146::-;49864:13;49911:43;-1:-1:-1;;;49911:20:0;:43::i;49394:121::-;49434:6;49467:39;49488:17;;49467:20;:39::i;49523:144::-;49571:14;49620:38;-1:-1:-1;;;49620:20:0;:38::i;36934:184::-;36992:7;37025:1;37020;:6;;37012:49;;;;;-1:-1:-1;;;37012:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37084:5:0;;;36934:184;;;;;:::o;40663:195::-;40727:4;39639:18;40835:8;:1;40841;40835:8;:5;:8;:::i;:::-;:15;;;;;;;40663:195;-1:-1:-1;;;40663:195:0:o;36478:181::-;36536:7;36568:5;;;36592:6;;;;36584:46;;;;;-1:-1:-1;;;36584:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;36650:1;36478:181;-1:-1:-1;;;36478:181:0:o;43804:186::-;43866:4;43964:18;43980:1;43964:11;:1;39639:18;43964:11;:5;:11;:::i;:::-;:15;:18;:15;:18;:::i;57076:1296::-;57376:84;;;-1:-1:-1;;;;;57376:84:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;57376:84:0;;;;;;;;25:18:-1;;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;57486:14:0;;57604:4;57231:12;57591:18;;;57231:12;57376:84;57486:14;;57231:12;;57486:14;;57231:12;57716:13;57709:5;57704:70;57694:2;;57805:1;57802;57795:12;57694:2;57851:4;57845:11;57879:4;57874:174;;;;58071:4;58066:64;;;;58148;;;;58333:1;58330;58323:12;57874:174;58028:1;58017:12;;57874:174;;58148:64;58192:1;58181:12;;57838:516;;57522:843;;;;;;;;:::o;55873:947::-;55921:13;55937;:11;:13::i;:::-;56119:17;;55921:29;;-1:-1:-1;56076:17:0;;56096:20;55921:29;56109:6;56096:20;:12;:20;:::i;:::-;:40;:90;;56185:1;56096:90;;;56164:17;;56139:43;;:20;:8;56152:6;56139:20;:12;:20;:::i;:::-;:24;:43;:24;:43;:::i;:::-;56076:110;;56199:20;56222:15;:13;:15::i;:::-;-1:-1:-1;;;;;56222:30:0;;56253:11;;56266:12;-1:-1:-1;;;56222:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56222:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56222:63:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56222:63:0;;-1:-1:-1;56350:7:0;:5;:7::i;:::-;-1:-1:-1;;;;;56350:12:0;;56363:10;56375:6;56350:32;;;;;;;;;;;;;-1:-1:-1;;;;;56350:32:0;-1:-1:-1;;;;;56350:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56350:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56350:32:0;;;;56581:1;56563:15;:19;56559:113;;;56599:11;:9;:11::i;:::-;-1:-1:-1;;;;;56599:17:0;;56625:16;:14;:16::i;:::-;56644:15;56599:61;;;;;;;;;;;;;-1:-1:-1;;;;;56599:61:0;-1:-1:-1;;;;;56599:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56599:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56599:61:0;;;;56559:113;56781:31;56803:8;56781:21;:31::i;:::-;55873:947;;;;:::o;34172:285::-;34243:3;34279:17;:15;:17::i;:::-;-1:-1:-1;;;;;34279:29:0;;-1:-1:-1;;;;;;34425:7:0;34377:56;;;;;;;;;;;-1:-1:-1;;;;;34377:56:0;-1:-1:-1;;;;;34377:56:0;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;34377:56:0;;;34367:67;;;;;;34279:170;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;43227:134:0;43296:4;43320:33;43342:1;43345;39639:18;43320:21;:33::i;28776:183::-;28885:16;;;28899:1;28885:16;;;;;;;;;28834:26;;28885:16;;;;;;105:10:-1;28885:16:0;88:34:-1;136:17;;-1:-1;28885:16:0;28873:28;;-1:-1:-1;;;28912:9:0;28922:1;28912:12;;;;;;;;;;;;;:39;;;;;28776:183;:::o;20434:458::-;20556:28;20645:6;:13;20630:5;:12;:28;20616:43;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;20616:43:0;-1:-1:-1;20602:57:0;-1:-1:-1;20677:6:0;20672:92;20693:5;:12;20689:1;:16;20672:92;;;20744:5;20750:1;20744:8;;;;;;;;;;;;;;20727:11;20739:1;20727:14;;;;;;;;;;;;;;;;;:25;20707:3;;20672:92;;;-1:-1:-1;20781:6:0;20776:109;20797:6;:13;20793:1;:17;20776:109;;;20864:6;20871:1;20864:9;;;;;;;;;;;;;;20832:11;20859:1;20844:5;:12;:16;20832:29;;;;;;;;;;;;;;;;;:41;20812:3;;20776:109;;;;20434:458;;;;:::o;33578:293::-;33652:4;33689:17;:15;:17::i;:::-;-1:-1:-1;;;;;33689:30:0;;-1:-1:-1;;;;;;33839:7:0;33788:59;;;;;;;;;;;-1:-1:-1;;;;;33788:59:0;-1:-1:-1;;;;;33788:59:0;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;33788:59:0;;;33778:70;;;;;;33689:174;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;55189:676:0;55237:13;55253;:11;:13::i;:::-;55237:29;;55279:17;55310:29;55332:6;55310:17;;:21;;:29;;;;:::i;:::-;55299:8;:40;:90;;55388:1;55299:90;;;55355:17;;55342:43;;55355:29;;55377:6;55355:29;:21;:29;:::i;:::-;55342:8;;:43;:12;:43;:::i;:::-;55279:110;;55400:20;55423:15;:13;:15::i;:::-;-1:-1:-1;;;;;55423:30:0;;55454:11;;55467:12;-1:-1:-1;;;55423:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55423:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55423:63:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55423:63:0;;-1:-1:-1;55534:7:0;:5;:7::i;:::-;-1:-1:-1;;;;;55534:13:0;;55548:10;55560:6;55534:33;;;;;;;;;;;;;-1:-1:-1;;;;;55534:33:0;-1:-1:-1;;;;;55534:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;28967:158:0;29017:16;29070:46;-1:-1:-1;;;22473:268:0;22540:7;22584:18;;;:12;:18;;;;;;;;;22657:43;;-1:-1:-1;;;22657:43:0;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;22657:43:0;;;;;;;-1:-1:-1;;;;;22584:18:0;;22621:27;22613:89;;;;-1:-1:-1;;;22613:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;22613:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37369:470;37427:7;37671:6;37667:47;;-1:-1:-1;37701:1:0;37694:8;;37667:47;37738:5;;;37742:1;37738;:5;:1;37762:5;;;;;:10;37754:56;;;;-1:-1:-1;;;37754:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38307:333;38365:7;38464:1;38460;:5;38452:44;;;;;-1:-1:-1;;;38452:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;38507:9;38523:1;38519;:5;;;;;;;38307:333;-1:-1:-1;;;;38307:333:0:o;49259:127::-;49303:6;49336:41;-1:-1:-1;;;49336:20:0;:41::i;49971:154::-;50020:15;50071:45;-1:-1:-1;;;50071:20:0;:45::i;56828:240::-;56904:11;:9;:11::i;:::-;-1:-1:-1;;;;;56904:36:0;;56941:11;;56990:17;;56961:18;56954:54;56904:105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56904:105:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;;57022:17:0;:38;;;;-1:-1:-1;56828:240:0:o;41477:421::-;41600:4;;41753:2;41737:13;:18;41725:8;:1;41731;41725:8;:5;:8;:::i;:::-;:31;;;;;;;-1:-1:-1;41798:1:0;41792:2;41725:31;41773:21;:26;41769:81;;41836:2;41816:22;41769:81;41888:2;41869:21;;;;-1:-1:-1;;;;41477:421:0:o;49675:134::-;49719:10;49760:40;-1:-1:-1;;;49760:20:0;:40::i
Swarm Source
bzzr://8ec50d2f478726a4ebd76ed5ccd94f51be6f5bcfb30e7fafaa463d9527413ff0
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ 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.