Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
TradeAccounting
Compiler Version
v0.5.15+commit.6a57276f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-01-19 */ // File: @openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol pragma solidity ^0.5.0; /** * @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) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); 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-contracts/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) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message 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. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); 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) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message 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. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: @openzeppelin/upgrades/contracts/Initializable.sol pragma solidity >=0.4.24 <0.7.0; /** * @title Initializable * * @dev Helper contract to support initializer functions. To use it, replace * the constructor with a function that has the `initializer` modifier. * WARNING: Unlike constructors, initializer functions must be manually * invoked. This applies both to deploying an Initializable contract, as well * as extending an Initializable contract via inheritance. * WARNING: When used with inheritance, manual care must be taken to not invoke * a parent initializer twice, or ensure that all initializers are idempotent, * because this is not dealt with automatically as with constructors. */ contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private initializing; /** * @dev Modifier to use in the initializer function of a contract. */ modifier initializer() { require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); bool isTopLevelCall = !initializing; if (isTopLevelCall) { initializing = true; initialized = true; } _; if (isTopLevelCall) { initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function isConstructor() private view returns (bool) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. address self = address(this); uint256 cs; assembly { cs := extcodesize(self) } return cs == 0; } // Reserved storage space to allow for layout changes in the future. uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/GSN/Context.sol pragma solidity ^0.5.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ contract Context is Initializable { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor () internal { } // solhint-disable-previous-line no-empty-blocks function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: @openzeppelin/contracts-ethereum-package/contracts/ownership/Ownable.sol pragma solidity ^0.5.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be aplied to your functions to restrict their use to * the owner. */ contract Ownable is Initializable, Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function initialize(address sender) public initializer { _owner = sender; emit OwnershipTransferred(address(0), _owner); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(), "Ownable: caller is not the owner"); _; } /** * @dev Returns true if the caller is the current owner. */ function isOwner() public view returns (bool) { return _msgSender() == _owner; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * > Note: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol pragma solidity ^0.5.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see {ERC20Detailed}. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Detailed.sol pragma solidity ^0.5.0; /** * @dev Optional functions from the ERC20 standard. */ contract ERC20Detailed is Initializable, IERC20 { string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of * these values are immutable: they can only be set once during * construction. */ function initialize(string memory name, string memory symbol, uint8 decimals) public initializer { _name = name; _symbol = symbol; _decimals = decimals; } /** * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view returns (uint8) { return _decimals; } uint256[50] private ______gap; } // File: synthetix/contracts/interfaces/ISynth.sol pragma solidity >=0.4.24; // https://docs.synthetix.io/contracts/source/interfaces/isynth interface ISynth { // Views function currencyKey() external view returns (bytes32); function transferableSynths(address account) external view returns (uint); // Mutative functions function transferAndSettle(address to, uint value) external returns (bool); function transferFromAndSettle( address from, address to, uint value ) external returns (bool); // Restricted: used internally to Synthetix function burn(address account, uint amount) external; function issue(address account, uint amount) external; } // File: synthetix/contracts/interfaces/IVirtualSynth.sol pragma solidity >=0.4.24; interface IVirtualSynth { // Views function balanceOfUnderlying(address account) external view returns (uint); function rate() external view returns (uint); function readyToSettle() external view returns (bool); function secsLeftInWaitingPeriod() external view returns (uint); function settled() external view returns (bool); function synth() external view returns (ISynth); // Mutative functions function settle(address account) external; } // File: synthetix/contracts/interfaces/ISynthetix.sol pragma solidity >=0.4.24; // https://docs.synthetix.io/contracts/source/interfaces/isynthetix interface ISynthetix { // Views function anySynthOrSNXRateIsInvalid() external view returns (bool anyRateInvalid); function availableCurrencyKeys() external view returns (bytes32[] memory); function availableSynthCount() external view returns (uint); function availableSynths(uint index) external view returns (ISynth); function collateral(address account) external view returns (uint); function collateralisationRatio(address issuer) external view returns (uint); function debtBalanceOf(address issuer, bytes32 currencyKey) external view returns (uint); function isWaitingPeriod(bytes32 currencyKey) external view returns (bool); function maxIssuableSynths(address issuer) external view returns (uint maxIssuable); function remainingIssuableSynths(address issuer) external view returns ( uint maxIssuable, uint alreadyIssued, uint totalSystemDebt ); function synths(bytes32 currencyKey) external view returns (ISynth); function synthsByAddress(address synthAddress) external view returns (bytes32); function totalIssuedSynths(bytes32 currencyKey) external view returns (uint); function totalIssuedSynthsExcludeEtherCollateral(bytes32 currencyKey) external view returns (uint); function transferableSynthetix(address account) external view returns (uint transferable); // Mutative Functions function burnSynths(uint amount) external; function burnSynthsOnBehalf(address burnForAddress, uint amount) external; function burnSynthsToTarget() external; function burnSynthsToTargetOnBehalf(address burnForAddress) external; function exchange( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external returns (uint amountReceived); function exchangeOnBehalf( address exchangeForAddress, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external returns (uint amountReceived); function exchangeWithTracking( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address originator, bytes32 trackingCode ) external returns (uint amountReceived); function exchangeOnBehalfWithTracking( address exchangeForAddress, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address originator, bytes32 trackingCode ) external returns (uint amountReceived); function exchangeWithVirtual( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, bytes32 trackingCode ) external returns (uint amountReceived, IVirtualSynth vSynth); function issueMaxSynths() external; function issueMaxSynthsOnBehalf(address issueForAddress) external; function issueSynths(uint amount) external; function issueSynthsOnBehalf(address issueForAddress, uint amount) external; function mint() external returns (bool); function settle(bytes32 currencyKey) external returns ( uint reclaimed, uint refunded, uint numEntries ); // Liquidations function liquidateDelinquentAccount(address account, uint susdAmount) external returns (bool); // Restricted Functions function mintSecondary(address account, uint amount) external; function mintSecondaryRewards(uint amount) external; function burnSecondary(address account, uint amount) external; } // File: synthetix/contracts/interfaces/IRewardEscrowV2.sol pragma solidity >=0.4.24; pragma experimental ABIEncoderV2; library VestingEntries { struct VestingEntry { uint64 endTime; uint256 escrowAmount; } struct VestingEntryWithID { uint64 endTime; uint256 escrowAmount; uint256 entryID; } } interface IRewardEscrowV2 { // Views function balanceOf(address account) external view returns (uint); function numVestingEntries(address account) external view returns (uint); function totalEscrowedAccountBalance(address account) external view returns (uint); function totalVestedAccountBalance(address account) external view returns (uint); function getVestingQuantity(address account, uint256[] calldata entryIDs) external view returns (uint); function getVestingSchedules( address account, uint256 index, uint256 pageSize ) external view returns (VestingEntries.VestingEntryWithID[] memory); function getAccountVestingEntryIDs( address account, uint256 index, uint256 pageSize ) external view returns (uint256[] memory); function getVestingEntryClaimable(address account, uint256 entryID) external view returns (uint); function getVestingEntry(address account, uint256 entryID) external view returns (uint64, uint256); // Mutative functions function vest(uint256[] calldata entryIDs) external; function createEscrowEntry( address beneficiary, uint256 deposit, uint256 duration ) external; function appendVestingEntry( address account, uint256 quantity, uint256 duration ) external; function migrateVestingSchedule(address _addressToMigrate) external; function migrateAccountEscrowBalances( address[] calldata accounts, uint256[] calldata escrowBalances, uint256[] calldata vestedBalances ) external; // Account Merging function startMergingWindow() external; function mergeAccount(address accountToMerge, uint256[] calldata entryIDs) external; function nominateAccountToMerge(address account) external; function accountMergingIsOpen() external view returns (bool); // L2 Migration function importVestingEntries( address account, uint256 escrowedAmount, VestingEntries.VestingEntry[] calldata vestingEntries ) external; // Return amount of SNX transfered to SynthetixBridgeToOptimism deposit contract function burnForMigration(address account, uint256[] calldata entryIDs) external returns (uint256 escrowedAccountBalance, VestingEntries.VestingEntry[] memory vestingEntries); } // File: synthetix/contracts/interfaces/IExchangeRates.sol pragma solidity >=0.4.24; // 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; } // File: synthetix/contracts/interfaces/ISynthetixState.sol pragma solidity >=0.4.24; // https://docs.synthetix.io/contracts/source/interfaces/isynthetixstate interface ISynthetixState { // Views function debtLedger(uint index) external view returns (uint); function issuanceData(address account) external view returns (uint initialDebtOwnership, uint debtEntryIndex); function debtLedgerLength() external view returns (uint); function hasIssued(address account) external view returns (bool); function lastDebtLedgerEntry() external view returns (uint); // Mutative functions function incrementTotalIssuerCount() external; function decrementTotalIssuerCount() external; function setCurrentIssuanceData(address account, uint initialDebtOwnership) external; function appendDebtLedgerValue(uint value) external; function clearIssuanceData(address account) external; } // File: synthetix/contracts/interfaces/IAddressResolver.sol pragma solidity >=0.4.24; // 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); } // File: contracts/interface/ISystemSettings.sol pragma solidity 0.5.15; interface ISystemSettings { function issuanceRatio() external view returns(uint); } // File: contracts/interface/ICurveFi.sol pragma solidity 0.5.15; interface ICurveFi { function exchange( int128 i, int128 j, uint256 dx, uint256 min_dy ) external; function exchange_underlying( int128 i, int128 j, uint256 dx, uint256 min_dy ) external; function get_dx_underlying( int128 i, int128 j, uint256 dy ) external view returns (uint256); function get_dy_underlying( int128 i, int128 j, uint256 dx ) external view returns (uint256); function get_dx( int128 i, int128 j, uint256 dy ) external view returns (uint256); function get_dy( int128 i, int128 j, uint256 dx ) external view returns (uint256); function get_virtual_price() external view returns (uint256); } // File: contracts/interface/ISetToken.sol pragma solidity 0.5.15; interface ISetToken { function unitShares() external view returns(uint); function naturalUnit() external view returns(uint); function currentSet() external view returns(address); // function getUnits() external view returns (uint256[] memory); } // File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol pragma solidity ^0.5.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20Mintable}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Initializable, Context, IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for `sender`'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal { require(account != address(0), "ERC20: mint to the zero address"); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal { require(account != address(0), "ERC20: burn from the zero address"); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * This is internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Destroys `amount` tokens from `account`.`amount` is then deducted * from the caller's allowance. * * See {_burn} and {_approve}. */ function _burnFrom(address account, uint256 amount) internal { _burn(account, amount); _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance")); } uint256[50] private ______gap; } // File: contracts/interface/IKyberNetworkProxy.sol pragma solidity 0.5.15; contract IKyberNetworkProxy { function getExpectedRate(ERC20 src, ERC20 dest, uint srcQty) external view returns (uint expectedRate, uint slippageRate); function swapEtherToToken(ERC20 token, uint minConversionRate) external payable returns(uint); function swapTokenToEther(ERC20 token, uint tokenQty, uint minRate) external payable returns(uint); function swapTokenToToken(ERC20 src, uint srcAmount, ERC20 dest, uint minConversionRate) public returns(uint); } // File: contracts/interface/ISetAssetBaseCollateral.sol pragma solidity 0.5.15; interface ISetAssetBaseCollateral { function getComponents() external view returns(address[] memory); function naturalUnit() external view returns(uint); function getUnits() external view returns (uint256[] memory); } // File: contracts/TradeAccounting.sol pragma solidity 0.5.15; /* xSNX Target Allocation (assuming 800% C-RATIO) ---------------------- Allocation | NAV | % NAV -------------------------------------- 800 SNX @ $1/token | $800 | 100% 100 sUSD Debt | ($100) | (12.5%) 75 USD equiv Set | $75 | 9.375% 25 USD equiv ETH | $25 | 3.125% -------------------------------------- Total $800 | 100% */ /* Conditions for `isRebalanceTowardsHedgeRequired` to return true Assuming 5% rebalance threshold Allocation | NAV | % NAV -------------------------------------- 800 SNX @ $1/token | $800 | 100.63% 105 sUSD Debt | ($105) | (13.21%) 75 USD equiv Set | $75 | 9.43% 25 USD equiv ETH | $25 | 3.14% -------------------------------------- Total $795 | 100% Debt value | $105 Hedge Assets | $100 ------------------------- Debt/hedge ratio | 105% */ /* Conditions for `isRebalanceTowardsSnxRequired` to return true Assuming 5% rebalance threshold Allocation | NAV | % NAV -------------------------------------- 800 SNX @ $1/token | $800 | 99.37% 100 sUSD Debt | ($100) | (12.42%) 75 USD equiv Set | $75 | 9.31% 30 USD equiv ETH | $30 | 3.72% -------------------------------------- Total $805 | 100% Hedge Assets | $105 Debt value | $100 ------------------------- Hedge/debt ratio | 105% */ contract TradeAccounting is Ownable { using SafeMath for uint256; uint256 private constant TEN = 10; uint256 private constant DEC_18 = 1e18; uint256 private constant PERCENT = 100; uint256 private constant ETH_TARGET = 4; // targets 1/4th of hedge portfolio uint256 private constant SLIPPAGE_RATE = 99; uint256 private constant MAX_UINT = 2**256 - 1; uint256 private constant RATE_STALE_TIME = 28800; // 8 hours uint256 private constant REBALANCE_THRESHOLD = 105; // 5% uint256 private constant INITIAL_SUPPLY_MULTIPLIER = 10; int128 usdcIndex; int128 susdIndex; ICurveFi private curveFi; ISynthetixState private synthetixState; IAddressResolver private addressResolver; IKyberNetworkProxy private kyberNetworkProxy; address private xSNXAdminInstance; address private addressValidator; address private setAddress; address private susdAddress; address private usdcAddress; address private nextCurveAddress; bytes32 constant snx = "SNX"; bytes32 constant susd = "sUSD"; bytes32 constant seth = "sETH"; bytes32[2] synthSymbols; address[2] setComponentAddresses; bytes32 constant rewardEscrowName = "RewardEscrow"; bytes32 constant exchangeRatesName = "ExchangeRates"; bytes32 constant synthetixName = "Synthetix"; bytes32 constant systemSettingsName = "SystemSettings"; bytes32 constant rewardEscrowV2Name = "RewardEscrowV2"; function initialize( address _setAddress, address _kyberProxyAddress, address _addressResolver, address _susdAddress, address _usdcAddress, address _addressValidator, bytes32[2] memory _synthSymbols, address[2] memory _setComponentAddresses, address _ownerAddress ) public initializer { Ownable.initialize(_ownerAddress); setAddress = _setAddress; kyberNetworkProxy = IKyberNetworkProxy(_kyberProxyAddress); addressResolver = IAddressResolver(_addressResolver); susdAddress = _susdAddress; usdcAddress = _usdcAddress; addressValidator = _addressValidator; synthSymbols = _synthSymbols; setComponentAddresses = _setComponentAddresses; } modifier onlyXSNXAdmin { require( msg.sender == xSNXAdminInstance, "Only xSNXAdmin contract can call" ); _; } /* ========================================================================================= */ /* Kyber/Curve */ /* ========================================================================================= */ /* * @dev Function that processes all token to token exchanges, * sometimes via Kyber and sometimes via a combination of Kyber & Curve * @dev Only callable by xSNXAdmin contract */ function swapTokenToToken( address fromToken, uint256 amount, address toToken, uint256 minKyberRate, uint256 minCurveReturn ) public onlyXSNXAdmin { if (fromToken == susdAddress) { _exchangeUnderlying(susdIndex, usdcIndex, amount, minCurveReturn); if (toToken != usdcAddress) { uint256 usdcBal = getUsdcBalance(); _swapTokenToToken(usdcAddress, usdcBal, toToken, minKyberRate); } } else if (toToken == susdAddress) { if (fromToken != usdcAddress) { _swapTokenToToken(fromToken, amount, usdcAddress, minKyberRate); } uint256 usdcBal = getUsdcBalance(); _exchangeUnderlying(usdcIndex, susdIndex, usdcBal, minCurveReturn); } else { _swapTokenToToken(fromToken, amount, toToken, minKyberRate); } IERC20(toToken).transfer( xSNXAdminInstance, IERC20(toToken).balanceOf(address(this)) ); } function _swapTokenToToken( address _fromToken, uint256 _amount, address _toToken, uint256 _minKyberRate ) private { kyberNetworkProxy.swapTokenToToken( ERC20(_fromToken), _amount, ERC20(_toToken), _minKyberRate ); } /* * @dev Function that processes all token to ETH exchanges, * sometimes via Kyber and sometimes via a combination of Kyber & Curve * @dev Only callable by xSNXAdmin contract */ function swapTokenToEther( address fromToken, uint256 amount, uint256 minKyberRate, uint256 minCurveReturn ) public onlyXSNXAdmin { if (fromToken == susdAddress) { _exchangeUnderlying(susdIndex, usdcIndex, amount, minCurveReturn); uint256 usdcBal = getUsdcBalance(); _swapTokenToEther(usdcAddress, usdcBal, minKyberRate); } else { _swapTokenToEther(fromToken, amount, minKyberRate); } uint256 ethBal = address(this).balance; (bool success, ) = msg.sender.call.value(ethBal)(""); require(success, "Transfer failed"); } function _swapTokenToEther( address _fromToken, uint256 _amount, uint256 _minKyberRate ) private { kyberNetworkProxy.swapTokenToEther( ERC20(_fromToken), _amount, _minKyberRate ); } function _exchangeUnderlying( int128 _inputIndex, int128 _outputIndex, uint256 _amount, uint256 _minReturn ) private { curveFi.exchange_underlying( _inputIndex, _outputIndex, _amount, _minReturn ); } function getUsdcBalance() internal view returns (uint256) { return IERC20(usdcAddress).balanceOf(address(this)); } /* ========================================================================================= */ /* NAV */ /* ========================================================================================= */ function getEthBalance() public view returns (uint256) { return address(xSNXAdminInstance).balance; } /* * @dev Helper function for `xSNX.burn` that outputs NAV * redemption value in ETH terms * @param totalSupply: xSNX.totalSupply() * @param tokensToRedeem: xSNX to burn */ function calculateRedemptionValue( uint256 totalSupply, uint256 tokensToRedeem ) public view returns (uint256 valueToRedeem) { uint256 snxBalanceOwned = getSnxBalanceOwned(); uint256 contractDebtValue = getContractDebtValue(); uint256 pricePerToken = calculateRedeemTokenPrice( totalSupply, snxBalanceOwned, contractDebtValue ); valueToRedeem = pricePerToken.mul(tokensToRedeem).div(DEC_18); } /* * @dev Helper function for `xSNX.mint` that * 1) determines whether ETH contribution should be maintained in ETH or exchanged for SNX and * 2) outputs the `nonSnxAssetValue` value to be used in NAV calculation * @param totalSupply: xSNX.totalSupply() */ function getMintWithEthUtils(uint256 totalSupply) public view returns (bool allocateToEth, uint256 nonSnxAssetValue) { uint256 setHoldingsInWei = getSetHoldingsValueInWei(); // called before eth transferred from xSNX to xSNXAdmin uint256 ethBalBefore = getEthBalance(); allocateToEth = shouldAllocateEthToEthReserve( setHoldingsInWei, ethBalBefore, totalSupply ); nonSnxAssetValue = setHoldingsInWei.add(ethBalBefore); } /* * @notice xSNX system targets 25% of hedge portfolio to be maintained in ETH * @dev Function produces binary yes allocate/no allocate decision point * determining whether ETH sent on xSNX.mint() is held or exchanged * @param setHoldingsInWei: value of Set portfolio in ETH terms * @param ethBalBefore: value of ETH reserve prior to tx * @param totalSupply: xSNX.totalSupply() */ function shouldAllocateEthToEthReserve( uint256 setHoldingsInWei, uint256 ethBalBefore, uint256 totalSupply ) public pure returns (bool allocateToEth) { if (totalSupply == 0) return false; if (ethBalBefore.mul(ETH_TARGET) < ethBalBefore.add(setHoldingsInWei)) { // ETH reserve is under target return true; } return false; } /* * @dev Helper function for calculateIssueTokenPrice * @dev Called indirectly by `xSNX.mint` and `xSNX.mintWithSnx` * @dev Calculates NAV of the fund, including value of escrowed SNX, in ETH terms * @param weiPerOneSnx: SNX price in ETH terms * @param snxBalanceBefore: SNX balance pre-mint * @param nonSnxAssetValue: NAV of non-SNX slice of fund */ function calculateNetAssetValueOnMint( uint256 weiPerOneSnx, uint256 snxBalanceBefore, uint256 nonSnxAssetValue ) internal view returns (uint256) { uint256 snxTokenValueInWei = snxBalanceBefore.mul(weiPerOneSnx).div( DEC_18 ); uint256 contractDebtValue = getContractDebtValue(); uint256 contractDebtValueInWei = calculateDebtValueInWei( contractDebtValue ); return snxTokenValueInWei.add(nonSnxAssetValue).sub( contractDebtValueInWei ); } /* * @dev Helper function for calculateRedeemTokenPrice * @dev Called indirectly by `xSNX.burn` * @dev Calculates NAV of the fund, excluding value of escrowed SNX, in ETH terms * @param weiPerOneSnx: SNX price in ETH terms * @param snxBalanceOwned: non-escrowed SNX balance * @param contractDebtValueInWei: sUSD debt balance of fund in ETH terms */ function calculateNetAssetValueOnRedeem( uint256 weiPerOneSnx, uint256 snxBalanceOwned, uint256 contractDebtValueInWei ) internal view returns (uint256) { uint256 snxTokenValueInWei = snxBalanceOwned.mul(weiPerOneSnx).div( DEC_18 ); uint256 nonSnxAssetValue = calculateNonSnxAssetValue(); return snxTokenValueInWei.add(nonSnxAssetValue).sub( contractDebtValueInWei ); } /* * @dev NAV value of non-SNX assets, computed in ETH terms */ function calculateNonSnxAssetValue() internal view returns (uint256) { return getSetHoldingsValueInWei().add(getEthBalance()); } /* * @dev SNX price in ETH terms, calculated for purposes of redemption NAV * @notice Return value discounted slightly to better represent liquidation price */ function getWeiPerOneSnxOnRedeem() internal view returns (uint256 weiPerOneSnx) { uint256 snxUsdPrice = getSnxPrice(); uint256 ethUsdPrice = getSynthPrice(seth); weiPerOneSnx = snxUsdPrice .mul(DEC_18) .div(ethUsdPrice) .mul(SLIPPAGE_RATE) // used to better represent liquidation price as volume scales .div(PERCENT); } /* * @dev Returns Synthetix synth symbol for asset currently held in TokenSet (e.g., sETH for WETH) * @notice xSNX contract complex only compatible with Sets that hold a single asset at a time */ function getActiveAssetSynthSymbol() internal view returns (bytes32 synthSymbol) { synthSymbol = getAssetCurrentlyActiveInSet() == setComponentAddresses[0] ? (synthSymbols[0]) : (synthSymbols[1]); } /* * @dev Returns SNX price in ETH terms, calculated for purposes of issuance NAV (when allocateToEth) */ function getWeiPerOneSnxOnMint() internal view returns (uint256) { uint256 snxUsd = getSynthPrice(snx); uint256 ethUsd = getSynthPrice(seth); return snxUsd.mul(DEC_18).div(ethUsd); } /* * @dev Single use function to define initial xSNX issuance */ function getInitialSupply() internal view returns (uint256) { return IERC20(addressResolver.getAddress(synthetixName)) .balanceOf(xSNXAdminInstance) .mul(INITIAL_SUPPLY_MULTIPLIER); } /* * @dev Helper function for `xSNX.mint` that calculates token issuance * @param snxBalanceBefore: SNX balance pre-mint * @param ethContributed: ETH payable on mint, less fees * @param nonSnxAssetValue: NAV of non-SNX slice of fund * @param totalSupply: xSNX.totalSupply() * @param allocateToEth: bool determining whether ETH payable is reserved in ETH or exchanged */ function calculateTokensToMintWithEth( uint256 snxBalanceBefore, uint256 ethContributed, uint256 nonSnxAssetValue, uint256 totalSupply, bool allocateToEth ) public view returns (uint256) { if (totalSupply == 0) { return getInitialSupply(); } uint256 weiPerOneSnx; if (allocateToEth) { weiPerOneSnx = getWeiPerOneSnxOnMint(); } else { uint256 snxBalanceAfter = getSnxBalance(); uint256 snxContributed = snxBalanceAfter.sub(snxBalanceBefore); weiPerOneSnx = ethContributed.mul(DEC_18).div(snxContributed); } uint256 pricePerToken = calculateIssueTokenPrice( weiPerOneSnx, snxBalanceBefore, nonSnxAssetValue, totalSupply ); return ethContributed.mul(DEC_18).div(pricePerToken); } /* * @dev Helper function for `xSNX.mintWithSnx` that calculates token issuance * @param snxBalanceBefore: SNX balance pre-mint * @param snxAddedToBalance: SNX contributed by mint * @param totalSupply: xSNX.totalSupply() */ function calculateTokensToMintWithSnx( uint256 snxBalanceBefore, uint256 snxAddedToBalance, uint256 totalSupply ) public view returns (uint256) { if (totalSupply == 0) { return getInitialSupply(); } uint256 weiPerOneSnx = getWeiPerOneSnxOnMint(); // need to derive snx contribution in eth terms for NAV calc uint256 proxyEthContribution = weiPerOneSnx.mul(snxAddedToBalance).div( DEC_18 ); uint256 nonSnxAssetValue = calculateNonSnxAssetValue(); uint256 pricePerToken = calculateIssueTokenPrice( weiPerOneSnx, snxBalanceBefore, nonSnxAssetValue, totalSupply ); return proxyEthContribution.mul(DEC_18).div(pricePerToken); } /* * @dev Called indirectly by `xSNX.mint` and `xSNX.mintWithSnx` * @dev Calculates token price on issuance, including value of escrowed SNX * @param weiPerOneSnx: SNX price in ETH terms * @param snxBalanceBefore: SNX balance pre-mint * @param nonSnxAssetValue: Non-SNX slice of fund * @param totalSupply: xSNX.totalSupply() */ function calculateIssueTokenPrice( uint256 weiPerOneSnx, uint256 snxBalanceBefore, uint256 nonSnxAssetValue, uint256 totalSupply ) public view returns (uint256 pricePerToken) { pricePerToken = calculateNetAssetValueOnMint( weiPerOneSnx, snxBalanceBefore, nonSnxAssetValue ) .mul(DEC_18) .div(totalSupply); } /* * @dev Called indirectly by `xSNX.burn` * @dev Calculates token price on redemption, excluding value of escrowed SNX * @param totalSupply: xSNX.totalSupply() * @param snxBalanceOwned: non-escrowed SNX balance * @param contractDebtValue: sUSD debt in USD terms */ function calculateRedeemTokenPrice( uint256 totalSupply, uint256 snxBalanceOwned, uint256 contractDebtValue ) public view returns (uint256 pricePerToken) { // SNX won't actually be sold (burns are only distributed in available ETH) but // this is a proxy for the return value of SNX that would be sold uint256 weiPerOneSnx = getWeiPerOneSnxOnRedeem(); uint256 debtValueInWei = calculateDebtValueInWei(contractDebtValue); pricePerToken = calculateNetAssetValueOnRedeem( weiPerOneSnx, snxBalanceOwned, debtValueInWei ) .mul(DEC_18) .div(totalSupply); } /* ========================================================================================= */ /* Set */ /* ========================================================================================= */ /* * @dev Balance of underlying asset "active" in Set (e.g., WETH or USDC) */ function getActiveSetAssetBalance() public view returns (uint256) { return IERC20(getAssetCurrentlyActiveInSet()).balanceOf(xSNXAdminInstance); } /* * @dev Calculates quantity of Set Token equivalent to quantity of underlying asset token * @notice rebalancingSetQuantity return value is reduced slightly to ensure successful execution * @param componentQuantity: balance of underlying Set asset, e.g., WETH */ function calculateSetQuantity(uint256 componentQuantity) public view returns (uint256 rebalancingSetQuantity) { uint256 baseSetNaturalUnit = getBaseSetNaturalUnit(); uint256 baseSetComponentUnits = getBaseSetComponentUnits(); uint256 baseSetIssuable = componentQuantity.mul(baseSetNaturalUnit).div( baseSetComponentUnits ); uint256 rebalancingSetNaturalUnit = getSetNaturalUnit(); uint256 unitShares = getSetUnitShares(); rebalancingSetQuantity = baseSetIssuable .mul(rebalancingSetNaturalUnit) .div(unitShares) .mul(99) // ensure sufficient balance in underlying asset .div(100) .div(rebalancingSetNaturalUnit) .mul(rebalancingSetNaturalUnit); } /* * @dev Calculates mintable quantity of Set Token given asset holdings */ function calculateSetIssuanceQuantity() public view returns (uint256 rebalancingSetIssuable) { uint256 componentQuantity = getActiveSetAssetBalance(); rebalancingSetIssuable = calculateSetQuantity(componentQuantity); } /* * @dev Calculates Set token to sell given sUSD burn requirements * @param totalSusdToBurn: sUSD to burn to fix ratio or unlock staked SNX */ function calculateSetRedemptionQuantity(uint256 totalSusdToBurn) public view returns (uint256 rebalancingSetRedeemable) { address currentSetAsset = getAssetCurrentlyActiveInSet(); bytes32 activeAssetSynthSymbol = getActiveAssetSynthSymbol(); uint256 synthUsd = getSynthPrice(activeAssetSynthSymbol); // expectedSetAssetRate = amount of current set asset needed to redeem for 1 sUSD uint256 expectedSetAssetRate = DEC_18.mul(DEC_18).div(synthUsd); uint256 setAssetCollateralToSell = expectedSetAssetRate .mul(totalSusdToBurn) .div(DEC_18) .mul(103) // err on the high side .div(PERCENT); uint256 decimals = (TEN**ERC20Detailed(currentSetAsset).decimals()); setAssetCollateralToSell = setAssetCollateralToSell.mul(decimals).div( DEC_18 ); rebalancingSetRedeemable = calculateSetQuantity( setAssetCollateralToSell ); } /* * @dev Calculates value of a single 1e18 Set unit in ETH terms */ function calculateEthValueOfOneSetUnit() internal view returns (uint256 ethValue) { uint256 unitShares = getSetUnitShares(); uint256 rebalancingSetNaturalUnit = getSetNaturalUnit(); uint256 baseSetRequired = DEC_18.mul(unitShares).div( rebalancingSetNaturalUnit ); uint256 unitsOfUnderlying = getBaseSetComponentUnits(); uint256 baseSetNaturalUnit = getBaseSetNaturalUnit(); uint256 componentRequired = baseSetRequired.mul(unitsOfUnderlying).div( baseSetNaturalUnit ); address currentSetAsset = getAssetCurrentlyActiveInSet(); uint256 decimals = (TEN**ERC20Detailed(currentSetAsset).decimals()); componentRequired = componentRequired.mul(DEC_18).div(decimals); bytes32 activeAssetSynthSymbol = getActiveAssetSynthSymbol(); uint256 synthUsd = getSynthPrice(activeAssetSynthSymbol); uint256 ethUsd = getSynthPrice(seth); ethValue = componentRequired.mul(synthUsd).div(ethUsd); } /* * @dev Calculates value of Set Holdings in ETH terms */ function getSetHoldingsValueInWei() public view returns (uint256 setValInWei) { uint256 setCollateralTokens = getSetCollateralTokens(); bytes32 synthSymbol = getActiveAssetSynthSymbol(); address currentSetAsset = getAssetCurrentlyActiveInSet(); uint256 synthUsd = getSynthPrice(synthSymbol); uint256 ethUsd = getSynthPrice(seth); uint256 decimals = (TEN**ERC20Detailed(currentSetAsset).decimals()); setCollateralTokens = setCollateralTokens.mul(DEC_18).div(decimals); setValInWei = setCollateralTokens.mul(synthUsd).div(ethUsd); } function getBaseSetNaturalUnit() internal view returns (uint256) { return getCurrentCollateralSet().naturalUnit(); } /* * @dev Outputs current active Set asset * @notice xSNX contracts complex only compatible with Sets that hold a single asset at a time */ function getAssetCurrentlyActiveInSet() public view returns (address) { address[] memory currentAllocation = getCurrentCollateralSet() .getComponents(); return currentAllocation[0]; } function getCurrentCollateralSet() internal view returns (ISetAssetBaseCollateral) { return ISetAssetBaseCollateral(getCurrentSet()); } function getCurrentSet() internal view returns (address) { return ISetToken(setAddress).currentSet(); } /* * @dev Returns the number of underlying tokens in the current Set asset * e.g., the contract's Set holdings are collateralized by 10.4 WETH */ function getSetCollateralTokens() internal view returns (uint256) { return getSetBalanceCollateral().mul(getBaseSetComponentUnits()).div( getBaseSetNaturalUnit() ); } function getSetBalanceCollateral() internal view returns (uint256) { uint256 unitShares = getSetUnitShares(); uint256 naturalUnit = getSetNaturalUnit(); return getContractSetBalance().mul(unitShares).div(naturalUnit); } function getSetUnitShares() internal view returns (uint256) { return ISetToken(setAddress).unitShares(); } function getSetNaturalUnit() internal view returns (uint256) { return ISetToken(setAddress).naturalUnit(); } function getContractSetBalance() internal view returns (uint256) { return IERC20(setAddress).balanceOf(xSNXAdminInstance); } function getBaseSetComponentUnits() internal view returns (uint256) { return ISetAssetBaseCollateral(getCurrentSet()).getUnits()[0]; } /* ========================================================================================= */ /* Synthetix */ /* ========================================================================================= */ function getSusdBalance() public view returns (uint256) { return IERC20(susdAddress).balanceOf(xSNXAdminInstance); } function getSnxBalance() public view returns (uint256) { return getSnxBalanceOwned().add(getSnxBalanceEscrowed()); } function getSnxBalanceOwned() internal view returns (uint256) { return IERC20(addressResolver.getAddress(synthetixName)).balanceOf( xSNXAdminInstance ); } function getSnxBalanceEscrowed() internal view returns (uint256) { return IRewardEscrowV2(addressResolver.getAddress(rewardEscrowV2Name)) .balanceOf(xSNXAdminInstance); } function getContractEscrowedSnxValue() internal view returns (uint256) { return getSnxBalanceEscrowed().mul(getSnxPrice()).div(DEC_18); } function getContractOwnedSnxValue() internal view returns (uint256) { return getSnxBalanceOwned().mul(getSnxPrice()).div(DEC_18); } function getSnxPrice() internal view returns (uint256) { (uint256 rate, uint256 time) = IExchangeRates( addressResolver.getAddress(exchangeRatesName) ) .rateAndUpdatedTime(snx); require(time.add(RATE_STALE_TIME) > block.timestamp, "Rate stale"); return rate; } function getSynthPrice(bytes32 synth) internal view returns (uint256) { (uint256 rate, uint256 time) = IExchangeRates( addressResolver.getAddress(exchangeRatesName) ) .rateAndUpdatedTime(synth); if (synth != susd) { require(time.add(RATE_STALE_TIME) > block.timestamp, "Rate stale"); } return rate; } /* * @dev Converts sUSD debt value into ETH terms * @param debtValue: sUSD-denominated debt value */ function calculateDebtValueInWei(uint256 debtValue) internal view returns (uint256 debtBalanceInWei) { uint256 ethUsd = getSynthPrice(seth); debtBalanceInWei = debtValue.mul(DEC_18).div(ethUsd); } function getContractDebtValue() internal view returns (uint256) { return ISynthetix(addressResolver.getAddress(synthetixName)).debtBalanceOf( xSNXAdminInstance, susd ); } /* * @notice Returns inverse of target C-RATIO */ function getIssuanceRatio() internal view returns (uint256) { return ISystemSettings(addressResolver.getAddress(systemSettingsName)) .issuanceRatio(); } /* * @notice Returns NAV contribution of SNX holdings in USD terms */ function getContractSnxValue() internal view returns (uint256) { return getSnxBalance().mul(getSnxPrice()).div(DEC_18); } /* ========================================================================================= */ /* Burning sUSD */ /* ========================================================================================= */ /* * @dev Calculates sUSD to burn to restore C-RATIO * @param snxValueHeld: USD value of SNX * @param contractDebtValue: USD value of sUSD debt * @param issuanceRatio: Synthetix C-RATIO requirement */ function calculateSusdToBurnToFixRatio( uint256 snxValueHeld, uint256 contractDebtValue, uint256 issuanceRatio ) internal pure returns (uint256) { uint256 subtractor = issuanceRatio.mul(snxValueHeld).div(DEC_18); if (subtractor > contractDebtValue) return 0; return contractDebtValue.sub(subtractor); } /* * @dev Calculates sUSD to burn to restore C-RATIO */ function calculateSusdToBurnToFixRatioExternal() public view returns (uint256) { uint256 snxValueHeld = getContractSnxValue(); uint256 debtValue = getContractDebtValue(); uint256 issuanceRatio = getIssuanceRatio(); return calculateSusdToBurnToFixRatio( snxValueHeld, debtValue, issuanceRatio ); } /* * @dev Calculates sUSD to burn to eclipse value of escrowed SNX * @notice Synthetix system requires escrowed SNX to be "unlocked" first * @param issuanceRatio: Synthetix C-RATIO requirement */ function calculateSusdToBurnToEclipseEscrowed(uint256 issuanceRatio) public view returns (uint256) { uint256 escrowedSnxValue = getContractEscrowedSnxValue(); if (escrowedSnxValue == 0) return 0; return escrowedSnxValue.mul(issuanceRatio).div(DEC_18); } /* * @dev Helper function to calculate sUSD burn required for a potential redemption * @param tokensToRedeem: potential tokens to burn * @param totalSupply: xSNX.totalSupply() * @param contractDebtValue: sUSD debt value * @param issuanceRatio: Synthetix C-RATIO requirement */ function calculateSusdToBurnForRedemption( uint256 tokensToRedeem, uint256 totalSupply, uint256 contractDebtValue, uint256 issuanceRatio ) public view returns (uint256 susdToBurn) { uint256 nonEscrowedSnxValue = getContractOwnedSnxValue(); uint256 lockedSnxValue = contractDebtValue.mul(DEC_18).div( issuanceRatio ); uint256 valueOfSnxToSell = nonEscrowedSnxValue.mul(tokensToRedeem).div( totalSupply ); susdToBurn = ( lockedSnxValue.add(valueOfSnxToSell).sub(nonEscrowedSnxValue) ) .mul(issuanceRatio) .div(DEC_18); } /* ========================================================================================= */ /* Rebalances */ /* ========================================================================================= */ /* * @dev Helper function to facilitate xSNXAdmin.rebalanceTowardsHedge() */ function calculateAssetChangesForRebalanceToHedge() internal view returns (uint256 totalSusdToBurn, uint256 snxToSell) { uint256 snxValueHeld = getContractSnxValue(); uint256 debtValueInUsd = getContractDebtValue(); uint256 issuanceRatio = getIssuanceRatio(); uint256 susdToBurnToFixRatio = calculateSusdToBurnToFixRatio( snxValueHeld, debtValueInUsd, issuanceRatio ); uint256 susdToBurnToEclipseEscrowed = calculateSusdToBurnToEclipseEscrowed(issuanceRatio); uint256 hedgeAssetsValueInUsd = calculateHedgeAssetsValueInUsd(); uint256 valueToUnlockInUsd = debtValueInUsd.sub(hedgeAssetsValueInUsd); uint256 susdToBurnToUnlockTransfer = valueToUnlockInUsd .mul(issuanceRatio) .div(DEC_18); totalSusdToBurn = ( susdToBurnToFixRatio.add(susdToBurnToEclipseEscrowed).add( susdToBurnToUnlockTransfer ) ); snxToSell = valueToUnlockInUsd.mul(DEC_18).div(getSnxPrice()); } /* * @dev Helper function to facilitate xSNXAdmin.rebalanceTowardsSnx() */ function calculateAssetChangesForRebalanceToSnx() public view returns (uint256 setToSell) { ( uint256 debtValueInWei, uint256 hedgeAssetsBalance ) = getRebalanceUtils(); uint256 setValueToSell = hedgeAssetsBalance.sub(debtValueInWei); uint256 ethValueOfOneSet = calculateEthValueOfOneSetUnit(); setToSell = setValueToSell.mul(DEC_18).div(ethValueOfOneSet); // Set quantity must be multiple of natural unit uint256 naturalUnit = getSetNaturalUnit(); setToSell = setToSell.div(naturalUnit).mul(naturalUnit); } /* * @dev Helper function to facilitate xSNXAdmin.rebalanceTowardsSnx() */ function getRebalanceTowardsSnxUtils() public view returns (uint256 setToSell, address activeAsset) { setToSell = calculateAssetChangesForRebalanceToSnx(); activeAsset = getAssetCurrentlyActiveInSet(); } /* * @dev Helper function to facilitate xSNXAdmin.rebalanceTowardsSnx(), xSNXAdmin.rebalanceTowardsHedge() * @dev Denominated in ETH terms */ function getRebalanceUtils() public view returns (uint256 debtValueInWei, uint256 hedgeAssetsBalance) { uint256 setHoldingsInWei = getSetHoldingsValueInWei(); uint256 ethBalance = getEthBalance(); uint256 debtValue = getContractDebtValue(); debtValueInWei = calculateDebtValueInWei(debtValue); hedgeAssetsBalance = setHoldingsInWei.add(ethBalance); } /* * @dev Helper function to facilitate xSNXAdmin.rebalanceTowardsHedge() * @dev Denominated in USD terms */ function calculateHedgeAssetsValueInUsd() internal view returns (uint256 hedgeAssetsValueInUsd) { address currentSetAsset = getAssetCurrentlyActiveInSet(); uint256 decimals = (TEN**ERC20Detailed(currentSetAsset).decimals()); uint256 setCollateralTokens = getSetCollateralTokens(); setCollateralTokens = setCollateralTokens.mul(DEC_18).div(decimals); bytes32 activeAssetSynthSymbol = getActiveAssetSynthSymbol(); uint256 synthUsd = getSynthPrice(activeAssetSynthSymbol); uint256 setValueUsd = setCollateralTokens.mul(synthUsd).div(DEC_18); uint256 ethBalance = getEthBalance(); uint256 ethUsd = getSynthPrice(seth); uint256 ethValueUsd = ethBalance.mul(ethUsd).div(DEC_18); hedgeAssetsValueInUsd = setValueUsd.add(ethValueUsd); } /* * @dev Helper function to determine whether xSNXAdmin.rebalanceTowardsSnx() is required */ function isRebalanceTowardsSnxRequired() public view returns (bool) { ( uint256 debtValueInWei, uint256 hedgeAssetsBalance ) = getRebalanceUtils(); if ( debtValueInWei.mul(REBALANCE_THRESHOLD).div(PERCENT) < hedgeAssetsBalance ) { return true; } return false; } /* * @dev Helper function to determine whether xSNXAdmin.rebalanceTowardsHedge() is required */ function isRebalanceTowardsHedgeRequired() public view returns (bool) { ( uint256 debtValueInWei, uint256 hedgeAssetsBalance ) = getRebalanceUtils(); if ( hedgeAssetsBalance.mul(REBALANCE_THRESHOLD).div(PERCENT) < debtValueInWei ) { return true; } return false; } /* * @dev Helper function to facilitate xSNXAdmin.rebalanceTowardsHedge() * @notice Will fail if !isRebalanceTowardsHedgeRequired() */ function getRebalanceTowardsHedgeUtils() public view returns ( uint256, uint256, address ) { ( uint256 totalSusdToBurn, uint256 snxToSell ) = calculateAssetChangesForRebalanceToHedge(); address activeAsset = getAssetCurrentlyActiveInSet(); return (totalSusdToBurn, snxToSell, activeAsset); } /* * @dev Helper for `hedge` function * @dev Determines share of sUSD to allocate to ETH * @dev Implicitly determines Set allocation as well * @param susdBal: sUSD balance post minting */ function getEthAllocationOnHedge(uint256 susdBal) public view returns (uint256 ethAllocation) { uint256 ethUsd = getSynthPrice(seth); uint256 setHoldingsInUsd = getSetHoldingsValueInWei().mul(ethUsd).div( DEC_18 ); uint256 ethBalInUsd = getEthBalance().mul(ethUsd).div(DEC_18); uint256 hedgeAssets = setHoldingsInUsd.add(ethBalInUsd); if (ethBalInUsd.mul(ETH_TARGET) >= hedgeAssets.add(susdBal)) { // full bal directed toward Set // eth allocation is 0 } else if ((ethBalInUsd.add(susdBal)).mul(ETH_TARGET) < hedgeAssets) { // full bal directed toward Eth ethAllocation = susdBal; } else { // fractionate allocation ethAllocation = ((hedgeAssets.add(susdBal)).div(ETH_TARGET)).sub( ethBalInUsd ); } } /* * @dev Helper function to facilitate xSNXAdmin.rebalanceSetToEth() */ function calculateSetToSellForRebalanceSetToEth() public view returns (uint256 setQuantityToSell) { uint256 setHoldingsInWei = getSetHoldingsValueInWei(); uint256 ethBal = getEthBalance(); uint256 hedgeAssets = setHoldingsInWei.add(ethBal); require( ethBal.mul(ETH_TARGET) < hedgeAssets, "Rebalance not necessary" ); uint256 ethToAdd = ((hedgeAssets.div(ETH_TARGET)).sub(ethBal)); setQuantityToSell = getContractSetBalance().mul(ethToAdd).div( setHoldingsInWei ); uint256 naturalUnit = getSetNaturalUnit(); setQuantityToSell = setQuantityToSell.div(naturalUnit).mul(naturalUnit); } /* ========================================================================================= */ /* Address Setters */ /* ========================================================================================= */ function setAdminInstanceAddress(address _xSNXAdminInstance) public onlyOwner { if (xSNXAdminInstance == address(0)) { xSNXAdminInstance = _xSNXAdminInstance; } } function setCurve( address curvePoolAddress, int128 _usdcIndex, int128 _susdIndex ) public onlyOwner { if (address(curveFi) == address(0)) { // if initial set on deployment, immediately activate Curve address curveFi = ICurveFi(curvePoolAddress); nextCurveAddress = curvePoolAddress; } else { // if updating Curve address (i.e., not initial setting of address on deployment), // store nextCurveAddress but don't activate until addressValidator has confirmed nextCurveAddress = curvePoolAddress; } usdcIndex = _usdcIndex; susdIndex = _susdIndex; } /* ========================================================================================= */ /* Utils */ /* ========================================================================================= */ // admin on deployment approve [snx, susd, setComponentA, setComponentB] function approveKyber(address tokenAddress) public onlyOwner { IERC20(tokenAddress).approve(address(kyberNetworkProxy), MAX_UINT); } // admin on deployment approve [susd, usdc] function approveCurve(address tokenAddress) public onlyOwner { IERC20(tokenAddress).approve(address(curveFi), MAX_UINT); } function confirmCurveAddress(address _nextCurveAddress) public { require(msg.sender == addressValidator, "Incorrect caller"); require(nextCurveAddress == _nextCurveAddress, "Addresses don't match"); curveFi = ICurveFi(nextCurveAddress); } function() external payable {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"approveCurve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"approveKyber","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"calculateAssetChangesForRebalanceToSnx","outputs":[{"internalType":"uint256","name":"setToSell","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"weiPerOneSnx","type":"uint256"},{"internalType":"uint256","name":"snxBalanceBefore","type":"uint256"},{"internalType":"uint256","name":"nonSnxAssetValue","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"calculateIssueTokenPrice","outputs":[{"internalType":"uint256","name":"pricePerToken","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"snxBalanceOwned","type":"uint256"},{"internalType":"uint256","name":"contractDebtValue","type":"uint256"}],"name":"calculateRedeemTokenPrice","outputs":[{"internalType":"uint256","name":"pricePerToken","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"tokensToRedeem","type":"uint256"}],"name":"calculateRedemptionValue","outputs":[{"internalType":"uint256","name":"valueToRedeem","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"calculateSetIssuanceQuantity","outputs":[{"internalType":"uint256","name":"rebalancingSetIssuable","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"componentQuantity","type":"uint256"}],"name":"calculateSetQuantity","outputs":[{"internalType":"uint256","name":"rebalancingSetQuantity","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"totalSusdToBurn","type":"uint256"}],"name":"calculateSetRedemptionQuantity","outputs":[{"internalType":"uint256","name":"rebalancingSetRedeemable","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"calculateSetToSellForRebalanceSetToEth","outputs":[{"internalType":"uint256","name":"setQuantityToSell","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokensToRedeem","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"contractDebtValue","type":"uint256"},{"internalType":"uint256","name":"issuanceRatio","type":"uint256"}],"name":"calculateSusdToBurnForRedemption","outputs":[{"internalType":"uint256","name":"susdToBurn","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"issuanceRatio","type":"uint256"}],"name":"calculateSusdToBurnToEclipseEscrowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"calculateSusdToBurnToFixRatioExternal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"snxBalanceBefore","type":"uint256"},{"internalType":"uint256","name":"ethContributed","type":"uint256"},{"internalType":"uint256","name":"nonSnxAssetValue","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"bool","name":"allocateToEth","type":"bool"}],"name":"calculateTokensToMintWithEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"snxBalanceBefore","type":"uint256"},{"internalType":"uint256","name":"snxAddedToBalance","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"calculateTokensToMintWithSnx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_nextCurveAddress","type":"address"}],"name":"confirmCurveAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getActiveSetAssetBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAssetCurrentlyActiveInSet","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"susdBal","type":"uint256"}],"name":"getEthAllocationOnHedge","outputs":[{"internalType":"uint256","name":"ethAllocation","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEthBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"getMintWithEthUtils","outputs":[{"internalType":"bool","name":"allocateToEth","type":"bool"},{"internalType":"uint256","name":"nonSnxAssetValue","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRebalanceTowardsHedgeUtils","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRebalanceTowardsSnxUtils","outputs":[{"internalType":"uint256","name":"setToSell","type":"uint256"},{"internalType":"address","name":"activeAsset","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRebalanceUtils","outputs":[{"internalType":"uint256","name":"debtValueInWei","type":"uint256"},{"internalType":"uint256","name":"hedgeAssetsBalance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getSetHoldingsValueInWei","outputs":[{"internalType":"uint256","name":"setValInWei","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getSnxBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getSusdBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_setAddress","type":"address"},{"internalType":"address","name":"_kyberProxyAddress","type":"address"},{"internalType":"address","name":"_addressResolver","type":"address"},{"internalType":"address","name":"_susdAddress","type":"address"},{"internalType":"address","name":"_usdcAddress","type":"address"},{"internalType":"address","name":"_addressValidator","type":"address"},{"internalType":"bytes32[2]","name":"_synthSymbols","type":"bytes32[2]"},{"internalType":"address[2]","name":"_setComponentAddresses","type":"address[2]"},{"internalType":"address","name":"_ownerAddress","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isRebalanceTowardsHedgeRequired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isRebalanceTowardsSnxRequired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_xSNXAdminInstance","type":"address"}],"name":"setAdminInstanceAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"curvePoolAddress","type":"address"},{"internalType":"int128","name":"_usdcIndex","type":"int128"},{"internalType":"int128","name":"_susdIndex","type":"int128"}],"name":"setCurve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"setHoldingsInWei","type":"uint256"},{"internalType":"uint256","name":"ethBalBefore","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"shouldAllocateEthToEthReserve","outputs":[{"internalType":"bool","name":"allocateToEth","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minKyberRate","type":"uint256"},{"internalType":"uint256","name":"minCurveReturn","type":"uint256"}],"name":"swapTokenToEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"toToken","type":"address"},{"internalType":"uint256","name":"minKyberRate","type":"uint256"},{"internalType":"uint256","name":"minCurveReturn","type":"uint256"}],"name":"swapTokenToToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052613912806100136000396000f3fe60806040526004361061023b5760003560e01c80638f32d59b1161012e578063be3b5a26116100ab578063d1bf22191161006f578063d1bf221914610653578063dc71b81414610676578063e2cb29a91461068b578063f2fde38b146106ab578063ff15b2c8146106cb5761023b565b8063be3b5a26146105b0578063c4d66de8146105d0578063ca0d50b3146105f0578063cd6ba3c614610610578063cf2fe8fd146106335761023b565b806399788dbd116100f257806399788dbd146105235780639d765ea614610538578063a24b624614610566578063b5fe7dc114610586578063bbd351141461059b5761023b565b80638f32d59b146104af5780638f964e45146104c45780638fbaec9e146104d95780638fd095a9146104f95780639604876c1461050e5761023b565b80634d647179116101bc57806370ed0ada1161018057806370ed0ada1461042e578063715018a61461044357806387af1b6e1461045857806389afb5b7146104785780638da5cb5b1461048d5761023b565b80634d647179146103815780634e7f77d2146103a157806353653394146103c15780635e2caeb9146103ee5780636f43e6eb1461040e5761023b565b80632bdbe219116102035780632bdbe219146102ec5780633b12321b1461030c5780633b94a7821461032157806347029e4b146103415780634b9c7c19146103615761023b565b8063095215301461023d5780630fb911951461025d57806318d814ba1461027d5780631f4981fe146102b35780632a54770b146102d7575b005b34801561024957600080fd5b5061023b610258366004612fd4565b6106e0565b34801561026957600080fd5b5061023b610278366004612e7e565b610904565b34801561028957600080fd5b5061029d61029836600461316e565b610980565b6040516102aa919061360f565b60405180910390f35b3480156102bf57600080fd5b506102c86109da565b6040516102aa9392919061378c565b3480156102e357600080fd5b5061029d610a05565b3480156102f857600080fd5b5061029d6103073660046131d8565b610a21565b34801561031857600080fd5b5061029d610aa9565b34801561032d57600080fd5b5061029d61033c366004613132565b610b72565b34801561034d57600080fd5b5061029d61035c36600461323d565b610be6565b34801561036d57600080fd5b5061023b61037c366004612e7e565b610c8e565b34801561038d57600080fd5b5061023b61039c366004613049565b610ce1565b3480156103ad57600080fd5b5061029d6103bc366004613132565b610deb565b3480156103cd57600080fd5b506103e16103dc3660046131d8565b610e2c565b6040516102aa91906135f3565b3480156103fa57600080fd5b5061029d61040936600461321b565b610e74565b34801561041a57600080fd5b5061023b610429366004612e7e565b610e91565b34801561043a57600080fd5b5061029d610f41565b34801561044f57600080fd5b5061023b610f52565b34801561046457600080fd5b5061029d610473366004613132565b610fc0565b34801561048457600080fd5b5061029d6110dc565b34801561049957600080fd5b506104a2611102565b6040516102aa91906135bc565b3480156104bb57600080fd5b506103e1611111565b3480156104d057600080fd5b506103e1611137565b3480156104e557600080fd5b5061023b6104f4366004612e7e565b61117a565b34801561050557600080fd5b5061029d6111d4565b34801561051a57600080fd5b5061029d6112d2565b34801561052f57600080fd5b5061029d61130a565b34801561054457600080fd5b50610558610553366004613132565b611358565b6040516102aa929190613601565b34801561057257600080fd5b5061023b610581366004612ec2565b611399565b34801561059257600080fd5b506104a26114ac565b3480156105a757600080fd5b506103e1611549565b3480156105bc57600080fd5b5061029d6105cb36600461321b565b611572565b3480156105dc57600080fd5b5061023b6105eb366004612e7e565b6115db565b3480156105fc57600080fd5b5061023b61060b366004612f87565b6116ad565b34801561061c57600080fd5b50610625611778565b6040516102aa929190613763565b34801561063f57600080fd5b5061029d61064e3660046131d8565b611793565b34801561065f57600080fd5b506106686117c8565b6040516102aa92919061377e565b34801561068257600080fd5b5061029d611813565b34801561069757600080fd5b5061029d6106a6366004613132565b61189e565b3480156106b757600080fd5b5061023b6106c6366004612e7e565b611973565b3480156106d757600080fd5b5061029d6119a0565b606b546001600160a01b031633146107135760405162461bcd60e51b815260040161070a90613703565b60405180910390fd5b606e546001600160a01b03868116911614156107875760665461074690600160801b8104600f90810b91900b86846119d8565b606f546001600160a01b03848116911614610782576000610765611a46565b606f54909150610780906001600160a01b0316828686611a77565b505b610802565b606e546001600160a01b03848116911614156107f657606f546001600160a01b038681169116146107cc57606f546107cc90869086906001600160a01b031685611a77565b60006107d6611a46565b60665490915061078090600f81810b91600160801b9004900b83856119d8565b61080285858585611a77565b606b546040516370a0823160e01b81526001600160a01b038086169263a9059cbb9291169083906370a082319061083d9030906004016135ca565b60206040518083038186803b15801561085557600080fd5b505afa158015610869573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061088d9190810190613150565b6040518363ffffffff1660e01b81526004016108aa9291906135d8565b602060405180830381600087803b1580156108c457600080fd5b505af11580156108d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108fc9190810190613114565b505050505050565b606c546001600160a01b0316331461092e5760405162461bcd60e51b815260040161070a90613713565b6070546001600160a01b0382811691161461095b5760405162461bcd60e51b815260040161070a906136e3565b50607054606780546001600160a01b0319166001600160a01b03909216919091179055565b60008061098b611b06565b90506000610997611b93565b905060006109a6868484611793565b90506109d0670de0b6b3a76400006109c4838863ffffffff611c5a16565b9063ffffffff611c9d16565b9695505050505050565b60008060008060006109ea611cdf565b9150915060006109f86114ac565b9296919550919350915050565b600080610a10611813565b9050610a1b81610b72565b91505090565b600081610a3757610a30611da9565b9050610aa2565b6000610a41611ebe565b90506000610a61670de0b6b3a76400006109c4848863ffffffff611c5a16565b90506000610a6d611f09565b90506000610a7d84898489610e74565b9050610a9b816109c485670de0b6b3a764000063ffffffff611c5a16565b9450505050505b9392505050565b600080610ab46111d4565b90506000610ac0610f41565b90506000610ad4838363ffffffff611f1e16565b905080610ae883600463ffffffff611c5a16565b10610b055760405162461bcd60e51b815260040161070a90613753565b6000610b2883610b1c84600463ffffffff611c9d16565b9063ffffffff611f4316565b9050610b46846109c483610b3a611f85565b9063ffffffff611c5a16565b94506000610b52611fbd565b9050610b6881610b3a888263ffffffff611c9d16565b9550505050505090565b600080610b7d612002565b90506000610b89612044565b90506000610ba1826109c4878663ffffffff611c5a16565b90506000610bad611fbd565b90506000610bb96120db565b9050610bdb82610b3a816109c460648160638589838d8863ffffffff611c5a16565b979650505050505050565b600082610bfc57610bf5611da9565b9050610c85565b60008215610c1357610c0c611ebe565b9050610c54565b6000610c1d6110dc565b90506000610c31828a63ffffffff611f4316565b9050610c4f816109c48a670de0b6b3a764000063ffffffff611c5a16565b925050505b6000610c6282898888610e74565b9050610c80816109c489670de0b6b3a764000063ffffffff611c5a16565b925050505b95945050505050565b610c96611111565b610cb25760405162461bcd60e51b815260040161070a90613733565b606b546001600160a01b0316610cde57606b80546001600160a01b0319166001600160a01b0383161790555b50565b606b546001600160a01b03163314610d0b5760405162461bcd60e51b815260040161070a90613703565b606e546001600160a01b0385811691161415610d6857606654610d3e90600160801b8104600f90810b91900b85846119d8565b6000610d48611a46565b606f54909150610d62906001600160a01b0316828561211f565b50610d73565b610d7384848461211f565b604051479060009033908390610d88906135b1565b60006040518083038185875af1925050503d8060008114610dc5576040519150601f19603f3d011682016040523d82523d6000602084013e610dca565b606091505b50509050806108fc5760405162461bcd60e51b815260040161070a906136c3565b600080610df66121ab565b905080610e07576000915050610e27565b610e23670de0b6b3a76400006109c4838663ffffffff611c5a16565b9150505b919050565b600081610e3b57506000610aa2565b610e4b838563ffffffff611f1e16565b610e5c84600463ffffffff611c5a16565b1015610e6a57506001610aa2565b5060009392505050565b6000610c85826109c4670de0b6b3a7640000610b3a8989896121cc565b610e99611111565b610eb55760405162461bcd60e51b815260040161070a90613733565b606a5460405163095ea7b360e01b81526001600160a01b038381169263095ea7b392610eeb9290911690600019906004016135d8565b602060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f3d9190810190613114565b5050565b606b546001600160a01b0316315b90565b610f5a611111565b610f765760405162461bcd60e51b815260040161070a90613733565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b600080610fcb6114ac565b90506000610fd761221a565b90506000610fe48261224e565b90506000611004826109c4670de0b6b3a76400008063ffffffff611c5a16565b9050600061102c60646109c46067610b3a670de0b6b3a764000083888e63ffffffff611c5a16565b90506000856001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561106957600080fd5b505afa15801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110a191908101906132a5565b60ff16600a0a90506110c5670de0b6b3a76400006109c4848463ffffffff611c5a16565b91506110d082610b72565b98975050505050505050565b60006110fd6110e96123a6565b6110f1611b06565b9063ffffffff611f1e16565b905090565b6033546001600160a01b031690565b6033546000906001600160a01b03166111286123e8565b6001600160a01b031614905090565b60008060006111446117c8565b90925090508161116060646109c484606963ffffffff611c5a16565b101561117157600192505050610f4f565b60009250505090565b611182611111565b61119e5760405162461bcd60e51b815260040161070a90613733565b60675460405163095ea7b360e01b81526001600160a01b038381169263095ea7b392610eeb9290911690600019906004016135d8565b6000806111df6123ec565b905060006111eb61221a565b905060006111f76114ac565b905060006112048361224e565b90506000611218630e68aa8960e31b61224e565b90506000836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561125557600080fd5b505afa158015611269573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061128d91908101906132a5565b60ff16600a0a90506112b1816109c488670de0b6b3a764000063ffffffff611c5a16565b95506112c7826109c4888663ffffffff611c5a16565b965050505050505090565b6000806112dd61240c565b905060006112e9611b93565b905060006112f561242d565b90506113028383836124f7565b935050505090565b60008060006113176117c8565b9092509050600061132e828463ffffffff611f4316565b9050600061133a61253a565b9050610b46816109c484670de0b6b3a764000063ffffffff611c5a16565b60008060006113656111d4565b90506000611371610f41565b905061137e828287610e2c565b9350611390828263ffffffff611f1e16565b92505050915091565b600054610100900460ff16806113b257506113b2612699565b806113c0575060005460ff16155b6113dc5760405162461bcd60e51b815260040161070a90613743565b600054610100900460ff16158015611407576000805460ff1961ff0019909116610100171660011790555b611410826115db565b606d80546001600160a01b03199081166001600160a01b038d811691909117909255606a805482168c84161790556069805482168b8416179055606e805482168a8416179055606f80548216898416179055606c805490911691871691909117905561147f6071856002612ba5565b5061148d6073846002612be3565b5080156114a0576000805461ff00191690555b50505050505050505050565b600060606114b861269f565b6001600160a01b03166399d50d5d6040518163ffffffff1660e01b815260040160006040518083038186803b1580156114f057600080fd5b505afa158015611504573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261152c91908101906130aa565b90508060008151811061153b57fe5b602002602001015191505090565b60008060006115566117c8565b90925090508061116060646109c485606963ffffffff611c5a16565b60008061157d6126a9565b9050600061159d846109c487670de0b6b3a764000063ffffffff611c5a16565b905060006115b5876109c4858b63ffffffff611c5a16565b90506110d0670de0b6b3a76400006109c487610b3a87610b1c888863ffffffff611f1e16565b600054610100900460ff16806115f457506115f4612699565b80611602575060005460ff16155b61161e5760405162461bcd60e51b815260040161070a90613743565b600054610100900460ff16158015611649576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610f3d576000805461ff00191690555050565b6116b5611111565b6116d15760405162461bcd60e51b815260040161070a90613733565b6067546001600160a01b031661171157606780546001600160a01b0385166001600160a01b0319918216811790925560708054909116909117905561172d565b607080546001600160a01b0319166001600160a01b0385161790555b60668054600f92830b6fffffffffffffffffffffffffffffffff908116600160801b029490930b83166fffffffffffffffffffffffffffffffff199091161790911691909117905550565b60008061178361130a565b915061178d6114ac565b90509091565b60008061179e6126ca565b905060006117ab8461270f565b90506109d0866109c4670de0b6b3a7640000610b3a868a87612740565b60008060006117d56111d4565b905060006117e1610f41565b905060006117ed611b93565b90506117f88161270f565b945061180a838363ffffffff611f1e16565b93505050509091565b600061181d6114ac565b606b546040516370a0823160e01b81526001600160a01b03928316926370a082319261184e929116906004016135bc565b60206040518083038186803b15801561186657600080fd5b505afa15801561187a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110fd9190810190613150565b6000806118b1630e68aa8960e31b61224e565b905060006118cd670de0b6b3a76400006109c484610b3a6111d4565b905060006118e9670de0b6b3a76400006109c485610b3a610f41565b905060006118fd838363ffffffff611f1e16565b905061190f818763ffffffff611f1e16565b61192083600463ffffffff611c5a16565b1061192a5761196a565b806119406004610b3a858a63ffffffff611f1e16565b101561194e5785945061196a565b61196782610b1c60046109c4858b63ffffffff611f1e16565b94505b50505050919050565b61197b611111565b6119975760405162461bcd60e51b815260040161070a90613733565b610cde81612781565b606e54606b546040516370a0823160e01b81526000926001600160a01b03908116926370a082319261184e92909116906004016135bc565b606754604051635320bf6b60e11b81526001600160a01b039091169063a6417ed690611a0e90879087908790879060040161367a565b600060405180830381600087803b158015611a2857600080fd5b505af1158015611a3c573d6000803e3d6000fd5b5050505050505050565b606f546040516370a0823160e01b81526000916001600160a01b0316906370a082319061184e9030906004016135ca565b606a54604051637409e2eb60e01b81526001600160a01b0390911690637409e2eb90611aad90879087908790879060040161361d565b602060405180830381600087803b158015611ac757600080fd5b505af1158015611adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611aff9190810190613150565b5050505050565b6069546040516321f8a72160e01b81526000916001600160a01b0316906321f8a72190611b4390680a6f2dce8d0cae8d2f60bb1b9060040161360f565b60206040518083038186803b158015611b5b57600080fd5b505afa158015611b6f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061181d9190810190612ea4565b6069546040516321f8a72160e01b81526000916001600160a01b0316906321f8a72190611bd090680a6f2dce8d0cae8d2f60bb1b9060040161360f565b60206040518083038186803b158015611be857600080fd5b505afa158015611bfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c209190810190612ea4565b606b5460405163d37c4d8b60e01b81526001600160a01b039283169263d37c4d8b9261184e92911690631cd554d160e21b906004016135d8565b600082611c6957506000611c97565b82820282848281611c7657fe5b0414611c945760405162461bcd60e51b815260040161070a90613723565b90505b92915050565b6000611c9483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612803565b6000806000611cec61240c565b90506000611cf8611b93565b90506000611d0461242d565b90506000611d138484846124f7565b90506000611d2083610deb565b90506000611d2c61283a565b90506000611d40868363ffffffff611f4316565b90506000611d60670de0b6b3a76400006109c4848963ffffffff611c5a16565b9050611d76816110f1878763ffffffff611f1e16565b9950611d9b611d83612983565b6109c484670de0b6b3a764000063ffffffff611c5a16565b985050505050505050509091565b6069546040516321f8a72160e01b81526000916110fd91600a916001600160a01b0316906321f8a72190611ded90680a6f2dce8d0cae8d2f60bb1b9060040161360f565b60206040518083038186803b158015611e0557600080fd5b505afa158015611e19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e3d9190810190612ea4565b606b546040516370a0823160e01b81526001600160a01b03928316926370a0823192611e6e929116906004016135bc565b60206040518083038186803b158015611e8657600080fd5b505afa158015611e9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b3a9190810190613150565b600080611ed0620a69cb60eb1b61224e565b90506000611ee4630e68aa8960e31b61224e565b9050611f02816109c484670de0b6b3a764000063ffffffff611c5a16565b9250505090565b60006110fd611f16610f41565b6110f16111d4565b600082820183811015611c945760405162461bcd60e51b815260040161070a906136d3565b6000611c9483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612ad3565b606d54606b546040516370a0823160e01b81526000926001600160a01b03908116926370a082319261184e92909116906004016135bc565b606d54604080516342a7cfd560e01b815290516000926001600160a01b0316916342a7cfd5916004808301926020929190829003018186803b15801561186657600080fd5b600061200c61269f565b6001600160a01b03166342a7cfd56040518163ffffffff1660e01b815260040160206040518083038186803b15801561186657600080fd5b600061204e612aff565b6001600160a01b031663027aa9f56040518163ffffffff1660e01b815260040160006040518083038186803b15801561208657600080fd5b505afa15801561209a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120c291908101906130df565b6000815181106120ce57fe5b6020026020010151905090565b606d546040805162c9d75160e11b815290516000926001600160a01b031691630193aea2916004808301926020929190829003018186803b15801561186657600080fd5b606a54604051630eee887760e21b81526001600160a01b0390911690633bba21dc9061215390869086908690600401613652565b602060405180830381600087803b15801561216d57600080fd5b505af1158015612181573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121a59190810190613150565b50505050565b60006110fd670de0b6b3a76400006109c46121c4612983565b610b3a6123a6565b6000806121eb670de0b6b3a76400006109c4868863ffffffff611c5a16565b905060006121f7611b93565b905060006122048261270f565b9050610bdb81610b1c858863ffffffff611f1e16565b6073546000906001600160a01b03166122316114ac565b6001600160a01b031614612247576072546110fd565b5060715490565b6069546040516321f8a72160e01b8152600091829182916001600160a01b0316906321f8a72190612293906c45786368616e6765526174657360981b9060040161360f565b60206040518083038186803b1580156122ab57600080fd5b505afa1580156122bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122e39190810190612ea4565b6001600160a01b0316634308a94f856040518263ffffffff1660e01b815260040161230e919061360f565b604080518083038186803b15801561232557600080fd5b505afa158015612339573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061235d91908101906131a8565b91509150631cd554d160e21b841461239f57426123828261708063ffffffff611f1e16565b1161239f5760405162461bcd60e51b815260040161070a906136f3565b5092915050565b6069546040516321f8a72160e01b81526000916001600160a01b0316906321f8a72190611b43906d2932bbb0b93222b9b1b937bbab1960911b9060040161360f565b3390565b60006110fd6123f9612002565b6109c4612404612044565b610b3a612b7c565b60006110fd670de0b6b3a76400006109c4612425612983565b610b3a6110dc565b6069546040516321f8a72160e01b81526000916001600160a01b0316906321f8a7219061246f906d53797374656d53657474696e677360901b9060040161360f565b60206040518083038186803b15801561248757600080fd5b505afa15801561249b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506124bf9190810190612ea4565b6001600160a01b031663b410a0346040518163ffffffff1660e01b815260040160206040518083038186803b15801561186657600080fd5b600080612516670de0b6b3a76400006109c4858863ffffffff611c5a16565b90508381111561252a576000915050610aa2565b610c85848263ffffffff611f4316565b6000806125456120db565b90506000612551611fbd565b90506000612571826109c4670de0b6b3a76400008663ffffffff611c5a16565b9050600061257d612044565b90506000612589612002565b905060006125a1826109c4868663ffffffff611c5a16565b905060006125ad6114ac565b90506000816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156125ea57600080fd5b505afa1580156125fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061262291908101906132a5565b60ff16600a0a9050612646816109c485670de0b6b3a764000063ffffffff611c5a16565b9250600061265261221a565b9050600061265f8261224e565b90506000612673630e68aa8960e31b61224e565b9050612689816109c4888563ffffffff611c5a16565b9b50505050505050505050505090565b303b1590565b60006110fd612aff565b60006110fd670de0b6b3a76400006109c46126c2612983565b610b3a611b06565b6000806126d5612983565b905060006126e9630e68aa8960e31b61224e565b9050611f0260646109c46063610b3a858388670de0b6b3a764000063ffffffff611c5a16565b600080612722630e68aa8960e31b61224e565b9050610e23816109c485670de0b6b3a764000063ffffffff611c5a16565b60008061275f670de0b6b3a76400006109c4868863ffffffff611c5a16565b9050600061276b611f09565b90506109d084610b1c848463ffffffff611f1e16565b6001600160a01b0381166127a75760405162461bcd60e51b815260040161070a906136b3565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b600081836128245760405162461bcd60e51b815260040161070a91906136a2565b50600083858161283057fe5b0495945050505050565b6000806128456114ac565b90506000816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561288257600080fd5b505afa158015612896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506128ba91908101906132a5565b60ff16600a0a905060006128cc6123ec565b90506128ea826109c483670de0b6b3a764000063ffffffff611c5a16565b905060006128f661221a565b905060006129038261224e565b90506000612923670de0b6b3a76400006109c4868563ffffffff611c5a16565b9050600061292f610f41565b90506000612943630e68aa8960e31b61224e565b90506000612963670de0b6b3a76400006109c4858563ffffffff611c5a16565b9050612975848263ffffffff611f1e16565b995050505050505050505090565b6069546040516321f8a72160e01b8152600091829182916001600160a01b0316906321f8a721906129c8906c45786368616e6765526174657360981b9060040161360f565b60206040518083038186803b1580156129e057600080fd5b505afa1580156129f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612a189190810190612ea4565b6001600160a01b0316634308a94f620a69cb60eb1b6040518263ffffffff1660e01b8152600401612a49919061360f565b604080518083038186803b158015612a6057600080fd5b505afa158015612a74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612a9891908101906131a8565b909250905042612ab08261708063ffffffff611f1e16565b11612acd5760405162461bcd60e51b815260040161070a906136f3565b50905090565b60008184841115612af75760405162461bcd60e51b815260040161070a91906136a2565b505050900390565b606d54604080516330b8662760e01b815290516000926001600160a01b0316916330b86627916004808301926020929190829003018186803b158015612b4457600080fd5b505afa158015612b58573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110fd9190810190612ea4565b600080612b876120db565b90506000612b93611fbd565b9050611f02816109c484610b3a611f85565b8260028101928215612bd3579160200282015b82811115612bd3578251825591602001919060010190612bb8565b50612bdf929150612c37565b5090565b8260028101928215612c2b579160200282015b82811115612c2b57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612bf6565b50612bdf929150612c51565b610f4f91905b80821115612bdf5760008155600101612c3d565b610f4f91905b80821115612bdf5780546001600160a01b0319168155600101612c57565b8035611c9781613897565b8051611c9781613897565b600082601f830112612c9c57600080fd5b6002612caf612caa826137db565b6137b4565b91508183856020840282011115612cc557600080fd5b60005b83811015612cf15781612cdb8882612c75565b8452506020928301929190910190600101612cc8565b5050505092915050565b600082601f830112612d0c57600080fd5b8151612d1a612caa826137f9565b91508181835260208401935060208101905083856020840282011115612d3f57600080fd5b60005b83811015612cf15781612d558882612c80565b8452506020928301929190910190600101612d42565b600082601f830112612d7c57600080fd5b6002612d8a612caa826137db565b91508183856020840282011115612da057600080fd5b60005b83811015612cf15781612db68882612e52565b8452506020928301929190910190600101612da3565b600082601f830112612ddd57600080fd5b8151612deb612caa826137f9565b91508181835260208401935060208101905083856020840282011115612e1057600080fd5b60005b83811015612cf15781612e268882612e68565b8452506020928301929190910190600101612e13565b8035611c97816138ab565b8051611c97816138ab565b8035611c97816138b4565b8035611c97816138bd565b8051611c97816138b4565b8051611c97816138c6565b600060208284031215612e9057600080fd5b6000612e9c8484612c75565b949350505050565b600060208284031215612eb657600080fd5b6000612e9c8484612c80565b60008060008060008060008060006101608a8c031215612ee157600080fd5b6000612eed8c8c612c75565b9950506020612efe8c828d01612c75565b9850506040612f0f8c828d01612c75565b9750506060612f208c828d01612c75565b9650506080612f318c828d01612c75565b95505060a0612f428c828d01612c75565b94505060c0612f538c828d01612d6b565b935050610100612f658c828d01612c8b565b925050610140612f778c828d01612c75565b9150509295985092959850929598565b600080600060608486031215612f9c57600080fd5b6000612fa88686612c75565b9350506020612fb986828701612e5d565b9250506040612fca86828701612e5d565b9150509250925092565b600080600080600060a08688031215612fec57600080fd5b6000612ff88888612c75565b955050602061300988828901612e52565b945050604061301a88828901612c75565b935050606061302b88828901612e52565b925050608061303c88828901612e52565b9150509295509295909350565b6000806000806080858703121561305f57600080fd5b600061306b8787612c75565b945050602061307c87828801612e52565b935050604061308d87828801612e52565b925050606061309e87828801612e52565b91505092959194509250565b6000602082840312156130bc57600080fd5b815167ffffffffffffffff8111156130d357600080fd5b612e9c84828501612cfb565b6000602082840312156130f157600080fd5b815167ffffffffffffffff81111561310857600080fd5b612e9c84828501612dcc565b60006020828403121561312657600080fd5b6000612e9c8484612e47565b60006020828403121561314457600080fd5b6000612e9c8484612e52565b60006020828403121561316257600080fd5b6000612e9c8484612e68565b6000806040838503121561318157600080fd5b600061318d8585612e52565b925050602061319e85828601612e52565b9150509250929050565b600080604083850312156131bb57600080fd5b60006131c78585612e68565b925050602061319e85828601612e68565b6000806000606084860312156131ed57600080fd5b60006131f98686612e52565b935050602061320a86828701612e52565b9250506040612fca86828701612e52565b6000806000806080858703121561323157600080fd5b600061306b8787612e52565b600080600080600060a0868803121561325557600080fd5b60006132618888612e52565b955050602061327288828901612e52565b945050604061328388828901612e52565b935050606061329488828901612e52565b925050608061303c88828901612e3c565b6000602082840312156132b757600080fd5b6000612e9c8484612e73565b6132cc8161384f565b82525050565b6132cc81613827565b6132cc81613832565b6132cc81610f4f565b6132cc81613856565b6132cc81613837565b600061330a8261381a565b613314818561381e565b9350613324818560208601613861565b61332d8161388d565b9093019392505050565b600061334460268361381e565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b600061338c600f8361381e565b6e151c985b9cd9995c8819985a5b1959608a1b815260200192915050565b60006133b7601b8361381e565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b60006133f060158361381e565b74082c8c8e4cae6e6cae640c8dedc4ee840dac2e8c6d605b1b815260200192915050565b6000613421600a8361381e565b6952617465207374616c6560b01b815260200192915050565b600061344760208361381e565b7f4f6e6c792078534e5841646d696e20636f6e74726163742063616e2063616c6c815260200192915050565b600061348060108361381e565b6f24b731b7b93932b1ba1031b0b63632b960811b815260200192915050565b60006134ac60218361381e565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b60006134ef60208361381e565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000613528602e8361381e565b7f436f6e747261637420696e7374616e63652068617320616c726561647920626581526d195b881a5b9a5d1a585b1a5e995960921b602082015260400192915050565b600061357860178361381e565b7f526562616c616e6365206e6f74206e6563657373617279000000000000000000815260200192915050565b6000611c97600083610e27565b6000611c97826135a4565b60208101611c9782846132d2565b60208101611c9782846132c3565b604081016135e682856132d2565b610aa260208301846132e4565b60208101611c9782846132db565b604081016135e682856132db565b60208101611c9782846132e4565b6080810161362b82876132ed565b61363860208301866132e4565b61364560408301856132ed565b610c8560608301846132e4565b6060810161366082866132ed565b61366d60208301856132e4565b612e9c60408301846132e4565b6080810161368882876132f6565b61369560208301866132f6565b61364560408301856132e4565b60208082528101611c9481846132ff565b60208082528101611c9781613337565b60208082528101611c978161337f565b60208082528101611c97816133aa565b60208082528101611c97816133e3565b60208082528101611c9781613414565b60208082528101611c978161343a565b60208082528101611c9781613473565b60208082528101611c978161349f565b60208082528101611c97816134e2565b60208082528101611c978161351b565b60208082528101611c978161356b565b6040810161377182856132e4565b610aa260208301846132d2565b604081016135e682856132e4565b6060810161379a82866132e4565b6137a760208301856132e4565b612e9c60408301846132d2565b60405181810167ffffffffffffffff811182821017156137d357600080fd5b604052919050565b600067ffffffffffffffff8211156137f257600080fd5b5060200290565b600067ffffffffffffffff82111561381057600080fd5b5060209081020190565b5190565b90815260200190565b6000611c978261383d565b151590565b600f0b90565b6001600160a01b031690565b60ff1690565b6000611c97825b6000611c9782613827565b60005b8381101561387c578181015183820152602001613864565b838111156121a55750506000910152565b601f01601f191690565b6138a081613827565b8114610cde57600080fd5b6138a081613832565b6138a081610f4f565b6138a081613837565b6138a08161384956fea365627a7a723158201abf0281a4134fd3a54833042e0c0056deec0a09674bbe7eae1509f7715c99666c6578706572696d656e74616cf564736f6c634300050f0040
Deployed Bytecode
0x60806040526004361061023b5760003560e01c80638f32d59b1161012e578063be3b5a26116100ab578063d1bf22191161006f578063d1bf221914610653578063dc71b81414610676578063e2cb29a91461068b578063f2fde38b146106ab578063ff15b2c8146106cb5761023b565b8063be3b5a26146105b0578063c4d66de8146105d0578063ca0d50b3146105f0578063cd6ba3c614610610578063cf2fe8fd146106335761023b565b806399788dbd116100f257806399788dbd146105235780639d765ea614610538578063a24b624614610566578063b5fe7dc114610586578063bbd351141461059b5761023b565b80638f32d59b146104af5780638f964e45146104c45780638fbaec9e146104d95780638fd095a9146104f95780639604876c1461050e5761023b565b80634d647179116101bc57806370ed0ada1161018057806370ed0ada1461042e578063715018a61461044357806387af1b6e1461045857806389afb5b7146104785780638da5cb5b1461048d5761023b565b80634d647179146103815780634e7f77d2146103a157806353653394146103c15780635e2caeb9146103ee5780636f43e6eb1461040e5761023b565b80632bdbe219116102035780632bdbe219146102ec5780633b12321b1461030c5780633b94a7821461032157806347029e4b146103415780634b9c7c19146103615761023b565b8063095215301461023d5780630fb911951461025d57806318d814ba1461027d5780631f4981fe146102b35780632a54770b146102d7575b005b34801561024957600080fd5b5061023b610258366004612fd4565b6106e0565b34801561026957600080fd5b5061023b610278366004612e7e565b610904565b34801561028957600080fd5b5061029d61029836600461316e565b610980565b6040516102aa919061360f565b60405180910390f35b3480156102bf57600080fd5b506102c86109da565b6040516102aa9392919061378c565b3480156102e357600080fd5b5061029d610a05565b3480156102f857600080fd5b5061029d6103073660046131d8565b610a21565b34801561031857600080fd5b5061029d610aa9565b34801561032d57600080fd5b5061029d61033c366004613132565b610b72565b34801561034d57600080fd5b5061029d61035c36600461323d565b610be6565b34801561036d57600080fd5b5061023b61037c366004612e7e565b610c8e565b34801561038d57600080fd5b5061023b61039c366004613049565b610ce1565b3480156103ad57600080fd5b5061029d6103bc366004613132565b610deb565b3480156103cd57600080fd5b506103e16103dc3660046131d8565b610e2c565b6040516102aa91906135f3565b3480156103fa57600080fd5b5061029d61040936600461321b565b610e74565b34801561041a57600080fd5b5061023b610429366004612e7e565b610e91565b34801561043a57600080fd5b5061029d610f41565b34801561044f57600080fd5b5061023b610f52565b34801561046457600080fd5b5061029d610473366004613132565b610fc0565b34801561048457600080fd5b5061029d6110dc565b34801561049957600080fd5b506104a2611102565b6040516102aa91906135bc565b3480156104bb57600080fd5b506103e1611111565b3480156104d057600080fd5b506103e1611137565b3480156104e557600080fd5b5061023b6104f4366004612e7e565b61117a565b34801561050557600080fd5b5061029d6111d4565b34801561051a57600080fd5b5061029d6112d2565b34801561052f57600080fd5b5061029d61130a565b34801561054457600080fd5b50610558610553366004613132565b611358565b6040516102aa929190613601565b34801561057257600080fd5b5061023b610581366004612ec2565b611399565b34801561059257600080fd5b506104a26114ac565b3480156105a757600080fd5b506103e1611549565b3480156105bc57600080fd5b5061029d6105cb36600461321b565b611572565b3480156105dc57600080fd5b5061023b6105eb366004612e7e565b6115db565b3480156105fc57600080fd5b5061023b61060b366004612f87565b6116ad565b34801561061c57600080fd5b50610625611778565b6040516102aa929190613763565b34801561063f57600080fd5b5061029d61064e3660046131d8565b611793565b34801561065f57600080fd5b506106686117c8565b6040516102aa92919061377e565b34801561068257600080fd5b5061029d611813565b34801561069757600080fd5b5061029d6106a6366004613132565b61189e565b3480156106b757600080fd5b5061023b6106c6366004612e7e565b611973565b3480156106d757600080fd5b5061029d6119a0565b606b546001600160a01b031633146107135760405162461bcd60e51b815260040161070a90613703565b60405180910390fd5b606e546001600160a01b03868116911614156107875760665461074690600160801b8104600f90810b91900b86846119d8565b606f546001600160a01b03848116911614610782576000610765611a46565b606f54909150610780906001600160a01b0316828686611a77565b505b610802565b606e546001600160a01b03848116911614156107f657606f546001600160a01b038681169116146107cc57606f546107cc90869086906001600160a01b031685611a77565b60006107d6611a46565b60665490915061078090600f81810b91600160801b9004900b83856119d8565b61080285858585611a77565b606b546040516370a0823160e01b81526001600160a01b038086169263a9059cbb9291169083906370a082319061083d9030906004016135ca565b60206040518083038186803b15801561085557600080fd5b505afa158015610869573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061088d9190810190613150565b6040518363ffffffff1660e01b81526004016108aa9291906135d8565b602060405180830381600087803b1580156108c457600080fd5b505af11580156108d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108fc9190810190613114565b505050505050565b606c546001600160a01b0316331461092e5760405162461bcd60e51b815260040161070a90613713565b6070546001600160a01b0382811691161461095b5760405162461bcd60e51b815260040161070a906136e3565b50607054606780546001600160a01b0319166001600160a01b03909216919091179055565b60008061098b611b06565b90506000610997611b93565b905060006109a6868484611793565b90506109d0670de0b6b3a76400006109c4838863ffffffff611c5a16565b9063ffffffff611c9d16565b9695505050505050565b60008060008060006109ea611cdf565b9150915060006109f86114ac565b9296919550919350915050565b600080610a10611813565b9050610a1b81610b72565b91505090565b600081610a3757610a30611da9565b9050610aa2565b6000610a41611ebe565b90506000610a61670de0b6b3a76400006109c4848863ffffffff611c5a16565b90506000610a6d611f09565b90506000610a7d84898489610e74565b9050610a9b816109c485670de0b6b3a764000063ffffffff611c5a16565b9450505050505b9392505050565b600080610ab46111d4565b90506000610ac0610f41565b90506000610ad4838363ffffffff611f1e16565b905080610ae883600463ffffffff611c5a16565b10610b055760405162461bcd60e51b815260040161070a90613753565b6000610b2883610b1c84600463ffffffff611c9d16565b9063ffffffff611f4316565b9050610b46846109c483610b3a611f85565b9063ffffffff611c5a16565b94506000610b52611fbd565b9050610b6881610b3a888263ffffffff611c9d16565b9550505050505090565b600080610b7d612002565b90506000610b89612044565b90506000610ba1826109c4878663ffffffff611c5a16565b90506000610bad611fbd565b90506000610bb96120db565b9050610bdb82610b3a816109c460648160638589838d8863ffffffff611c5a16565b979650505050505050565b600082610bfc57610bf5611da9565b9050610c85565b60008215610c1357610c0c611ebe565b9050610c54565b6000610c1d6110dc565b90506000610c31828a63ffffffff611f4316565b9050610c4f816109c48a670de0b6b3a764000063ffffffff611c5a16565b925050505b6000610c6282898888610e74565b9050610c80816109c489670de0b6b3a764000063ffffffff611c5a16565b925050505b95945050505050565b610c96611111565b610cb25760405162461bcd60e51b815260040161070a90613733565b606b546001600160a01b0316610cde57606b80546001600160a01b0319166001600160a01b0383161790555b50565b606b546001600160a01b03163314610d0b5760405162461bcd60e51b815260040161070a90613703565b606e546001600160a01b0385811691161415610d6857606654610d3e90600160801b8104600f90810b91900b85846119d8565b6000610d48611a46565b606f54909150610d62906001600160a01b0316828561211f565b50610d73565b610d7384848461211f565b604051479060009033908390610d88906135b1565b60006040518083038185875af1925050503d8060008114610dc5576040519150601f19603f3d011682016040523d82523d6000602084013e610dca565b606091505b50509050806108fc5760405162461bcd60e51b815260040161070a906136c3565b600080610df66121ab565b905080610e07576000915050610e27565b610e23670de0b6b3a76400006109c4838663ffffffff611c5a16565b9150505b919050565b600081610e3b57506000610aa2565b610e4b838563ffffffff611f1e16565b610e5c84600463ffffffff611c5a16565b1015610e6a57506001610aa2565b5060009392505050565b6000610c85826109c4670de0b6b3a7640000610b3a8989896121cc565b610e99611111565b610eb55760405162461bcd60e51b815260040161070a90613733565b606a5460405163095ea7b360e01b81526001600160a01b038381169263095ea7b392610eeb9290911690600019906004016135d8565b602060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f3d9190810190613114565b5050565b606b546001600160a01b0316315b90565b610f5a611111565b610f765760405162461bcd60e51b815260040161070a90613733565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b600080610fcb6114ac565b90506000610fd761221a565b90506000610fe48261224e565b90506000611004826109c4670de0b6b3a76400008063ffffffff611c5a16565b9050600061102c60646109c46067610b3a670de0b6b3a764000083888e63ffffffff611c5a16565b90506000856001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561106957600080fd5b505afa15801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110a191908101906132a5565b60ff16600a0a90506110c5670de0b6b3a76400006109c4848463ffffffff611c5a16565b91506110d082610b72565b98975050505050505050565b60006110fd6110e96123a6565b6110f1611b06565b9063ffffffff611f1e16565b905090565b6033546001600160a01b031690565b6033546000906001600160a01b03166111286123e8565b6001600160a01b031614905090565b60008060006111446117c8565b90925090508161116060646109c484606963ffffffff611c5a16565b101561117157600192505050610f4f565b60009250505090565b611182611111565b61119e5760405162461bcd60e51b815260040161070a90613733565b60675460405163095ea7b360e01b81526001600160a01b038381169263095ea7b392610eeb9290911690600019906004016135d8565b6000806111df6123ec565b905060006111eb61221a565b905060006111f76114ac565b905060006112048361224e565b90506000611218630e68aa8960e31b61224e565b90506000836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561125557600080fd5b505afa158015611269573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061128d91908101906132a5565b60ff16600a0a90506112b1816109c488670de0b6b3a764000063ffffffff611c5a16565b95506112c7826109c4888663ffffffff611c5a16565b965050505050505090565b6000806112dd61240c565b905060006112e9611b93565b905060006112f561242d565b90506113028383836124f7565b935050505090565b60008060006113176117c8565b9092509050600061132e828463ffffffff611f4316565b9050600061133a61253a565b9050610b46816109c484670de0b6b3a764000063ffffffff611c5a16565b60008060006113656111d4565b90506000611371610f41565b905061137e828287610e2c565b9350611390828263ffffffff611f1e16565b92505050915091565b600054610100900460ff16806113b257506113b2612699565b806113c0575060005460ff16155b6113dc5760405162461bcd60e51b815260040161070a90613743565b600054610100900460ff16158015611407576000805460ff1961ff0019909116610100171660011790555b611410826115db565b606d80546001600160a01b03199081166001600160a01b038d811691909117909255606a805482168c84161790556069805482168b8416179055606e805482168a8416179055606f80548216898416179055606c805490911691871691909117905561147f6071856002612ba5565b5061148d6073846002612be3565b5080156114a0576000805461ff00191690555b50505050505050505050565b600060606114b861269f565b6001600160a01b03166399d50d5d6040518163ffffffff1660e01b815260040160006040518083038186803b1580156114f057600080fd5b505afa158015611504573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261152c91908101906130aa565b90508060008151811061153b57fe5b602002602001015191505090565b60008060006115566117c8565b90925090508061116060646109c485606963ffffffff611c5a16565b60008061157d6126a9565b9050600061159d846109c487670de0b6b3a764000063ffffffff611c5a16565b905060006115b5876109c4858b63ffffffff611c5a16565b90506110d0670de0b6b3a76400006109c487610b3a87610b1c888863ffffffff611f1e16565b600054610100900460ff16806115f457506115f4612699565b80611602575060005460ff16155b61161e5760405162461bcd60e51b815260040161070a90613743565b600054610100900460ff16158015611649576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610f3d576000805461ff00191690555050565b6116b5611111565b6116d15760405162461bcd60e51b815260040161070a90613733565b6067546001600160a01b031661171157606780546001600160a01b0385166001600160a01b0319918216811790925560708054909116909117905561172d565b607080546001600160a01b0319166001600160a01b0385161790555b60668054600f92830b6fffffffffffffffffffffffffffffffff908116600160801b029490930b83166fffffffffffffffffffffffffffffffff199091161790911691909117905550565b60008061178361130a565b915061178d6114ac565b90509091565b60008061179e6126ca565b905060006117ab8461270f565b90506109d0866109c4670de0b6b3a7640000610b3a868a87612740565b60008060006117d56111d4565b905060006117e1610f41565b905060006117ed611b93565b90506117f88161270f565b945061180a838363ffffffff611f1e16565b93505050509091565b600061181d6114ac565b606b546040516370a0823160e01b81526001600160a01b03928316926370a082319261184e929116906004016135bc565b60206040518083038186803b15801561186657600080fd5b505afa15801561187a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110fd9190810190613150565b6000806118b1630e68aa8960e31b61224e565b905060006118cd670de0b6b3a76400006109c484610b3a6111d4565b905060006118e9670de0b6b3a76400006109c485610b3a610f41565b905060006118fd838363ffffffff611f1e16565b905061190f818763ffffffff611f1e16565b61192083600463ffffffff611c5a16565b1061192a5761196a565b806119406004610b3a858a63ffffffff611f1e16565b101561194e5785945061196a565b61196782610b1c60046109c4858b63ffffffff611f1e16565b94505b50505050919050565b61197b611111565b6119975760405162461bcd60e51b815260040161070a90613733565b610cde81612781565b606e54606b546040516370a0823160e01b81526000926001600160a01b03908116926370a082319261184e92909116906004016135bc565b606754604051635320bf6b60e11b81526001600160a01b039091169063a6417ed690611a0e90879087908790879060040161367a565b600060405180830381600087803b158015611a2857600080fd5b505af1158015611a3c573d6000803e3d6000fd5b5050505050505050565b606f546040516370a0823160e01b81526000916001600160a01b0316906370a082319061184e9030906004016135ca565b606a54604051637409e2eb60e01b81526001600160a01b0390911690637409e2eb90611aad90879087908790879060040161361d565b602060405180830381600087803b158015611ac757600080fd5b505af1158015611adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611aff9190810190613150565b5050505050565b6069546040516321f8a72160e01b81526000916001600160a01b0316906321f8a72190611b4390680a6f2dce8d0cae8d2f60bb1b9060040161360f565b60206040518083038186803b158015611b5b57600080fd5b505afa158015611b6f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061181d9190810190612ea4565b6069546040516321f8a72160e01b81526000916001600160a01b0316906321f8a72190611bd090680a6f2dce8d0cae8d2f60bb1b9060040161360f565b60206040518083038186803b158015611be857600080fd5b505afa158015611bfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c209190810190612ea4565b606b5460405163d37c4d8b60e01b81526001600160a01b039283169263d37c4d8b9261184e92911690631cd554d160e21b906004016135d8565b600082611c6957506000611c97565b82820282848281611c7657fe5b0414611c945760405162461bcd60e51b815260040161070a90613723565b90505b92915050565b6000611c9483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612803565b6000806000611cec61240c565b90506000611cf8611b93565b90506000611d0461242d565b90506000611d138484846124f7565b90506000611d2083610deb565b90506000611d2c61283a565b90506000611d40868363ffffffff611f4316565b90506000611d60670de0b6b3a76400006109c4848963ffffffff611c5a16565b9050611d76816110f1878763ffffffff611f1e16565b9950611d9b611d83612983565b6109c484670de0b6b3a764000063ffffffff611c5a16565b985050505050505050509091565b6069546040516321f8a72160e01b81526000916110fd91600a916001600160a01b0316906321f8a72190611ded90680a6f2dce8d0cae8d2f60bb1b9060040161360f565b60206040518083038186803b158015611e0557600080fd5b505afa158015611e19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e3d9190810190612ea4565b606b546040516370a0823160e01b81526001600160a01b03928316926370a0823192611e6e929116906004016135bc565b60206040518083038186803b158015611e8657600080fd5b505afa158015611e9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b3a9190810190613150565b600080611ed0620a69cb60eb1b61224e565b90506000611ee4630e68aa8960e31b61224e565b9050611f02816109c484670de0b6b3a764000063ffffffff611c5a16565b9250505090565b60006110fd611f16610f41565b6110f16111d4565b600082820183811015611c945760405162461bcd60e51b815260040161070a906136d3565b6000611c9483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612ad3565b606d54606b546040516370a0823160e01b81526000926001600160a01b03908116926370a082319261184e92909116906004016135bc565b606d54604080516342a7cfd560e01b815290516000926001600160a01b0316916342a7cfd5916004808301926020929190829003018186803b15801561186657600080fd5b600061200c61269f565b6001600160a01b03166342a7cfd56040518163ffffffff1660e01b815260040160206040518083038186803b15801561186657600080fd5b600061204e612aff565b6001600160a01b031663027aa9f56040518163ffffffff1660e01b815260040160006040518083038186803b15801561208657600080fd5b505afa15801561209a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120c291908101906130df565b6000815181106120ce57fe5b6020026020010151905090565b606d546040805162c9d75160e11b815290516000926001600160a01b031691630193aea2916004808301926020929190829003018186803b15801561186657600080fd5b606a54604051630eee887760e21b81526001600160a01b0390911690633bba21dc9061215390869086908690600401613652565b602060405180830381600087803b15801561216d57600080fd5b505af1158015612181573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121a59190810190613150565b50505050565b60006110fd670de0b6b3a76400006109c46121c4612983565b610b3a6123a6565b6000806121eb670de0b6b3a76400006109c4868863ffffffff611c5a16565b905060006121f7611b93565b905060006122048261270f565b9050610bdb81610b1c858863ffffffff611f1e16565b6073546000906001600160a01b03166122316114ac565b6001600160a01b031614612247576072546110fd565b5060715490565b6069546040516321f8a72160e01b8152600091829182916001600160a01b0316906321f8a72190612293906c45786368616e6765526174657360981b9060040161360f565b60206040518083038186803b1580156122ab57600080fd5b505afa1580156122bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122e39190810190612ea4565b6001600160a01b0316634308a94f856040518263ffffffff1660e01b815260040161230e919061360f565b604080518083038186803b15801561232557600080fd5b505afa158015612339573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061235d91908101906131a8565b91509150631cd554d160e21b841461239f57426123828261708063ffffffff611f1e16565b1161239f5760405162461bcd60e51b815260040161070a906136f3565b5092915050565b6069546040516321f8a72160e01b81526000916001600160a01b0316906321f8a72190611b43906d2932bbb0b93222b9b1b937bbab1960911b9060040161360f565b3390565b60006110fd6123f9612002565b6109c4612404612044565b610b3a612b7c565b60006110fd670de0b6b3a76400006109c4612425612983565b610b3a6110dc565b6069546040516321f8a72160e01b81526000916001600160a01b0316906321f8a7219061246f906d53797374656d53657474696e677360901b9060040161360f565b60206040518083038186803b15801561248757600080fd5b505afa15801561249b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506124bf9190810190612ea4565b6001600160a01b031663b410a0346040518163ffffffff1660e01b815260040160206040518083038186803b15801561186657600080fd5b600080612516670de0b6b3a76400006109c4858863ffffffff611c5a16565b90508381111561252a576000915050610aa2565b610c85848263ffffffff611f4316565b6000806125456120db565b90506000612551611fbd565b90506000612571826109c4670de0b6b3a76400008663ffffffff611c5a16565b9050600061257d612044565b90506000612589612002565b905060006125a1826109c4868663ffffffff611c5a16565b905060006125ad6114ac565b90506000816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156125ea57600080fd5b505afa1580156125fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061262291908101906132a5565b60ff16600a0a9050612646816109c485670de0b6b3a764000063ffffffff611c5a16565b9250600061265261221a565b9050600061265f8261224e565b90506000612673630e68aa8960e31b61224e565b9050612689816109c4888563ffffffff611c5a16565b9b50505050505050505050505090565b303b1590565b60006110fd612aff565b60006110fd670de0b6b3a76400006109c46126c2612983565b610b3a611b06565b6000806126d5612983565b905060006126e9630e68aa8960e31b61224e565b9050611f0260646109c46063610b3a858388670de0b6b3a764000063ffffffff611c5a16565b600080612722630e68aa8960e31b61224e565b9050610e23816109c485670de0b6b3a764000063ffffffff611c5a16565b60008061275f670de0b6b3a76400006109c4868863ffffffff611c5a16565b9050600061276b611f09565b90506109d084610b1c848463ffffffff611f1e16565b6001600160a01b0381166127a75760405162461bcd60e51b815260040161070a906136b3565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b600081836128245760405162461bcd60e51b815260040161070a91906136a2565b50600083858161283057fe5b0495945050505050565b6000806128456114ac565b90506000816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561288257600080fd5b505afa158015612896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506128ba91908101906132a5565b60ff16600a0a905060006128cc6123ec565b90506128ea826109c483670de0b6b3a764000063ffffffff611c5a16565b905060006128f661221a565b905060006129038261224e565b90506000612923670de0b6b3a76400006109c4868563ffffffff611c5a16565b9050600061292f610f41565b90506000612943630e68aa8960e31b61224e565b90506000612963670de0b6b3a76400006109c4858563ffffffff611c5a16565b9050612975848263ffffffff611f1e16565b995050505050505050505090565b6069546040516321f8a72160e01b8152600091829182916001600160a01b0316906321f8a721906129c8906c45786368616e6765526174657360981b9060040161360f565b60206040518083038186803b1580156129e057600080fd5b505afa1580156129f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612a189190810190612ea4565b6001600160a01b0316634308a94f620a69cb60eb1b6040518263ffffffff1660e01b8152600401612a49919061360f565b604080518083038186803b158015612a6057600080fd5b505afa158015612a74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612a9891908101906131a8565b909250905042612ab08261708063ffffffff611f1e16565b11612acd5760405162461bcd60e51b815260040161070a906136f3565b50905090565b60008184841115612af75760405162461bcd60e51b815260040161070a91906136a2565b505050900390565b606d54604080516330b8662760e01b815290516000926001600160a01b0316916330b86627916004808301926020929190829003018186803b158015612b4457600080fd5b505afa158015612b58573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110fd9190810190612ea4565b600080612b876120db565b90506000612b93611fbd565b9050611f02816109c484610b3a611f85565b8260028101928215612bd3579160200282015b82811115612bd3578251825591602001919060010190612bb8565b50612bdf929150612c37565b5090565b8260028101928215612c2b579160200282015b82811115612c2b57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612bf6565b50612bdf929150612c51565b610f4f91905b80821115612bdf5760008155600101612c3d565b610f4f91905b80821115612bdf5780546001600160a01b0319168155600101612c57565b8035611c9781613897565b8051611c9781613897565b600082601f830112612c9c57600080fd5b6002612caf612caa826137db565b6137b4565b91508183856020840282011115612cc557600080fd5b60005b83811015612cf15781612cdb8882612c75565b8452506020928301929190910190600101612cc8565b5050505092915050565b600082601f830112612d0c57600080fd5b8151612d1a612caa826137f9565b91508181835260208401935060208101905083856020840282011115612d3f57600080fd5b60005b83811015612cf15781612d558882612c80565b8452506020928301929190910190600101612d42565b600082601f830112612d7c57600080fd5b6002612d8a612caa826137db565b91508183856020840282011115612da057600080fd5b60005b83811015612cf15781612db68882612e52565b8452506020928301929190910190600101612da3565b600082601f830112612ddd57600080fd5b8151612deb612caa826137f9565b91508181835260208401935060208101905083856020840282011115612e1057600080fd5b60005b83811015612cf15781612e268882612e68565b8452506020928301929190910190600101612e13565b8035611c97816138ab565b8051611c97816138ab565b8035611c97816138b4565b8035611c97816138bd565b8051611c97816138b4565b8051611c97816138c6565b600060208284031215612e9057600080fd5b6000612e9c8484612c75565b949350505050565b600060208284031215612eb657600080fd5b6000612e9c8484612c80565b60008060008060008060008060006101608a8c031215612ee157600080fd5b6000612eed8c8c612c75565b9950506020612efe8c828d01612c75565b9850506040612f0f8c828d01612c75565b9750506060612f208c828d01612c75565b9650506080612f318c828d01612c75565b95505060a0612f428c828d01612c75565b94505060c0612f538c828d01612d6b565b935050610100612f658c828d01612c8b565b925050610140612f778c828d01612c75565b9150509295985092959850929598565b600080600060608486031215612f9c57600080fd5b6000612fa88686612c75565b9350506020612fb986828701612e5d565b9250506040612fca86828701612e5d565b9150509250925092565b600080600080600060a08688031215612fec57600080fd5b6000612ff88888612c75565b955050602061300988828901612e52565b945050604061301a88828901612c75565b935050606061302b88828901612e52565b925050608061303c88828901612e52565b9150509295509295909350565b6000806000806080858703121561305f57600080fd5b600061306b8787612c75565b945050602061307c87828801612e52565b935050604061308d87828801612e52565b925050606061309e87828801612e52565b91505092959194509250565b6000602082840312156130bc57600080fd5b815167ffffffffffffffff8111156130d357600080fd5b612e9c84828501612cfb565b6000602082840312156130f157600080fd5b815167ffffffffffffffff81111561310857600080fd5b612e9c84828501612dcc565b60006020828403121561312657600080fd5b6000612e9c8484612e47565b60006020828403121561314457600080fd5b6000612e9c8484612e52565b60006020828403121561316257600080fd5b6000612e9c8484612e68565b6000806040838503121561318157600080fd5b600061318d8585612e52565b925050602061319e85828601612e52565b9150509250929050565b600080604083850312156131bb57600080fd5b60006131c78585612e68565b925050602061319e85828601612e68565b6000806000606084860312156131ed57600080fd5b60006131f98686612e52565b935050602061320a86828701612e52565b9250506040612fca86828701612e52565b6000806000806080858703121561323157600080fd5b600061306b8787612e52565b600080600080600060a0868803121561325557600080fd5b60006132618888612e52565b955050602061327288828901612e52565b945050604061328388828901612e52565b935050606061329488828901612e52565b925050608061303c88828901612e3c565b6000602082840312156132b757600080fd5b6000612e9c8484612e73565b6132cc8161384f565b82525050565b6132cc81613827565b6132cc81613832565b6132cc81610f4f565b6132cc81613856565b6132cc81613837565b600061330a8261381a565b613314818561381e565b9350613324818560208601613861565b61332d8161388d565b9093019392505050565b600061334460268361381e565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b600061338c600f8361381e565b6e151c985b9cd9995c8819985a5b1959608a1b815260200192915050565b60006133b7601b8361381e565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b60006133f060158361381e565b74082c8c8e4cae6e6cae640c8dedc4ee840dac2e8c6d605b1b815260200192915050565b6000613421600a8361381e565b6952617465207374616c6560b01b815260200192915050565b600061344760208361381e565b7f4f6e6c792078534e5841646d696e20636f6e74726163742063616e2063616c6c815260200192915050565b600061348060108361381e565b6f24b731b7b93932b1ba1031b0b63632b960811b815260200192915050565b60006134ac60218361381e565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b60006134ef60208361381e565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000613528602e8361381e565b7f436f6e747261637420696e7374616e63652068617320616c726561647920626581526d195b881a5b9a5d1a585b1a5e995960921b602082015260400192915050565b600061357860178361381e565b7f526562616c616e6365206e6f74206e6563657373617279000000000000000000815260200192915050565b6000611c97600083610e27565b6000611c97826135a4565b60208101611c9782846132d2565b60208101611c9782846132c3565b604081016135e682856132d2565b610aa260208301846132e4565b60208101611c9782846132db565b604081016135e682856132db565b60208101611c9782846132e4565b6080810161362b82876132ed565b61363860208301866132e4565b61364560408301856132ed565b610c8560608301846132e4565b6060810161366082866132ed565b61366d60208301856132e4565b612e9c60408301846132e4565b6080810161368882876132f6565b61369560208301866132f6565b61364560408301856132e4565b60208082528101611c9481846132ff565b60208082528101611c9781613337565b60208082528101611c978161337f565b60208082528101611c97816133aa565b60208082528101611c97816133e3565b60208082528101611c9781613414565b60208082528101611c978161343a565b60208082528101611c9781613473565b60208082528101611c978161349f565b60208082528101611c97816134e2565b60208082528101611c978161351b565b60208082528101611c978161356b565b6040810161377182856132e4565b610aa260208301846132d2565b604081016135e682856132e4565b6060810161379a82866132e4565b6137a760208301856132e4565b612e9c60408301846132d2565b60405181810167ffffffffffffffff811182821017156137d357600080fd5b604052919050565b600067ffffffffffffffff8211156137f257600080fd5b5060200290565b600067ffffffffffffffff82111561381057600080fd5b5060209081020190565b5190565b90815260200190565b6000611c978261383d565b151590565b600f0b90565b6001600160a01b031690565b60ff1690565b6000611c97825b6000611c9782613827565b60005b8381101561387c578181015183820152602001613864565b838111156121a55750506000910152565b601f01601f191690565b6138a081613827565b8114610cde57600080fd5b6138a081613832565b6138a081610f4f565b6138a081613837565b6138a08161384956fea365627a7a723158201abf0281a4134fd3a54833042e0c0056deec0a09674bbe7eae1509f7715c99666c6578706572696d656e74616cf564736f6c634300050f0040
Deployed Bytecode Sourcemap
41645:40862:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44662:1078;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;44662:1078:0;;;;;;;;:::i;82196:270::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;82196:270:0;;;;;;;;:::i;48355:509::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;48355:509:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;77760:438;;8:9:-1;5:2;;;30:1;27;20:12;5:2;77760:438:0;;;:::i;:::-;;;;;;;;;;60640:273;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60640:273:0;;;:::i;56148:829::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;56148:829:0;;;;;;;;:::i;79470:751::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;79470:751:0;;;:::i;59700:839::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;59700:839:0;;;;;;;;:::i;54946:935::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;54946:935:0;;;;;;;;:::i;80534:221::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;80534:221:0;;;;;;;;:::i;46296:673::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;46296:673:0;;;;;;;;:::i;70967:319::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;70967:319:0;;;;;;;;:::i;50155:426::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;50155:426:0;;;;;;;;:::i;:::-;;;;;;;;57360:436;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;57360:436:0;;;;;;;;:::i;81849:146::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;81849:146:0;;;;;;;;:::i;48024:115::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48024:115:0;;;:::i;10717:140::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;10717:140:0;;;:::i;61088:1039::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61088:1039:0;;;;;;;;:::i;66539:130::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66539:130:0;;;:::i;9904:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9904:79:0;;;:::i;:::-;;;;;;;;10270:94;;8:9:-1;5:2;;;30:1;27;20:12;5:2;10270:94:0;;;:::i;77203:391::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;77203:391:0;;;:::i;82052:136::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;82052:136:0;;;;;;;;:::i;63387:643::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63387:643:0;;;:::i;70288:446::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70288:446:0;;;:::i;73953:644::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73953:644:0;;;:::i;49164:554::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;49164:554:0;;;;;;;;:::i;:::-;;;;;;;;;43155:809;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;43155:809:0;;;;;;;;:::i;64339:219::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64339:219:0;;;:::i;76693:389::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;76693:389:0;;;:::i;71612:692::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;71612:692:0;;;;;;;;:::i;9678:145::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9678:145:0;;;;;;;;:::i;80763:706::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;80763:706:0;;;;;;;;:::i;74697:258::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74697:258:0;;;:::i;:::-;;;;;;;;;58111:708;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;58111:708:0;;;;;;;;:::i;75128:434::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;75128:434:0;;;:::i;:::-;;;;;;;;;59227:172;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59227:172:0;;;:::i;78429:943::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;78429:943:0;;;;;;;;:::i;11012:109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;11012:109:0;;;;;;;;:::i;66401:130::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66401:130:0;;;:::i;44662:1078::-;44042:17;;-1:-1:-1;;;;;44042:17:0;44028:10;:31;44006:113;;;;-1:-1:-1;;;44006:113:0;;;;;;;;;;;;;;;;;44887:11;;-1:-1:-1;;;;;44874:24:0;;;44887:11;;44874:24;44870:728;;;44935:9;;44915:65;;-1:-1:-1;;;44935:9:0;;;;;;;44946;;44957:6;44965:14;44915:19;:65::i;:::-;45012:11;;-1:-1:-1;;;;;45001:22:0;;;45012:11;;45001:22;44997:178;;45044:15;45062:16;:14;:16::i;:::-;45115:11;;45044:34;;-1:-1:-1;45097:62:0;;-1:-1:-1;;;;;45115:11:0;45044:34;45137:7;45146:12;45097:17;:62::i;:::-;44997:178;;44870:728;;;45207:11;;-1:-1:-1;;;;;45196:22:0;;;45207:11;;45196:22;45192:406;;;45252:11;;-1:-1:-1;;;;;45239:24:0;;;45252:11;;45239:24;45235:128;;45321:11;;45284:63;;45302:9;;45313:6;;-1:-1:-1;;;;;45321:11:0;45334:12;45284:17;:63::i;:::-;45379:15;45397:16;:14;:16::i;:::-;45448:9;;45379:34;;-1:-1:-1;45428:66:0;;45448:9;;;;;-1:-1:-1;;;45459:9:0;;;;45379:34;45479:14;45428:19;:66::i;45192:406::-;45527:59;45545:9;45556:6;45564:7;45573:12;45527:17;:59::i;:::-;45649:17;;45681:40;;-1:-1:-1;;;45681:40:0;;-1:-1:-1;;;;;45610:24:0;;;;;;45649:17;;;45610:24;;45681:25;;:40;;45715:4;;45681:40;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;45681:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;45681:40: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;45681:40:0;;;;;;;;;45610:122;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;45610:122:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;45610:122: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;45610:122:0;;;;;;;;;;44662:1078;;;;;:::o;82196:270::-;82292:16;;-1:-1:-1;;;;;82292:16:0;82278:10;:30;82270:59;;;;-1:-1:-1;;;82270:59:0;;;;;;;;;82348:16;;-1:-1:-1;;;;;82348:37:0;;;:16;;:37;82340:71;;;;-1:-1:-1;;;82340:71:0;;;;;;;;;-1:-1:-1;82441:16:0;;82422:7;:36;;-1:-1:-1;;;;;;82422:36:0;-1:-1:-1;;;;;82441:16:0;;;82422:36;;;;;;82196:270::o;48355:509::-;48480:21;48514:23;48540:20;:18;:20::i;:::-;48514:46;;48571:25;48599:22;:20;:22::i;:::-;48571:50;;48634:21;48658:124;48698:11;48724:15;48754:17;48658:25;:124::i;:::-;48634:148;-1:-1:-1;48811:45:0;41797:4;48811:33;48634:148;48829:14;48811:33;:17;:33;:::i;:::-;:37;:45;:37;:45;:::i;:::-;48795:61;48355:509;-1:-1:-1;;;;;;48355:509:0:o;77760:438::-;77863:7;77885;77907;77957:23;77995:17;78026:42;:40;:42::i;:::-;77942:126;;;;78079:19;78101:30;:28;:30::i;:::-;78150:15;;78167:9;;-1:-1:-1;78150:15:0;;-1:-1:-1;77760:438:0;-1:-1:-1;;77760:438:0:o;60640:273::-;60728:30;60776:25;60804:26;:24;:26::i;:::-;60776:54;;60866:39;60887:17;60866:20;:39::i;:::-;60841:64;;60640:273;;:::o;56148:829::-;56315:7;56339:16;56335:74;;56379:18;:16;:18::i;:::-;56372:25;;;;56335:74;56421:20;56444:23;:21;:23::i;:::-;56421:46;-1:-1:-1;56548:28:0;56579:71;41797:4;56579:35;56421:46;56596:17;56579:35;:16;:35;:::i;:71::-;56548:102;;56661:24;56688:27;:25;:27::i;:::-;56661:54;;56726:21;56750:150;56789:12;56816:16;56847;56878:11;56750:24;:150::i;:::-;56726:174;-1:-1:-1;56918:51:0;56726:174;56918:32;:20;41797:4;56918:32;:24;:32;:::i;:51::-;56911:58;;;;;;56148:829;;;;;;:::o;79470:751::-;79568:25;79611:24;79638:26;:24;:26::i;:::-;79611:53;;79675:14;79692:15;:13;:15::i;:::-;79675:32;-1:-1:-1;79718:19:0;79740:28;:16;79675:32;79740:28;:20;:28;:::i;:::-;79718:50;-1:-1:-1;79718:50:0;79801:22;:6;41891:1;79801:22;:10;:22;:::i;:::-;:36;79779:109;;;;-1:-1:-1;;;79779:109:0;;;;;;;;;79901:16;79921:41;79955:6;79922:27;:11;41891:1;79922:27;:15;:27;:::i;:::-;79921:33;:41;:33;:41;:::i;:::-;79901:62;;79994:83;80050:16;79994:37;80022:8;79994:23;:21;:23::i;:::-;:27;:37;:27;:37;:::i;:83::-;79974:103;;80090:19;80112;:17;:19::i;:::-;80090:41;-1:-1:-1;80162:51:0;80090:41;80162:34;:17;80090:41;80162:34;:21;:34;:::i;:51::-;80142:71;;79470:751;;;;;;:::o;59700:839::-;59805:30;59853:26;59882:23;:21;:23::i;:::-;59853:52;;59916:29;59948:26;:24;:26::i;:::-;59916:58;-1:-1:-1;59985:23:0;60011:92;59916:58;60011:41;:17;60033:18;60011:41;:21;:41;:::i;:92::-;59985:118;;60116:33;60152:19;:17;:19::i;:::-;60116:55;;60182:18;60203;:16;:18::i;:::-;60182:39;-1:-1:-1;60257:274:0;60505:25;60257:229;60505:25;60257:184;60437:3;60257:184;60366:2;60257:229;60182:39;60257:184;:15;60505:25;60257:60;:33;:60;:::i;:274::-;60232:299;59700:839;-1:-1:-1;;;;;;;59700:839:0:o;54946:935::-;55174:7;55198:16;55194:74;;55238:18;:16;:18::i;:::-;55231:25;;;;55194:74;55280:20;55315:13;55311:311;;;55360:23;:21;:23::i;:::-;55345:38;;55311:311;;;55416:23;55442:15;:13;:15::i;:::-;55416:41;-1:-1:-1;55472:22:0;55497:37;55416:41;55517:16;55497:37;:19;:37;:::i;:::-;55472:62;-1:-1:-1;55564:46:0;55472:62;55564:26;:14;41797:4;55564:26;:18;:26;:::i;:46::-;55549:61;;55311:311;;;55634:21;55658:150;55697:12;55724:16;55755;55786:11;55658:24;:150::i;:::-;55634:174;-1:-1:-1;55828:45:0;55634:174;55828:26;:14;41797:4;55828:26;:18;:26;:::i;:45::-;55821:52;;;;54946:935;;;;;;;;:::o;80534:221::-;10116:9;:7;:9::i;:::-;10108:54;;;;-1:-1:-1;;;10108:54:0;;;;;;;;;80650:17;;-1:-1:-1;;;;;80650:17:0;80646:102;;80698:17;:38;;-1:-1:-1;;;;;;80698:38:0;-1:-1:-1;;;;;80698:38:0;;;;;80646:102;80534:221;:::o;46296:673::-;44042:17;;-1:-1:-1;;;;;44042:17:0;44028:10;:31;44006:113;;;;-1:-1:-1;;;44006:113:0;;;;;;;;;46495:11;;-1:-1:-1;;;;;46482:24:0;;;46495:11;;46482:24;46478:324;;;46543:9;;46523:65;;-1:-1:-1;;;46543:9:0;;;;;;;46554;;46565:6;46573:14;46523:19;:65::i;:::-;46605:15;46623:16;:14;:16::i;:::-;46672:11;;46605:34;;-1:-1:-1;46654:53:0;;-1:-1:-1;;;;;46672:11:0;46605:34;46694:12;46654:17;:53::i;:::-;46478:324;;;;46740:50;46758:9;46769:6;46777:12;46740:17;:50::i;:::-;46882:33;;46831:21;;46814:14;;46882:10;;46831:21;;46882:33;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;46863:52:0;;;46934:7;46926:35;;;;-1:-1:-1;;;46926:35:0;;;;;;;;70967:319;71084:7;71109:24;71136:29;:27;:29::i;:::-;71109:56;-1:-1:-1;71180:21:0;71176:35;;71210:1;71203:8;;;;;71176:35;71231:47;41797:4;71231:35;:16;71252:13;71231:35;:20;:35;:::i;:47::-;71224:54;;;70967:319;;;;:::o;50155:426::-;50318:18;50353:16;50349:34;;-1:-1:-1;50378:5:0;50371:12;;50349:34;50431;:12;50448:16;50431:34;:16;:34;:::i;:::-;50400:28;:12;41891:1;50400:28;:16;:28;:::i;:::-;:65;50396:153;;;-1:-1:-1;50533:4:0;50526:11;;50396:153;-1:-1:-1;50568:5:0;50155:426;;;;;:::o;57360:436::-;57553:21;57603:185;57776:11;57603:154;41797:4;57603:128;57646:12;57673:16;57704;57603:28;:128::i;81849:146::-;10116:9;:7;:9::i;:::-;10108:54;;;;-1:-1:-1;;;10108:54:0;;;;;;;;;81958:17;;81921:66;;-1:-1:-1;;;81921:66:0;;-1:-1:-1;;;;;81921:28:0;;;;;;:66;;81958:17;;;;-1:-1:-1;;42021:10:0;81921:66;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;81921:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;81921:66: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;81921:66:0;;;;;;;;;;81849:146;:::o;48024:115::-;48105:17;;-1:-1:-1;;;;;48105:17:0;48097:34;48024:115;;:::o;10717:140::-;10116:9;:7;:9::i;:::-;10108:54;;;;-1:-1:-1;;;10108:54:0;;;;;;;;;10800:6;;10779:40;;10816:1;;-1:-1:-1;;;;;10800:6:0;;10779:40;;10816:1;;10779:40;10830:6;:19;;-1:-1:-1;;;;;;10830:19:0;;;10717:140::o;61088:1039::-;61201:32;61251:23;61277:30;:28;:30::i;:::-;61251:56;;61320:30;61353:27;:25;:27::i;:::-;61320:60;;61391:16;61410:37;61424:22;61410:13;:37::i;:::-;61391:56;-1:-1:-1;61551:28:0;61582:32;61391:56;61582:18;41797:4;;61582:18;:10;:18;:::i;:32::-;61551:63;-1:-1:-1;61627:32:0;61662:155;41843:3;61662:104;61762:3;61662:81;41797:4;61662:104;61551:63;61701:15;61662:55;:38;:55;:::i;:155::-;61627:190;;61830:16;61869:15;-1:-1:-1;;;;;61855:39:0;;:41;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61855:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61855:41: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;61855:41:0;;;;;;;;;61850:46;;41754:2;61850:46;;-1:-1:-1;61935:74:0;41797:4;61935:38;:24;61850:46;61935:38;:28;:38;:::i;:74::-;61908:101;;62049:70;62084:24;62049:20;:70::i;:::-;62022:97;61088:1039;-1:-1:-1;;;;;;;;61088:1039:0:o;66539:130::-;66585:7;66612:49;66637:23;:21;:23::i;:::-;66612:20;:18;:20::i;:::-;:24;:49;:24;:49;:::i;:::-;66605:56;;66539:130;:::o;9904:79::-;9969:6;;-1:-1:-1;;;;;9969:6:0;9904:79;:::o;10270:94::-;10350:6;;10310:4;;-1:-1:-1;;;;;10350:6:0;10334:12;:10;:12::i;:::-;-1:-1:-1;;;;;10334:22:0;;10327:29;;10270:94;:::o;77203:391::-;77267:4;77299:22;77336:26;77376:19;:17;:19::i;:::-;77284:111;;-1:-1:-1;77284:111:0;-1:-1:-1;77284:111:0;77426:56;41843:3;77426:43;77284:111;42151:3;77426:43;:22;:43;:::i;:56::-;:86;77408:154;;;77546:4;77539:11;;;;;;77408:154;77581:5;77574:12;;;;77203:391;:::o;82052:136::-;10116:9;:7;:9::i;:::-;10108:54;;;;-1:-1:-1;;;10108:54:0;;;;;;;;;82161:7;;82124:56;;-1:-1:-1;;;82124:56:0;;-1:-1:-1;;;;;82124:28:0;;;;;;:56;;82161:7;;;;-1:-1:-1;;42021:10:0;82124:56;;;;63387:643;63471:19;63508:27;63538:24;:22;:24::i;:::-;63508:54;;63573:19;63595:27;:25;:27::i;:::-;63573:49;;63633:23;63659:30;:28;:30::i;:::-;63633:56;;63702:16;63721:26;63735:11;63721:13;:26::i;:::-;63702:45;;63758:14;63775:19;-1:-1:-1;;;63775:13:0;:19::i;:::-;63758:36;;63807:16;63846:15;-1:-1:-1;;;;;63832:39:0;;:41;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63832:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63832:41: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;63832:41:0;;;;;;;;;63827:46;;41754:2;63827:46;;-1:-1:-1;63907:45:0;63827:46;63907:31;:19;41797:4;63907:31;:23;:31;:::i;:45::-;63885:67;-1:-1:-1;63977:45:0;64015:6;63977:33;63885:67;64001:8;63977:33;:23;:33;:::i;:45::-;63963:59;;63387:643;;;;;;;:::o;70288:446::-;70385:7;70410:20;70433:21;:19;:21::i;:::-;70410:44;;70465:17;70485:22;:20;:22::i;:::-;70465:42;;70518:21;70542:18;:16;:18::i;:::-;70518:42;;70591:135;70639:12;70670:9;70698:13;70591:29;:135::i;:::-;70571:155;;;;;70288:446;:::o;73953:644::-;74051:17;74101:22;74138:26;74178:19;:17;:19::i;:::-;74086:111;;-1:-1:-1;74086:111:0;-1:-1:-1;74208:22:0;74233:38;74086:111;;74233:38;:22;:38;:::i;:::-;74208:63;;74282:24;74309:31;:29;:31::i;:::-;74282:58;-1:-1:-1;74363:48:0;74282:58;74363:26;:14;41797:4;74363:26;:18;:26;:::i;49164:554::-;49262:18;49282:24;49324;49351:26;:24;:26::i;:::-;49324:53;;49455:20;49478:15;:13;:15::i;:::-;49455:38;;49522:124;49566:16;49597:12;49624:11;49522:29;:124::i;:::-;49506:140;-1:-1:-1;49676:34:0;:16;49697:12;49676:34;:20;:34;:::i;:::-;49657:53;;49164:554;;;;;:::o;43155:809::-;6655:12;;;;;;;;:31;;;6671:15;:13;:15::i;:::-;6655:47;;;-1:-1:-1;6691:11:0;;;;6690:12;6655:47;6647:106;;;;-1:-1:-1;;;6647:106:0;;;;;;;;;6762:19;6785:12;;;;;;6784:13;6804:83;;;;6833:12;:19;;-1:-1:-1;;;;6833:19:0;;;;;6861:18;6848:4;6861:18;;;6804:83;43537:33;43556:13;43537:18;:33::i;:::-;43583:10;:24;;-1:-1:-1;;;;;;43583:24:0;;;-1:-1:-1;;;;;43583:24:0;;;;;;;;;;43618:17;:58;;;;;;;;;;43687:15;:52;;;;;;;;;;43750:11;:26;;;;;;;;;;43787:11;:26;;;;;;;;;;43824:16;:36;;;;;;;;;;;;;;43871:28;:12;43886:13;-1:-1:-1;43871:28:0;:::i;:::-;-1:-1:-1;43910:46:0;:21;43934:22;43910:46;;:::i;:::-;;6909:14;6905:57;;;6949:5;6934:20;;-1:-1:-1;;6934:20:0;;;6905:57;43155:809;;;;;;;;;;:::o;64339:219::-;64400:7;64420:34;64457:25;:23;:25::i;:::-;-1:-1:-1;;;;;64457:53:0;;:55;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64457:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64457:55:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;64457:55:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;64457:55:0;;;;;;;;;64420:92;;64530:17;64548:1;64530:20;;;;;;;;;;;;;;64523:27;;;64339:219;:::o;76693:389::-;76755:4;76787:22;76824:26;76864:19;:17;:19::i;:::-;76772:111;;-1:-1:-1;76772:111:0;-1:-1:-1;76772:111:0;76914:52;41843:3;76914:39;76772:111;42151:3;76914:39;:18;:39;:::i;71612:692::-;71813:18;71844:27;71874:26;:24;:26::i;:::-;71844:56;-1:-1:-1;71911:22:0;71936:72;71984:13;71936:29;:17;41797:4;71936:29;:21;:29;:::i;:72::-;71911:97;-1:-1:-1;72019:24:0;72046:80;72104:11;72046:39;:19;72070:14;72046:39;:23;:39;:::i;:80::-;72019:107;-1:-1:-1;72150:146:0;41797:4;72150:120;72256:13;72165:61;72206:19;72165:36;:14;72019:107;72165:36;:18;:36;:::i;9678:145::-;6655:12;;;;;;;;:31;;;6671:15;:13;:15::i;:::-;6655:47;;;-1:-1:-1;6691:11:0;;;;6690:12;6655:47;6647:106;;;;-1:-1:-1;;;6647:106:0;;;;;;;;;6762:19;6785:12;;;;;;6784:13;6804:83;;;;6833:12;:19;;-1:-1:-1;;;;6833:19:0;;;;;6861:18;6848:4;6861:18;;;6804:83;9744:6;:15;;-1:-1:-1;;;;;;9744:15:0;-1:-1:-1;;;;;9744:15:0;;;;;;;;;;;9775:40;;9808:6;;;-1:-1:-1;;9775:40:0;;-1:-1:-1;;9775:40:0;6909:14;6905:57;;;6949:5;6934:20;;-1:-1:-1;;6934:20:0;;;9678:145;;:::o;80763:706::-;10116:9;:7;:9::i;:::-;10108:54;;;;-1:-1:-1;;;10108:54:0;;;;;;;;;80919:7;;-1:-1:-1;;;;;80919:7:0;80907:489;;81039:7;:36;;-1:-1:-1;;;;;81039:36:0;;-1:-1:-1;;;;;;81039:36:0;;;;;;;;81090:16;:35;;;;;;;;;;80907:489;;;81349:16;:35;;-1:-1:-1;;;;;;81349:35:0;-1:-1:-1;;;;;81349:35:0;;;;;80907:489;81406:9;:22;;;81439;;;81406;81439;;;-1:-1:-1;;;81439:22:0;81406;;;;;;-1:-1:-1;;81406:22:0;;;;81439;;;;;;;;;-1:-1:-1;80763:706:0:o;74697:258::-;74784:17;74803:19;74852:40;:38;:40::i;:::-;74840:52;;74917:30;:28;:30::i;:::-;74903:44;;74697:258;;:::o;58111:708::-;58274:21;58472:20;58495:25;:23;:25::i;:::-;58472:48;;58533:22;58558:42;58582:17;58558:23;:42::i;:::-;58533:67;;58627:184;58799:11;58627:153;41797:4;58627:127;58672:12;58699:15;58729:14;58627:30;:127::i;75128:434::-;75205:22;75229:26;75273:24;75300:26;:24;:26::i;:::-;75273:53;;75337:18;75358:15;:13;:15::i;:::-;75337:36;;75386:17;75406:22;:20;:22::i;:::-;75386:42;;75456:34;75480:9;75456:23;:34::i;:::-;75439:51;-1:-1:-1;75522:32:0;:16;75543:10;75522:32;:20;:32;:::i;:::-;75501:53;;75128:434;;;;;:::o;59227:172::-;59284:7;59331:30;:28;:30::i;:::-;59373:17;;59324:67;;-1:-1:-1;;;59324:67:0;;-1:-1:-1;;;;;59324:48:0;;;;;;:67;;59373:17;;;59324:67;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59324:67:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59324:67: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;59324:67:0;;;;;;;;78429:943;78527:21;78566:14;78583:19;-1:-1:-1;;;78583:13:0;:19::i;:::-;78566:36;;78615:24;78642:74;41797:4;78642:38;78673:6;78642:26;:24;:26::i;:74::-;78615:101;;78727:19;78749:39;41797:4;78749:27;78769:6;78749:15;:13;:15::i;:39::-;78727:61;-1:-1:-1;78799:19:0;78821:33;:16;78727:61;78821:33;:20;:33;:::i;:::-;78799:55;-1:-1:-1;78902:24:0;78799:55;78918:7;78902:24;:15;:24;:::i;:::-;78871:27;:11;41891:1;78871:27;:15;:27;:::i;:::-;:55;78867:498;;;;;79076:11;79031:42;41891:1;79032:24;:11;79048:7;79032:24;:15;:24;:::i;79031:42::-;:56;79027:338;;;79165:7;79149:23;;79027:338;;;79260:93;79327:11;79261:42;41891:1;79262:24;:11;79278:7;79262:24;:15;:24;:::i;79260:93::-;79244:109;;79027:338;78429:943;;;;;;;:::o;11012:109::-;10116:9;:7;:9::i;:::-;10108:54;;;;-1:-1:-1;;;10108:54:0;;;;;;;;;11085:28;11104:8;11085:18;:28::i;66401:130::-;66482:11;;66505:17;;66475:48;;-1:-1:-1;;;66475:48:0;;66448:7;;-1:-1:-1;;;;;66482:11:0;;;;66475:29;;:48;;66505:17;;;;66475:48;;;;47260:315;47429:7;;:138;;-1:-1:-1;;;47429:138:0;;-1:-1:-1;;;;;47429:7:0;;;;:27;;:138;;47471:11;;47497:12;;47524:7;;47546:10;;47429:138;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47429:138:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47429:138:0;;;;47260:315;;;;:::o;47583:128::-;47666:11;;47659:44;;-1:-1:-1;;;47659:44:0;;47632:7;;-1:-1:-1;;;;;47666:11:0;;47659:29;;:44;;47697:4;;47659:44;;;;45748:332;45915:17;;:157;;-1:-1:-1;;;45915:157:0;;-1:-1:-1;;;;;45915:17:0;;;;:34;;:157;;45970:10;;45996:7;;46024:8;;46048:13;;45915:157;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;45915:157:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;45915:157: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;45915:157:0;;;;;;;;;;45748:332;;;;:::o;66677:211::-;66777:15;;:41;;-1:-1:-1;;;66777:41:0;;66730:7;;-1:-1:-1;;;;;66777:15:0;;:26;;:41;;-1:-1:-1;;;66804:13:0;66777:41;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66777:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;66777:41: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;66777:41:0;;;;;;;;68545:244;68651:15;;:41;;-1:-1:-1;;;68651:41:0;;68600:7;;-1:-1:-1;;;;;68651:15:0;;:26;;:41;;-1:-1:-1;;;68678:13:0;68651:41;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68651:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68651:41: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;68651:41:0;;;;;;;;;68726:17;;68640:141;;-1:-1:-1;;;68640:141:0;;-1:-1:-1;;;;;68640:67:0;;;;;;:141;;68726:17;;;-1:-1:-1;;;68762:4:0;68640:141;;;;2312:471;2370:7;2615:6;2611:47;;-1:-1:-1;2645:1:0;2638:8;;2611:47;2682:5;;;2686:1;2682;:5;:1;2706:5;;;;;:10;2698:56;;;;-1:-1:-1;;;2698:56:0;;;;;;;;;2774:1;-1:-1:-1;2312:471:0;;;;;:::o;3251:132::-;3309:7;3336:39;3340:1;3343;3336:39;;;;;;;;;;;;;;;;;:3;:39::i;72711:1142::-;72813:23;72838:17;72873:20;72896:21;:19;:21::i;:::-;72873:44;;72928:22;72953;:20;:22::i;:::-;72928:47;;72986:21;73010:18;:16;:18::i;:::-;72986:42;;73041:28;73072:124;73116:12;73143:14;73172:13;73072:29;:124::i;:::-;73041:155;;73215:35;73263:51;73300:13;73263:36;:51::i;:::-;73215:99;;73327:29;73359:32;:30;:32::i;:::-;73327:64;-1:-1:-1;73402:26:0;73431:41;:14;73327:64;73431:41;:18;:41;:::i;:::-;73402:70;-1:-1:-1;73485:34:0;73522:77;41797:4;73522:51;73402:70;73559:13;73522:51;:36;:51;:::i;:77::-;73485:114;-1:-1:-1;73645:117:0;73485:114;73645:53;:20;73670:27;73645:53;:24;:53;:::i;:117::-;73612:161;;73796:49;73831:13;:11;:13::i;:::-;73796:30;:18;41797:4;73796:30;:22;:30;:::i;:49::-;73784:61;;72711:1142;;;;;;;;;;:::o;54277:244::-;54375:15;;:41;;-1:-1:-1;;;54375:41:0;;54328:7;;54368:145;;42220:2;;-1:-1:-1;;;;;54375:15:0;;:26;;:41;;-1:-1:-1;;;54402:13:0;54375:41;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54375:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54375:41: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;54375:41:0;;;;;;;;;54446:17;;54368:96;;-1:-1:-1;;;54368:96:0;;-1:-1:-1;;;;;54368:77:0;;;;;;:96;;54446:17;;;54368:96;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54368:96:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54368: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;54368:96:0;;;;;;;;53973:214;54029:7;54049:14;54066:18;-1:-1:-1;;;54066:13:0;:18::i;:::-;54049:35;;54095:14;54112:19;-1:-1:-1;;;54112:13:0;:19::i;:::-;54095:36;-1:-1:-1;54149:30:0;54095:36;54149:18;:6;41797:4;54149:18;:10;:18;:::i;:30::-;54142:37;;;;53973:214;:::o;52577:142::-;52637:7;52664:47;52695:15;:13;:15::i;:::-;52664:26;:24;:26::i;940:181::-;998:7;1030:5;;;1054:6;;;;1046:46;;;;-1:-1:-1;;;1046:46:0;;;;;;;;1396:136;1454:7;1481:43;1485:1;1488;1481:43;;;;;;;;;;;;;;;;;:3;:43::i;65797:138::-;65887:10;;65909:17;;65880:47;;-1:-1:-1;;;65880:47:0;;65853:7;;-1:-1:-1;;;;;65887:10:0;;;;65880:28;;:47;;65909:17;;;;65880:47;;;;65667:122;65756:10;;65746:35;;;-1:-1:-1;;;65746:35:0;;;;65719:7;;-1:-1:-1;;;;;65756:10:0;;65746:33;;:35;;;;;;;;;;;;;;65756:10;65746:35;;;5:2:-1;;;;30:1;27;20:12;64038:130:0;64094:7;64121:25;:23;:25::i;:::-;-1:-1:-1;;;;;64121:37:0;;:39;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;65943:148:0;66002:7;66053:15;:13;:15::i;:::-;-1:-1:-1;;;;;66029:49:0;;:51;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66029:51:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;66029:51:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;66029:51:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;66029:51:0;;;;;;;;;66081:1;66029:54;;;;;;;;;;;;;;66022:61;;65943:148;:::o;65539:120::-;65627:10;;65617:34;;;-1:-1:-1;;;65617:34:0;;;;65590:7;;-1:-1:-1;;;;;65627:10:0;;65617:32;;:34;;;;;;;;;;;;;;65627:10;65617:34;;;5:2:-1;;;;30:1;27;20:12;46977:275:0;47117:17;;:127;;-1:-1:-1;;;47117:127:0;;-1:-1:-1;;;;;47117:17:0;;;;:34;;:127;;47172:10;;47198:7;;47220:13;;47117:127;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47117:127:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47117:127: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;47117:127:0;;;;;;;;;;46977:275;;;:::o;67118:151::-;67180:7;67207:54;41797:4;67207:42;67235:13;:11;:13::i;:::-;67207:23;:21;:23::i;50988:598::-;51157:7;;51206:70;41797:4;51206:34;:16;51227:12;51206:34;:20;:34;:::i;:70::-;51177:99;;51287:25;51315:22;:20;:22::i;:::-;51287:50;;51348:30;51381:66;51419:17;51381:23;:66::i;:::-;51348:99;-1:-1:-1;51478:100:0;51348:99;51478:40;:18;51501:16;51478:40;:22;:40;:::i;53572:270::-;53744:21;:24;53659:19;;-1:-1:-1;;;;;53744:24:0;53710:30;:28;:30::i;:::-;-1:-1:-1;;;;;53710:58:0;;:124;;53818:15;;53710:124;;;-1:-1:-1;53785:12:0;:15;;53572:270::o;67765:389::-;67906:15;;:45;;-1:-1:-1;;;67906:45:0;;67826:7;;;;;;-1:-1:-1;;;;;67906:15:0;;:26;;:45;;-1:-1:-1;;;67933:17:0;67906:45;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67906:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67906:45: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;67906:45:0;;;;;;;;;-1:-1:-1;;;;;67877:118:0;;67996:5;67877:125;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67877:125:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67877:125: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;67877:125:0;;;;;;;;;67846:156;;;;-1:-1:-1;;;68017:5:0;:13;68013:112;;68083:15;68055:25;:4;42081:5;68055:25;:8;:25;:::i;:::-;:43;68047:66;;;;-1:-1:-1;;;68047:66:0;;;;;;;;;-1:-1:-1;68142:4:0;67765:389;-1:-1:-1;;67765:389:0:o;66896:214::-;67008:15;;:46;;-1:-1:-1;;;67008:46:0;;66952:7;;-1:-1:-1;;;;;67008:15:0;;:26;;:46;;-1:-1:-1;;;67035:18:0;67008:46;;;;8583:98;8663:10;8583:98;:::o;65049:223::-;65106:7;65146:118;65226:23;:21;:23::i;:::-;65146:57;65176:26;:24;:26::i;:::-;65146:25;:23;:25::i;69155:135::-;69209:7;69236:46;41797:4;69236:34;69256:13;:11;:13::i;:::-;69236:15;:13;:15::i;68864:196::-;68971:15;;:46;;-1:-1:-1;;;68971:46:0;;68915:7;;-1:-1:-1;;;;;68971:15:0;;:26;;:46;;-1:-1:-1;;;68998:18:0;68971:46;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68971:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68971: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;68971:46:0;;;;;;;;;-1:-1:-1;;;;;68955:95:0;;:97;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;69839:368:0;70007:7;;70048:43;41797:4;70048:31;:13;70066:12;70048:31;:17;:31;:::i;:43::-;70027:64;;70121:17;70108:10;:30;70104:44;;;70147:1;70140:8;;;;;70104:44;70166:33;:17;70188:10;70166:33;:21;:33;:::i;62221:1082::-;62312:16;62346:18;62367;:16;:18::i;:::-;62346:39;;62396:33;62432:19;:17;:19::i;:::-;62396:55;-1:-1:-1;62462:23:0;62488:77;62396:55;62488:22;41797:4;62499:10;62488:22;:10;:22;:::i;:77::-;62462:103;;62578:25;62606:26;:24;:26::i;:::-;62578:54;;62643:26;62672:23;:21;:23::i;:::-;62643:52;-1:-1:-1;62706:25:0;62734:86;62643:52;62734:38;:15;62754:17;62734:38;:19;:38;:::i;:86::-;62706:114;;62833:23;62859:30;:28;:30::i;:::-;62833:56;;62900:16;62939:15;-1:-1:-1;;;;;62925:39:0;;:41;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62925:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62925:41: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;62925:41:0;;;;;;;;;62920:46;;41754:2;62920:46;;-1:-1:-1;62998:43:0;62920:46;62998:29;:17;41797:4;62998:29;:21;:29;:::i;:43::-;62978:63;;63054:30;63087:27;:25;:27::i;:::-;63054:60;;63127:16;63146:37;63160:22;63146:13;:37::i;:::-;63127:56;;63194:14;63211:19;-1:-1:-1;;;63211:13:0;:19::i;:::-;63194:36;-1:-1:-1;63252:43:0;63194:36;63252:31;:17;63274:8;63252:31;:21;:31;:::i;:43::-;63241:54;;62221:1082;;;;;;;;;;;;:::o;7056:508::-;7473:4;7519:17;7551:7;7056:508;:::o;64566:181::-;64651:23;64723:15;:13;:15::i;67277:145::-;67336:7;67363:51;41797:4;67363:39;67388:13;:11;:13::i;:::-;67363:20;:18;:20::i;52910:435::-;52995:20;53033:19;53055:13;:11;:13::i;:::-;53033:35;;53079:19;53101;-1:-1:-1;;;53101:13:0;:19::i;:::-;53079:41;-1:-1:-1;53146:191:0;41843:3;53146:101;41976:2;53146:68;53079:41;53146:101;:11;41797:4;53146:37;:29;:37;:::i;68286:251::-;68388:24;68430:14;68447:19;-1:-1:-1;;;68447:13:0;:19::i;:::-;68430:36;-1:-1:-1;68496:33:0;68430:36;68496:21;:9;41797:4;68496:21;:13;:21;:::i;51990:498::-;52166:7;;52215:69;41797:4;52215:33;:15;52235:12;52215:33;:19;:33;:::i;:69::-;52186:98;;52295:24;52322:27;:25;:27::i;:::-;52295:54;-1:-1:-1;52380:100:0;52443:22;52380:40;:18;52295:54;52380:40;:22;:40;:::i;11227:229::-;-1:-1:-1;;;;;11301:22:0;;11293:73;;;;-1:-1:-1;;;11293:73:0;;;;;;;;;11403:6;;11382:38;;-1:-1:-1;;;;;11382:38:0;;;;11403:6;;11382:38;;11403:6;;11382:38;11431:6;:17;;-1:-1:-1;;;;;;11431:17:0;-1:-1:-1;;;;;11431:17:0;;;;;;;;;;11227:229::o;3913:345::-;3999:7;4101:12;4094:5;4086:28;;;;-1:-1:-1;;;4086:28:0;;;;;;;;;;;4125:9;4141:1;4137;:5;;;;;;;3913:345;-1:-1:-1;;;;;3913:345:0:o;75702:872::-;75794:29;75841:23;75867:30;:28;:30::i;:::-;75841:56;;75908:16;75947:15;-1:-1:-1;;;;;75933:39:0;;:41;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;75933:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75933:41: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;75933:41:0;;;;;;;;;75928:46;;41754:2;75928:46;75908:67;;75986:27;76016:24;:22;:24::i;:::-;75986:54;-1:-1:-1;76073:45:0;76109:8;76073:31;75986:54;41797:4;76073:31;:23;:31;:::i;:45::-;76051:67;;76131:30;76164:27;:25;:27::i;:::-;76131:60;;76204:16;76223:37;76237:22;76223:13;:37::i;:::-;76204:56;-1:-1:-1;76271:19:0;76293:45;41797:4;76293:33;:19;76204:56;76293:33;:23;:33;:::i;:45::-;76271:67;;76351:18;76372:15;:13;:15::i;:::-;76351:36;;76398:14;76415:19;-1:-1:-1;;;76415:13:0;:19::i;:::-;76398:36;-1:-1:-1;76445:19:0;76467:34;41797:4;76467:22;:10;76398:36;76467:22;:14;:22;:::i;:34::-;76445:56;-1:-1:-1;76538:28:0;:11;76445:56;76538:28;:15;:28;:::i;:::-;76514:52;;75702:872;;;;;;;;;;:::o;67430:327::-;67556:15;;:45;;-1:-1:-1;;;67556:45:0;;67476:7;;;;;;-1:-1:-1;;;;;67556:15:0;;:26;;:45;;-1:-1:-1;;;67583:17:0;67556:45;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67556:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67556:45: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;67556:45:0;;;;;;;;;-1:-1:-1;;;;;67527:118:0;;-1:-1:-1;;;67527:123:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67527:123:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67527:123: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;67527:123:0;;;;;;;;;67496:154;;-1:-1:-1;67496:154:0;-1:-1:-1;67697:15:0;67669:25;67496:154;42081:5;67669:25;:8;:25;:::i;:::-;:43;67661:66;;;;-1:-1:-1;;;67661:66:0;;;;;;;;;-1:-1:-1;67745:4:0;-1:-1:-1;67430:327:0;:::o;1869:192::-;1955:7;1991:12;1983:6;;;;1975:29;;;;-1:-1:-1;;;1975:29:0;;;;;;;;;;-1:-1:-1;;;2027:5:0;;;1869:192::o;64755:117::-;64840:10;;64830:34;;;-1:-1:-1;;;64830:34:0;;;;64803:7;;-1:-1:-1;;;;;64840:10:0;;64830:32;;:34;;;;;;;;;;;;;;64840:10;64830:34;;;5:2:-1;;;;30:1;27;20:12;5:2;64830:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64830:34: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;64830:34:0;;;;;;;;65280:251;65338:7;65358:18;65379;:16;:18::i;:::-;65358:39;;65408:19;65430;:17;:19::i;:::-;65408:41;;65467:56;65511:11;65467:39;65495:10;65467:23;:21;:23::i;41645:40862::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41645:40862:0;;;-1:-1:-1;41645:40862:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;41645:40862:0;-1:-1:-1;;;;;41645:40862:0;;;;;;;;;;;-1:-1:-1;41645:40862:0;;;;;;;-1:-1:-1;41645:40862:0;;;-1:-1:-1;41645:40862:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;41645:40862:0;;;;;;;5:130:-1;72:20;;97:33;72:20;97:33;;142:134;220:13;;238:33;220:13;238:33;;302:616;;417:3;410:4;402:6;398:17;394:27;384:2;;435:1;432;425:12;384:2;459:4;478:78;493:62;548:6;493:62;;;478:78;;;469:87;;573:5;632:6;679:3;671:4;663:6;659:17;654:3;650:27;647:36;644:2;;;696:1;693;686:12;644:2;721:1;706:206;731:6;728:1;725:13;706:206;;;789:3;811:37;844:3;832:10;811:37;;;799:50;;-1:-1;872:4;863:14;;;;891;;;;;753:1;746:9;706:206;;;710:14;377:541;;;;;;;;944:722;;1072:3;1065:4;1057:6;1053:17;1049:27;1039:2;;1090:1;1087;1080:12;1039:2;1120:6;1114:13;1142:80;1157:64;1214:6;1157:64;;1142:80;1133:89;;1239:5;1264:6;1257:5;1250:21;1294:4;1286:6;1282:17;1272:27;;1316:4;1311:3;1307:14;1300:21;;1369:6;1416:3;1408:4;1400:6;1396:17;1391:3;1387:27;1384:36;1381:2;;;1433:1;1430;1423:12;1381:2;1458:1;1443:217;1468:6;1465:1;1462:13;1443:217;;;1526:3;1548:48;1592:3;1580:10;1548:48;;;1536:61;;-1:-1;1620:4;1611:14;;;;1639;;;;;1490:1;1483:9;1443:217;;1693:616;;1808:3;1801:4;1793:6;1789:17;1785:27;1775:2;;1826:1;1823;1816:12;1775:2;1850:4;1869:78;1884:62;1939:6;1884:62;;1869:78;1860:87;;1964:5;2023:6;2070:3;2062:4;2054:6;2050:17;2045:3;2041:27;2038:36;2035:2;;;2087:1;2084;2077:12;2035:2;2112:1;2097:206;2122:6;2119:1;2116:13;2097:206;;;2180:3;2202:37;2235:3;2223:10;2202:37;;;2190:50;;-1:-1;2263:4;2254:14;;;;2282;;;;;2144:1;2137:9;2097:206;;2335:722;;2463:3;2456:4;2448:6;2444:17;2440:27;2430:2;;2481:1;2478;2471:12;2430:2;2511:6;2505:13;2533:80;2548:64;2605:6;2548:64;;2533:80;2524:89;;2630:5;2655:6;2648:5;2641:21;2685:4;2677:6;2673:17;2663:27;;2707:4;2702:3;2698:14;2691:21;;2760:6;2807:3;2799:4;2791:6;2787:17;2782:3;2778:27;2775:36;2772:2;;;2824:1;2821;2814:12;2772:2;2849:1;2834:217;2859:6;2856:1;2853:13;2834:217;;;2917:3;2939:48;2983:3;2971:10;2939:48;;;2927:61;;-1:-1;3011:4;3002:14;;;;3030;;;;;2881:1;2874:9;2834:217;;3065:124;3129:20;;3154:30;3129:20;3154:30;;3196:128;3271:13;;3289:30;3271:13;3289:30;;3331:130;3398:20;;3423:33;3398:20;3423:33;;3468:128;3534:20;;3559:32;3534:20;3559:32;;3740:134;3818:13;;3836:33;3818:13;3836:33;;3881:130;3957:13;;3975:31;3957:13;3975:31;;4018:241;;4122:2;4110:9;4101:7;4097:23;4093:32;4090:2;;;4138:1;4135;4128:12;4090:2;4173:1;4190:53;4235:7;4215:9;4190:53;;;4180:63;4084:175;-1:-1;;;;4084:175;4266:263;;4381:2;4369:9;4360:7;4356:23;4352:32;4349:2;;;4397:1;4394;4387:12;4349:2;4432:1;4449:64;4505:7;4485:9;4449:64;;4536:1339;;;;;;;;;;4822:3;4810:9;4801:7;4797:23;4793:33;4790:2;;;4839:1;4836;4829:12;4790:2;4874:1;4891:53;4936:7;4916:9;4891:53;;;4881:63;;4853:97;4981:2;4999:53;5044:7;5035:6;5024:9;5020:22;4999:53;;;4989:63;;4960:98;5089:2;5107:53;5152:7;5143:6;5132:9;5128:22;5107:53;;;5097:63;;5068:98;5197:2;5215:53;5260:7;5251:6;5240:9;5236:22;5215:53;;;5205:63;;5176:98;5305:3;5324:53;5369:7;5360:6;5349:9;5345:22;5324:53;;;5314:63;;5284:99;5414:3;5433:53;5478:7;5469:6;5458:9;5454:22;5433:53;;;5423:63;;5393:99;5523:3;5542:76;5610:7;5601:6;5590:9;5586:22;5542:76;;;5532:86;;5502:122;5655:3;5674:76;5742:7;5733:6;5722:9;5718:22;5674:76;;;5664:86;;5634:122;5787:3;5806:53;5851:7;5842:6;5831:9;5827:22;5806:53;;;5796:63;;5766:99;4784:1091;;;;;;;;;;;;5882:487;;;;6018:2;6006:9;5997:7;5993:23;5989:32;5986:2;;;6034:1;6031;6024:12;5986:2;6069:1;6086:53;6131:7;6111:9;6086:53;;;6076:63;;6048:97;6176:2;6194:52;6238:7;6229:6;6218:9;6214:22;6194:52;;;6184:62;;6155:97;6283:2;6301:52;6345:7;6336:6;6325:9;6321:22;6301:52;;;6291:62;;6262:97;5980:389;;;;;;6376:743;;;;;;6548:3;6536:9;6527:7;6523:23;6519:33;6516:2;;;6565:1;6562;6555:12;6516:2;6600:1;6617:53;6662:7;6642:9;6617:53;;;6607:63;;6579:97;6707:2;6725:53;6770:7;6761:6;6750:9;6746:22;6725:53;;;6715:63;;6686:98;6815:2;6833:53;6878:7;6869:6;6858:9;6854:22;6833:53;;;6823:63;;6794:98;6923:2;6941:53;6986:7;6977:6;6966:9;6962:22;6941:53;;;6931:63;;6902:98;7031:3;7050:53;7095:7;7086:6;7075:9;7071:22;7050:53;;;7040:63;;7010:99;6510:609;;;;;;;;;7126:617;;;;;7281:3;7269:9;7260:7;7256:23;7252:33;7249:2;;;7298:1;7295;7288:12;7249:2;7333:1;7350:53;7395:7;7375:9;7350:53;;;7340:63;;7312:97;7440:2;7458:53;7503:7;7494:6;7483:9;7479:22;7458:53;;;7448:63;;7419:98;7548:2;7566:53;7611:7;7602:6;7591:9;7587:22;7566:53;;;7556:63;;7527:98;7656:2;7674:53;7719:7;7710:6;7699:9;7695:22;7674:53;;;7664:63;;7635:98;7243:500;;;;;;;;7750:392;;7890:2;7878:9;7869:7;7865:23;7861:32;7858:2;;;7906:1;7903;7896:12;7858:2;7941:24;;7985:18;7974:30;;7971:2;;;8017:1;8014;8007:12;7971:2;8037:89;8118:7;8109:6;8098:9;8094:22;8037:89;;8149:392;;8289:2;8277:9;8268:7;8264:23;8260:32;8257:2;;;8305:1;8302;8295:12;8257:2;8340:24;;8384:18;8373:30;;8370:2;;;8416:1;8413;8406:12;8370:2;8436:89;8517:7;8508:6;8497:9;8493:22;8436:89;;8548:257;;8660:2;8648:9;8639:7;8635:23;8631:32;8628:2;;;8676:1;8673;8666:12;8628:2;8711:1;8728:61;8781:7;8761:9;8728:61;;8812:241;;8916:2;8904:9;8895:7;8891:23;8887:32;8884:2;;;8932:1;8929;8922:12;8884:2;8967:1;8984:53;9029:7;9009:9;8984:53;;9060:263;;9175:2;9163:9;9154:7;9150:23;9146:32;9143:2;;;9191:1;9188;9181:12;9143:2;9226:1;9243:64;9299:7;9279:9;9243:64;;9330:366;;;9451:2;9439:9;9430:7;9426:23;9422:32;9419:2;;;9467:1;9464;9457:12;9419:2;9502:1;9519:53;9564:7;9544:9;9519:53;;;9509:63;;9481:97;9609:2;9627:53;9672:7;9663:6;9652:9;9648:22;9627:53;;;9617:63;;9588:98;9413:283;;;;;;9703:399;;;9835:2;9823:9;9814:7;9810:23;9806:32;9803:2;;;9851:1;9848;9841:12;9803:2;9886:1;9903:64;9959:7;9939:9;9903:64;;;9893:74;;9865:108;10004:2;10022:64;10078:7;10069:6;10058:9;10054:22;10022:64;;10109:491;;;;10247:2;10235:9;10226:7;10222:23;10218:32;10215:2;;;10263:1;10260;10253:12;10215:2;10298:1;10315:53;10360:7;10340:9;10315:53;;;10305:63;;10277:97;10405:2;10423:53;10468:7;10459:6;10448:9;10444:22;10423:53;;;10413:63;;10384:98;10513:2;10531:53;10576:7;10567:6;10556:9;10552:22;10531:53;;10607:617;;;;;10762:3;10750:9;10741:7;10737:23;10733:33;10730:2;;;10779:1;10776;10769:12;10730:2;10814:1;10831:53;10876:7;10856:9;10831:53;;11231:737;;;;;;11400:3;11388:9;11379:7;11375:23;11371:33;11368:2;;;11417:1;11414;11407:12;11368:2;11452:1;11469:53;11514:7;11494:9;11469:53;;;11459:63;;11431:97;11559:2;11577:53;11622:7;11613:6;11602:9;11598:22;11577:53;;;11567:63;;11538:98;11667:2;11685:53;11730:7;11721:6;11710:9;11706:22;11685:53;;;11675:63;;11646:98;11775:2;11793:53;11838:7;11829:6;11818:9;11814:22;11793:53;;;11783:63;;11754:98;11883:3;11902:50;11944:7;11935:6;11924:9;11920:22;11902:50;;11975:259;;12088:2;12076:9;12067:7;12063:23;12059:32;12056:2;;;12104:1;12101;12094:12;12056:2;12139:1;12156:62;12210:7;12190:9;12156:62;;12241:142;12332:45;12371:5;12332:45;;;12327:3;12320:58;12314:69;;;12390:113;12473:24;12491:5;12473:24;;12510:104;12587:21;12602:5;12587:21;;12621:113;12704:24;12722:5;12704:24;;12741:154;12838:51;12883:5;12838:51;;12902:110;12983:23;13000:5;12983:23;;13019:347;;13131:39;13164:5;13131:39;;;13182:71;13246:6;13241:3;13182:71;;;13175:78;;13258:52;13303:6;13298:3;13291:4;13284:5;13280:16;13258:52;;;13331:29;13353:6;13331:29;;;13322:39;;;;13111:255;-1:-1;;;13111:255;13374:375;;13534:67;13598:2;13593:3;13534:67;;;13634:34;13614:55;;-1:-1;;;13698:2;13689:12;;13682:30;13740:2;13731:12;;13520:229;-1:-1;;13520:229;13758:315;;13918:67;13982:2;13977:3;13918:67;;;-1:-1;;;13998:38;;14064:2;14055:12;;13904:169;-1:-1;;13904:169;14082:327;;14242:67;14306:2;14301:3;14242:67;;;14342:29;14322:50;;14400:2;14391:12;;14228:181;-1:-1;;14228:181;14418:321;;14578:67;14642:2;14637:3;14578:67;;;-1:-1;;;14658:44;;14730:2;14721:12;;14564:175;-1:-1;;14564:175;14748:310;;14908:67;14972:2;14967:3;14908:67;;;-1:-1;;;14988:33;;15049:2;15040:12;;14894:164;-1:-1;;14894:164;15067:332;;15227:67;15291:2;15286:3;15227:67;;;15327:34;15307:55;;15390:2;15381:12;;15213:186;-1:-1;;15213:186;15408:316;;15568:67;15632:2;15627:3;15568:67;;;-1:-1;;;15648:39;;15715:2;15706:12;;15554:170;-1:-1;;15554:170;15733:370;;15893:67;15957:2;15952:3;15893:67;;;15993:34;15973:55;;-1:-1;;;16057:2;16048:12;;16041:25;16094:2;16085:12;;15879:224;-1:-1;;15879:224;16112:332;;16272:67;16336:2;16331:3;16272:67;;;16372:34;16352:55;;16435:2;16426:12;;16258:186;-1:-1;;16258:186;16453:383;;16613:67;16677:2;16672:3;16613:67;;;16713:34;16693:55;;-1:-1;;;16777:2;16768:12;;16761:38;16827:2;16818:12;;16599:237;-1:-1;;16599:237;16845:323;;17005:67;17069:2;17064:3;17005:67;;;17105:25;17085:46;;17159:2;17150:12;;16991:177;-1:-1;;16991:177;17177:296;;17354:83;17435:1;17430:3;17354:83;;17601:370;;17799:147;17942:3;17799:147;;17978:213;18096:2;18081:18;;18110:71;18085:9;18154:6;18110:71;;18198:229;18324:2;18309:18;;18338:79;18313:9;18390:6;18338:79;;18434:324;18580:2;18565:18;;18594:71;18569:9;18638:6;18594:71;;;18676:72;18744:2;18733:9;18729:18;18720:6;18676:72;;19096:201;19208:2;19193:18;;19222:65;19197:9;19260:6;19222:65;;19304:312;19444:2;19429:18;;19458:65;19433:9;19496:6;19458:65;;19623:213;19741:2;19726:18;;19755:71;19730:9;19799:6;19755:71;;19843:603;20073:3;20058:19;;20088:85;20062:9;20146:6;20088:85;;;20184:72;20252:2;20241:9;20237:18;20228:6;20184:72;;;20267:86;20349:2;20338:9;20334:18;20325:6;20267:86;;;20364:72;20432:2;20421:9;20417:18;20408:6;20364:72;;20453:463;20641:2;20626:18;;20655:85;20630:9;20713:6;20655:85;;;20751:72;20819:2;20808:9;20804:18;20795:6;20751:72;;;20834;20902:2;20891:9;20887:18;20878:6;20834:72;;20923:539;21121:3;21106:19;;21136:69;21110:9;21178:6;21136:69;;;21216:70;21282:2;21271:9;21267:18;21258:6;21216:70;;;21297:72;21365:2;21354:9;21350:18;21341:6;21297:72;;21469:301;21607:2;21621:47;;;21592:18;;21682:78;21592:18;21746:6;21682:78;;21777:407;21968:2;21982:47;;;21953:18;;22043:131;21953:18;22043:131;;22191:407;22382:2;22396:47;;;22367:18;;22457:131;22367:18;22457:131;;22605:407;22796:2;22810:47;;;22781:18;;22871:131;22781:18;22871:131;;23019:407;23210:2;23224:47;;;23195:18;;23285:131;23195:18;23285:131;;23433:407;23624:2;23638:47;;;23609:18;;23699:131;23609:18;23699:131;;23847:407;24038:2;24052:47;;;24023:18;;24113:131;24023:18;24113:131;;24261:407;24452:2;24466:47;;;24437:18;;24527:131;24437:18;24527:131;;24675:407;24866:2;24880:47;;;24851:18;;24941:131;24851:18;24941:131;;25089:407;25280:2;25294:47;;;25265:18;;25355:131;25265:18;25355:131;;25503:407;25694:2;25708:47;;;25679:18;;25769:131;25679:18;25769:131;;25917:407;26108:2;26122:47;;;26093:18;;26183:131;26093:18;26183:131;;26551:324;26697:2;26682:18;;26711:71;26686:9;26755:6;26711:71;;;26793:72;26861:2;26850:9;26846:18;26837:6;26793:72;;26882:324;27028:2;27013:18;;27042:71;27017:9;27086:6;27042:71;;27213:435;27387:2;27372:18;;27401:71;27376:9;27445:6;27401:71;;;27483:72;27551:2;27540:9;27536:18;27527:6;27483:72;;;27566;27634:2;27623:9;27619:18;27610:6;27566:72;;27655:256;27717:2;27711:9;27743:17;;;27818:18;27803:34;;27839:22;;;27800:62;27797:2;;;27875:1;27872;27865:12;27797:2;27891;27884:22;27695:216;;-1:-1;27695:216;27918:244;;28075:18;28067:6;28064:30;28061:2;;;28107:1;28104;28097:12;28061:2;-1:-1;28142:4;28130:17;;27998:164;28169:304;;28328:18;28320:6;28317:30;28314:2;;;28360:1;28357;28350:12;28314:2;-1:-1;28395:4;28383:17;;;28448:15;;28251:222;29042:122;29130:12;;29101:63;29325:163;29428:19;;;29477:4;29468:14;;29421:67;29496:91;;29558:24;29576:5;29558:24;;29594:85;29660:13;29653:21;;29636:43;29765:87;29837:2;29826:21;;29809:43;29859:121;-1:-1;;;;;29921:54;;29904:76;30066:81;30137:4;30126:16;;30109:38;30154:129;;30241:37;30272:5;30290:149;;30383:51;30428:5;30383:51;;30819:268;30884:1;30891:101;30905:6;30902:1;30899:13;30891:101;;;30972:11;;;30966:18;30953:11;;;30946:39;30927:2;30920:10;30891:101;;;31007:6;31004:1;31001:13;30998:2;;;-1:-1;;31072:1;31054:16;;31047:27;30868:219;31095:97;31183:2;31163:14;-1:-1;;31159:28;;31143:49;31200:117;31269:24;31287:5;31269:24;;;31262:5;31259:35;31249:2;;31308:1;31305;31298:12;31324:111;31390:21;31405:5;31390:21;;31442:117;31511:24;31529:5;31511:24;;31566:115;31634:23;31651:5;31634:23;;31812:113;31879:22;31895:5;31879:22;
Swarm Source
bzzr://1abf0281a4134fd3a54833042e0c0056deec0a09674bbe7eae1509f7715c9966
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.