Source Code
Overview
ETH Balance
0 ETH
Token Holdings
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 74 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
Amount
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Mint | 20088917 | 427 days ago | IN | 0 ETH | 0.00000026781 | ||||
| Mint | 19635005 | 438 days ago | IN | 0 ETH | 0.000000105848 | ||||
| Mint | 19634898 | 438 days ago | IN | 0 ETH | 0.000000100992 | ||||
| Mint | 19634854 | 438 days ago | IN | 0 ETH | 0.000000100436 | ||||
| Mint | 16435611 | 512 days ago | IN | 0 ETH | 0.000008303382 | ||||
| Mint | 13800593 | 573 days ago | IN | 0 ETH | 0.000038446026 | ||||
| Mint | 13100113 | 589 days ago | IN | 0 ETH | 0.000029672197 | ||||
| Mint | 13100053 | 589 days ago | IN | 0 ETH | 0.00000004152 | ||||
| Mint | 13100027 | 589 days ago | IN | 0 ETH | 0.000000041533 | ||||
| Mint | 12673752 | 599 days ago | IN | 0 ETH | 0.000372988506 | ||||
| Mint | 12673307 | 599 days ago | IN | 0 ETH | 0.000110929978 | ||||
| Mint | 11947754 | 616 days ago | IN | 0 ETH | 0.001122219182 | ||||
| Mint | 11945491 | 616 days ago | IN | 0 ETH | 0.000459804183 | ||||
| Mint | 11691294 | 622 days ago | IN | 0 ETH | 0.001366101001 | ||||
| Mint | 11691179 | 622 days ago | IN | 0 ETH | 0.001462715938 | ||||
| Mint | 11690648 | 622 days ago | IN | 0 ETH | 0.001115876887 | ||||
| Mint | 11690515 | 622 days ago | IN | 0 ETH | 0.001445529989 | ||||
| Mint | 11690491 | 622 days ago | IN | 0 ETH | 0.00092356599 | ||||
| Mint | 11690476 | 622 days ago | IN | 0 ETH | 0.001036531374 | ||||
| Mint | 11690458 | 622 days ago | IN | 0 ETH | 0.000956133648 | ||||
| Mint | 11690403 | 622 days ago | IN | 0 ETH | 0.001046540446 | ||||
| Mint | 11690284 | 622 days ago | IN | 0 ETH | 0.001440533663 | ||||
| Mint | 11690273 | 622 days ago | IN | 0 ETH | 0.00149566063 | ||||
| Mint | 11690253 | 622 days ago | IN | 0 ETH | 0.001195342408 | ||||
| Mint | 11690131 | 622 days ago | IN | 0 ETH | 0.001158030999 |
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 sepolia-optimism.etherscan.io on 2024-02-28
*/
/**
*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;
pragma experimental ABIEncoderV2;
// 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 ABI
API[{"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
60806040523480156200001157600080fd5b50604051620029a3380380620029a38339810160408190526200003491620001f7565b8380866001600160a01b038116620000695760405162461bcd60e51b8152600401620000609062000388565b60405180910390fd5b600080546001600160a01b0319166001600160a01b0383161781556040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91620000b691849062000331565b60405180910390a1506000546001600160a01b0316620000ea5760405162461bcd60e51b8152600401620000609062000376565b60038054610100600160a81b0319166101006001600160a01b0393841602179055600580546001600160a01b031916868316179081905560068590556007849055600060085560405163095ea7b360e01b81529116915063095ea7b3906200015b9030906000199060040162000357565b602060405180830381600087803b1580156200017657600080fd5b505af11580156200018b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620001b1919081019062000277565b50505050505062000419565b8051620001ca81620003de565b92915050565b8051620001ca81620003f8565b8051620001ca8162000403565b8051620001ca816200040e565b600080600080600060a086880312156200021057600080fd5b60006200021e8888620001bd565b95505060206200023188828901620001bd565b94505060406200024488828901620001ea565b93505060606200025788828901620001dd565b92505060806200026a88828901620001dd565b9150509295509295909350565b6000602082840312156200028a57600080fd5b6000620002988484620001d0565b949350505050565b620002ab81620003d1565b82525050565b620002ab81620003a3565b6000620002cb6011836200039a565b7013dddb995c881b5d5cdd081899481cd95d607a1b815260200192915050565b6000620002fa6019836200039a565b7f4f776e657220616464726573732063616e6e6f74206265203000000000000000815260200192915050565b620002ab81620003b5565b60408101620003418285620002a0565b620003506020830184620002b1565b9392505050565b60408101620003678285620002a0565b62000350602083018462000326565b60208082528101620001ca81620002bc565b60208082528101620001ca81620002eb565b90815260200190565b6000620001ca82620003c5565b151590565b90565b6000620001ca82620003a3565b6001600160a01b031690565b6000620001ca82620003b8565b620003e981620003a3565b8114620003f557600080fd5b50565b620003e981620003b0565b620003e981620003b5565b620003e981620003b8565b61257a80620004296000396000f3fe6080604052600436106101665760003560e01c80635c975abb116100d15780638a926d0f1161008a578063a0712d6811610064578063a0712d68146103d1578063dbd06c85146103f1578063ee5f3f5c14610406578063fc0c546a1461041b57610166565b80638a926d0f146103925780638da5cb5b146103a757806391b4ded9146103bc57610166565b80635c975abb146102fc5780635cfc1a51146103115780636ad8826914610326578063741853601461034657806379ba50971461035b578063899ffef41461037057610166565b80631f23a352116101235780631f23a352146102405780632af64bd31461025557806342966c6814610277578063509bf42a1461029757806353a47bb7146102ac5780635c095e54146102ce57610166565b806304f3bcec146101875780630902f1ac146101b25780631627540c146101d457806316c38b3c146101f657806317c943bc1461021657806318819a311461022b575b60405162461bcd60e51b815260040161017e90612393565b60405180910390fd5b34801561019357600080fd5b5061019c610430565b6040516101a99190612364565b60405180910390f35b3480156101be57600080fd5b506101c7610444565b6040516101a991906122ff565b3480156101e057600080fd5b506101f46101ef366004611c2a565b6104cb565b005b34801561020257600080fd5b506101f4610211366004611c6e565b610529565b34801561022257600080fd5b506101c761059e565b34801561023757600080fd5b506101c76105a4565b34801561024c57600080fd5b506101c76105af565b34801561026157600080fd5b5061026a6105b5565b6040516101a991906122f1565b34801561028357600080fd5b506101f4610292366004611cc8565b6106d1565b3480156102a357600080fd5b506101c7610b13565b3480156102b857600080fd5b506102c1610b1e565b6040516101a9919061223d565b3480156102da57600080fd5b506102ee6102e9366004611cc8565b610b2d565b6040516101a9929190612463565b34801561030857600080fd5b5061026a610b82565b34801561031d57600080fd5b506101c7610b8b565b34801561033257600080fd5b506102ee610341366004611cc8565b610bcd565b34801561035257600080fd5b506101f4610bda565b34801561036757600080fd5b506101f4610d30565b34801561037c57600080fd5b50610385610dcc565b6040516101a991906122e0565b34801561039e57600080fd5b506101c7610eee565b3480156103b357600080fd5b506102c1610ef9565b3480156103c857600080fd5b506101c7610f08565b3480156103dd57600080fd5b506101f46103ec366004611cc8565b610f0e565b3480156103fd57600080fd5b506101c761126d565b34801561041257600080fd5b506101c7611273565b34801561042757600080fd5b5061019c6112b7565b60035461010090046001600160a01b031681565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a082319061047590309060040161224b565b60206040518083038186803b15801561048d57600080fd5b505afa1580156104a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104c59190810190611caa565b90505b90565b6104d36112c6565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229061051e90839061223d565b60405180910390a150565b6105316112c6565b60035460ff16151581151514156105475761059b565b6003805460ff1916821515179081905560ff161561056457426002555b6003546040517f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec59161051e9160ff909116906122f1565b50565b60085481565b60006104c5306112f2565b60075481565b600060606105c1610dcc565b905060005b81518110156106c85760008282815181106105dd57fe5b60209081029190910181015160008181526004928390526040908190205460035491516321f8a72160e01b81529294506001600160a01b039081169361010090920416916321f8a72191610633918691016122ff565b60206040518083038186803b15801561064b57600080fd5b505afa15801561065f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106839190810190611c50565b6001600160a01b03161415806106ae57506000818152600460205260409020546001600160a01b0316155b156106bf57600093505050506104c8565b506001016105c6565b50600191505090565b60035460ff16156106f45760405162461bcd60e51b815260040161017e90612433565b6106fc6113cd565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b15801561073457600080fd5b505afa158015610748573d6000803e3d6000fd5b505050506107546113e7565b6001600160a01b03166370a08231336040518263ffffffff1660e01b815260040161077f919061224b565b60206040518083038186803b15801561079757600080fd5b505afa1580156107ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107cf9190810190611caa565b8111156107ee5760405162461bcd60e51b815260040161017e90612423565b6107f66113f4565b6001600160a01b0316632528f0fe6006546040518263ffffffff1660e01b815260040161082391906122ff565b60206040518083038186803b15801561083b57600080fd5b505afa15801561084f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108739190810190611c8c565b156108905760405162461bcd60e51b815260040161017e906123c3565b600061089a611273565b116108b75760405162461bcd60e51b815260040161017e90612453565b6000806108c5600854610bcd565b9150915060008082156109935784600854106108e157846108f4565b6008546108f4908563ffffffff61140f16565b915061098c610901610b13565b732ad7ccaac0eeb396c3a5fc2b73a885435688c0d563907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b15801561094557600080fd5b505af4158015610959573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061097d9190810190611caa565b8491900363ffffffff61143716565b9050610a60565b60085485906109a8908663ffffffff61146116565b106109b357846109c6565b6008546109c6908563ffffffff61146116565b9150610a5d6109d3610b13565b732ad7ccaac0eeb396c3a5fc2b73a885435688c0d563907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1757600080fd5b505af4158015610a2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a4f9190810190611caa565b84910163ffffffff61148d16565b90505b600083610a7c57610a77838363ffffffff61140f16565b610a7f565b60005b600554909150600090610a9d906001600160a01b03163033866114b7565b905080610abc5760405162461bcd60e51b815260040161017e906123f3565b610ac58461154f565b336001600160a01b03167f4c60206a5c1de41f3376d1d60f0949d96cb682033c90b1c2d9d9a62d4c4120c0848487604051610b0293929190612349565b60405180910390a250505050505050565b60006104c530611725565b6001546001600160a01b031681565b6000806000610b3a6105a4565b90506000811215610b6557610b5984600083900363ffffffff61177716565b60019250925050610b7d565b610b75848263ffffffff61177716565b600092509250505b915091565b60035460ff1681565b600080610b96610444565b90506000610ba2610eee565b9050808210610bb6576000925050506104c8565b610bc6818363ffffffff61140f16565b9250505090565b6000806000610b3a610b13565b6060610be4610dcc565b905060005b8151811015610d2c576000828281518110610c0057fe5b602002602001015190506000600360019054906101000a90046001600160a01b03166001600160a01b031663dacb2d018384604051602001610c429190612232565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401610c6e929190612329565b60206040518083038186803b158015610c8657600080fd5b505afa158015610c9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610cbe9190810190611c50565b6000838152600460205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa6890610d1a908490849061230d565b60405180910390a15050600101610be9565b5050565b6001546001600160a01b03163314610d5a5760405162461bcd60e51b815260040161017e90612383565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c92610d9d926001600160a01b039182169291169061228f565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b606080610dd761178c565b60408051600680825260e08201909252919250606091906020820160c0803883390190505090506814de5b9d1a1cd554d160ba1b81600081518110610e1857fe5b60200260200101818152505060075481600181518110610e3457fe5b6020026020010181815250506c45786368616e6765526174657360981b81600281518110610e5e57fe5b6020026020010181815250506844656274436163686560b81b81600381518110610e8457fe5b6020026020010181815250506b53797374656d53746174757360a01b81600481518110610ead57fe5b6020026020010181815250506d57726170706572466163746f727960901b81600581518110610ed857fe5b602002602001018181525050610bc682826117dd565b60006104c530611899565b6000546001600160a01b031681565b60025481565b60035460ff1615610f315760405162461bcd60e51b815260040161017e90612433565b610f396113cd565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015610f7157600080fd5b505afa158015610f85573d6000803e3d6000fd5b5050600554604051636eb1769f60e11b81526001600160a01b03909116925063dd62ed3e9150610fbb9033903090600401612259565b60206040518083038186803b158015610fd357600080fd5b505afa158015610fe7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061100b9190810190611caa565b81111561102a5760405162461bcd60e51b815260040161017e906123a3565b6005546040516370a0823160e01b81526001600160a01b03909116906370a082319061105a90339060040161224b565b60206040518083038186803b15801561107257600080fd5b505afa158015611086573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110aa9190810190611caa565b8111156110c95760405162461bcd60e51b815260040161017e90612423565b6110d16113f4565b6001600160a01b0316632528f0fe6006546040518263ffffffff1660e01b81526004016110fe91906122ff565b60206040518083038186803b15801561111657600080fd5b505afa15801561112a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061114e9190810190611c8c565b1561116b5760405162461bcd60e51b815260040161017e906123c3565b6000611175610b8b565b9050600081116111975760405162461bcd60e51b815260040161017e90612443565b60008282106111a657826111a8565b815b90506000806111b683610b2d565b915091506000816111d6576111d1848463ffffffff61140f16565b6111e6565b6111e6848463ffffffff61146116565b600554909150600090611204906001600160a01b03163330886114b7565b9050806112235760405162461bcd60e51b815260040161017e906123f3565b61122c826118e9565b337f5a3358a3d27a5373c0df2604662088d37894d56b7cfd27f315770440f4e0d919838561125a578661125d565b60005b88604051610b0293929190612349565b60065481565b600061127d6113f4565b6001600160a01b031663654a60ac600654600854631cd554d160e21b6040518463ffffffff1660e01b815260040161047593929190612349565b6005546001600160a01b031681565b6000546001600160a01b031633146112f05760405162461bcd60e51b815260040161017e90612403565b565b60006112fc611a08565b6001600160a01b031663c4f610ed6d53797374656d53657474696e677360901b71777261707065724d696e744665655261746560701b856040516020016113449291906121ec565b604051602081830303815290604052805190602001206040518363ffffffff1660e01b815260040161137792919061231b565b60206040518083038186803b15801561138f57600080fd5b505afa1580156113a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113c79190810190611caa565b92915050565b60006104c56b53797374656d53746174757360a01b611a21565b60006104c5600754611a21565b60006104c56c45786368616e6765526174657360981b611a21565b6000828211156114315760405162461bcd60e51b815260040161017e906123d3565b50900390565b6000670de0b6b3a7640000611452848463ffffffff611a7e16565b8161145957fe5b049392505050565b6000828201838110156114865760405162461bcd60e51b815260040161017e906123b3565b9392505050565b6000611486826114ab85670de0b6b3a764000063ffffffff611a7e16565b9063ffffffff611ab816565b600060608484846040516024016114d0939291906122aa565b60408051601f19818403018152919052602080820180516001600160e01b03166323b872dd60e01b178152825160ff600090815293945092908390828b5af161151857600080fd5b60005160ff8114611536576001811461153657801561153f57600080fd5b60019350611544565b600093505b505050949350505050565b6000611559610444565b600854909150600090611572838563ffffffff61146116565b1161157e5760006115a1565b6008546115a190611595848663ffffffff61146116565b9063ffffffff61140f16565b905060006115ad6113f4565b6001600160a01b031663654a60ac60065484631cd554d160e21b6040518463ffffffff1660e01b81526004016115e593929190612349565b60206040518083038186803b1580156115fd57600080fd5b505afa158015611611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116359190810190611caa565b905061163f6113e7565b6001600160a01b0316639dc29fac33866040518363ffffffff1660e01b815260040161166c929190612274565b600060405180830381600087803b15801561168657600080fd5b505af115801561169a573d6000803e3d6000fd5b505050506000811115611716576116af611aed565b6001600160a01b031663867904b46116c5611b04565b836040518363ffffffff1660e01b81526004016116e39291906122d2565b600060405180830381600087803b1580156116fd57600080fd5b505af1158015611711573d6000803e3d6000fd5b505050505b61171f83611b20565b50505050565b600061172f611a08565b6001600160a01b031663c4f610ed6d53797374656d53657474696e677360901b71777261707065724275726e4665655261746560701b856040516020016113449291906121ec565b60006114868383670de0b6b3a7640000611b95565b604080516001808252818301909252606091602080830190803883390190505090506e466c657869626c6553746f7261676560881b816000815181106117ce57fe5b60200260200101818152505090565b6060815183510160405190808252806020026020018201604052801561180d578160200160208202803883390190505b50905060005b835181101561184f5783818151811061182857fe5b602002602001015182828151811061183c57fe5b6020908102919091010152600101611813565b5060005b82518110156118925782818151811061186857fe5b602002602001015182828651018151811061187f57fe5b6020908102919091010152600101611853565b5092915050565b60006118a3611a08565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b6f777261707065724d6178546f6b656e7360801b856040516020016113449291906121ec565b60006118f3610444565b9050600061190c8360085461146190919063ffffffff16565b821161191957600061193d565b60085461193d90611930908563ffffffff61146116565b839063ffffffff61140f16565b905060006119496113f4565b6001600160a01b031663654a60ac60065484631cd554d160e21b6040518463ffffffff1660e01b815260040161198193929190612349565b60206040518083038186803b15801561199957600080fd5b505afa1580156119ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506119d19190810190611caa565b90506119db6113e7565b6001600160a01b031663867904b433866040518363ffffffff1660e01b815260040161166c929190612274565b60006104c56e466c657869626c6553746f7261676560881b5b60008181526004602090815260408083205490516001600160a01b039091169182151591611a5191869101612212565b604051602081830303815290604052906118925760405162461bcd60e51b815260040161017e9190612372565b600082611a8d575060006113c7565b82820282848281611a9a57fe5b04146114865760405162461bcd60e51b815260040161017e90612413565b6000808211611ad95760405162461bcd60e51b815260040161017e906123e3565b6000828481611ae457fe5b04949350505050565b60006104c56814de5b9d1a1cd554d160ba1b611a21565b60006104c56d57726170706572466163746f727960901b611a21565b611b28611bd1565b6001600160a01b0316639e3b92ca60065460085484036040518363ffffffff1660e01b8152600401611b5b92919061231b565b600060405180830381600087803b158015611b7557600080fd5b505af1158015611b89573d6000803e3d6000fd5b50505060089190915550565b600080600a8304611bac868663ffffffff611a7e16565b81611bb357fe5b0490506005600a820610611bc557600a015b600a9004949350505050565b60006104c56844656274436163686560b81b611a21565b80356113c781612511565b80516113c781612511565b80356113c781612525565b80516113c781612525565b80516113c78161252e565b80356113c78161252e565b600060208284031215611c3c57600080fd5b6000611c488484611be8565b949350505050565b600060208284031215611c6257600080fd5b6000611c488484611bf3565b600060208284031215611c8057600080fd5b6000611c488484611bfe565b600060208284031215611c9e57600080fd5b6000611c488484611c09565b600060208284031215611cbc57600080fd5b6000611c488484611c14565b600060208284031215611cda57600080fd5b6000611c488484611c1f565b6000611cf28383611d85565b505060200190565b611d03816124b2565b82525050565b611d0381612496565b611d03611d1e82612496565b6124f0565b6000611d2e82612484565b611d388185612488565b9350611d438361247e565b8060005b83811015611d71578151611d5b8882611ce6565b9750611d668361247e565b925050600101611d47565b509495945050505050565b611d03816124a1565b611d03816104c8565b611d03611d9a826104c8565b6104c8565b611d03816124b9565b6000611db382612484565b611dbd8185612488565b9350611dcd8185602086016124c4565b611dd681612501565b9093019392505050565b6000611ded603583612488565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527402063616e20616363657074206f776e65727368697605c1b602082015260400192915050565b6000611e44601d83612488565b7f46616c6c6261636b2064697361626c65642c20757365206d696e742829000000815260200192915050565b6000611e7d601983612488565b7f416c6c6f77616e6365206e6f74206869676820656e6f75676800000000000000815260200192915050565b6000611eb6601b83612488565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000611eef601883612488565b7f43757272656e6379207261746520697320696e76616c69640000000000000000815260200192915050565b6000611f28601e83612488565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b6000611f61601a83612488565b7f536166654d6174683a206469766973696f6e206279207a65726f000000000000815260200192915050565b6000611f9a601183612491565b70026b4b9b9b4b7339030b2323932b9b99d1607d1b815260110192915050565b6000611fc7601883612488565b7f5472616e7366657220646964206e6f7420737563636565640000000000000000815260200192915050565b6000612000602f83612488565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681526e37b936903a3434b99030b1ba34b7b760891b602082015260400192915050565b6000612051602183612488565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000612094601283612488565b7142616c616e636520697320746f6f206c6f7760701b815260200192915050565b60006120c2603c83612488565b7f5468697320616374696f6e2063616e6e6f7420626520706572666f726d65642081527f7768696c652074686520636f6e74726163742069732070617573656400000000602082015260400192915050565b6000612121601983612491565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b600061215a602683612488565b7f436f6e747261637420686173206e6f20737061726520636170616369747920748152651bc81b5a5b9d60d21b602082015260400192915050565b60006121a2603583612488565b7f436f6e74726163742063616e6e6f74206275726e20666f7220746f6b656e2c20815274746f6b656e2062616c616e6365206973207a65726f60581b602082015260400192915050565b60006121f88285611d8e565b6020820191506122088284611d12565b5060140192915050565b600061221d82611f8d565b91506122298284611d8e565b50602001919050565b600061221d82612114565b602081016113c78284611d09565b602081016113c78284611cfa565b604081016122678285611cfa565b6114866020830184611cfa565b604081016122828285611cfa565b6114866020830184611d85565b6040810161229d8285611d09565b6114866020830184611d09565b606081016122b88286611d09565b6122c56020830185611d09565b611c486040830184611d85565b604081016122828285611d09565b602080825281016114868184611d23565b602081016113c78284611d7c565b602081016113c78284611d85565b6040810161229d8285611d85565b604081016122828285611d85565b604081016123378285611d85565b8181036020830152611c488184611da8565b606081016123578286611d85565b6122c56020830185611d85565b602081016113c78284611d9f565b602080825281016114868184611da8565b602080825281016113c781611de0565b602080825281016113c781611e37565b602080825281016113c781611e70565b602080825281016113c781611ea9565b602080825281016113c781611ee2565b602080825281016113c781611f1b565b602080825281016113c781611f54565b602080825281016113c781611fba565b602080825281016113c781611ff3565b602080825281016113c781612044565b602080825281016113c781612087565b602080825281016113c7816120b5565b602080825281016113c78161214d565b602080825281016113c781612195565b604081016124718285611d85565b6114866020830184611d7c565b60200190565b5190565b90815260200190565b919050565b60006113c7826124a6565b151590565b6001600160a01b031690565b60006113c7825b60006113c782612496565b60005b838110156124df5781810151838201526020016124c7565b8381111561171f5750506000910152565b60006113c78260006113c78261250b565b601f01601f191690565b60601b90565b61251a81612496565b811461059b57600080fd5b61251a816124a1565b61251a816104c856fea365627a7a72315820b1c4b0e75aa342df894bad2f1424212f7596a6f05c247520dbb2ceecb0ea92b26c6578706572696d656e74616cf564736f6c6343000510004000000000000000000000000048914229dedd5a9922f44441ffccfc2cb7856ee9000000000000000000000000529c553ef2d0370279dc8abf19702b98b166d2520000000000000000000000004200000000000000000000000000000000000006734554480000000000000000000000000000000000000000000000000000000053796e7468734554480000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101665760003560e01c80635c975abb116100d15780638a926d0f1161008a578063a0712d6811610064578063a0712d68146103d1578063dbd06c85146103f1578063ee5f3f5c14610406578063fc0c546a1461041b57610166565b80638a926d0f146103925780638da5cb5b146103a757806391b4ded9146103bc57610166565b80635c975abb146102fc5780635cfc1a51146103115780636ad8826914610326578063741853601461034657806379ba50971461035b578063899ffef41461037057610166565b80631f23a352116101235780631f23a352146102405780632af64bd31461025557806342966c6814610277578063509bf42a1461029757806353a47bb7146102ac5780635c095e54146102ce57610166565b806304f3bcec146101875780630902f1ac146101b25780631627540c146101d457806316c38b3c146101f657806317c943bc1461021657806318819a311461022b575b60405162461bcd60e51b815260040161017e90612393565b60405180910390fd5b34801561019357600080fd5b5061019c610430565b6040516101a99190612364565b60405180910390f35b3480156101be57600080fd5b506101c7610444565b6040516101a991906122ff565b3480156101e057600080fd5b506101f46101ef366004611c2a565b6104cb565b005b34801561020257600080fd5b506101f4610211366004611c6e565b610529565b34801561022257600080fd5b506101c761059e565b34801561023757600080fd5b506101c76105a4565b34801561024c57600080fd5b506101c76105af565b34801561026157600080fd5b5061026a6105b5565b6040516101a991906122f1565b34801561028357600080fd5b506101f4610292366004611cc8565b6106d1565b3480156102a357600080fd5b506101c7610b13565b3480156102b857600080fd5b506102c1610b1e565b6040516101a9919061223d565b3480156102da57600080fd5b506102ee6102e9366004611cc8565b610b2d565b6040516101a9929190612463565b34801561030857600080fd5b5061026a610b82565b34801561031d57600080fd5b506101c7610b8b565b34801561033257600080fd5b506102ee610341366004611cc8565b610bcd565b34801561035257600080fd5b506101f4610bda565b34801561036757600080fd5b506101f4610d30565b34801561037c57600080fd5b50610385610dcc565b6040516101a991906122e0565b34801561039e57600080fd5b506101c7610eee565b3480156103b357600080fd5b506102c1610ef9565b3480156103c857600080fd5b506101c7610f08565b3480156103dd57600080fd5b506101f46103ec366004611cc8565b610f0e565b3480156103fd57600080fd5b506101c761126d565b34801561041257600080fd5b506101c7611273565b34801561042757600080fd5b5061019c6112b7565b60035461010090046001600160a01b031681565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a082319061047590309060040161224b565b60206040518083038186803b15801561048d57600080fd5b505afa1580156104a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104c59190810190611caa565b90505b90565b6104d36112c6565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229061051e90839061223d565b60405180910390a150565b6105316112c6565b60035460ff16151581151514156105475761059b565b6003805460ff1916821515179081905560ff161561056457426002555b6003546040517f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec59161051e9160ff909116906122f1565b50565b60085481565b60006104c5306112f2565b60075481565b600060606105c1610dcc565b905060005b81518110156106c85760008282815181106105dd57fe5b60209081029190910181015160008181526004928390526040908190205460035491516321f8a72160e01b81529294506001600160a01b039081169361010090920416916321f8a72191610633918691016122ff565b60206040518083038186803b15801561064b57600080fd5b505afa15801561065f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106839190810190611c50565b6001600160a01b03161415806106ae57506000818152600460205260409020546001600160a01b0316155b156106bf57600093505050506104c8565b506001016105c6565b50600191505090565b60035460ff16156106f45760405162461bcd60e51b815260040161017e90612433565b6106fc6113cd565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b15801561073457600080fd5b505afa158015610748573d6000803e3d6000fd5b505050506107546113e7565b6001600160a01b03166370a08231336040518263ffffffff1660e01b815260040161077f919061224b565b60206040518083038186803b15801561079757600080fd5b505afa1580156107ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107cf9190810190611caa565b8111156107ee5760405162461bcd60e51b815260040161017e90612423565b6107f66113f4565b6001600160a01b0316632528f0fe6006546040518263ffffffff1660e01b815260040161082391906122ff565b60206040518083038186803b15801561083b57600080fd5b505afa15801561084f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108739190810190611c8c565b156108905760405162461bcd60e51b815260040161017e906123c3565b600061089a611273565b116108b75760405162461bcd60e51b815260040161017e90612453565b6000806108c5600854610bcd565b9150915060008082156109935784600854106108e157846108f4565b6008546108f4908563ffffffff61140f16565b915061098c610901610b13565b732ad7ccaac0eeb396c3a5fc2b73a885435688c0d563907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b15801561094557600080fd5b505af4158015610959573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061097d9190810190611caa565b8491900363ffffffff61143716565b9050610a60565b60085485906109a8908663ffffffff61146116565b106109b357846109c6565b6008546109c6908563ffffffff61146116565b9150610a5d6109d3610b13565b732ad7ccaac0eeb396c3a5fc2b73a885435688c0d563907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1757600080fd5b505af4158015610a2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a4f9190810190611caa565b84910163ffffffff61148d16565b90505b600083610a7c57610a77838363ffffffff61140f16565b610a7f565b60005b600554909150600090610a9d906001600160a01b03163033866114b7565b905080610abc5760405162461bcd60e51b815260040161017e906123f3565b610ac58461154f565b336001600160a01b03167f4c60206a5c1de41f3376d1d60f0949d96cb682033c90b1c2d9d9a62d4c4120c0848487604051610b0293929190612349565b60405180910390a250505050505050565b60006104c530611725565b6001546001600160a01b031681565b6000806000610b3a6105a4565b90506000811215610b6557610b5984600083900363ffffffff61177716565b60019250925050610b7d565b610b75848263ffffffff61177716565b600092509250505b915091565b60035460ff1681565b600080610b96610444565b90506000610ba2610eee565b9050808210610bb6576000925050506104c8565b610bc6818363ffffffff61140f16565b9250505090565b6000806000610b3a610b13565b6060610be4610dcc565b905060005b8151811015610d2c576000828281518110610c0057fe5b602002602001015190506000600360019054906101000a90046001600160a01b03166001600160a01b031663dacb2d018384604051602001610c429190612232565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401610c6e929190612329565b60206040518083038186803b158015610c8657600080fd5b505afa158015610c9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610cbe9190810190611c50565b6000838152600460205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa6890610d1a908490849061230d565b60405180910390a15050600101610be9565b5050565b6001546001600160a01b03163314610d5a5760405162461bcd60e51b815260040161017e90612383565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c92610d9d926001600160a01b039182169291169061228f565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b606080610dd761178c565b60408051600680825260e08201909252919250606091906020820160c0803883390190505090506814de5b9d1a1cd554d160ba1b81600081518110610e1857fe5b60200260200101818152505060075481600181518110610e3457fe5b6020026020010181815250506c45786368616e6765526174657360981b81600281518110610e5e57fe5b6020026020010181815250506844656274436163686560b81b81600381518110610e8457fe5b6020026020010181815250506b53797374656d53746174757360a01b81600481518110610ead57fe5b6020026020010181815250506d57726170706572466163746f727960901b81600581518110610ed857fe5b602002602001018181525050610bc682826117dd565b60006104c530611899565b6000546001600160a01b031681565b60025481565b60035460ff1615610f315760405162461bcd60e51b815260040161017e90612433565b610f396113cd565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015610f7157600080fd5b505afa158015610f85573d6000803e3d6000fd5b5050600554604051636eb1769f60e11b81526001600160a01b03909116925063dd62ed3e9150610fbb9033903090600401612259565b60206040518083038186803b158015610fd357600080fd5b505afa158015610fe7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061100b9190810190611caa565b81111561102a5760405162461bcd60e51b815260040161017e906123a3565b6005546040516370a0823160e01b81526001600160a01b03909116906370a082319061105a90339060040161224b565b60206040518083038186803b15801561107257600080fd5b505afa158015611086573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110aa9190810190611caa565b8111156110c95760405162461bcd60e51b815260040161017e90612423565b6110d16113f4565b6001600160a01b0316632528f0fe6006546040518263ffffffff1660e01b81526004016110fe91906122ff565b60206040518083038186803b15801561111657600080fd5b505afa15801561112a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061114e9190810190611c8c565b1561116b5760405162461bcd60e51b815260040161017e906123c3565b6000611175610b8b565b9050600081116111975760405162461bcd60e51b815260040161017e90612443565b60008282106111a657826111a8565b815b90506000806111b683610b2d565b915091506000816111d6576111d1848463ffffffff61140f16565b6111e6565b6111e6848463ffffffff61146116565b600554909150600090611204906001600160a01b03163330886114b7565b9050806112235760405162461bcd60e51b815260040161017e906123f3565b61122c826118e9565b337f5a3358a3d27a5373c0df2604662088d37894d56b7cfd27f315770440f4e0d919838561125a578661125d565b60005b88604051610b0293929190612349565b60065481565b600061127d6113f4565b6001600160a01b031663654a60ac600654600854631cd554d160e21b6040518463ffffffff1660e01b815260040161047593929190612349565b6005546001600160a01b031681565b6000546001600160a01b031633146112f05760405162461bcd60e51b815260040161017e90612403565b565b60006112fc611a08565b6001600160a01b031663c4f610ed6d53797374656d53657474696e677360901b71777261707065724d696e744665655261746560701b856040516020016113449291906121ec565b604051602081830303815290604052805190602001206040518363ffffffff1660e01b815260040161137792919061231b565b60206040518083038186803b15801561138f57600080fd5b505afa1580156113a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113c79190810190611caa565b92915050565b60006104c56b53797374656d53746174757360a01b611a21565b60006104c5600754611a21565b60006104c56c45786368616e6765526174657360981b611a21565b6000828211156114315760405162461bcd60e51b815260040161017e906123d3565b50900390565b6000670de0b6b3a7640000611452848463ffffffff611a7e16565b8161145957fe5b049392505050565b6000828201838110156114865760405162461bcd60e51b815260040161017e906123b3565b9392505050565b6000611486826114ab85670de0b6b3a764000063ffffffff611a7e16565b9063ffffffff611ab816565b600060608484846040516024016114d0939291906122aa565b60408051601f19818403018152919052602080820180516001600160e01b03166323b872dd60e01b178152825160ff600090815293945092908390828b5af161151857600080fd5b60005160ff8114611536576001811461153657801561153f57600080fd5b60019350611544565b600093505b505050949350505050565b6000611559610444565b600854909150600090611572838563ffffffff61146116565b1161157e5760006115a1565b6008546115a190611595848663ffffffff61146116565b9063ffffffff61140f16565b905060006115ad6113f4565b6001600160a01b031663654a60ac60065484631cd554d160e21b6040518463ffffffff1660e01b81526004016115e593929190612349565b60206040518083038186803b1580156115fd57600080fd5b505afa158015611611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116359190810190611caa565b905061163f6113e7565b6001600160a01b0316639dc29fac33866040518363ffffffff1660e01b815260040161166c929190612274565b600060405180830381600087803b15801561168657600080fd5b505af115801561169a573d6000803e3d6000fd5b505050506000811115611716576116af611aed565b6001600160a01b031663867904b46116c5611b04565b836040518363ffffffff1660e01b81526004016116e39291906122d2565b600060405180830381600087803b1580156116fd57600080fd5b505af1158015611711573d6000803e3d6000fd5b505050505b61171f83611b20565b50505050565b600061172f611a08565b6001600160a01b031663c4f610ed6d53797374656d53657474696e677360901b71777261707065724275726e4665655261746560701b856040516020016113449291906121ec565b60006114868383670de0b6b3a7640000611b95565b604080516001808252818301909252606091602080830190803883390190505090506e466c657869626c6553746f7261676560881b816000815181106117ce57fe5b60200260200101818152505090565b6060815183510160405190808252806020026020018201604052801561180d578160200160208202803883390190505b50905060005b835181101561184f5783818151811061182857fe5b602002602001015182828151811061183c57fe5b6020908102919091010152600101611813565b5060005b82518110156118925782818151811061186857fe5b602002602001015182828651018151811061187f57fe5b6020908102919091010152600101611853565b5092915050565b60006118a3611a08565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b6f777261707065724d6178546f6b656e7360801b856040516020016113449291906121ec565b60006118f3610444565b9050600061190c8360085461146190919063ffffffff16565b821161191957600061193d565b60085461193d90611930908563ffffffff61146116565b839063ffffffff61140f16565b905060006119496113f4565b6001600160a01b031663654a60ac60065484631cd554d160e21b6040518463ffffffff1660e01b815260040161198193929190612349565b60206040518083038186803b15801561199957600080fd5b505afa1580156119ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506119d19190810190611caa565b90506119db6113e7565b6001600160a01b031663867904b433866040518363ffffffff1660e01b815260040161166c929190612274565b60006104c56e466c657869626c6553746f7261676560881b5b60008181526004602090815260408083205490516001600160a01b039091169182151591611a5191869101612212565b604051602081830303815290604052906118925760405162461bcd60e51b815260040161017e9190612372565b600082611a8d575060006113c7565b82820282848281611a9a57fe5b04146114865760405162461bcd60e51b815260040161017e90612413565b6000808211611ad95760405162461bcd60e51b815260040161017e906123e3565b6000828481611ae457fe5b04949350505050565b60006104c56814de5b9d1a1cd554d160ba1b611a21565b60006104c56d57726170706572466163746f727960901b611a21565b611b28611bd1565b6001600160a01b0316639e3b92ca60065460085484036040518363ffffffff1660e01b8152600401611b5b92919061231b565b600060405180830381600087803b158015611b7557600080fd5b505af1158015611b89573d6000803e3d6000fd5b50505060089190915550565b600080600a8304611bac868663ffffffff611a7e16565b81611bb357fe5b0490506005600a820610611bc557600a015b600a9004949350505050565b60006104c56844656274436163686560b81b611a21565b80356113c781612511565b80516113c781612511565b80356113c781612525565b80516113c781612525565b80516113c78161252e565b80356113c78161252e565b600060208284031215611c3c57600080fd5b6000611c488484611be8565b949350505050565b600060208284031215611c6257600080fd5b6000611c488484611bf3565b600060208284031215611c8057600080fd5b6000611c488484611bfe565b600060208284031215611c9e57600080fd5b6000611c488484611c09565b600060208284031215611cbc57600080fd5b6000611c488484611c14565b600060208284031215611cda57600080fd5b6000611c488484611c1f565b6000611cf28383611d85565b505060200190565b611d03816124b2565b82525050565b611d0381612496565b611d03611d1e82612496565b6124f0565b6000611d2e82612484565b611d388185612488565b9350611d438361247e565b8060005b83811015611d71578151611d5b8882611ce6565b9750611d668361247e565b925050600101611d47565b509495945050505050565b611d03816124a1565b611d03816104c8565b611d03611d9a826104c8565b6104c8565b611d03816124b9565b6000611db382612484565b611dbd8185612488565b9350611dcd8185602086016124c4565b611dd681612501565b9093019392505050565b6000611ded603583612488565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527402063616e20616363657074206f776e65727368697605c1b602082015260400192915050565b6000611e44601d83612488565b7f46616c6c6261636b2064697361626c65642c20757365206d696e742829000000815260200192915050565b6000611e7d601983612488565b7f416c6c6f77616e6365206e6f74206869676820656e6f75676800000000000000815260200192915050565b6000611eb6601b83612488565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000611eef601883612488565b7f43757272656e6379207261746520697320696e76616c69640000000000000000815260200192915050565b6000611f28601e83612488565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b6000611f61601a83612488565b7f536166654d6174683a206469766973696f6e206279207a65726f000000000000815260200192915050565b6000611f9a601183612491565b70026b4b9b9b4b7339030b2323932b9b99d1607d1b815260110192915050565b6000611fc7601883612488565b7f5472616e7366657220646964206e6f7420737563636565640000000000000000815260200192915050565b6000612000602f83612488565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681526e37b936903a3434b99030b1ba34b7b760891b602082015260400192915050565b6000612051602183612488565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000612094601283612488565b7142616c616e636520697320746f6f206c6f7760701b815260200192915050565b60006120c2603c83612488565b7f5468697320616374696f6e2063616e6e6f7420626520706572666f726d65642081527f7768696c652074686520636f6e74726163742069732070617573656400000000602082015260400192915050565b6000612121601983612491565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b600061215a602683612488565b7f436f6e747261637420686173206e6f20737061726520636170616369747920748152651bc81b5a5b9d60d21b602082015260400192915050565b60006121a2603583612488565b7f436f6e74726163742063616e6e6f74206275726e20666f7220746f6b656e2c20815274746f6b656e2062616c616e6365206973207a65726f60581b602082015260400192915050565b60006121f88285611d8e565b6020820191506122088284611d12565b5060140192915050565b600061221d82611f8d565b91506122298284611d8e565b50602001919050565b600061221d82612114565b602081016113c78284611d09565b602081016113c78284611cfa565b604081016122678285611cfa565b6114866020830184611cfa565b604081016122828285611cfa565b6114866020830184611d85565b6040810161229d8285611d09565b6114866020830184611d09565b606081016122b88286611d09565b6122c56020830185611d09565b611c486040830184611d85565b604081016122828285611d09565b602080825281016114868184611d23565b602081016113c78284611d7c565b602081016113c78284611d85565b6040810161229d8285611d85565b604081016122828285611d85565b604081016123378285611d85565b8181036020830152611c488184611da8565b606081016123578286611d85565b6122c56020830185611d85565b602081016113c78284611d9f565b602080825281016114868184611da8565b602080825281016113c781611de0565b602080825281016113c781611e37565b602080825281016113c781611e70565b602080825281016113c781611ea9565b602080825281016113c781611ee2565b602080825281016113c781611f1b565b602080825281016113c781611f54565b602080825281016113c781611fba565b602080825281016113c781611ff3565b602080825281016113c781612044565b602080825281016113c781612087565b602080825281016113c7816120b5565b602080825281016113c78161214d565b602080825281016113c781612195565b604081016124718285611d85565b6114866020830184611d7c565b60200190565b5190565b90815260200190565b919050565b60006113c7826124a6565b151590565b6001600160a01b031690565b60006113c7825b60006113c782612496565b60005b838110156124df5781810151838201526020016124c7565b8381111561171f5750506000910152565b60006113c78260006113c78261250b565b601f01601f191690565b60601b90565b61251a81612496565b811461059b57600080fd5b61251a816124a1565b61251a816104c856fea365627a7a72315820b1c4b0e75aa342df894bad2f1424212f7596a6f05c247520dbb2ceecb0ea92b26c6578706572696d656e74616cf564736f6c63430005100040
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000048914229dedd5a9922f44441ffccfc2cb7856ee9000000000000000000000000529c553ef2d0370279dc8abf19702b98b166d2520000000000000000000000004200000000000000000000000000000000000006734554480000000000000000000000000000000000000000000000000000000053796e7468734554480000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _owner (address): 0x48914229deDd5A9922f44441ffCCfC2Cb7856Ee9
Arg [1] : _resolver (address): 0x529C553eF2d0370279DC8AbF19702B98b166D252
Arg [2] : _token (address): 0x4200000000000000000000000000000000000006
Arg [3] : _currencyKey (bytes32): 0x7345544800000000000000000000000000000000000000000000000000000000
Arg [4] : _synthContractName (bytes32): 0x53796e7468734554480000000000000000000000000000000000000000000000
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 00000000000000000000000048914229dedd5a9922f44441ffccfc2cb7856ee9
Arg [1] : 000000000000000000000000529c553ef2d0370279dc8abf19702b98b166d252
Arg [2] : 0000000000000000000000004200000000000000000000000000000000000006
Arg [3] : 7345544800000000000000000000000000000000000000000000000000000000
Arg [4] : 53796e7468734554480000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
47301:11504:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55197:39;;-1:-1:-1;;;55197:39:0;;;;;;;;;;;;;;;;20296:31;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20296:31:0;;;:::i;:::-;;;;;;;;;;;;;;;;50904:106;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50904:106:0;;;:::i;:::-;;;;;;;;2288:141;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2288:141:0;;;;;;;;:::i;:::-;;6306:488;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;6306:488:0;;;;;;;;:::i;48184:29::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48184:29:0;;;:::i;51761:114::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51761:114:0;;;:::i;48143:32::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48143:32:0;;;:::i;21991:537::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21991:537:0;;;:::i;:::-;;;;;;;;53482:1573;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;53482:1573:0;;;;;;;;:::i;51883:114::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51883:114:0;;;:::i;2057:29::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2057:29:0;;;:::i;:::-;;;;;;;;51018:299;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;51018:299:0;;;;;;;;:::i;:::-;;;;;;;;;5892:18;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5892:18:0;;;:::i;50340:304::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50340:304:0;;;:::i;51325:299::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;51325:299:0;;;;;;;;:::i;21285:657::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21285:657:0;;;:::i;2437:271::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2437:271:0;;;:::i;48688:632::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48688:632:0;;;:::i;:::-;;;;;;;;51632:121;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51632:121:0;;;:::i;2030:20::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2030:20:0;;;:::i;5860:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5860:25:0;;;:::i;52212:1116::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;52212:1116:0;;;;;;;;:::i;48110:26::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48110:26:0;;;:::i;50652:244::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50652:244:0;;;:::i;48084:19::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48084:19:0;;;:::i;20296:31::-;;;;;;-1:-1:-1;;;;;20296:31:0;;:::o;50904:106::-;50972:5;;:30;;-1:-1:-1;;;50972:30:0;;50948:4;;-1:-1:-1;;;;;50972:5:0;;:15;;:30;;50996:4;;50972:30;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50972:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50972:30:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;50972:30:0;;;;;;;;;50965:37;;50904:106;;:::o;2288:141::-;2746:12;:10;:12::i;:::-;2360:14;:23;;-1:-1:-1;;;;;;2360:23:0;-1:-1:-1;;;;;2360:23:0;;;;;2399:22;;;;;;2360:23;;2399:22;;;;;;;;;;2288:141;:::o;6306:488::-;2746:12;:10;:12::i;:::-;6459:6;;;;6448:17;;;;;;6444:56;;;6482:7;;6444:56;6546:6;:16;;-1:-1:-1;;6546:16:0;;;;;;;;;;6631:6;6627:58;;;6670:3;6654:13;:19;6627:58;6779:6;;6766:20;;;;;;6779:6;;;;;6766:20;;2769:1;6306:488;:::o;48184:29::-;;;;:::o;51761:114::-;51805:6;51831:36;51861:4;51831:21;:36::i;48143:32::-;;;;:::o;21991:537::-;22042:4;22059:34;22096:27;:25;:27::i;:::-;22059:64;-1:-1:-1;22139:6:0;22134:363;22155:17;:24;22151:1;:28;22134:363;;;22201:12;22216:17;22234:1;22216:20;;;;;;;;;;;;;;;;;;;22383:18;;;;:12;:18;;;;;;;;;;22354:8;;:25;;-1:-1:-1;;;22354:25:0;;22216:20;;-1:-1:-1;;;;;;22383:18:0;;;;;22354:8;;;;;:19;;:25;;22216:20;;22354:25;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22354:25:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22354:25:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;22354:25:0;;;;;;;;;-1:-1:-1;;;;;22354:47:0;;;:83;;;-1:-1:-1;22435:1:0;22405:18;;;:12;:18;;;;;;-1:-1:-1;;;;;22405:18:0;:32;22354:83;22350:136;;;22465:5;22458:12;;;;;;;22350:136;-1:-1:-1;22181:3:0;;22134:363;;;;22516:4;22509:11;;;21991:537;:::o;53482:1573::-;6883:6;;;;6882:7;6874:80;;;;-1:-1:-1;;;6874:80:0;;;;;;;;;58532:14;:12;:14::i;:::-;-1:-1:-1;;;;;58532:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58532:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58532:38:0;;;;53591:7;:5;:7::i;:::-;-1:-1:-1;;;;;53576:34:0;;53611:10;53576:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53576:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53576:46:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;53576:46:0;;;;;;;;;53564:8;:58;;53556:89;;;;-1:-1:-1;;;53556:89:0;;;;;;;;;53665:15;:13;:15::i;:::-;-1:-1:-1;;;;;53665:29:0;;53695:11;;53665:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53665:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53665:42:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;53665:42:0;;;;;;;;;53664:43;53656:80;;;;-1:-1:-1;;;53656:80:0;;;;;;;;;53777:1;53755:19;:17;:19::i;:::-;:23;53747:89;;;;-1:-1:-1;;;53747:89:0;;;;;;;;;53850:12;53864:13;53881:35;53898:17;;53881:16;:35::i;:::-;53849:67;;;;53929:15;53955:14;53984:8;53980:679;;;54042:8;54022:17;;:28;:72;;54086:8;54022:72;;;54053:17;;:30;;54075:7;54053:30;:21;:30;:::i;:::-;54009:85;;54123:184;54278:13;:11;:13::i;:::-;54252:15;:20;:22;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54252:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54252:22:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;54252:22:0;;;;;;;;;54123:10;;54248:43;;54123:184;:26;:184;:::i;:::-;54111:196;;53980:679;;;54353:17;;54386:8;;54353:30;;54375:7;54353:30;:21;:30;:::i;:::-;:41;:85;;54430:8;54353:85;;;54397:17;;:30;;54419:7;54397:30;:21;:30;:::i;:::-;54340:98;;54465:182;54618:13;:11;:13::i;:::-;54592:15;:20;:22;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54592:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54592:22:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;54592:22:0;;;;;;;;;54465:10;;54588:43;54465:182;:24;:182;:::i;:::-;54453:194;;53980:679;54671:20;54694:8;:40;;54709:25;:10;54724:9;54709:25;:14;:25;:::i;:::-;54694:40;;;54705:1;54694:40;54824:5;;54671:63;;-1:-1:-1;54783:12:0;;54798:71;;-1:-1:-1;;;;;54824:5:0;54840:4;54847:10;54859:9;54798:17;:71::i;:::-;54783:86;;54888:7;54880:44;;;;-1:-1:-1;;;54880:44:0;;;;;;;;;54954:17;54960:10;54954:5;:17::i;:::-;54996:10;-1:-1:-1;;;;;54989:58:0;;55008:9;55019:15;55036:10;54989:58;;;;;;;;;;;;;;;;;58581:1;;;;;;53482:1573;:::o;51883:114::-;51927:6;51953:36;51983:4;51953:21;:36::i;2057:29::-;;;-1:-1:-1;;;;;2057:29:0;;:::o;51018:299::-;51078:4;51084;51101:5;51109:13;:11;:13::i;:::-;51101:21;;51143:1;51139;:5;51135:175;;;51169:37;:6;51202:2;;;;51169:37;:27;:37;:::i;:::-;51208:4;51161:52;;;;;;;51135:175;51254:36;:6;51287:1;51254:36;:27;:36;:::i;:::-;51292:5;51246:52;;;;;51018:299;;;;:::o;5892:18::-;;;;;;:::o;50340:304::-;50381:14;50456:12;50471:13;:11;:13::i;:::-;50456:28;;50495:13;50511:16;:14;:16::i;:::-;50495:32;;50553:8;50542:7;:19;50538:60;;50585:1;50578:8;;;;;;50538:60;50615:21;:8;50628:7;50615:21;:12;:21;:::i;:::-;50608:28;;;;50340:304;:::o;51325:299::-;51385:4;51391;51408:5;51416:13;:11;:13::i;21285:657::-;21327:34;21364:27;:25;:27::i;:::-;21327:64;-1:-1:-1;21485:6:0;21480:455;21501:17;:24;21497:1;:28;21480:455;;;21547:12;21562:17;21580:1;21562:20;;;;;;;;;;;;;;21547:35;;21690:19;21729:8;;;;;;;;;-1:-1:-1;;;;;21729:8:0;-1:-1:-1;;;;;21729:29:0;;21759:4;21818;21772:51;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;21772:51:0;;;21729:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21729:96:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21729:96:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;21729:96:0;;;;;;;;;21840:18;;;;:12;:18;;;;;;;:32;;-1:-1:-1;;;;;;21840:32:0;-1:-1:-1;;;;;21840:32:0;;;;;21892:31;21840:32;;-1:-1:-1;21892:31:0;;;;21840:18;;:32;;21892:31;;;;;;;;;;-1:-1:-1;;21527:3:0;;21480:455;;;;21285:657;:::o;2437:271::-;2506:14;;-1:-1:-1;;;;;2506:14:0;2492:10;:28;2484:94;;;;-1:-1:-1;;;2484:94:0;;;;;;;;;2607:5;;;2614:14;2594:35;;;;;;-1:-1:-1;;;;;2607:5:0;;;;2614:14;;;2594:35;;;;;;;;;;2648:14;;;;2640:22;;-1:-1:-1;;;;;;2640:22:0;;;-1:-1:-1;;;;;2648:14:0;;2640:22;;;;2673:27;;;2437:271::o;48688:632::-;48746:26;48785:34;48822:47;:45;:47::i;:::-;48912:16;;;48926:1;48912:16;;;;;;;;;48785:84;;-1:-1:-1;48880:29:0;;48912:16;;;;17:15:-1;;105:10;48912:16:0;88:34:-1;136:17;;-1:-1;48912:16:0;48880:48;;-1:-1:-1;;;48939:12:0;48952:1;48939:15;;;;;;;;;;;;;:37;;;;;49005:17;;48987:12;49000:1;48987:15;;;;;;;;;;;;;:35;;;;;-1:-1:-1;;;49033:12:0;49046:1;49033:15;;;;;;;;;;;;;:34;;;;;-1:-1:-1;;;49078:12:0;49091:1;49078:15;;;;;;;;;;;;;:36;;;;;-1:-1:-1;;;49125:12:0;49138:1;49125:15;;;;;;;;;;;;;:39;;;;;-1:-1:-1;;;49175:12:0;49188:1;49175:15;;;;;;;;;;;;;:41;;;;;49239:46;49253:17;49272:12;49239:13;:46::i;51632:121::-;51679:7;51706:39;51739:4;51706:24;:39::i;2030:20::-;;;-1:-1:-1;;;;;2030:20:0;;:::o;5860:25::-;;;;:::o;52212:1116::-;6883:6;;;;6882:7;6874:80;;;;-1:-1:-1;;;6874:80:0;;;;;;;;;58532:14;:12;:14::i;:::-;-1:-1:-1;;;;;58532:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58532:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;52306:5:0;;:42;;-1:-1:-1;;;52306:42:0;;-1:-1:-1;;;;;52306:5:0;;;;-1:-1:-1;52306:15:0;;-1:-1:-1;52306:42:0;;52322:10;;52342:4;;52306:42;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52306:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52306:42:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;52306:42:0;;;;;;;;;52294:8;:54;;52286:92;;;;-1:-1:-1;;;52286:92:0;;;;;;;;;52409:5;;:27;;-1:-1:-1;;;52409:27:0;;-1:-1:-1;;;;;52409:5:0;;;;:15;;:27;;52425:10;;52409:27;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52409:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52409:27:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;52409:27:0;;;;;;;;;52397:8;:39;;52389:70;;;;-1:-1:-1;;;52389:70:0;;;;;;;;;52479:15;:13;:15::i;:::-;-1:-1:-1;;;;;52479:29:0;;52509:11;;52479:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52479:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52479:42:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;52479:42:0;;;;;;;;;52478:43;52470:80;;;;-1:-1:-1;;;52470:80:0;;;;;;;;;52563:20;52586:10;:8;:10::i;:::-;52563:33;;52633:1;52615:15;:19;52607:70;;;;-1:-1:-1;;;52607:70:0;;;;;;;;;52690:19;52730:8;52712:15;:26;:55;;52759:8;52712:55;;;52741:15;52712:55;52690:77;;52781:20;52803:13;52820:32;52837:14;52820:16;:32::i;:::-;52780:72;;;;52863:15;52881:8;:84;;52930:35;:14;52949:15;52930:35;:18;:35;:::i;:::-;52881:84;;;52892:35;:14;52911:15;52892:35;:18;:35;:::i;:::-;53057:5;;52863:102;;-1:-1:-1;53016:12:0;;53031:76;;-1:-1:-1;;;;;53057:5:0;53065:10;53085:4;53092:14;53031:17;:76::i;:::-;53016:91;;53126:7;53118:44;;;;-1:-1:-1;;;53118:44:0;;;;;;;;;53207:17;53213:10;53207:5;:17::i;:::-;53249:10;53242:78;53261:10;53273:8;:30;;53288:15;53273:30;;;53284:1;53273:30;53305:14;53242:78;;;;;;;;;48110:26;;;;:::o;50652:244::-;50702:4;50820:15;:13;:15::i;:::-;-1:-1:-1;;;;;50820:30:0;;50851:11;;50864:17;;-1:-1:-1;;;50820:68:0;;;;;;;;;;;;;;;;;;48084:19;;;-1:-1:-1;;;;;48084:19:0;;:::o;2786:133::-;2854:5;;-1:-1:-1;;;;;2854:5:0;2840:10;:19;2832:79;;;;-1:-1:-1;;;2832:79:0;;;;;;;;;2786:133::o;33996:285::-;34067:3;34103:17;:15;:17::i;:::-;-1:-1:-1;;;;;34103:29:0;;-1:-1:-1;;;;;;34249:7:0;34201:56;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;34201:56:0;;;34191:67;;;;;;34103:170;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;34103:170:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;34103:170:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;34103:170:0;;;;;;;;;34083:190;33996:285;-1:-1:-1;;33996:285:0:o;49934:146::-;49981:13;50028:43;-1:-1:-1;;;50028:20:0;:43::i;49511:121::-;49551:6;49584:39;49605:17;;49584:20;:39::i;49640:144::-;49688:14;49737:38;-1:-1:-1;;;49737:20:0;:38::i;37051:184::-;37109:7;37142:1;37137;:6;;37129:49;;;;-1:-1:-1;;;37129:49:0;;;;;;;;;-1:-1:-1;37201:5:0;;;37051:184::o;40780:195::-;40844:4;39756:18;40952:8;:1;40958;40952:8;:5;:8;:::i;:::-;:15;;;;;;;40780:195;-1:-1:-1;;;40780:195:0:o;36595:181::-;36653:7;36685:5;;;36709:6;;;;36701:46;;;;-1:-1:-1;;;36701:46:0;;;;;;;;;36767:1;36595:181;-1:-1:-1;;;36595:181:0:o;43921:186::-;43983:4;44081:18;44097:1;44081:11;:1;39756:18;44081:11;:5;:11;:::i;:::-;:15;:18;:15;:18;:::i;57193:1296::-;57348:12;57470:20;57558:5;57565:3;57570:6;57493:84;;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;57493:84:0;;;49:4:-1;25:18;;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;57603:14:0;;57721:4;-1:-1:-1;57708:18:0;;;57493:84;;-1:-1:-1;57603:14:0;-1:-1:-1;57603:14:0;;-1:-1:-1;57833:13:0;57826:5;57821:70;57811:2;;57922:1;57919;57912:12;57811:2;57968:4;57962:11;57996:4;57991:174;;;;58188:4;58183:64;;;;58265;;;;58450:1;58447;58440:12;57991:174;58145:1;58134:12;;57991:174;;58265:64;58309:1;58298:12;;57955:516;;57639:843;;;;;;;;:::o;55990:947::-;56038:13;56054;:11;:13::i;:::-;56236:17;;56038:29;;-1:-1:-1;56193:17:0;;56213:20;56038:29;56226:6;56213:20;:12;:20;:::i;:::-;:40;:90;;56302:1;56213:90;;;56281:17;;56256:43;;:20;:8;56269:6;56256:20;:12;:20;:::i;:::-;:24;:43;:24;:43;:::i;:::-;56193:110;;56316:20;56339:15;:13;:15::i;:::-;-1:-1:-1;;;;;56339:30:0;;56370:11;;56383:12;-1:-1:-1;;;56339:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56339:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56339:63:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;56339:63:0;;;;;;;;;56316:86;;56467:7;:5;:7::i;:::-;-1:-1:-1;;;;;56467:12:0;;56480:10;56492:6;56467:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56467:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56467:32:0;;;;56698:1;56680:15;:19;56676:113;;;56716:11;:9;:11::i;:::-;-1:-1:-1;;;;;56716:17:0;;56742:16;:14;:16::i;:::-;56761:15;56716:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56716:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56716:61:0;;;;56676:113;56898:31;56920:8;56898:21;:31::i;:::-;55990:947;;;;:::o;34289:285::-;34360:3;34396:17;:15;:17::i;:::-;-1:-1:-1;;;;;34396:29:0;;-1:-1:-1;;;;;;34542:7:0;34494:56;;;;;;;;;;43344:134;43413:4;43437:33;43459:1;43462;39756:18;43437:21;:33::i;28893:183::-;29002:16;;;29016:1;29002:16;;;;;;;;;28951:26;;29002:16;;;;;;105:10:-1;29002:16:0;88:34:-1;136:17;;-1:-1;29002:16:0;28990:28;;-1:-1:-1;;;29029:9:0;29039:1;29029:12;;;;;;;;;;;;;:39;;;;;28893:183;:::o;20551:458::-;20673:28;20762:6;:13;20747:5;:12;:28;20733:43;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;20733:43:0;-1:-1:-1;20719:57:0;-1:-1:-1;20794:6:0;20789:92;20810:5;:12;20806:1;:16;20789:92;;;20861:5;20867:1;20861:8;;;;;;;;;;;;;;20844:11;20856:1;20844:14;;;;;;;;;;;;;;;;;:25;20824:3;;20789:92;;;-1:-1:-1;20898:6:0;20893:109;20914:6;:13;20910:1;:17;20893:109;;;20981:6;20988:1;20981:9;;;;;;;;;;;;;;20949:11;20976:1;20961:5;:12;:16;20949:29;;;;;;;;;;;;;;;;;:41;20929:3;;20893:109;;;;20551:458;;;;:::o;33695:293::-;33769:4;33806:17;:15;:17::i;:::-;-1:-1:-1;;;;;33806:30:0;;-1:-1:-1;;;;;;33956:7:0;33905:59;;;;;;;;;;55306:676;55354:13;55370;:11;:13::i;:::-;55354:29;;55396:17;55427:29;55449:6;55427:17;;:21;;:29;;;;:::i;:::-;55416:8;:40;:90;;55505:1;55416:90;;;55472:17;;55459:43;;55472:29;;55494:6;55472:29;:21;:29;:::i;:::-;55459:8;;:43;:12;:43;:::i;:::-;55396:110;;55517:20;55540:15;:13;:15::i;:::-;-1:-1:-1;;;;;55540:30:0;;55571:11;;55584:12;-1:-1:-1;;;55540:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55540:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55540:63:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;55540:63:0;;;;;;;;;55517:86;;55651:7;:5;:7::i;:::-;-1:-1:-1;;;;;55651:13:0;;55665:10;55677:6;55651:33;;;;;;;;;;;;;;;;;29084:158;29134:16;29187:46;-1:-1:-1;;;22590:268:0;22657:7;22701:18;;;:12;:18;;;;;;;;;22774:43;;-1:-1:-1;;;;;22701:18:0;;;;22738:27;;;;22774:43;;22714:4;;22774:43;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;22774:43:0;;;22730:89;;;;;-1:-1:-1;;;22730:89:0;;;;;;;;;37486:470;37544:7;37788:6;37784:47;;-1:-1:-1;37818:1:0;37811:8;;37784:47;37855:5;;;37859:1;37855;:5;:1;37879:5;;;;;:10;37871:56;;;;-1:-1:-1;;;37871:56:0;;;;;;;;38424:333;38482:7;38581:1;38577;:5;38569:44;;;;-1:-1:-1;;;38569:44:0;;;;;;;;;38624:9;38640:1;38636;:5;;;;;;;38424:333;-1:-1:-1;;;;38424:333:0:o;49376:127::-;49420:6;49453:41;-1:-1:-1;;;49453:20:0;:41::i;50088:154::-;50137:15;50188:45;-1:-1:-1;;;50188:20:0;:45::i;56945:240::-;57021:11;:9;:11::i;:::-;-1:-1:-1;;;;;57021:36:0;;57058:11;;57107:17;;57078:18;57071:54;57021:105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57021:105:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;;57139:17:0;:38;;;;-1:-1:-1;56945:240:0:o;41594:421::-;41717:4;;41870:2;41854:13;:18;41842:8;:1;41848;41842:8;:5;:8;:::i;:::-;:31;;;;;;;-1:-1:-1;41915:1:0;41909:2;41842:31;41890:21;:26;41886:81;;41953:2;41933:22;41886:81;42005:2;41986:21;;;41594:421;-1:-1:-1;;;;41594:421:0:o;49792:134::-;49836:10;49877:40;-1:-1:-1;;;49877:20:0;:40::i;5:130:-1:-;72:20;;97:33;72:20;97:33;;142:134;220:13;;238:33;220:13;238:33;;283:124;347:20;;372:30;347:20;372:30;;414:128;489:13;;507:30;489:13;507:30;;549:132;626:13;;644:32;626:13;644:32;;688:130;755:20;;780:33;755:20;780:33;;966:241;;1070:2;1058:9;1049:7;1045:23;1041:32;1038:2;;;1086:1;1083;1076:12;1038:2;1121:1;1138:53;1183:7;1163:9;1138:53;;;1128:63;1032:175;-1:-1;;;;1032:175;1214:263;;1329:2;1317:9;1308:7;1304:23;1300:32;1297:2;;;1345:1;1342;1335:12;1297:2;1380:1;1397:64;1453:7;1433:9;1397:64;;1484:235;;1585:2;1573:9;1564:7;1560:23;1556:32;1553:2;;;1601:1;1598;1591:12;1553:2;1636:1;1653:50;1695:7;1675:9;1653:50;;1726:257;;1838:2;1826:9;1817:7;1813:23;1809:32;1806:2;;;1854:1;1851;1844:12;1806:2;1889:1;1906:61;1959:7;1939:9;1906:61;;1990:261;;2104:2;2092:9;2083:7;2079:23;2075:32;2072:2;;;2120:1;2117;2110:12;2072:2;2155:1;2172:63;2227:7;2207:9;2172:63;;2258:241;;2362:2;2350:9;2341:7;2337:23;2333:32;2330:2;;;2378:1;2375;2368:12;2330:2;2413:1;2430:53;2475:7;2455:9;2430:53;;2777:173;;2864:46;2906:3;2898:6;2864:46;;;-1:-1;;2939:4;2930:14;;2857:93;2958:142;3049:45;3088:5;3049:45;;;3044:3;3037:58;3031:69;;;3107:113;3190:24;3208:5;3190:24;;3227:152;3328:45;3348:24;3366:5;3348:24;;;3328:45;;3417:690;;3562:54;3610:5;3562:54;;;3629:86;3708:6;3703:3;3629:86;;;3622:93;;3736:56;3786:5;3736:56;;;3812:7;3840:1;3825:260;3850:6;3847:1;3844:13;3825:260;;;3917:6;3911:13;3938:63;3997:3;3982:13;3938:63;;;3931:70;;4018:60;4071:6;4018:60;;;4008:70;-1:-1;;3872:1;3865:9;3825:260;;;-1:-1;4098:3;;3541:566;-1:-1;;;;;3541:566;4115:104;4192:21;4207:5;4192:21;;4226:103;4299:24;4317:5;4299:24;;4456:152;4557:45;4577:24;4595:5;4577:24;;;4557:45;;4615:174;4722:61;4777:5;4722:61;;5074:347;;5186:39;5219:5;5186:39;;;5237:71;5301:6;5296:3;5237:71;;;5230:78;;5313:52;5358:6;5353:3;5346:4;5339:5;5335:16;5313:52;;;5386:29;5408:6;5386:29;;;5377:39;;;;5166:255;-1:-1;;;5166:255;5429:390;;5589:67;5653:2;5648:3;5589:67;;;5689:34;5669:55;;-1:-1;;;5753:2;5744:12;;5737:45;5810:2;5801:12;;5575:244;-1:-1;;5575:244;5828:329;;5988:67;6052:2;6047:3;5988:67;;;6088:31;6068:52;;6148:2;6139:12;;5974:183;-1:-1;;5974:183;6166:325;;6326:67;6390:2;6385:3;6326:67;;;6426:27;6406:48;;6482:2;6473:12;;6312:179;-1:-1;;6312:179;6500:327;;6660:67;6724:2;6719:3;6660:67;;;6760:29;6740:50;;6818:2;6809:12;;6646:181;-1:-1;;6646:181;6836:324;;6996:67;7060:2;7055:3;6996:67;;;7096:26;7076:47;;7151:2;7142:12;;6982:178;-1:-1;;6982:178;7169:330;;7329:67;7393:2;7388:3;7329:67;;;7429:32;7409:53;;7490:2;7481:12;;7315:184;-1:-1;;7315:184;7508:326;;7668:67;7732:2;7727:3;7668:67;;;7768:28;7748:49;;7825:2;7816:12;;7654:180;-1:-1;;7654:180;7843:353;;8021:85;8103:2;8098:3;8021:85;;;-1:-1;;;8119:40;;8187:2;8178:12;;8007:189;-1:-1;;8007:189;8205:324;;8365:67;8429:2;8424:3;8365:67;;;8465:26;8445:47;;8520:2;8511:12;;8351:178;-1:-1;;8351:178;8538:384;;8698:67;8762:2;8757:3;8698:67;;;8798:34;8778:55;;-1:-1;;;8862:2;8853:12;;8846:39;8913:2;8904:12;;8684:238;-1:-1;;8684:238;8931:370;;9091:67;9155:2;9150:3;9091:67;;;9191:34;9171:55;;-1:-1;;;9255:2;9246:12;;9239:25;9292:2;9283:12;;9077:224;-1:-1;;9077:224;9310:318;;9470:67;9534:2;9529:3;9470:67;;;-1:-1;;;9550:41;;9619:2;9610:12;;9456:172;-1:-1;;9456:172;9637:397;;9797:67;9861:2;9856:3;9797:67;;;9897:34;9877:55;;9966:30;9961:2;9952:12;;9945:52;10025:2;10016:12;;9783:251;-1:-1;;9783:251;10043:361;;10221:85;10303:2;10298:3;10221:85;;;10339:27;10319:48;;10395:2;10386:12;;10207:197;-1:-1;;10207:197;10413:375;;10573:67;10637:2;10632:3;10573:67;;;10673:34;10653:55;;-1:-1;;;10737:2;10728:12;;10721:30;10779:2;10770:12;;10559:229;-1:-1;;10559:229;10797:390;;10957:67;11021:2;11016:3;10957:67;;;11057:34;11037:55;;-1:-1;;;11121:2;11112:12;;11105:45;11178:2;11169:12;;10943:244;-1:-1;;10943:244;11315:383;;11462:75;11533:3;11524:6;11462:75;;;11559:2;11554:3;11550:12;11543:19;;11573:75;11644:3;11635:6;11573:75;;;-1:-1;11670:2;11661:12;;11450:248;-1:-1;;11450:248;11705:511;;11932:148;12076:3;11932:148;;;11925:155;;12091:75;12162:3;12153:6;12091:75;;;-1:-1;12188:2;12179:12;;11913:303;-1:-1;11913:303;12223:511;;12450:148;12594:3;12450:148;;12741:213;12859:2;12844:18;;12873:71;12848:9;12917:6;12873:71;;12961:229;13087:2;13072:18;;13101:79;13076:9;13153:6;13101:79;;13197:356;13359:2;13344:18;;13373:79;13348:9;13425:6;13373:79;;;13463:80;13539:2;13528:9;13524:18;13515:6;13463:80;;13560:340;13714:2;13699:18;;13728:79;13703:9;13780:6;13728:79;;;13818:72;13886:2;13875:9;13871:18;13862:6;13818:72;;13907:324;14053:2;14038:18;;14067:71;14042:9;14111:6;14067:71;;;14149:72;14217:2;14206:9;14202:18;14193:6;14149:72;;14238:435;14412:2;14397:18;;14426:71;14401:9;14470:6;14426:71;;;14508:72;14576:2;14565:9;14561:18;14552:6;14508:72;;;14591;14659:2;14648:9;14644:18;14635:6;14591:72;;14680:324;14826:2;14811:18;;14840:71;14815:9;14884:6;14840:71;;15011:361;15179:2;15193:47;;;15164:18;;15254:108;15164:18;15348:6;15254:108;;15379:201;15491:2;15476:18;;15505:65;15480:9;15543:6;15505:65;;15587:213;15705:2;15690:18;;15719:71;15694:9;15763:6;15719:71;;15807:324;15953:2;15938:18;;15967:71;15942:9;16011:6;15967:71;;16138:324;16284:2;16269:18;;16298:71;16273:9;16342:6;16298:71;;16796:412;16962:2;16947:18;;16976:71;16951:9;17020:6;16976:71;;;17095:9;17089:4;17085:20;17080:2;17069:9;17065:18;17058:48;17120:78;17193:4;17184:6;17120:78;;17215:435;17389:2;17374:18;;17403:71;17378:9;17447:6;17403:71;;;17485:72;17553:2;17542:9;17538:18;17529:6;17485:72;;17657:261;17799:2;17784:18;;17813:95;17788:9;17881:6;17813:95;;18389:301;18527:2;18541:47;;;18512:18;;18602:78;18512:18;18666:6;18602:78;;18697:407;18888:2;18902:47;;;18873:18;;18963:131;18873:18;18963:131;;19111:407;19302:2;19316:47;;;19287:18;;19377:131;19287:18;19377:131;;19525:407;19716:2;19730:47;;;19701:18;;19791:131;19701:18;19791:131;;19939:407;20130:2;20144:47;;;20115:18;;20205:131;20115:18;20205:131;;20353:407;20544:2;20558:47;;;20529:18;;20619:131;20529:18;20619:131;;20767:407;20958:2;20972:47;;;20943:18;;21033:131;20943:18;21033:131;;21181:407;21372:2;21386:47;;;21357:18;;21447:131;21357:18;21447:131;;21595:407;21786:2;21800:47;;;21771:18;;21861:131;21771:18;21861:131;;22009:407;22200:2;22214:47;;;22185:18;;22275:131;22185:18;22275:131;;22423:407;22614:2;22628:47;;;22599:18;;22689:131;22599:18;22689:131;;22837:407;23028:2;23042:47;;;23013:18;;23103:131;23013:18;23103:131;;23251:407;23442:2;23456:47;;;23427:18;;23517:131;23427:18;23517:131;;23665:407;23856:2;23870:47;;;23841:18;;23931:131;23841:18;23931:131;;24079:407;24270:2;24284:47;;;24255:18;;24345:131;24255:18;24345:131;;24713:312;24853:2;24838:18;;24867:71;24842:9;24911:6;24867:71;;;24949:66;25011:2;25000:9;24996:18;24987:6;24949:66;;25474:151;25598:4;25589:14;;25546:79;25632:137;25735:12;;25706:63;26021:178;26139:19;;;26188:4;26179:14;;26132:67;26380:145;26516:3;26494:31;-1:-1;26494:31;26533:91;;26595:24;26613:5;26595:24;;26631:85;26697:13;26690:21;;26673:43;26880:121;-1:-1;;;;;26942:54;;26925:76;27087:129;;27174:37;27205:5;27223:169;;27326:61;27381:5;27326:61;;28067:268;28132:1;28139:101;28153:6;28150:1;28147:13;28139:101;;;28220:11;;;28214:18;28201:11;;;28194:39;28175:2;28168:10;28139:101;;;28255:6;28252:1;28249:13;28246:2;;;-1:-1;;28320:1;28302:16;;28295:27;28116:219;28343:95;;28407:26;28427:5;28526:89;28590:20;28604:5;28590:20;;28622:97;28710:2;28690:14;-1:-1;;28686:28;;28670:49;28727:94;28801:2;28797:14;;28769:52;28829:117;28898:24;28916:5;28898:24;;;28891:5;28888:35;28878:2;;28937:1;28934;28927:12;28953:111;29019:21;29034:5;29019:21;;29071:115;29139:23;29156:5;29139:23;
Swarm Source
bzzr://b1c4b0e75aa342df894bad2f1424212f7596a6f05c247520dbb2ceecb0ea92b2
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.