Source Code
Overview
DEV Balance
0 DEV
More Info
ContractCreator:
Multichain Info
N/A
Latest 11 from a total of 11 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Claim Fees | 1965286 | 721 days ago | IN | 0 DEV | 0.00106667 | ||||
Claim Fees | 1951708 | 724 days ago | IN | 0 DEV | 0.00256675 | ||||
Claim Fees | 1951493 | 724 days ago | IN | 0 DEV | 0.00206164 | ||||
Allocate Fee Rew... | 1951486 | 724 days ago | IN | 0 DEV | 0.00062554 | ||||
Allocate Fee Rew... | 1951452 | 724 days ago | IN | 0 DEV | 0.00019023 | ||||
Close Current Fe... | 1951441 | 724 days ago | IN | 0 DEV | 0.00041643 | ||||
Allocate Fee Rew... | 1951434 | 724 days ago | IN | 0 DEV | 0.00055589 | ||||
Close Current Fe... | 1922370 | 730 days ago | IN | 0 DEV | 0.00041643 | ||||
Distribute Fee R... | 1922368 | 730 days ago | IN | 0 DEV | 0.0003423 | ||||
Close Current Fe... | 1922298 | 730 days ago | IN | 0 DEV | 0.00036071 | ||||
0x60806040 | 1428316 | 822 days ago | IN | Create: FeePool | 0 DEV | 0.0091933 |
Latest 25 internal transactions (View All)
Parent Txn Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
1989970 | 716 days ago | 0 DEV | ||||
1989970 | 716 days ago | 0 DEV | ||||
1989970 | 716 days ago | 0 DEV | ||||
1989970 | 716 days ago | 0 DEV | ||||
1989970 | 716 days ago | 0 DEV | ||||
1989970 | 716 days ago | 0 DEV | ||||
1989970 | 716 days ago | 0 DEV | ||||
1989968 | 716 days ago | 0 DEV | ||||
1989968 | 716 days ago | 0 DEV | ||||
1989968 | 716 days ago | 0 DEV | ||||
1989968 | 716 days ago | 0 DEV | ||||
1989968 | 716 days ago | 0 DEV | ||||
1989968 | 716 days ago | 0 DEV | ||||
1989968 | 716 days ago | 0 DEV | ||||
1989959 | 716 days ago | 0 DEV | ||||
1989959 | 716 days ago | 0 DEV | ||||
1989861 | 716 days ago | 0 DEV | ||||
1989861 | 716 days ago | 0 DEV | ||||
1989861 | 716 days ago | 0 DEV | ||||
1989861 | 716 days ago | 0 DEV | ||||
1989861 | 716 days ago | 0 DEV | ||||
1989861 | 716 days ago | 0 DEV | ||||
1989861 | 716 days ago | 0 DEV | ||||
1989859 | 716 days ago | 0 DEV | ||||
1989859 | 716 days ago | 0 DEV |
Loading...
Loading
This contract contains unverified libraries: SafeDecimalMath
Contract Name:
FeePool
Compiler Version
v0.5.16+commit.9c3226ce
Contract Source Code (Solidity)
/** *Submitted for verification at moonbase.moonscan.io on 2021-12-28 */ /* ___ _ ___ _ | .\ ___ _ _ <_> ___ | __><_>._ _ ___ ._ _ ___ ___ | _// ._>| '_>| ||___|| _> | || ' |<_> || ' |/ | '/ ._> |_| \___.|_| |_| |_| |_||_|_|<___||_|_|\_|_.\___. * PeriFinance: FeePool.sol * * Latest source (may be newer): https://github.com/perifinance/peri-finance/blob/master/contracts/FeePool.sol * Docs: Will be added in the future. * https://docs.peri.finance/contracts/source/contracts/FeePool * * Contract Dependencies: * - EternalStorage * - IAddressResolver * - IFeePool * - LimitedSetup * - MixinResolver * - MixinSystemSettings * - Owned * - Proxyable * - State * Libraries: * - SafeDecimalMath * - SafeMath * - VestingEntries * * MIT License * =========== * * Copyright (c) 2021 PeriFinance * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity 0.5.16; // https://docs.peri.finance/contracts/source/contracts/owned contract Owned { address public owner; address public nominatedOwner; constructor(address _owner) public { require(_owner != address(0), "Owner address cannot be 0"); owner = _owner; emit OwnerChanged(address(0), _owner); } function nominateNewOwner(address _owner) external onlyOwner { nominatedOwner = _owner; emit OwnerNominated(_owner); } function acceptOwnership() external { require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership"); emit OwnerChanged(owner, nominatedOwner); owner = nominatedOwner; nominatedOwner = address(0); } modifier onlyOwner { _onlyOwner(); _; } function _onlyOwner() private view { require(msg.sender == owner, "Only the contract owner may perform this action"); } event OwnerNominated(address newOwner); event OwnerChanged(address oldOwner, address newOwner); } // Inheritance // Internal references // https://docs.peri.finance/contracts/source/contracts/proxy contract Proxy is Owned { Proxyable public target; constructor(address _owner) public Owned(_owner) {} function setTarget(Proxyable _target) external onlyOwner { target = _target; emit TargetUpdated(_target); } function _emit( bytes calldata callData, uint numTopics, bytes32 topic1, bytes32 topic2, bytes32 topic3, bytes32 topic4 ) external onlyTarget { uint size = callData.length; bytes memory _callData = callData; assembly { /* The first 32 bytes of callData contain its length (as specified by the abi). * Length is assumed to be a uint256 and therefore maximum of 32 bytes * in length. It is also leftpadded to be a multiple of 32 bytes. * This means moving call_data across 32 bytes guarantees we correctly access * the data itself. */ switch numTopics case 0 { log0(add(_callData, 32), size) } case 1 { log1(add(_callData, 32), size, topic1) } case 2 { log2(add(_callData, 32), size, topic1, topic2) } case 3 { log3(add(_callData, 32), size, topic1, topic2, topic3) } case 4 { log4(add(_callData, 32), size, topic1, topic2, topic3, topic4) } } } // solhint-disable no-complex-fallback function() external payable { // Mutable call setting Proxyable.messageSender as this is using call not delegatecall target.setMessageSender(msg.sender); assembly { let free_ptr := mload(0x40) calldatacopy(free_ptr, 0, calldatasize) /* We must explicitly forward ether to the underlying contract as well. */ let result := call(gas, sload(target_slot), callvalue, free_ptr, calldatasize, 0, 0) returndatacopy(free_ptr, 0, returndatasize) if iszero(result) { revert(free_ptr, returndatasize) } return(free_ptr, returndatasize) } } modifier onlyTarget { require(Proxyable(msg.sender) == target, "Must be proxy target"); _; } event TargetUpdated(Proxyable newTarget); } // Inheritance // Internal references // https://docs.peri.finance/contracts/source/contracts/proxyable contract Proxyable is Owned { // This contract should be treated like an abstract contract /* The proxy this contract exists behind. */ Proxy public proxy; Proxy public integrationProxy; /* The caller of the proxy, passed through to this contract. * Note that every function using this member must apply the onlyProxy or * optionalProxy modifiers, otherwise their invocations can use stale values. */ address public messageSender; constructor(address payable _proxy) internal { // This contract is abstract, and thus cannot be instantiated directly require(owner != address(0), "Owner must be set"); proxy = Proxy(_proxy); emit ProxyUpdated(_proxy); } function setProxy(address payable _proxy) external onlyOwner { proxy = Proxy(_proxy); emit ProxyUpdated(_proxy); } function setIntegrationProxy(address payable _integrationProxy) external onlyOwner { integrationProxy = Proxy(_integrationProxy); } function setMessageSender(address sender) external onlyProxy { messageSender = sender; } modifier onlyProxy { _onlyProxy(); _; } function _onlyProxy() private view { require(Proxy(msg.sender) == proxy || Proxy(msg.sender) == integrationProxy, "Only the proxy can call"); } modifier optionalProxy { _optionalProxy(); _; } function _optionalProxy() private { if (Proxy(msg.sender) != proxy && Proxy(msg.sender) != integrationProxy && messageSender != msg.sender) { messageSender = msg.sender; } } modifier optionalProxy_onlyOwner { _optionalProxy_onlyOwner(); _; } // solhint-disable-next-line func-name-mixedcase function _optionalProxy_onlyOwner() private { if (Proxy(msg.sender) != proxy && Proxy(msg.sender) != integrationProxy && messageSender != msg.sender) { messageSender = msg.sender; } require(messageSender == owner, "Owner only function"); } event ProxyUpdated(address proxyAddress); } // https://docs.peri.finance/contracts/source/contracts/limitedsetup contract LimitedSetup { uint public setupExpiryTime; /** * @dev LimitedSetup Constructor. * @param setupDuration The time the setup period will last for. */ constructor(uint setupDuration) internal { setupExpiryTime = now + setupDuration; } modifier onlyDuringSetup { require(now < setupExpiryTime, "Can only perform this action during setup"); _; } } // https://docs.peri.finance/contracts/source/interfaces/iaddressresolver interface IAddressResolver { function getAddress(bytes32 name) external view returns (address); function getPynth(bytes32 key) external view returns (address); function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address); } // https://docs.peri.finance/contracts/source/interfaces/ipynth interface IPynth { // Views function currencyKey() external view returns (bytes32); function transferablePynths(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 PeriFinance function burn(address account, uint amount) external; function issue(address account, uint amount) external; } // https://docs.peri.finance/contracts/source/interfaces/iissuer interface IIssuer { // Views function anyPynthOrPERIRateIsInvalid() external view returns (bool anyRateInvalid); function availableCurrencyKeys() external view returns (bytes32[] memory); function availablePynthCount() external view returns (uint); function availablePynths(uint index) external view returns (IPynth); function canBurnPynths(address account) external view returns (bool); function collateral(address account) external view returns (uint); function collateralisationRatio(address issuer) external view returns (uint); function collateralisationRatioAndAnyRatesInvalid(address _issuer) external view returns (uint cratio, bool anyRateIsInvalid); function debtBalanceOf(address issuer, bytes32 currencyKey) external view returns (uint debtBalance); function lastIssueEvent(address account) external view returns (uint); function maxIssuablePynths(address issuer) external view returns (uint maxIssuable); function externalTokenQuota( address _account, uint _addtionalpUSD, uint _addtionalExToken, bool _isIssue ) external view returns (uint); function remainingIssuablePynths(address issuer) external view returns ( uint maxIssuable, uint alreadyIssued, uint totalSystemDebt ); function pynths(bytes32 currencyKey) external view returns (IPynth); function getPynths(bytes32[] calldata currencyKeys) external view returns (IPynth[] memory); function pynthsByAddress(address pynthAddress) external view returns (bytes32); function totalIssuedPynths(bytes32 currencyKey, bool excludeEtherCollateral) external view returns (uint, bool); function transferablePeriFinanceAndAnyRateIsInvalid(address account, uint balance) external view returns (uint transferable, bool anyRateIsInvalid); function amountsToFitClaimable(address _account) external view returns (uint burnAmount, uint exTokenAmountToUnstake); // Restricted: used internally to PeriFinance function issuePynths( address _issuer, bytes32 _currencyKey, uint _issueAmount ) external; function issueMaxPynths(address _issuer) external; function issuePynthsToMaxQuota(address _issuer, bytes32 _currencyKey) external; function burnPynths( address _from, bytes32 _currencyKey, uint _burnAmount ) external; function fitToClaimable(address _from) external; function exit(address _from) external; function liquidateDelinquentAccount( address account, uint pusdAmount, address liquidator ) external returns (uint totalRedeemed, uint amountToLiquidate); } // Inheritance // Internal references // https://docs.peri.finance/contracts/source/contracts/addressresolver contract AddressResolver is Owned, IAddressResolver { mapping(bytes32 => address) public repository; constructor(address _owner) public Owned(_owner) {} /* ========== RESTRICTED FUNCTIONS ========== */ function importAddresses(bytes32[] calldata names, address[] calldata destinations) external onlyOwner { require(names.length == destinations.length, "Input lengths must match"); for (uint i = 0; i < names.length; i++) { bytes32 name = names[i]; address destination = destinations[i]; repository[name] = destination; emit AddressImported(name, destination); } } /* ========= PUBLIC FUNCTIONS ========== */ function rebuildCaches(MixinResolver[] calldata destinations) external { for (uint i = 0; i < destinations.length; i++) { destinations[i].rebuildCache(); } } /* ========== VIEWS ========== */ function areAddressesImported(bytes32[] calldata names, address[] calldata destinations) external view returns (bool) { for (uint i = 0; i < names.length; i++) { if (repository[names[i]] != destinations[i]) { return false; } } return true; } function getAddress(bytes32 name) external view returns (address) { return repository[name]; } function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address) { address _foundAddress = repository[name]; require(_foundAddress != address(0), reason); return _foundAddress; } function getPynth(bytes32 key) external view returns (address) { IIssuer issuer = IIssuer(repository["Issuer"]); require(address(issuer) != address(0), "Cannot find Issuer address"); return address(issuer.pynths(key)); } /* ========== EVENTS ========== */ event AddressImported(bytes32 name, address destination); } // solhint-disable payable-fallback // https://docs.peri.finance/contracts/source/contracts/readproxy contract ReadProxy is Owned { address public target; constructor(address _owner) public Owned(_owner) {} function setTarget(address _target) external onlyOwner { target = _target; emit TargetUpdated(target); } function() external { // The basics of a proxy read call // Note that msg.sender in the underlying will always be the address of this contract. assembly { calldatacopy(0, 0, calldatasize) // Use of staticcall - this will revert if the underlying function mutates state let result := staticcall(gas, sload(target_slot), 0, calldatasize, 0, 0) returndatacopy(0, 0, returndatasize) if iszero(result) { revert(0, returndatasize) } return(0, returndatasize) } } event TargetUpdated(address newTarget); } // Inheritance // Internal references // https://docs.peri.finance/contracts/source/contracts/mixinresolver contract MixinResolver { AddressResolver public resolver; mapping(bytes32 => address) private addressCache; constructor(address _resolver) internal { resolver = AddressResolver(_resolver); } /* ========== INTERNAL FUNCTIONS ========== */ function combineArrays(bytes32[] memory first, bytes32[] memory second) internal pure returns (bytes32[] memory combination) { combination = new bytes32[](first.length + second.length); for (uint i = 0; i < first.length; i++) { combination[i] = first[i]; } for (uint j = 0; j < second.length; j++) { combination[first.length + j] = second[j]; } } /* ========== PUBLIC FUNCTIONS ========== */ // Note: this function is public not external in order for it to be overridden and invoked via super in subclasses function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {} function rebuildCache() public { bytes32[] memory requiredAddresses = resolverAddressesRequired(); // The resolver must call this function whenver it updates its state for (uint i = 0; i < requiredAddresses.length; i++) { bytes32 name = requiredAddresses[i]; // Note: can only be invoked once the resolver has all the targets needed added address destination = resolver.requireAndGetAddress(name, string(abi.encodePacked("Resolver missing target: ", name))); addressCache[name] = destination; emit CacheUpdated(name, destination); } } /* ========== VIEWS ========== */ function isResolverCached() external view returns (bool) { bytes32[] memory requiredAddresses = resolverAddressesRequired(); for (uint i = 0; i < requiredAddresses.length; i++) { bytes32 name = requiredAddresses[i]; // false if our cache is invalid or if the resolver doesn't have the required address if (resolver.getAddress(name) != addressCache[name] || addressCache[name] == address(0)) { return false; } } return true; } /* ========== INTERNAL FUNCTIONS ========== */ function requireAndGetAddress(bytes32 name) internal view returns (address) { address _foundAddress = addressCache[name]; require(_foundAddress != address(0), string(abi.encodePacked("Missing address: ", name))); return _foundAddress; } /* ========== EVENTS ========== */ event CacheUpdated(bytes32 name, address destination); } // https://docs.peri.finance/contracts/source/interfaces/iflexiblestorage interface IFlexibleStorage { // Views function getUIntValue(bytes32 contractName, bytes32 record) external view returns (uint); function getUIntValues(bytes32 contractName, bytes32[] calldata records) external view returns (uint[] memory); function getIntValue(bytes32 contractName, bytes32 record) external view returns (int); function getIntValues(bytes32 contractName, bytes32[] calldata records) external view returns (int[] memory); function getAddressValue(bytes32 contractName, bytes32 record) external view returns (address); function getAddressValues(bytes32 contractName, bytes32[] calldata records) external view returns (address[] memory); function getBoolValue(bytes32 contractName, bytes32 record) external view returns (bool); function getBoolValues(bytes32 contractName, bytes32[] calldata records) external view returns (bool[] memory); function getBytes32Value(bytes32 contractName, bytes32 record) external view returns (bytes32); function getBytes32Values(bytes32 contractName, bytes32[] calldata records) external view returns (bytes32[] memory); // Mutative functions function deleteUIntValue(bytes32 contractName, bytes32 record) external; function deleteIntValue(bytes32 contractName, bytes32 record) external; function deleteAddressValue(bytes32 contractName, bytes32 record) external; function deleteBoolValue(bytes32 contractName, bytes32 record) external; function deleteBytes32Value(bytes32 contractName, bytes32 record) external; function setUIntValue( bytes32 contractName, bytes32 record, uint value ) external; function setUIntValues( bytes32 contractName, bytes32[] calldata records, uint[] calldata values ) external; function setIntValue( bytes32 contractName, bytes32 record, int value ) external; function setIntValues( bytes32 contractName, bytes32[] calldata records, int[] calldata values ) external; function setAddressValue( bytes32 contractName, bytes32 record, address value ) external; function setAddressValues( bytes32 contractName, bytes32[] calldata records, address[] calldata values ) external; function setBoolValue( bytes32 contractName, bytes32 record, bool value ) external; function setBoolValues( bytes32 contractName, bytes32[] calldata records, bool[] calldata values ) external; function setBytes32Value( bytes32 contractName, bytes32 record, bytes32 value ) external; function setBytes32Values( bytes32 contractName, bytes32[] calldata records, bytes32[] calldata values ) external; } // Internal references // https://docs.peri.finance/contracts/source/contracts/mixinsystemsettings contract MixinSystemSettings is MixinResolver { bytes32 internal constant SETTING_CONTRACT_NAME = "SystemSettings"; bytes32 internal constant SETTING_WAITING_PERIOD_SECS = "waitingPeriodSecs"; bytes32 internal constant SETTING_PRICE_DEVIATION_THRESHOLD_FACTOR = "priceDeviationThresholdFactor"; bytes32 internal constant SETTING_ISSUANCE_RATIO = "issuanceRatio"; bytes32 internal constant SETTING_FEE_PERIOD_DURATION = "feePeriodDuration"; bytes32 internal constant SETTING_TARGET_THRESHOLD = "targetThreshold"; bytes32 internal constant SETTING_LIQUIDATION_DELAY = "liquidationDelay"; bytes32 internal constant SETTING_LIQUIDATION_RATIO = "liquidationRatio"; bytes32 internal constant SETTING_LIQUIDATION_PENALTY = "liquidationPenalty"; bytes32 internal constant SETTING_RATE_STALE_PERIOD = "rateStalePeriod"; bytes32 internal constant SETTING_EXCHANGE_FEE_RATE = "exchangeFeeRate"; bytes32 internal constant SETTING_MINIMUM_STAKE_TIME = "minimumStakeTime"; bytes32 internal constant SETTING_AGGREGATOR_WARNING_FLAGS = "aggregatorWarningFlags"; bytes32 internal constant SETTING_TRADING_REWARDS_ENABLED = "tradingRewardsEnabled"; bytes32 internal constant SETTING_DEBT_SNAPSHOT_STALE_TIME = "debtSnapshotStaleTime"; bytes32 internal constant SETTING_CROSS_DOMAIN_DEPOSIT_GAS_LIMIT = "crossDomainDepositGasLimit"; bytes32 internal constant SETTING_CROSS_DOMAIN_ESCROW_GAS_LIMIT = "crossDomainEscrowGasLimit"; bytes32 internal constant SETTING_CROSS_DOMAIN_REWARD_GAS_LIMIT = "crossDomainRewardGasLimit"; bytes32 internal constant SETTING_CROSS_DOMAIN_WITHDRAWAL_GAS_LIMIT = "crossDomainWithdrawalGasLimit"; bytes32 internal constant SETTING_EXTERNAL_TOKEN_QUOTA = "externalTokenQuota"; bytes32 internal constant SETTING_BRIDGE_TRANSFER_GAS_COST = "bridgeTransferGasCost"; bytes32 internal constant SETTING_BRIDGE_CLAIM_GAS_COST = "bridgeClaimGasCost"; bytes32 internal constant CONTRACT_FLEXIBLESTORAGE = "FlexibleStorage"; enum CrossDomainMessageGasLimits {Deposit, Escrow, Reward, Withdrawal} constructor(address _resolver) internal MixinResolver(_resolver) {} function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { addresses = new bytes32[](1); addresses[0] = CONTRACT_FLEXIBLESTORAGE; } function flexibleStorage() internal view returns (IFlexibleStorage) { return IFlexibleStorage(requireAndGetAddress(CONTRACT_FLEXIBLESTORAGE)); } function _getGasLimitSetting(CrossDomainMessageGasLimits gasLimitType) internal pure returns (bytes32) { if (gasLimitType == CrossDomainMessageGasLimits.Deposit) { return SETTING_CROSS_DOMAIN_DEPOSIT_GAS_LIMIT; } else if (gasLimitType == CrossDomainMessageGasLimits.Escrow) { return SETTING_CROSS_DOMAIN_ESCROW_GAS_LIMIT; } else if (gasLimitType == CrossDomainMessageGasLimits.Reward) { return SETTING_CROSS_DOMAIN_REWARD_GAS_LIMIT; } else if (gasLimitType == CrossDomainMessageGasLimits.Withdrawal) { return SETTING_CROSS_DOMAIN_WITHDRAWAL_GAS_LIMIT; } else { revert("Unknown gas limit type"); } } function getCrossDomainMessageGasLimit(CrossDomainMessageGasLimits gasLimitType) internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, _getGasLimitSetting(gasLimitType)); } function getTradingRewardsEnabled() internal view returns (bool) { return flexibleStorage().getBoolValue(SETTING_CONTRACT_NAME, SETTING_TRADING_REWARDS_ENABLED); } function getWaitingPeriodSecs() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_WAITING_PERIOD_SECS); } function getPriceDeviationThresholdFactor() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_PRICE_DEVIATION_THRESHOLD_FACTOR); } function getIssuanceRatio() internal view returns (uint) { // lookup on flexible storage directly for gas savings (rather than via SystemSettings) return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_ISSUANCE_RATIO); } function getFeePeriodDuration() internal view returns (uint) { // lookup on flexible storage directly for gas savings (rather than via SystemSettings) return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_FEE_PERIOD_DURATION); } function getTargetThreshold() internal view returns (uint) { // lookup on flexible storage directly for gas savings (rather than via SystemSettings) return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_TARGET_THRESHOLD); } function getLiquidationDelay() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_DELAY); } function getLiquidationRatio() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_RATIO); } function getLiquidationPenalty() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_LIQUIDATION_PENALTY); } function getRateStalePeriod() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_RATE_STALE_PERIOD); } function getExchangeFeeRate(bytes32 currencyKey) internal view returns (uint) { return flexibleStorage().getUIntValue( SETTING_CONTRACT_NAME, keccak256(abi.encodePacked(SETTING_EXCHANGE_FEE_RATE, currencyKey)) ); } function getMinimumStakeTime() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_MINIMUM_STAKE_TIME); } function getAggregatorWarningFlags() internal view returns (address) { return flexibleStorage().getAddressValue(SETTING_CONTRACT_NAME, SETTING_AGGREGATOR_WARNING_FLAGS); } function getDebtSnapshotStaleTime() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_DEBT_SNAPSHOT_STALE_TIME); } function getExternalTokenQuota() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_EXTERNAL_TOKEN_QUOTA); } function getBridgeTransferGasCost() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_BRIDGE_TRANSFER_GAS_COST); } function getBridgeClaimGasCost() internal view returns (uint) { return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_BRIDGE_CLAIM_GAS_COST); } } // https://docs.peri.finance/contracts/source/interfaces/ifeepool interface IFeePool { // Views // solhint-disable-next-line func-name-mixedcase function FEE_ADDRESS() external view returns (address); function feesAvailable(address account) external view returns (uint, uint); function feePeriodDuration() external view returns (uint); function isFeesClaimable(address account) external view returns (bool); function targetThreshold() external view returns (uint); function totalFeesAvailable() external view returns (uint); function totalRewardsAvailable() external view returns (uint); function everDistributedFeeRewards() external view returns (bool); function everAllocatedFeeRewards() external view returns (bool); // Mutative Functions function claimFees() external returns (bool); function claimOnBehalf(address claimingForAddress) external returns (bool); function closeCurrentFeePeriod() external; // Restricted: used internally to PeriFinance function appendAccountIssuanceRecord( address account, uint lockedAmount, uint debtEntryIndex ) external; function recordFeePaid(uint pUSDAmount) external; function setRewardsToDistribute(uint amount) external; function distributeFeeRewards() external; function allocateFeeRewards(uint amount) external; } /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // Libraries // https://docs.peri.finance/contracts/source/libraries/safedecimalmath library SafeDecimalMath { using SafeMath for uint; /* Number of decimal places in the representations. */ uint8 public constant decimals = 18; uint8 public constant highPrecisionDecimals = 27; /* The number representing 1.0. */ uint public constant UNIT = 10**uint(decimals); /* The number representing 1.0 for higher fidelity numbers. */ uint public constant PRECISE_UNIT = 10**uint(highPrecisionDecimals); uint private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR = 10**uint(highPrecisionDecimals - decimals); /** * @return Provides an interface to UNIT. */ function unit() external pure returns (uint) { return UNIT; } /** * @return Provides an interface to PRECISE_UNIT. */ function preciseUnit() external pure returns (uint) { return PRECISE_UNIT; } /** * @return The result of multiplying x and y, interpreting the operands as fixed-point * decimals. * * @dev A unit factor is divided out after the product of x and y is evaluated, * so that product must be less than 2**256. As this is an integer division, * the internal division always rounds down. This helps save on gas. Rounding * is more expensive on gas. */ function multiplyDecimal(uint x, uint y) internal pure returns (uint) { /* Divide by UNIT to remove the extra factor introduced by the product. */ return x.mul(y) / UNIT; } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of the specified precision unit. * * @dev The operands should be in the form of a the specified unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function _multiplyDecimalRound( uint x, uint y, uint precisionUnit ) private pure returns (uint) { /* Divide by UNIT to remove the extra factor introduced by the product. */ uint quotientTimesTen = x.mul(y) / (precisionUnit / 10); if (quotientTimesTen % 10 >= 5) { quotientTimesTen += 10; } return quotientTimesTen / 10; } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of a precise unit. * * @dev The operands should be in the precise unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function multiplyDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) { return _multiplyDecimalRound(x, y, PRECISE_UNIT); } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of a standard unit. * * @dev The operands should be in the standard unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function multiplyDecimalRound(uint x, uint y) internal pure returns (uint) { return _multiplyDecimalRound(x, y, UNIT); } /** * @return The result of safely dividing x and y. The return value is a high * precision decimal. * * @dev y is divided after the product of x and the standard precision unit * is evaluated, so the product of x and UNIT must be less than 2**256. As * this is an integer division, the result is always rounded down. * This helps save on gas. Rounding is more expensive on gas. */ function divideDecimal(uint x, uint y) internal pure returns (uint) { /* Reintroduce the UNIT factor that will be divided out by y. */ return x.mul(UNIT).div(y); } /** * @return The result of safely dividing x and y. The return value is as a rounded * decimal in the precision unit specified in the parameter. * * @dev y is divided after the product of x and the specified precision unit * is evaluated, so the product of x and the specified precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function _divideDecimalRound( uint x, uint y, uint precisionUnit ) private pure returns (uint) { uint resultTimesTen = x.mul(precisionUnit * 10).div(y); if (resultTimesTen % 10 >= 5) { resultTimesTen += 10; } return resultTimesTen / 10; } /** * @return The result of safely dividing x and y. The return value is as a rounded * standard precision decimal. * * @dev y is divided after the product of x and the standard precision unit * is evaluated, so the product of x and the standard precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function divideDecimalRound(uint x, uint y) internal pure returns (uint) { return _divideDecimalRound(x, y, UNIT); } /** * @return The result of safely dividing x and y. The return value is as a rounded * high precision decimal. * * @dev y is divided after the product of x and the high precision unit * is evaluated, so the product of x and the high precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function divideDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) { return _divideDecimalRound(x, y, PRECISE_UNIT); } /** * @dev Convert a standard decimal representation to a high precision one. */ function decimalToPreciseDecimal(uint i) internal pure returns (uint) { return i.mul(UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR); } /** * @dev Convert a high precision decimal to a standard decimal representation. */ function preciseDecimalToDecimal(uint i) internal pure returns (uint) { uint quotientTimesTen = i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10); if (quotientTimesTen % 10 >= 5) { quotientTimesTen += 10; } return quotientTimesTen / 10; } /** * @dev Round down the value with given number */ function roundDownDecimal(uint x, uint d) internal pure returns (uint) { return x.div(10**d).mul(10**d); } /** * @dev Round up the value with given number */ function roundUpDecimal(uint x, uint d) internal pure returns (uint) { uint _decimal = 10**d; if (x % _decimal > 0) { x = x.add(10**d); } return x.div(_decimal).mul(_decimal); } } // https://docs.peri.finance/contracts/source/interfaces/ierc20 interface IERC20 { // ERC20 Optional Views function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); // Views function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); // Mutative functions function transfer(address to, uint value) external returns (bool); function approve(address spender, uint value) external returns (bool); function transferFrom( address from, address to, uint value ) external returns (bool); // Events event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); } // https://docs.peri.finance/contracts/source/interfaces/isystemstatus interface ISystemStatus { struct Status { bool canSuspend; bool canResume; } struct Suspension { bool suspended; // reason is an integer code, // 0 => no reason, 1 => upgrading, 2+ => defined by system usage uint248 reason; } // Views function accessControl(bytes32 section, address account) external view returns (bool canSuspend, bool canResume); function requireSystemActive() external view; function requireIssuanceActive() external view; function requireExchangeActive() external view; function requireExchangeBetweenPynthsAllowed(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) external view; function requirePynthActive(bytes32 currencyKey) external view; function requirePynthsActive(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) external view; function systemSuspension() external view returns (bool suspended, uint248 reason); function issuanceSuspension() external view returns (bool suspended, uint248 reason); function exchangeSuspension() external view returns (bool suspended, uint248 reason); function pynthExchangeSuspension(bytes32 currencyKey) external view returns (bool suspended, uint248 reason); function pynthSuspension(bytes32 currencyKey) external view returns (bool suspended, uint248 reason); function getPynthExchangeSuspensions(bytes32[] calldata pynths) external view returns (bool[] memory exchangeSuspensions, uint256[] memory reasons); function getPynthSuspensions(bytes32[] calldata pynths) external view returns (bool[] memory suspensions, uint256[] memory reasons); // Restricted functions function suspendPynth(bytes32 currencyKey, uint256 reason) external; function updateAccessControl( bytes32 section, address account, bool canSuspend, bool canResume ) external; } interface IVirtualPynth { // 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 pynth() external view returns (IPynth); // Mutative functions function settle(address account) external; } // https://docs.peri.finance/contracts/source/interfaces/iperiFinance interface IPeriFinance { // Views function getRequiredAddress(bytes32 contractName) external view returns (address); function anyPynthOrPERIRateIsInvalid() external view returns (bool anyRateInvalid); function availableCurrencyKeys() external view returns (bytes32[] memory); function availablePynthCount() external view returns (uint); function availablePynths(uint index) external view returns (IPynth); 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 maxIssuablePynths(address issuer) external view returns (uint maxIssuable); function remainingIssuablePynths(address issuer) external view returns ( uint maxIssuable, uint alreadyIssued, uint totalSystemDebt ); function pynths(bytes32 currencyKey) external view returns (IPynth); function pynthsByAddress(address pynthAddress) external view returns (bytes32); function totalIssuedPynths(bytes32 currencyKey) external view returns (uint); function totalIssuedPynthsExcludeEtherCollateral(bytes32 currencyKey) external view returns (uint); function transferablePeriFinance(address account) external view returns (uint transferable); function amountsToFitClaimable(address account) external view returns (uint burnAmount, uint exTokenAmountToUnstake); // Mutative Functions function issuePynths(bytes32 _currencyKey, uint _issueAmount) external; function issueMaxPynths() external; function issuePynthsToMaxQuota(bytes32 _currencyKey) external; function burnPynths(bytes32 _currencyKey, uint _burnAmount) external; function fitToClaimable() external; function exit() 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, IVirtualPynth vPynth); function mint(address _user, uint _amount) external returns (bool); function inflationalMint(uint _networkDebtShare) external returns (bool); function settle(bytes32 currencyKey) external returns ( uint reclaimed, uint refunded, uint numEntries ); // Liquidations function liquidateDelinquentAccount(address account, uint pusdAmount) external returns (bool); // Restricted Functions function mintSecondary(address account, uint amount) external; function mintSecondaryRewards(uint amount) external; function burnSecondary(address account, uint amount) external; } // Inheritance // Libraries // Internal references // https://docs.peri.finance/contracts/source/contracts/feepoolstate contract FeePoolState is Owned, LimitedSetup { using SafeMath for uint; using SafeDecimalMath for uint; /* ========== STATE VARIABLES ========== */ uint8 public constant FEE_PERIOD_LENGTH = 6; address public feePool; // The IssuanceData activity that's happened in a fee period. struct IssuanceData { uint debtPercentage; uint debtEntryIndex; } // The IssuanceData activity that's happened in a fee period. mapping(address => IssuanceData[FEE_PERIOD_LENGTH]) public accountIssuanceLedger; constructor(address _owner, IFeePool _feePool) public Owned(_owner) LimitedSetup(6 weeks) { feePool = address(_feePool); } /* ========== SETTERS ========== */ /** * @notice set the FeePool contract as it is the only authority to be able to call * appendAccountIssuanceRecord with the onlyFeePool modifer * @dev Must be set by owner when FeePool logic is upgraded */ function setFeePool(IFeePool _feePool) external onlyOwner { feePool = address(_feePool); } /* ========== VIEWS ========== */ /** * @notice Get an accounts issuanceData for * @param account users account * @param index Index in the array to retrieve. Upto FEE_PERIOD_LENGTH */ function getAccountsDebtEntry(address account, uint index) public view returns (uint debtPercentage, uint debtEntryIndex) { require(index < FEE_PERIOD_LENGTH, "index exceeds the FEE_PERIOD_LENGTH"); debtPercentage = accountIssuanceLedger[account][index].debtPercentage; debtEntryIndex = accountIssuanceLedger[account][index].debtEntryIndex; } /** * @notice Find the oldest debtEntryIndex for the corresponding closingDebtIndex * @param account users account * @param closingDebtIndex the last periods debt index on close */ function applicableIssuanceData(address account, uint closingDebtIndex) external view returns (uint, uint) { IssuanceData[FEE_PERIOD_LENGTH] memory issuanceData = accountIssuanceLedger[account]; // We want to use the user's debtEntryIndex at when the period closed // Find the oldest debtEntryIndex for the corresponding closingDebtIndex for (uint i = 0; i < FEE_PERIOD_LENGTH; i++) { if (closingDebtIndex >= issuanceData[i].debtEntryIndex) { return (issuanceData[i].debtPercentage, issuanceData[i].debtEntryIndex); } } } /* ========== MUTATIVE FUNCTIONS ========== */ /** * @notice Logs an accounts issuance data in the current fee period which is then stored historically * @param account Message.Senders account address * @param debtRatio Debt of this account as a percentage of the global debt. * @param debtEntryIndex The index in the global debt ledger. periFinance.periFinanceState().issuanceData(account) * @param currentPeriodStartDebtIndex The startingDebtIndex of the current fee period * @dev onlyFeePool to call me on periFinance.issue() & periFinance.burn() calls to store the locked PERI * per fee period so we know to allocate the correct proportions of fees and rewards per period accountIssuanceLedger[account][0] has the latest locked amount for the current period. This can be update as many time accountIssuanceLedger[account][1-2] has the last locked amount for a previous period they minted or burned */ function appendAccountIssuanceRecord( address account, uint debtRatio, uint debtEntryIndex, uint currentPeriodStartDebtIndex ) external onlyFeePool { // Is the current debtEntryIndex within this fee period if (accountIssuanceLedger[account][0].debtEntryIndex < currentPeriodStartDebtIndex) { // If its older then shift the previous IssuanceData entries periods down to make room for the new one. issuanceDataIndexOrder(account); } // Always store the latest IssuanceData entry at [0] accountIssuanceLedger[account][0].debtPercentage = debtRatio; accountIssuanceLedger[account][0].debtEntryIndex = debtEntryIndex; } /** * @notice Pushes down the entire array of debt ratios per fee period */ function issuanceDataIndexOrder(address account) private { for (uint i = FEE_PERIOD_LENGTH - 2; i < FEE_PERIOD_LENGTH; i--) { uint next = i + 1; accountIssuanceLedger[account][next].debtPercentage = accountIssuanceLedger[account][i].debtPercentage; accountIssuanceLedger[account][next].debtEntryIndex = accountIssuanceLedger[account][i].debtEntryIndex; } } /** * @notice Import issuer data from periFinanceState.issuerData on FeePeriodClose() block # * @dev Only callable by the contract owner, and only for 6 weeks after deployment. * @param accounts Array of issuing addresses * @param ratios Array of debt ratios * @param periodToInsert The Fee Period to insert the historical records into * @param feePeriodCloseIndex An accounts debtEntryIndex is valid when within the fee peroid, * since the input ratio will be an average of the pervious periods it just needs to be * > recentFeePeriods[periodToInsert].startingDebtIndex * < recentFeePeriods[periodToInsert - 1].startingDebtIndex */ function importIssuerData( address[] calldata accounts, uint[] calldata ratios, uint periodToInsert, uint feePeriodCloseIndex ) external onlyOwner onlyDuringSetup { require(accounts.length == ratios.length, "Length mismatch"); for (uint i = 0; i < accounts.length; i++) { accountIssuanceLedger[accounts[i]][periodToInsert].debtPercentage = ratios[i]; accountIssuanceLedger[accounts[i]][periodToInsert].debtEntryIndex = feePeriodCloseIndex; emit IssuanceDebtRatioEntry(accounts[i], ratios[i], feePeriodCloseIndex); } } /* ========== MODIFIERS ========== */ modifier onlyFeePool { require(msg.sender == address(feePool), "Only the FeePool contract can perform this action"); _; } /* ========== Events ========== */ event IssuanceDebtRatioEntry(address indexed account, uint debtRatio, uint feePeriodCloseIndex); } // Inheritance // https://docs.peri.finance/contracts/source/contracts/state contract State is Owned { // the address of the contract that can modify variables // this can only be changed by the owner of this contract address public associatedContract; constructor(address _associatedContract) internal { // This contract is abstract, and thus cannot be instantiated directly require(owner != address(0), "Owner must be set"); associatedContract = _associatedContract; emit AssociatedContractUpdated(_associatedContract); } /* ========== SETTERS ========== */ // Change the associated contract to a new address function setAssociatedContract(address _associatedContract) external onlyOwner { associatedContract = _associatedContract; emit AssociatedContractUpdated(_associatedContract); } /* ========== MODIFIERS ========== */ modifier onlyAssociatedContract { require(msg.sender == associatedContract, "Only the associated contract can perform this action"); _; } /* ========== EVENTS ========== */ event AssociatedContractUpdated(address associatedContract); } // Inheritance // https://docs.peri.finance/contracts/source/contracts/eternalstorage /** * @notice This contract is based on the code available from this blog * https://blog.colony.io/writing-upgradeable-contracts-in-solidity-6743f0eecc88/ * Implements support for storing a keccak256 key and value pairs. It is the more flexible * and extensible option. This ensures data schema changes can be implemented without * requiring upgrades to the storage contract. */ contract EternalStorage is Owned, State { constructor(address _owner, address _associatedContract) public Owned(_owner) State(_associatedContract) {} /* ========== DATA TYPES ========== */ mapping(bytes32 => uint) internal UIntStorage; mapping(bytes32 => string) internal StringStorage; mapping(bytes32 => address) internal AddressStorage; mapping(bytes32 => bytes) internal BytesStorage; mapping(bytes32 => bytes32) internal Bytes32Storage; mapping(bytes32 => bool) internal BooleanStorage; mapping(bytes32 => int) internal IntStorage; // UIntStorage; function getUIntValue(bytes32 record) external view returns (uint) { return UIntStorage[record]; } function setUIntValue(bytes32 record, uint value) external onlyAssociatedContract { UIntStorage[record] = value; } function deleteUIntValue(bytes32 record) external onlyAssociatedContract { delete UIntStorage[record]; } // StringStorage function getStringValue(bytes32 record) external view returns (string memory) { return StringStorage[record]; } function setStringValue(bytes32 record, string calldata value) external onlyAssociatedContract { StringStorage[record] = value; } function deleteStringValue(bytes32 record) external onlyAssociatedContract { delete StringStorage[record]; } // AddressStorage function getAddressValue(bytes32 record) external view returns (address) { return AddressStorage[record]; } function setAddressValue(bytes32 record, address value) external onlyAssociatedContract { AddressStorage[record] = value; } function deleteAddressValue(bytes32 record) external onlyAssociatedContract { delete AddressStorage[record]; } // BytesStorage function getBytesValue(bytes32 record) external view returns (bytes memory) { return BytesStorage[record]; } function setBytesValue(bytes32 record, bytes calldata value) external onlyAssociatedContract { BytesStorage[record] = value; } function deleteBytesValue(bytes32 record) external onlyAssociatedContract { delete BytesStorage[record]; } // Bytes32Storage function getBytes32Value(bytes32 record) external view returns (bytes32) { return Bytes32Storage[record]; } function setBytes32Value(bytes32 record, bytes32 value) external onlyAssociatedContract { Bytes32Storage[record] = value; } function deleteBytes32Value(bytes32 record) external onlyAssociatedContract { delete Bytes32Storage[record]; } // BooleanStorage function getBooleanValue(bytes32 record) external view returns (bool) { return BooleanStorage[record]; } function setBooleanValue(bytes32 record, bool value) external onlyAssociatedContract { BooleanStorage[record] = value; } function deleteBooleanValue(bytes32 record) external onlyAssociatedContract { delete BooleanStorage[record]; } // IntStorage function getIntValue(bytes32 record) external view returns (int) { return IntStorage[record]; } function setIntValue(bytes32 record, int value) external onlyAssociatedContract { IntStorage[record] = value; } function deleteIntValue(bytes32 record) external onlyAssociatedContract { delete IntStorage[record]; } } // Inheritance // https://docs.peri.finance/contracts/source/contracts/feepooleternalstorage contract FeePoolEternalStorage is EternalStorage, LimitedSetup { bytes32 internal constant LAST_FEE_WITHDRAWAL = "last_fee_withdrawal"; constructor(address _owner, address _feePool) public EternalStorage(_owner, _feePool) LimitedSetup(6 weeks) {} function importFeeWithdrawalData(address[] calldata accounts, uint[] calldata feePeriodIDs) external onlyOwner onlyDuringSetup { require(accounts.length == feePeriodIDs.length, "Length mismatch"); for (uint8 i = 0; i < accounts.length; i++) { this.setUIntValue(keccak256(abi.encodePacked(LAST_FEE_WITHDRAWAL, accounts[i])), feePeriodIDs[i]); } } } // https://docs.peri.finance/contracts/source/interfaces/iexchanger interface IExchanger { // Views function calculateAmountAfterSettlement( address from, bytes32 currencyKey, uint amount, uint refunded ) external view returns (uint amountAfterSettlement); function isPynthRateInvalid(bytes32 currencyKey) external view returns (bool); function maxSecsLeftInWaitingPeriod(address account, bytes32 currencyKey) external view returns (uint); function settlementOwing(address account, bytes32 currencyKey) external view returns ( uint reclaimAmount, uint rebateAmount, uint numEntries ); function hasWaitingPeriodOrSettlementOwing(address account, bytes32 currencyKey) external view returns (bool); function feeRateForExchange(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) external view returns (uint exchangeFeeRate); function getAmountsForExchange( uint sourceAmount, bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey ) external view returns ( uint amountReceived, uint fee, uint exchangeFeeRate ); function priceDeviationThresholdFactor() external view returns (uint); function waitingPeriodSecs() external view returns (uint); // Mutative functions function exchange( address from, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address destinationAddress ) external returns (uint amountReceived); function exchangeOnBehalf( address exchangeForAddress, address from, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external returns (uint amountReceived); function exchangeWithTracking( address from, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address destinationAddress, address originator, bytes32 trackingCode ) external returns (uint amountReceived); function exchangeOnBehalfWithTracking( address exchangeForAddress, address from, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address originator, bytes32 trackingCode ) external returns (uint amountReceived); function exchangeWithVirtual( address from, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address destinationAddress, bytes32 trackingCode ) external returns (uint amountReceived, IVirtualPynth vPynth); function settle(address from, bytes32 currencyKey) external returns ( uint reclaimed, uint refunded, uint numEntries ); function setLastExchangeRateForPynth(bytes32 currencyKey, uint rate) external; function suspendPynthWithInvalidRate(bytes32 currencyKey) external; } // https://docs.peri.finance/contracts/source/interfaces/iperiFinancestate interface IPeriFinanceState { // 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; } 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 PERI transfered to PeriFinanceBridgeToOptimism deposit contract function burnForMigration(address account, uint256[] calldata entryIDs) external returns (uint256 escrowedAccountBalance, VestingEntries.VestingEntry[] memory vestingEntries); } // https://docs.peri.finance/contracts/source/interfaces/idelegateapprovals interface IDelegateApprovals { // Views function canBurnFor(address authoriser, address delegate) external view returns (bool); function canIssueFor(address authoriser, address delegate) external view returns (bool); function canClaimFor(address authoriser, address delegate) external view returns (bool); function canExchangeFor(address authoriser, address delegate) external view returns (bool); // Mutative function approveAllDelegatePowers(address delegate) external; function removeAllDelegatePowers(address delegate) external; function approveBurnOnBehalf(address delegate) external; function removeBurnOnBehalf(address delegate) external; function approveIssueOnBehalf(address delegate) external; function removeIssueOnBehalf(address delegate) external; function approveClaimOnBehalf(address delegate) external; function removeClaimOnBehalf(address delegate) external; function approveExchangeOnBehalf(address delegate) external; function removeExchangeOnBehalf(address delegate) external; } // https://docs.peri.finance/contracts/source/interfaces/irewardsdistribution interface IRewardsDistribution { // Structs struct DistributionData { address destination; uint amount; } // Views function authority() external view returns (address); function distributions(uint index) external view returns (address destination, uint amount); // DistributionData function distributionsLength() external view returns (uint); // Mutative Functions function distributeRewards(uint amount) external returns (bool); } // https://docs.peri.finance/contracts/source/interfaces/iethercollateralsusd interface IEtherCollateralpUSD { // Views function totalIssuedPynths() external view returns (uint256); function totalLoansCreated() external view returns (uint256); function totalOpenLoanCount() external view returns (uint256); // Mutative functions function openLoan(uint256 _loanAmount) external payable returns (uint256 loanID); function closeLoan(uint256 loanID) external; function liquidateUnclosedLoan(address _loanCreatorsAddress, uint256 _loanID) external; function depositCollateral(address account, uint256 loanID) external payable; function withdrawCollateral(uint256 loanID, uint256 withdrawAmount) external; function repayLoan( address _loanCreatorsAddress, uint256 _loanID, uint256 _repayAmount ) external; } interface ICollateralManager { // Manager information function hasCollateral(address collateral) external view returns (bool); function isPynthManaged(bytes32 currencyKey) external view returns (bool); // State information function long(bytes32 pynth) external view returns (uint amount); function short(bytes32 pynth) external view returns (uint amount); function totalLong() external view returns (uint pusdValue, bool anyRateIsInvalid); function totalShort() external view returns (uint pusdValue, bool anyRateIsInvalid); function getBorrowRate() external view returns (uint borrowRate, bool anyRateIsInvalid); function getShortRate(bytes32 pynth) external view returns (uint shortRate, bool rateIsInvalid); function getRatesAndTime(uint index) external view returns ( uint entryRate, uint lastRate, uint lastUpdated, uint newIndex ); function getShortRatesAndTime(bytes32 currency, uint index) external view returns ( uint entryRate, uint lastRate, uint lastUpdated, uint newIndex ); function exceedsDebtLimit(uint amount, bytes32 currency) external view returns (bool canIssue, bool anyRateIsInvalid); function arePynthsAndCurrenciesSet(bytes32[] calldata requiredPynthNamesInResolver, bytes32[] calldata pynthKeys) external view returns (bool); function areShortablePynthsSet(bytes32[] calldata requiredPynthNamesInResolver, bytes32[] calldata pynthKeys) external view returns (bool); // Loans function getNewLoanId() external returns (uint id); // Manager mutative function addCollaterals(address[] calldata collaterals) external; function removeCollaterals(address[] calldata collaterals) external; function addPynths(bytes32[] calldata pynthNamesInResolver, bytes32[] calldata pynthKeys) external; function removePynths(bytes32[] calldata pynths, bytes32[] calldata pynthKeys) external; function addShortablePynths(bytes32[2][] calldata requiredPynthAndInverseNamesInResolver, bytes32[] calldata pynthKeys) external; function removeShortablePynths(bytes32[] calldata pynths) external; // State mutative function updateBorrowRates(uint rate) external; function updateShortRates(bytes32 currency, uint rate) external; function incrementLongs(bytes32 pynth, uint amount) external; function decrementLongs(bytes32 pynth, uint amount) external; function incrementShorts(bytes32 pynth, uint amount) external; function decrementShorts(bytes32 pynth, uint amount) external; } interface ICrossChainManager { // View Functions function crossChainState() external view returns (address); function debtManager() external view returns (address); function userIssuanceDataForTotalNetwork(address) external view returns (uint, uint); function getTotalNetworkAdaptedTotalSystemValue(bytes32 currencyKey) external view returns (uint, bool); function currentTotalNetworkDebt() external view returns (uint); function totalNetworkDebtAtIndex(uint index) external view returns (uint); function networkDebtPercentageAtIndex(uint) external view returns (uint); function totalNetworkDebtEntryLength() external view returns (uint); function currentNetworkDebtPercentage() external view returns (uint); // Mutative functions function setCrossChainState(address) external; function setDebtManager(address) external; function appendTotalNetworkDebt(uint) external; function addTotalNetworkDebt(uint) external; function subtractTotalNetworkDebt(uint) external; function setCrossNetworkUserDebt(address, uint) external; function clearCrossNetworkUserDebt(address) external; } // Inheritance // Libraries // Internal references // https://docs.peri.finance/contracts/source/contracts/feepool contract FeePool is Owned, Proxyable, LimitedSetup, MixinSystemSettings, IFeePool { using SafeMath for uint; using SafeDecimalMath for uint; // Where fees are pooled in pUSD. address public constant FEE_ADDRESS = 0xfeEFEEfeefEeFeefEEFEEfEeFeefEEFeeFEEFEeF; // pUSD currencyKey. Fees stored and paid in pUSD bytes32 private pUSD = "pUSD"; // This struct represents the issuance activity that's happened in a fee period. struct FeePeriod { uint64 feePeriodId; uint64 startingDebtIndex; uint64 startTime; uint feesToDistribute; uint feesClaimed; uint rewardsToDistribute; uint rewardsClaimed; } // A staker(mintr) can claim from the previous fee period (7 days) only. // Fee Periods stored and managed from [0], such that [0] is always // the current active fee period which is not claimable until the // public function closeCurrentFeePeriod() is called closing the // current weeks collected fees. [1] is last weeks feeperiod uint8 public constant FEE_PERIOD_LENGTH = 2; FeePeriod[FEE_PERIOD_LENGTH] private _recentFeePeriods; uint256 private _currentFeePeriod; bool private _everDistributedFeeRewards; bool private _everAllocatedFeeRewards; uint256 public feeRewardsToBeAllocated; uint256 public quotaTolerance; /* ========== ADDRESS RESOLVER CONFIGURATION ========== */ bytes32 private constant CONTRACT_SYSTEMSTATUS = "SystemStatus"; bytes32 private constant CONTRACT_PERIFINANCE = "PeriFinance"; bytes32 private constant CONTRACT_FEEPOOLSTATE = "FeePoolState"; bytes32 private constant CONTRACT_FEEPOOLETERNALSTORAGE = "FeePoolEternalStorage"; bytes32 private constant CONTRACT_EXCHANGER = "Exchanger"; bytes32 private constant CONTRACT_ISSUER = "Issuer"; bytes32 private constant CONTRACT_PERIFINANCESTATE = "PeriFinanceState"; bytes32 private constant CONTRACT_REWARDESCROW_V2 = "RewardEscrowV2"; bytes32 private constant CONTRACT_DELEGATEAPPROVALS = "DelegateApprovals"; bytes32 private constant CONTRACT_ETH_COLLATERAL_PUSD = "EtherCollateralpUSD"; bytes32 private constant CONTRACT_COLLATERALMANAGER = "CollateralManager"; bytes32 private constant CONTRACT_REWARDSDISTRIBUTION = "RewardsDistribution"; bytes32 private constant CONTRACT_CROSSCHAINMANAGER = "CrossChainManager"; /* ========== ETERNAL STORAGE CONSTANTS ========== */ bytes32 private constant LAST_FEE_WITHDRAWAL = "last_fee_withdrawal"; constructor( address payable _proxy, address _owner, address _resolver ) public Owned(_owner) Proxyable(_proxy) LimitedSetup(3 weeks) MixinSystemSettings(_resolver) { // Set our initial fee period _recentFeePeriodsStorage(0).feePeriodId = 1; _recentFeePeriodsStorage(0).startTime = uint64(now); } /* ========== VIEWS ========== */ function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { bytes32[] memory existingAddresses = MixinSystemSettings.resolverAddressesRequired(); bytes32[] memory newAddresses = new bytes32[](13); newAddresses[0] = CONTRACT_SYSTEMSTATUS; newAddresses[1] = CONTRACT_PERIFINANCE; newAddresses[2] = CONTRACT_FEEPOOLSTATE; newAddresses[3] = CONTRACT_FEEPOOLETERNALSTORAGE; newAddresses[4] = CONTRACT_EXCHANGER; newAddresses[5] = CONTRACT_ISSUER; newAddresses[6] = CONTRACT_PERIFINANCESTATE; newAddresses[7] = CONTRACT_REWARDESCROW_V2; newAddresses[8] = CONTRACT_DELEGATEAPPROVALS; newAddresses[9] = CONTRACT_ETH_COLLATERAL_PUSD; newAddresses[10] = CONTRACT_REWARDSDISTRIBUTION; newAddresses[11] = CONTRACT_COLLATERALMANAGER; newAddresses[12] = CONTRACT_CROSSCHAINMANAGER; addresses = combineArrays(existingAddresses, newAddresses); } function systemStatus() internal view returns (ISystemStatus) { return ISystemStatus(requireAndGetAddress(CONTRACT_SYSTEMSTATUS)); } function periFinance() internal view returns (IPeriFinance) { return IPeriFinance(requireAndGetAddress(CONTRACT_PERIFINANCE)); } function feePoolState() internal view returns (FeePoolState) { return FeePoolState(requireAndGetAddress(CONTRACT_FEEPOOLSTATE)); } function feePoolEternalStorage() internal view returns (FeePoolEternalStorage) { return FeePoolEternalStorage(requireAndGetAddress(CONTRACT_FEEPOOLETERNALSTORAGE)); } function exchanger() internal view returns (IExchanger) { return IExchanger(requireAndGetAddress(CONTRACT_EXCHANGER)); } function etherCollateralpUSD() internal view returns (IEtherCollateralpUSD) { return IEtherCollateralpUSD(requireAndGetAddress(CONTRACT_ETH_COLLATERAL_PUSD)); } function collateralManager() internal view returns (ICollateralManager) { return ICollateralManager(requireAndGetAddress(CONTRACT_COLLATERALMANAGER)); } function crossChainManager() internal view returns (ICrossChainManager) { return ICrossChainManager(requireAndGetAddress(CONTRACT_CROSSCHAINMANAGER)); } function issuer() internal view returns (IIssuer) { return IIssuer(requireAndGetAddress(CONTRACT_ISSUER)); } function periFinanceState() internal view returns (IPeriFinanceState) { return IPeriFinanceState(requireAndGetAddress(CONTRACT_PERIFINANCESTATE)); } function rewardEscrowV2() internal view returns (IRewardEscrowV2) { return IRewardEscrowV2(requireAndGetAddress(CONTRACT_REWARDESCROW_V2)); } function delegateApprovals() internal view returns (IDelegateApprovals) { return IDelegateApprovals(requireAndGetAddress(CONTRACT_DELEGATEAPPROVALS)); } function rewardsDistribution() internal view returns (IRewardsDistribution) { return IRewardsDistribution(requireAndGetAddress(CONTRACT_REWARDSDISTRIBUTION)); } function issuanceRatio() external view returns (uint) { return getIssuanceRatio(); } function feePeriodDuration() external view returns (uint) { return getFeePeriodDuration(); } function targetThreshold() external view returns (uint) { return getTargetThreshold(); } function recentFeePeriods(uint index) external view returns ( uint64 feePeriodId, uint64 startingDebtIndex, uint64 startTime, uint feesToDistribute, uint feesClaimed, uint rewardsToDistribute, uint rewardsClaimed ) { FeePeriod memory feePeriod = _recentFeePeriodsStorage(index); return ( feePeriod.feePeriodId, feePeriod.startingDebtIndex, feePeriod.startTime, feePeriod.feesToDistribute, feePeriod.feesClaimed, feePeriod.rewardsToDistribute, feePeriod.rewardsClaimed ); } function everDistributedFeeRewards() external view returns (bool) { return _everDistributedFeeRewards; } function everAllocatedFeeRewards() external view returns (bool) { return _everAllocatedFeeRewards; } function allocatedOtherNetworkFeeRewards() external view returns (uint) { return _allocatedOtherNetworkFeeRewards(); } function _recentFeePeriodsStorage(uint index) internal view returns (FeePeriod storage) { return _recentFeePeriods[(_currentFeePeriod + index) % FEE_PERIOD_LENGTH]; } function _allocatedOtherNetworkFeeRewards() internal view returns (uint allocatedFeesForOtherNetworks) { uint otherNetworksShare = SafeDecimalMath.preciseUnit().sub(crossChainManager().currentNetworkDebtPercentage()); allocatedFeesForOtherNetworks = _recentFeePeriodsStorage(0) .feesToDistribute .decimalToPreciseDecimal() .multiplyDecimalRoundPrecise(otherNetworksShare) .preciseDecimalToDecimal(); } /* ========== MUTATIVE FUNCTIONS ========== */ function distributeFeeRewards() external optionalProxy onlyDebtManager { require(getFeePeriodDuration() > 0, "Fee Period Duration not set"); require( _recentFeePeriodsStorage(0).startTime <= (now - getFeePeriodDuration()), "distributing fee reward not yet available" ); require(_everDistributedFeeRewards == false, "Distributing fee rewards is possible only once in a period"); _everDistributedFeeRewards = true; uint _allocatedFeeRewards = _allocatedOtherNetworkFeeRewards(); if (_allocatedFeeRewards <= 0) { feeRewardsToBeAllocated = 0; return; } issuer().pynths(pUSD).burn(FEE_ADDRESS, _allocatedFeeRewards); feeRewardsToBeAllocated = _allocatedFeeRewards; _recentFeePeriodsStorage(0).feesToDistribute = _recentFeePeriodsStorage(0).feesToDistribute.sub( _allocatedFeeRewards ); } function allocateFeeRewards(uint amount) external optionalProxy onlyDebtManager { require(getFeePeriodDuration() > 0, "Fee Period Duration not set"); require( _recentFeePeriodsStorage(0).startTime <= (now - getFeePeriodDuration()), "allocating fee reward not yet available" ); require(_everAllocatedFeeRewards == false, "Allocating fee rewards is possible only once in a period"); _everAllocatedFeeRewards = true; if (amount == 0) return; uint currentNetworkAllocatedFeeRewards = amount .decimalToPreciseDecimal() .multiplyDecimalRoundPrecise(crossChainManager().currentNetworkDebtPercentage()) .preciseDecimalToDecimal(); issuer().pynths(pUSD).issue(FEE_ADDRESS, currentNetworkAllocatedFeeRewards); _recentFeePeriodsStorage(0).feesToDistribute = _recentFeePeriodsStorage(0).feesToDistribute.add( currentNetworkAllocatedFeeRewards ); } /** * @notice Logs an accounts issuance data per fee period * @param account Message.Senders account address * @param debtRatio Debt percentage this account has locked after minting or burning their pynth * @param debtEntryIndex The index in the global debt ledger. periFinanceState.issuanceData(account) * @dev onlyIssuer to call me on periFinance.issue() & periFinance.burn() calls to store the locked PERI * per fee period so we know to allocate the correct proportions of fees and rewards per period */ function appendAccountIssuanceRecord( address account, uint debtRatio, uint debtEntryIndex ) external onlyIssuerAndPeriFinanceState { feePoolState().appendAccountIssuanceRecord( account, debtRatio, debtEntryIndex, _recentFeePeriodsStorage(0).startingDebtIndex ); emitIssuanceDebtRatioEntry(account, debtRatio, debtEntryIndex, _recentFeePeriodsStorage(0).startingDebtIndex); } /** * @notice The Exchanger contract informs us when fees are paid. * @param amount susd amount in fees being paid. */ function recordFeePaid(uint amount) external onlyInternalContracts { // Keep track off fees in pUSD in the open fee pool period. _recentFeePeriodsStorage(0).feesToDistribute = _recentFeePeriodsStorage(0).feesToDistribute.add(amount); } /** * @notice The RewardsDistribution contract informs us how many PERI rewards are sent to RewardEscrow to be claimed. */ function setRewardsToDistribute(uint amount) external { address rewardsAuthority = address(rewardsDistribution()); require(messageSender == rewardsAuthority || msg.sender == rewardsAuthority, "Caller is not rewardsAuthority"); // Add the amount of PERI rewards to distribute on top of any rolling unclaimed amount _recentFeePeriodsStorage(0).rewardsToDistribute = _recentFeePeriodsStorage(0).rewardsToDistribute.add(amount); } function setQuotaTolerance(uint _val) external onlyOwner { require(_val < SafeDecimalMath.unit(), "Tolerance value cannot exceeds 1"); quotaTolerance = _val; } /** * @notice Close the current fee period and start a new one. */ function closeCurrentFeePeriod() external issuanceActive { require(getFeePeriodDuration() > 0, "Fee Period Duration not set"); require(_recentFeePeriodsStorage(0).startTime <= (now - getFeePeriodDuration()), "Too early to close fee period"); require( _everDistributedFeeRewards || _everAllocatedFeeRewards, "fee rewards should be distributed or allocated before closing period" ); // Note: when FEE_PERIOD_LENGTH = 2, periodClosing is the current period & periodToRollover is the last open claimable period FeePeriod storage periodClosing = _recentFeePeriodsStorage(FEE_PERIOD_LENGTH - 2); FeePeriod storage periodToRollover = _recentFeePeriodsStorage(FEE_PERIOD_LENGTH - 1); // Any unclaimed fees from the last period in the array roll back one period. // Because of the subtraction here, they're effectively proportionally redistributed to those who // have already claimed from the old period, available in the new period. // The subtraction is important so we don't create a ticking time bomb of an ever growing // number of fees that can never decrease and will eventually overflow at the end of the fee pool. _recentFeePeriodsStorage(FEE_PERIOD_LENGTH - 2).feesToDistribute = periodToRollover .feesToDistribute .sub(periodToRollover.feesClaimed) .add(periodClosing.feesToDistribute); _recentFeePeriodsStorage(FEE_PERIOD_LENGTH - 2).rewardsToDistribute = periodToRollover .rewardsToDistribute .sub(periodToRollover.rewardsClaimed) .add(periodClosing.rewardsToDistribute); // Shift the previous fee periods across to make room for the new one. _currentFeePeriod = _currentFeePeriod.add(FEE_PERIOD_LENGTH).sub(1).mod(FEE_PERIOD_LENGTH); // Clear the first element of the array to make sure we don't have any stale values. delete _recentFeePeriods[_currentFeePeriod]; // Open up the new fee period. // Increment periodId from the recent closed period feePeriodId _recentFeePeriodsStorage(0).feePeriodId = uint64(uint256(_recentFeePeriodsStorage(1).feePeriodId).add(1)); _recentFeePeriodsStorage(0).startingDebtIndex = uint64(periFinanceState().debtLedgerLength()); _recentFeePeriodsStorage(0).startTime = uint64(now); // allow fee rewards to be distributed when the period is closed _everDistributedFeeRewards = false; _everAllocatedFeeRewards = false; emitFeePeriodClosed(_recentFeePeriodsStorage(1).feePeriodId); } /** * @notice Claim fees for last period when available or not already withdrawn. */ function claimFees() external issuanceActive optionalProxy returns (bool) { return _claimFees(messageSender); } /** * @notice Delegated claimFees(). Call from the deletegated address * and the fees will be sent to the claimingForAddress. * approveClaimOnBehalf() must be called first to approve the deletage address * @param claimingForAddress The account you are claiming fees for */ function claimOnBehalf(address claimingForAddress) external issuanceActive optionalProxy returns (bool) { require(delegateApprovals().canClaimFor(claimingForAddress, messageSender), "Not approved to claim on behalf"); return _claimFees(claimingForAddress); } function _claimFees(address claimingAddress) internal returns (bool) { uint rewardsPaid = 0; uint feesPaid = 0; uint availableFees; uint availableRewards; // Address won't be able to claim fees if it is too far below the target c-ratio. // It will need to burn pynths then try claiming again. (bool feesClaimable, bool anyRateIsInvalid) = _isFeesClaimableAndAnyRatesInvalid(claimingAddress); require(feesClaimable, "C-Ratio below penalty threshold"); require(!anyRateIsInvalid, "A pynth or PERI rate is invalid"); // Get the claimingAddress available fees and rewards (availableFees, availableRewards) = feesAvailable(claimingAddress); require( availableFees > 0 || availableRewards > 0, "No fees or rewards available for period, or fees already claimed" ); // Record the address has claimed for this period _setLastFeeWithdrawal(claimingAddress, _recentFeePeriodsStorage(1).feePeriodId); if (availableFees > 0) { // Record the fee payment in our recentFeePeriods feesPaid = _recordFeePayment(availableFees); // Send them their fees _payFees(claimingAddress, feesPaid); } if (availableRewards > 0) { // Record the reward payment in our recentFeePeriods rewardsPaid = _recordRewardPayment(availableRewards); // Send them their rewards _payRewards(claimingAddress, rewardsPaid); } emitFeesClaimed(claimingAddress, feesPaid, rewardsPaid); return true; } /** * @notice Admin function to import the FeePeriod data from the previous contract */ function importFeePeriod( uint feePeriodIndex, uint feePeriodId, uint startingDebtIndex, uint startTime, uint feesToDistribute, uint feesClaimed, uint rewardsToDistribute, uint rewardsClaimed ) public optionalProxy_onlyOwner onlyDuringSetup { require(startingDebtIndex <= periFinanceState().debtLedgerLength(), "Cannot import bad data"); _recentFeePeriods[_currentFeePeriod.add(feePeriodIndex).mod(FEE_PERIOD_LENGTH)] = FeePeriod({ feePeriodId: uint64(feePeriodId), startingDebtIndex: uint64(startingDebtIndex), startTime: uint64(startTime), feesToDistribute: feesToDistribute, feesClaimed: feesClaimed, rewardsToDistribute: rewardsToDistribute, rewardsClaimed: rewardsClaimed }); } /** * @notice Record the fee payment in our recentFeePeriods. * @param pUSDAmount The amount of fees priced in pUSD. */ function _recordFeePayment(uint pUSDAmount) internal returns (uint) { // Don't assign to the parameter uint remainingToAllocate = pUSDAmount; uint feesPaid; // Start at the oldest period and record the amount, moving to newer periods // until we've exhausted the amount. // The condition checks for overflow because we're going to 0 with an unsigned int. for (uint i = FEE_PERIOD_LENGTH - 1; i < FEE_PERIOD_LENGTH; i--) { uint feesAlreadyClaimed = _recentFeePeriodsStorage(i).feesClaimed; uint delta = _recentFeePeriodsStorage(i).feesToDistribute.sub(feesAlreadyClaimed); if (delta > 0) { // Take the smaller of the amount left to claim in the period and the amount we need to allocate uint amountInPeriod = delta < remainingToAllocate ? delta : remainingToAllocate; _recentFeePeriodsStorage(i).feesClaimed = feesAlreadyClaimed.add(amountInPeriod); remainingToAllocate = remainingToAllocate.sub(amountInPeriod); feesPaid = feesPaid.add(amountInPeriod); // No need to continue iterating if we've recorded the whole amount; if (remainingToAllocate == 0) return feesPaid; // We've exhausted feePeriods to distribute and no fees remain in last period // User last to claim would in this scenario have their remainder slashed if (i == 0 && remainingToAllocate > 0) { remainingToAllocate = 0; } } } return feesPaid; } /** * @notice Record the reward payment in our recentFeePeriods. * @param periAmount The amount of PERI tokens. */ function _recordRewardPayment(uint periAmount) internal returns (uint) { // Don't assign to the parameter uint remainingToAllocate = periAmount; uint rewardPaid; // Start at the oldest period and record the amount, moving to newer periods // until we've exhausted the amount. // The condition checks for overflow because we're going to 0 with an unsigned int. for (uint i = FEE_PERIOD_LENGTH - 1; i < FEE_PERIOD_LENGTH; i--) { uint toDistribute = _recentFeePeriodsStorage(i).rewardsToDistribute.sub(_recentFeePeriodsStorage(i).rewardsClaimed); if (toDistribute > 0) { // Take the smaller of the amount left to claim in the period and the amount we need to allocate uint amountInPeriod = toDistribute < remainingToAllocate ? toDistribute : remainingToAllocate; _recentFeePeriodsStorage(i).rewardsClaimed = _recentFeePeriodsStorage(i).rewardsClaimed.add(amountInPeriod); remainingToAllocate = remainingToAllocate.sub(amountInPeriod); rewardPaid = rewardPaid.add(amountInPeriod); // No need to continue iterating if we've recorded the whole amount; if (remainingToAllocate == 0) return rewardPaid; // We've exhausted feePeriods to distribute and no rewards remain in last period // User last to claim would in this scenario have their remainder slashed // due to rounding up of PreciseDecimal if (i == 0 && remainingToAllocate > 0) { remainingToAllocate = 0; } } } return rewardPaid; } /** * @notice Send the fees to claiming address. * @param account The address to send the fees to. * @param pUSDAmount The amount of fees priced in pUSD. */ function _payFees(address account, uint pUSDAmount) internal notFeeAddress(account) { // Grab the pUSD Pynth IPynth pUSDPynth = issuer().pynths(pUSD); // NOTE: we do not control the FEE_ADDRESS so it is not possible to do an // ERC20.approve() transaction to allow this feePool to call ERC20.transferFrom // to the accounts address // Burn the source amount pUSDPynth.burn(FEE_ADDRESS, pUSDAmount); // Mint their new pynths pUSDPynth.issue(account, pUSDAmount); } /** * @notice Send the rewards to claiming address - will be locked in rewardEscrow. * @param account The address to send the fees to. * @param periAmount The amount of PERI. */ function _payRewards(address account, uint periAmount) internal notFeeAddress(account) { /* Escrow the tokens for 1 year. */ uint escrowDuration = 52 weeks; // Record vesting entry for claiming address and amount // PERI already minted to rewardEscrow balance rewardEscrowV2().appendVestingEntry(account, periAmount, escrowDuration); } /** * @notice The total fees available in the system to be withdrawnn in pUSD */ function totalFeesAvailable() external view returns (uint) { uint totalFees = 0; // Fees in fee period [0] are not yet available for withdrawal for (uint i = 1; i < FEE_PERIOD_LENGTH; i++) { totalFees = totalFees.add(_recentFeePeriodsStorage(i).feesToDistribute); totalFees = totalFees.sub(_recentFeePeriodsStorage(i).feesClaimed); } return totalFees; } /** * @notice The total PERI rewards available in the system to be withdrawn */ function totalRewardsAvailable() external view returns (uint) { uint totalRewards = 0; // Rewards in fee period [0] are not yet available for withdrawal for (uint i = 1; i < FEE_PERIOD_LENGTH; i++) { totalRewards = totalRewards.add(_recentFeePeriodsStorage(i).rewardsToDistribute); totalRewards = totalRewards.sub(_recentFeePeriodsStorage(i).rewardsClaimed); } return totalRewards; } /** * @notice The fees available to be withdrawn by a specific account, priced in pUSD * @dev Returns two amounts, one for fees and one for PERI rewards */ function feesAvailable(address account) public view returns (uint, uint) { // Add up the fees uint[2][FEE_PERIOD_LENGTH] memory userFees = feesByPeriod(account); uint totalFees = 0; uint totalRewards = 0; // Fees & Rewards in fee period [0] are not yet available for withdrawal for (uint i = 1; i < FEE_PERIOD_LENGTH; i++) { totalFees = totalFees.add(userFees[i][0]); totalRewards = totalRewards.add(userFees[i][1]); } // And convert totalFees to pUSD // Return totalRewards as is in PERI amount return (totalFees, totalRewards); } function _isFeesClaimableAndAnyRatesInvalid(address account) internal view returns (bool, bool) { // External token staked amount should not over the quota limit. uint accountExternalTokenQuota = issuer().externalTokenQuota(account, 0, 0, true); if ( accountExternalTokenQuota > getExternalTokenQuota().multiplyDecimal(SafeDecimalMath.unit().add(quotaTolerance)) ) { return (false, false); } // Threshold is calculated from ratio % above the target ratio (issuanceRatio). // 0 < 10%: Claimable // 10% > above: Unable to claim (uint ratio, bool anyRateIsInvalid) = issuer().collateralisationRatioAndAnyRatesInvalid(account); uint targetRatio = getIssuanceRatio(); // Claimable if collateral ratio below target ratio if (ratio < targetRatio) { return (true, anyRateIsInvalid); } // Calculate the threshold for collateral ratio before fees can't be claimed. uint ratio_threshold = targetRatio.multiplyDecimal(SafeDecimalMath.unit().add(getTargetThreshold())); // Not claimable if collateral ratio above threshold if (ratio > ratio_threshold) { return (false, anyRateIsInvalid); } return (true, anyRateIsInvalid); } function isFeesClaimable(address account) external view returns (bool feesClaimable) { (feesClaimable, ) = _isFeesClaimableAndAnyRatesInvalid(account); } /** * @notice Calculates fees by period for an account, priced in pUSD * @param account The address you want to query the fees for */ function feesByPeriod(address account) public view returns (uint[2][FEE_PERIOD_LENGTH] memory results) { // What's the user's debt entry index and the debt they owe to the system at current feePeriod uint userOwnershipPercentage; uint debtEntryIndex; FeePoolState _feePoolState = feePoolState(); (userOwnershipPercentage, debtEntryIndex) = _feePoolState.getAccountsDebtEntry(account, 0); // If they don't have any debt ownership and they never minted, they don't have any fees. // User ownership can reduce to 0 if user burns all pynths, // however they could have fees applicable for periods they had minted in before so we check debtEntryIndex. if (debtEntryIndex == 0 && userOwnershipPercentage == 0) { uint[2][FEE_PERIOD_LENGTH] memory nullResults; return nullResults; } // The [0] fee period is not yet ready to claim, but it is a fee period that they can have // fees owing for, so we need to report on it anyway. uint feesFromPeriod; uint rewardsFromPeriod; (feesFromPeriod, rewardsFromPeriod) = _feesAndRewardsFromPeriod(0, userOwnershipPercentage, debtEntryIndex); results[0][0] = feesFromPeriod; results[0][1] = rewardsFromPeriod; // Retrieve user's last fee claim by periodId uint lastFeeWithdrawal = getLastFeeWithdrawal(account); // Go through our fee periods from the oldest feePeriod[FEE_PERIOD_LENGTH - 1] and figure out what we owe them. // Condition checks for periods > 0 for (uint i = FEE_PERIOD_LENGTH - 1; i > 0; i--) { uint next = i - 1; uint nextPeriodStartingDebtIndex = _recentFeePeriodsStorage(next).startingDebtIndex; // We can skip the period, as no debt minted during period (next period's startingDebtIndex is still 0) if (nextPeriodStartingDebtIndex > 0 && lastFeeWithdrawal < _recentFeePeriodsStorage(i).feePeriodId) { // We calculate a feePeriod's closingDebtIndex by looking at the next feePeriod's startingDebtIndex // we can use the most recent issuanceData[0] for the current feePeriod // else find the applicableIssuanceData for the feePeriod based on the StartingDebtIndex of the period uint closingDebtIndex = uint256(nextPeriodStartingDebtIndex).sub(1); // Gas optimisation - to reuse debtEntryIndex if found new applicable one // if applicable is 0,0 (none found) we keep most recent one from issuanceData[0] // return if userOwnershipPercentage = 0) (userOwnershipPercentage, debtEntryIndex) = _feePoolState.applicableIssuanceData(account, closingDebtIndex); (feesFromPeriod, rewardsFromPeriod) = _feesAndRewardsFromPeriod(i, userOwnershipPercentage, debtEntryIndex); results[i][0] = feesFromPeriod; results[i][1] = rewardsFromPeriod; } } } /** * @notice ownershipPercentage is a high precision decimals uint based on * wallet's debtPercentage. Gives a precise amount of the feesToDistribute * for fees in the period. Precision factor is removed before results are * returned. * @dev The reported fees owing for the current period [0] are just a * running balance until the fee period closes */ function _feesAndRewardsFromPeriod( uint period, uint ownershipPercentage, uint debtEntryIndex ) internal view returns (uint, uint) { // If it's zero, they haven't issued, and they have no fees OR rewards. if (ownershipPercentage == 0) return (0, 0); uint debtOwnershipForPeriod = ownershipPercentage; // If period has closed we want to calculate debtPercentage for the period if (period > 0) { uint closingDebtIndex = uint256(_recentFeePeriodsStorage(period - 1).startingDebtIndex).sub(1); debtOwnershipForPeriod = _effectiveDebtRatioForPeriod(closingDebtIndex, ownershipPercentage, debtEntryIndex); } // Calculate their percentage of the fees / rewards in this period // This is a high precision integer. uint feesFromPeriod = _recentFeePeriodsStorage(period).feesToDistribute.multiplyDecimal(debtOwnershipForPeriod); uint rewardsFromPeriod = _recentFeePeriodsStorage(period).rewardsToDistribute.multiplyDecimal(debtOwnershipForPeriod); return (feesFromPeriod.preciseDecimalToDecimal(), rewardsFromPeriod.preciseDecimalToDecimal()); } function _effectiveDebtRatioForPeriod( uint closingDebtIndex, uint ownershipPercentage, uint debtEntryIndex ) internal view returns (uint) { // Figure out their global debt percentage delta at end of fee Period. // This is a high precision integer. IPeriFinanceState _periFinanceState = periFinanceState(); uint feePeriodDebtOwnership = _periFinanceState .debtLedger(closingDebtIndex) .divideDecimalRoundPrecise(_periFinanceState.debtLedger(debtEntryIndex)) .multiplyDecimalRoundPrecise(ownershipPercentage); return feePeriodDebtOwnership; } function effectiveDebtRatioForPeriod(address account, uint period) external view returns (uint) { require(period != 0, "Current period is not closed yet"); require(period < FEE_PERIOD_LENGTH, "Exceeds the FEE_PERIOD_LENGTH"); // If the period being checked is uninitialised then return 0. This is only at the start of the system. if (_recentFeePeriodsStorage(period - 1).startingDebtIndex == 0) return 0; uint closingDebtIndex = uint256(_recentFeePeriodsStorage(period - 1).startingDebtIndex).sub(1); uint ownershipPercentage; uint debtEntryIndex; (ownershipPercentage, debtEntryIndex) = feePoolState().applicableIssuanceData(account, closingDebtIndex); // internal function will check closingDebtIndex has corresponding debtLedger entry return _effectiveDebtRatioForPeriod(closingDebtIndex, ownershipPercentage, debtEntryIndex); } /** * @notice Get the feePeriodID of the last claim this account made * @param _claimingAddress account to check the last fee period ID claim for * @return uint of the feePeriodID this account last claimed */ function getLastFeeWithdrawal(address _claimingAddress) public view returns (uint) { return feePoolEternalStorage().getUIntValue(keccak256(abi.encodePacked(LAST_FEE_WITHDRAWAL, _claimingAddress))); } /** * @notice Calculate the collateral ratio before user is blocked from claiming. */ function getPenaltyThresholdRatio() public view returns (uint) { return getIssuanceRatio().multiplyDecimal(SafeDecimalMath.unit().add(getTargetThreshold())); } /** * @notice Set the feePeriodID of the last claim this account made * @param _claimingAddress account to set the last feePeriodID claim for * @param _feePeriodID the feePeriodID this account claimed fees for */ function _setLastFeeWithdrawal(address _claimingAddress, uint _feePeriodID) internal { feePoolEternalStorage().setUIntValue( keccak256(abi.encodePacked(LAST_FEE_WITHDRAWAL, _claimingAddress)), _feePeriodID ); } function _debtManager() internal view returns (address) { return crossChainManager().debtManager(); } /* ========== Modifiers ========== */ modifier onlyInternalContracts { bool isExchanger = msg.sender == address(exchanger()); bool isPynth = issuer().pynthsByAddress(msg.sender) != bytes32(0); bool isEtherCollateralpUSD = msg.sender == address(etherCollateralpUSD()); bool isCollateral = collateralManager().hasCollateral(msg.sender); require(isExchanger || isPynth || isEtherCollateralpUSD || isCollateral, "Only Internal Contracts"); _; } modifier onlyIssuerAndPeriFinanceState { bool isIssuer = msg.sender == address(issuer()); bool isPeriFinanceState = msg.sender == address(periFinanceState()); require(isIssuer || isPeriFinanceState, "Issuer and PeriFinanceState only"); _; } modifier onlyDebtManager { bool isDebtManager = messageSender == _debtManager(); require(isDebtManager, "debt manager only"); _; } modifier notFeeAddress(address account) { require(account != FEE_ADDRESS, "Fee address not allowed"); _; } modifier issuanceActive() { systemStatus().requireIssuanceActive(); _; } /* ========== Proxy Events ========== */ event IssuanceDebtRatioEntry( address indexed account, uint debtRatio, uint debtEntryIndex, uint feePeriodStartingDebtIndex ); bytes32 private constant ISSUANCEDEBTRATIOENTRY_SIG = keccak256("IssuanceDebtRatioEntry(address,uint256,uint256,uint256)"); function emitIssuanceDebtRatioEntry( address account, uint debtRatio, uint debtEntryIndex, uint feePeriodStartingDebtIndex ) internal { proxy._emit( abi.encode(debtRatio, debtEntryIndex, feePeriodStartingDebtIndex), 2, ISSUANCEDEBTRATIOENTRY_SIG, bytes32(uint256(uint160(account))), 0, 0 ); } event FeePeriodClosed(uint feePeriodId); bytes32 private constant FEEPERIODCLOSED_SIG = keccak256("FeePeriodClosed(uint256)"); function emitFeePeriodClosed(uint feePeriodId) internal { proxy._emit(abi.encode(feePeriodId), 1, FEEPERIODCLOSED_SIG, 0, 0, 0); } event FeesClaimed(address account, uint pUSDAmount, uint periRewards); bytes32 private constant FEESCLAIMED_SIG = keccak256("FeesClaimed(address,uint256,uint256)"); function emitFeesClaimed( address account, uint pUSDAmount, uint periRewards ) internal { proxy._emit(abi.encode(account, pUSDAmount, periRewards), 1, FEESCLAIMED_SIG, 0, 0, 0); } }
[{"inputs":[{"internalType":"address payable","name":"_proxy","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_resolver","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"name","type":"bytes32"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"CacheUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"feePeriodId","type":"uint256"}],"name":"FeePeriodClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"pUSDAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"periRewards","type":"uint256"}],"name":"FeesClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"debtRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtEntryIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feePeriodStartingDebtIndex","type":"uint256"}],"name":"IssuanceDebtRatioEntry","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"proxyAddress","type":"address"}],"name":"ProxyUpdated","type":"event"},{"constant":true,"inputs":[],"name":"FEE_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FEE_PERIOD_LENGTH","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"allocateFeeRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"allocatedOtherNetworkFeeRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"debtRatio","type":"uint256"},{"internalType":"uint256","name":"debtEntryIndex","type":"uint256"}],"name":"appendAccountIssuanceRecord","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"claimingForAddress","type":"address"}],"name":"claimOnBehalf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"closeCurrentFeePeriod","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"distributeFeeRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"period","type":"uint256"}],"name":"effectiveDebtRatioForPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"everAllocatedFeeRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"everDistributedFeeRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"feePeriodDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"feeRewardsToBeAllocated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"feesAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"feesByPeriod","outputs":[{"internalType":"uint256[2][2]","name":"results","type":"uint256[2][2]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_claimingAddress","type":"address"}],"name":"getLastFeeWithdrawal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getPenaltyThresholdRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"feePeriodIndex","type":"uint256"},{"internalType":"uint256","name":"feePeriodId","type":"uint256"},{"internalType":"uint256","name":"startingDebtIndex","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"feesToDistribute","type":"uint256"},{"internalType":"uint256","name":"feesClaimed","type":"uint256"},{"internalType":"uint256","name":"rewardsToDistribute","type":"uint256"},{"internalType":"uint256","name":"rewardsClaimed","type":"uint256"}],"name":"importFeePeriod","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"integrationProxy","outputs":[{"internalType":"contract Proxy","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isFeesClaimable","outputs":[{"internalType":"bool","name":"feesClaimable","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isResolverCached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"issuanceRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"messageSender","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"proxy","outputs":[{"internalType":"contract Proxy","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"quotaTolerance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"rebuildCache","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"recentFeePeriods","outputs":[{"internalType":"uint64","name":"feePeriodId","type":"uint64"},{"internalType":"uint64","name":"startingDebtIndex","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint256","name":"feesToDistribute","type":"uint256"},{"internalType":"uint256","name":"feesClaimed","type":"uint256"},{"internalType":"uint256","name":"rewardsToDistribute","type":"uint256"},{"internalType":"uint256","name":"rewardsClaimed","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recordFeePaid","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"resolver","outputs":[{"internalType":"contract AddressResolver","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"resolverAddressesRequired","outputs":[{"internalType":"bytes32[]","name":"addresses","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address payable","name":"_integrationProxy","type":"address"}],"name":"setIntegrationProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"setMessageSender","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address payable","name":"_proxy","type":"address"}],"name":"setProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_val","type":"uint256"}],"name":"setQuotaTolerance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setRewardsToDistribute","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"setupExpiryTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"targetThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalFeesAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalRewardsAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052631c1554d160e21b6008553480156200001c57600080fd5b506040516200537c3803806200537c8339810160408190526200003f9162000221565b8080621baf8085856001600160a01b038116620000795760405162461bcd60e51b8152600401620000709062000343565b60405180910390fd5b600080546001600160a01b0319166001600160a01b0383161781556040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91620000c69184906200030b565b60405180910390a1506000546001600160a01b0316620000fa5760405162461bcd60e51b8152600401620000709062000331565b600280546001600160a01b0319166001600160a01b0383161790556040517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e9062000147908390620002fb565b60405180910390a1504201600555600680546001600160a01b0319166001600160a01b0392909216919091179055506001620001846000620001e2565b80546001600160401b0319166001600160401b039290921691909117905542620001af6000620001e2565b80546001600160401b0392909216600160801b02600160801b600160c01b0319909216919091179055506200039e915050565b60006009600260ff16836013540181620001f857fe5b06600281106200020457fe5b6005020192915050565b80516200021b8162000384565b92915050565b6000806000606084860312156200023757600080fd5b60006200024586866200020e565b935050602062000258868287016200020e565b92505060406200026b868287016200020e565b9150509250925092565b620002808162000370565b82525050565b62000280816200035e565b6000620002a060118362000355565b7013dddb995c881b5d5cdd081899481cd95d607a1b815260200192915050565b6000620002cf60198362000355565b7f4f776e657220616464726573732063616e6e6f74206265203000000000000000815260200192915050565b602081016200021b828462000275565b604081016200031b828562000275565b6200032a602083018462000286565b9392505050565b602080825281016200021b8162000291565b602080825281016200021b81620002c0565b90815260200190565b60006001600160a01b0382166200021b565b60006200021b8260006200021b826200035e565b6200038f816200035e565b81146200039b57600080fd5b50565b614fce80620003ae6000396000f3fe608060405234801561001057600080fd5b50600436106102f45760003560e01c80636683051b11610191578063ac834193116100e3578063d294f09311610097578063eb1edd6111610071578063eb1edd6114610578578063ec55688914610580578063fd1f498d14610588576102f4565b8063d294f09314610560578063d67bdd2514610568578063e0e6393d14610570576102f4565b8063b410a034116100c8578063b410a03414610530578063bc67f83214610538578063cff2ddad1461054b576102f4565b8063ac83419314610515578063b10090b81461051d576102f4565b806386645274116101455780638da5cb5b1161011f5780638da5cb5b146104f257806397107d6d146104fa5780639cbdaeb61461050d576102f4565b806386645274146104b75780638844578a146104ca578063899ffef4146104dd576102f4565b80636de813f1116101765780636de813f11461049f57806374185360146104a757806379ba5097146104af576102f4565b80636683051b146104845780636841e9b41461048c576102f4565b80633c41d1731161024a57806353a47bb7116101fe5780635fe47778116101d85780635fe477781461046157806362115496146104695780636466f45e14610471576102f4565b806353a47bb714610431578063569249d01461044657806359a2f19f1461044e576102f4565b80633fcd22401161022f5780633fcd2240146103fb578063446530d11461042157806346ba2d9014610429576102f4565b80633c41d173146103eb5780633ebc457a146103f3576102f4565b80631627540c116102ac578063269652671161028657806326965267146103ae5780632af64bd3146103b657806333140016146103cb576102f4565b80631627540c1461038057806322425fa41461039357806322bf55ef1461039b576102f4565b80630813071c116102dd5780630813071c146103375780630de586151461034a578063131b0ae71461036b576102f4565b806304f3bcec146102f957806307ea50cd14610317575b600080fd5b61030161059b565b60405161030e9190614c06565b60405180910390f35b61032a610325366004613b9d565b6105aa565b60405161030e9190614b23565b61032a610345366004613be1565b61067f565b61035d610358366004613b9d565b6107cb565b60405161030e929190614b3f565b61037e610379366004613b9d565b61084d565b005b61037e61038e366004613b9d565b610877565b61032a6108d5565b61037e6103a9366004613cc2565b6108e5565b61032a610a95565b6103be610a9f565b60405161030e9190614b15565b6103de6103d9366004613b9d565b610bcf565b60405161030e9190614af6565b6103be610e33565b61037e610e41565b61040e610409366004613cc2565b6111cf565b60405161030e9796959493929190614e13565b61032a611278565b61032a61127e565b610439611284565b60405161030e91906149ee565b61032a611293565b6103be61045c366004613b9d565b6112ee565b61037e611300565b61032a61152a565b6103be61047f366004613b9d565b611530565b6103be61165a565b61037e61049a366004613cc2565b611663565b61032a611906565b61037e61195b565b61037e611aad565b61037e6104c5366004613c1b565b611b49565b61037e6104d8366004613cc2565b611c89565b6104e5611d30565b60405161030e9190614b04565b610439612050565b61037e610508366004613b9d565b61205f565b6103016120b2565b61032a6120c1565b61037e61052b366004613d40565b612161565b61032a61235b565b61037e610546366004613b9d565b612365565b61055361238f565b60405161030e9190614e7b565b6103be612394565b61043961240b565b61032a61241a565b610439612424565b61030161243c565b61037e610596366004613cc2565b61244b565b6006546001600160a01b031681565b60006105b46124c8565b6001600160a01b031663bdc963d87f6c6173745f6665655f7769746864726177616c00000000000000000000000000846040516020016105f592919061497c565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004016106279190614b23565b60206040518083038186803b15801561063f57600080fd5b505afa158015610653573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106779190810190613c86565b90505b919050565b6000816106a75760405162461bcd60e51b815260040161069e90614dd5565b60405180910390fd5b600282106106c75760405162461bcd60e51b815260040161069e90614d65565b6106d3600183036124f3565b5468010000000000000000900467ffffffffffffffff166106f6575060006107c5565b60006107266001610709600186036124f3565b5468010000000000000000900467ffffffffffffffff169061251d565b9050600080610733612545565b6001600160a01b031663d29c000a87856040518363ffffffff1660e01b8152600401610760929190614a7e565b604080518083038186803b15801561077757600080fd5b505afa15801561078b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107af9190810190613d10565b90925090506107bf838383612570565b93505050505b92915050565b6000806107d6613ab5565b6107df84610bcf565b905060008060015b60028110156108405761080c8482600281106107ff57fe5b60200201515184906126af565b925061083684826002811061081d57fe5b602002015160016020020151839063ffffffff6126af16565b91506001016107e7565b509093509150505b915091565b6108556126d4565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61087f6126d4565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906108ca9083906149ee565b60405180910390a150565b60006108df612700565b90505b90565b60006108ef6127b8565b6001600160a01b0316331490506000806109076127e3565b6001600160a01b031663c9a2f3ad336040518263ffffffff1660e01b815260040161093291906149fc565b60206040518083038186803b15801561094a57600080fd5b505afa15801561095e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109829190810190613c86565b1415905060006109906127f7565b6001600160a01b0316336001600160a01b031614905060006109b0612822565b6001600160a01b031663b38988f7336040518263ffffffff1660e01b81526004016109db91906149fc565b60206040518083038186803b1580156109f357600080fd5b505afa158015610a07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a2b9190810190613c68565b90508380610a365750825b80610a3e5750815b80610a465750805b610a625760405162461bcd60e51b815260040161069e90614c35565b610a8085610a7060006124f3565b600101549063ffffffff6126af16565b610a8a60006124f3565b600101555050505050565b60006108df61284d565b60006060610aab611d30565b905060005b8151811015610bc6576000828281518110610ac757fe5b602090810291909101810151600081815260079092526040918290205460065492517f21f8a7210000000000000000000000000000000000000000000000000000000081529193506001600160a01b039081169216906321f8a72190610b31908590600401614b23565b60206040518083038186803b158015610b4957600080fd5b505afa158015610b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b819190810190613bc3565b6001600160a01b0316141580610bac57506000818152600760205260409020546001600160a01b0316155b15610bbd57600093505050506108e2565b50600101610ab0565b50600191505090565b610bd7613ab5565b6000806000610be4612545565b6040517fb326f84e0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0382169063b326f84e90610c2f908890600090600401614a25565b604080518083038186803b158015610c4657600080fd5b505afa158015610c5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c7e9190810190613d10565b909350915081158015610c8f575082155b15610ca757610c9c613ab5565b935061067a92505050565b600080610cb66000868661296c565b8751829052875160200181905290925090506000610cd3886105aa565b905060015b8015610e275760001981016000610cee826124f3565b5468010000000000000000900467ffffffffffffffff1690508015801590610d285750610d1a836124f3565b5467ffffffffffffffff1684105b15610e1c576000610d4082600163ffffffff61251d16565b6040517fd29c000a0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0389169063d29c000a90610d8a908f908590600401614a7e565b604080518083038186803b158015610da157600080fd5b505afa158015610db5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610dd99190810190613d10565b909a509850610de9848b8b61296c565b9097509550868b8560028110610dfb57fe5b602002015152858b8560028110610e0e57fe5b602002015160016020020152505b505060001901610cd8565b50505050505050919050565b601454610100900460ff1690565b610e49612a0e565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015610e8157600080fd5b505afa158015610e95573d6000803e3d6000fd5b505050506000610ea3612700565b11610ec05760405162461bcd60e51b815260040161069e90614de5565b610ec8612700565b4203610ed460006124f3565b54600160801b900467ffffffffffffffff161115610f045760405162461bcd60e51b815260040161069e90614c65565b60145460ff1680610f1c5750601454610100900460ff165b610f385760405162461bcd60e51b815260040161069e90614da5565b6000610f43816124f3565b90506000610f5160016124f3565b9050610f828260010154610f768360020154846001015461251d90919063ffffffff16565b9063ffffffff6126af16565b610f8c60006124f3565b60010155600380830154600483015491830154610fb392610f76919063ffffffff61251d16565b610fbd60006124f3565b60030155601354610ffa90600290610fee90600190610fe2908463ffffffff6126af16565b9063ffffffff61251d16565b9063ffffffff612a3916565b60138190556009906002811061100c57fe5b6005020180547fffffffffffffffff00000000000000000000000000000000000000000000000016815560006001808301829055600283018290556003830182905560049092015561107890611061816124f3565b5467ffffffffffffffff169063ffffffff6126af16565b61108260006124f3565b805467ffffffffffffffff191667ffffffffffffffff929092169190911790556110aa612a69565b6001600160a01b031663cd92eba96040518163ffffffff1660e01b815260040160206040518083038186803b1580156110e257600080fd5b505afa1580156110f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061111a9190810190613c86565b61112460006124f3565b805467ffffffffffffffff9290921668010000000000000000026fffffffffffffffff0000000000000000199092169190911790554261116460006124f3565b805467ffffffffffffffff92909216600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9092169190911790556014805461ffff191690556111cb6111bb60016124f3565b5467ffffffffffffffff16612a94565b5050565b60008060008060008060006111e2613ae2565b6111eb896124f3565b6040805160e081018252825467ffffffffffffffff808216808452680100000000000000008304821660208501819052600160801b909304909116938301849052600185015460608401819052600286015460808501819052600387015460a0860181905260049097015460c0909501859052919f929e50939c50929a5091985091965090945092505050565b60165481565b60055481565b6001546001600160a01b031681565b60008060015b60028110156112e8576112bf6112ae826124f3565b60010154839063ffffffff6126af16565b91506112de6112cd826124f3565b60020154839063ffffffff61251d16565b9150600101611299565b50905090565b60006112f982612b4c565b5092915050565b611308612d3b565b6000611312612d91565b6004546001600160a01b039081169116149050806113425760405162461bcd60e51b815260040161069e90614d85565b600061134c612700565b116113695760405162461bcd60e51b815260040161069e90614de5565b611371612700565b420361137d60006124f3565b54600160801b900467ffffffffffffffff1611156113ad5760405162461bcd60e51b815260040161069e90614c55565b60145460ff16156113d05760405162461bcd60e51b815260040161069e90614db5565b6014805460ff1916600117905560006113e761284d565b9050600081116113fc57506000601555611527565b6114046127e3565b6001600160a01b03166357ad46636008546040518263ffffffff1660e01b81526004016114319190614b23565b60206040518083038186803b15801561144957600080fd5b505afa15801561145d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114819190810190613ca4565b6001600160a01b0316639dc29fac73feefeefeefeefeefeefeefeefeefeefeefeefeef836040518363ffffffff1660e01b81526004016114c2929190614a7e565b600060405180830381600087803b1580156114dc57600080fd5b505af11580156114f0573d6000803e3d6000fd5b5050506015829055506115178161150760006124f3565b600101549063ffffffff61251d16565b61152160006124f3565b60010155505b50565b60155481565b600061153a612a0e565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b15801561157257600080fd5b505afa158015611586573d6000803e3d6000fd5b50505050611592612d3b565b61159a612e0b565b600480546040517f21f4ae570000000000000000000000000000000000000000000000000000000081526001600160a01b03938416936321f4ae57936115e593889392169101614a0a565b60206040518083038186803b1580156115fd57600080fd5b505afa158015611611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116359190810190613c68565b6116515760405162461bcd60e51b815260040161069e90614cf5565b61067782612e36565b60145460ff1690565b61166b612d3b565b6000611675612d91565b6004546001600160a01b039081169116149050806116a55760405162461bcd60e51b815260040161069e90614d85565b60006116af612700565b116116cc5760405162461bcd60e51b815260040161069e90614de5565b6116d4612700565b42036116e060006124f3565b54600160801b900467ffffffffffffffff1611156117105760405162461bcd60e51b815260040161069e90614c95565b601454610100900460ff16156117385760405162461bcd60e51b815260040161069e90614c85565b6014805461ff00191661010017905581611751576111cb565b60006117eb6117e6611761612f2b565b6001600160a01b03166302760d946040518163ffffffff1660e01b815260040160206040518083038186803b15801561179957600080fd5b505afa1580156117ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117d19190810190613c86565b6117da86612f56565b9063ffffffff612f6c16565b612f85565b90506117f56127e3565b6001600160a01b03166357ad46636008546040518263ffffffff1660e01b81526004016118229190614b23565b60206040518083038186803b15801561183a57600080fd5b505afa15801561184e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118729190810190613ca4565b6001600160a01b031663867904b473feefeefeefeefeefeefeefeefeefeefeefeefeef836040518363ffffffff1660e01b81526004016118b3929190614a7e565b600060405180830381600087803b1580156118cd57600080fd5b505af11580156118e1573d6000803e3d6000fd5b505050506118f381610a7060006124f3565b6118fd60006124f3565b60010155505050565b60008060015b60028110156112e857611932611921826124f3565b60030154839063ffffffff6126af16565b9150611951611940826124f3565b60040154839063ffffffff61251d16565b915060010161190c565b6060611965611d30565b905060005b81518110156111cb57600082828151811061198157fe5b602002602001015190506000600660009054906101000a90046001600160a01b03166001600160a01b031663dacb2d0183846040516020016119c391906149d8565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016119ef929190614b4d565b60206040518083038186803b158015611a0757600080fd5b505afa158015611a1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a3f9190810190613bc3565b6000838152600760205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa6890611a9b9084908490614b31565b60405180910390a1505060010161196a565b6001546001600160a01b03163314611ad75760405162461bcd60e51b815260040161069e90614c45565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c92611b1a926001600160a01b0391821692911690614a0a565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6000611b536127e3565b6001600160a01b0316336001600160a01b03161490506000611b73612a69565b6001600160a01b0316336001600160a01b03161490508180611b925750805b611bae5760405162461bcd60e51b815260040161069e90614c25565b611bb6612545565b6001600160a01b03166394e1a448868686611bd160006124f3565b5460405160e086901b7fffffffff00000000000000000000000000000000000000000000000000000000168152611c249493929168010000000000000000900467ffffffffffffffff1690600401614ac1565b600060405180830381600087803b158015611c3e57600080fd5b505af1158015611c52573d6000803e3d6000fd5b50505050611c82858585611c6660006124f3565b5468010000000000000000900467ffffffffffffffff16612fa7565b5050505050565b611c916126d4565b73c59ba4786ca553a4591100e97673c1cff98e5b3763907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015611cd557600080fd5b505af4158015611ce9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d0d9190810190613c86565b8110611d2b5760405162461bcd60e51b815260040161069e90614df5565b601655565b606080611d3b613076565b60408051600d8082526101c0820190925291925060609190602082016101a0803883390190505090507f53797374656d537461747573000000000000000000000000000000000000000081600081518110611d9257fe5b6020026020010181815250507f5065726946696e616e636500000000000000000000000000000000000000000081600181518110611dcc57fe5b6020026020010181815250507f466565506f6f6c5374617465000000000000000000000000000000000000000081600281518110611e0657fe5b6020026020010181815250507f466565506f6f6c457465726e616c53746f72616765000000000000000000000081600381518110611e4057fe5b6020026020010181815250507f45786368616e676572000000000000000000000000000000000000000000000081600481518110611e7a57fe5b6020026020010181815250506524b9b9bab2b960d11b81600581518110611e9d57fe5b6020026020010181815250507f5065726946696e616e636553746174650000000000000000000000000000000081600681518110611ed757fe5b6020026020010181815250507f526577617264457363726f77563200000000000000000000000000000000000081600781518110611f1157fe5b6020026020010181815250507f44656c6567617465417070726f76616c7300000000000000000000000000000081600881518110611f4b57fe5b6020026020010181815250507f4574686572436f6c6c61746572616c705553440000000000000000000000000081600981518110611f8557fe5b6020026020010181815250507f52657761726473446973747269627574696f6e0000000000000000000000000081600a81518110611fbf57fe5b6020026020010181815250507f436f6c6c61746572616c4d616e6167657200000000000000000000000000000081600b81518110611ff957fe5b6020026020010181815250507f43726f7373436861696e4d616e6167657200000000000000000000000000000081600c8151811061203357fe5b60200260200101818152505061204982826130d5565b9250505090565b6000546001600160a01b031681565b6120676126d4565b600280546001600160a01b0319166001600160a01b0383161790556040517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e906108ca9083906149fc565b6003546001600160a01b031681565b60006108df61214d6120d161318a565b73c59ba4786ca553a4591100e97673c1cff98e5b3763907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b15801561211557600080fd5b505af4158015612129573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f769190810190613c86565b6121556131f2565b9063ffffffff61325a16565b612169613284565b600554421061218a5760405162461bcd60e51b815260040161069e90614d75565b612192612a69565b6001600160a01b031663cd92eba96040518163ffffffff1660e01b815260040160206040518083038186803b1580156121ca57600080fd5b505afa1580156121de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122029190810190613c86565b8611156122215760405162461bcd60e51b815260040161069e90614d55565b6040518060e001604052808867ffffffffffffffff1681526020018767ffffffffffffffff1681526020018667ffffffffffffffff168152602001858152602001848152602001838152602001828152506009612291600260ff16610fee8c6013546126af90919063ffffffff16565b6002811061229b57fe5b82516005919091029190910180546020840151604085015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff000000000000000019166801000000000000000091851691909102177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16600160801b9390911692909202919091178155606082015160018201556080820151600282015560a0820151600382015560c0909101516004909101555050505050505050565b60006108df6131f2565b61236d613309565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b600281565b600061239e612a0e565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b1580156123d657600080fd5b505afa1580156123ea573d6000803e3d6000fd5b505050506123f6612d3b565b6004546108df906001600160a01b0316612e36565b6004546001600160a01b031681565b60006108df61318a565b73feefeefeefeefeefeefeefeefeefeefeefeefeef81565b6002546001600160a01b031681565b6000612455613348565b6004549091506001600160a01b038083169116148061247c5750336001600160a01b038216145b6124985760405162461bcd60e51b815260040161069e90614d05565b6124b6826124a660006124f3565b600301549063ffffffff6126af16565b6124c060006124f3565b600301555050565b60006108df7f466565506f6f6c457465726e616c53746f72616765000000000000000000000061336f565b60006009600260ff1683601354018161250857fe5b066002811061251357fe5b6005020192915050565b60008282111561253f5760405162461bcd60e51b815260040161069e90614cb5565b50900390565b60006108df7f466565506f6f6c5374617465000000000000000000000000000000000000000061336f565b60008061257b612a69565b905060006126a3856117da846001600160a01b03166308d95cd5886040518263ffffffff1660e01b81526004016125b29190614b23565b60206040518083038186803b1580156125ca57600080fd5b505afa1580156125de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126029190810190613c86565b6040517f08d95cd50000000000000000000000000000000000000000000000000000000081526001600160a01b038716906308d95cd590612647908d90600401614b23565b60206040518083038186803b15801561265f57600080fd5b505afa158015612673573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126979190810190613c86565b9063ffffffff6133cc16565b925050505b9392505050565b6000828201838110156126a85760405162461bcd60e51b815260040161069e90614ca5565b6000546001600160a01b031633146126fe5760405162461bcd60e51b815260040161069e90614d15565b565b600061270a6133e5565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b7f666565506572696f644475726174696f6e0000000000000000000000000000006040518363ffffffff1660e01b8152600401612768929190614b3f565b60206040518083038186803b15801561278057600080fd5b505afa158015612794573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108df9190810190613c86565b60006108df7f45786368616e676572000000000000000000000000000000000000000000000061336f565b60006108df6524b9b9bab2b960d11b61336f565b60006108df7f4574686572436f6c6c61746572616c705553440000000000000000000000000061336f565b60006108df7f436f6c6c61746572616c4d616e6167657200000000000000000000000000000061336f565b60008061294761285b612f2b565b6001600160a01b03166302760d946040518163ffffffff1660e01b815260040160206040518083038186803b15801561289357600080fd5b505afa1580156128a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506128cb9190810190613c86565b73c59ba4786ca553a4591100e97673c1cff98e5b3763d5e5e6e66040518163ffffffff1660e01b815260040160206040518083038186803b15801561290f57600080fd5b505af4158015612923573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610fe29190810190613c86565b90506129666117e6826117da61295d60006124f3565b60010154612f56565b91505090565b6000808361297f57506000905080612a06565b8385156129aa576000612999600161070960018a036124f3565b90506129a6818787612570565b9150505b60006129c9826129b9896124f3565b600101549063ffffffff61325a16565b905060006129ea836129da8a6124f3565b600301549063ffffffff61325a16565b90506129f582612f85565b6129fe82612f85565b945094505050505b935093915050565b60006108df7f53797374656d537461747573000000000000000000000000000000000000000061336f565b600081612a585760405162461bcd60e51b815260040161069e90614ce5565b818381612a6157fe5b069392505050565b60006108df7f5065726946696e616e636553746174650000000000000000000000000000000061336f565b6002546040516001600160a01b039091169063907dff9790612aba908490602001614b23565b6040516020818303038152906040526001604051612ad7906149e3565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b168252612b1e93929160009081908190600401614b6d565b600060405180830381600087803b158015612b3857600080fd5b505af1158015611c82573d6000803e3d6000fd5b6000806000612b596127e3565b6001600160a01b0316639288e7048560008060016040518563ffffffff1660e01b8152600401612b8c9493929190614a40565b60206040518083038186803b158015612ba457600080fd5b505afa158015612bb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612bdc9190810190613c86565b9050612c33612c2b60165473c59ba4786ca553a4591100e97673c1cff98e5b3763907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b15801561211557600080fd5b612155613410565b811115612c47576000809250925050610848565b600080612c526127e3565b6001600160a01b031663ae3bbbbb876040518263ffffffff1660e01b8152600401612c7d91906149ee565b604080518083038186803b158015612c9457600080fd5b505afa158015612ca8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612ccc9190810190613ce0565b915091506000612cda6131f2565b905080831015612cf35750600194509250610848915050565b6000612d10612d036120d161318a565b839063ffffffff61325a16565b905080841115612d2b57600083965096505050505050610848565b5060019550909350505050915091565b6002546001600160a01b03163314801590612d6157506003546001600160a01b03163314155b8015612d7857506004546001600160a01b03163314155b156126fe57600480546001600160a01b03191633179055565b6000612d9b612f2b565b6001600160a01b03166360b3a0336040518163ffffffff1660e01b815260040160206040518083038186803b158015612dd357600080fd5b505afa158015612de7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108df9190810190613bc3565b60006108df7f44656c6567617465417070726f76616c7300000000000000000000000000000061336f565b6000808080808080612e4788612b4c565b9150915081612e685760405162461bcd60e51b815260040161069e90614d25565b8015612e865760405162461bcd60e51b815260040161069e90614d35565b612e8f886107cb565b909450925083151580612ea25750600083115b612ebe5760405162461bcd60e51b815260040161069e90614cd5565b612edc88612ecc60016124f3565b5467ffffffffffffffff16613478565b8315612ef757612eeb8461352b565b9450612ef788866135f7565b8215612f1257612f0683613793565b9550612f12888761386d565b612f1d8886886138e7565b506001979650505050505050565b60006108df7f43726f7373436861696e4d616e6167657200000000000000000000000000000061336f565b600061067782633b9aca0063ffffffff6139ac16565b60006126a883836b033b2e3c9fd0803ce80000006139e6565b60006305f5e10082046005600a820610612f9d57600a015b600a900492915050565b6002546040516001600160a01b039091169063907dff9790612fd190869086908690602001614e05565b6040516020818303038152906040526002604051612fee906149ad565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261303e9392916001600160a01b038b16906000908190600401614bcc565b600060405180830381600087803b15801561305857600080fd5b505af115801561306c573d6000803e3d6000fd5b5050505050505050565b604080516001808252818301909252606091602080830190803883390190505090507f466c657869626c6553746f726167650000000000000000000000000000000000816000815181106130c657fe5b60200260200101818152505090565b60608151835101604051908082528060200260200182016040528015613105578160200160208202803883390190505b50905060005b83518110156131475783818151811061312057fe5b602002602001015182828151811061313457fe5b602090810291909101015260010161310b565b5060005b82518110156112f95782818151811061316057fe5b602002602001015182828651018151811061317757fe5b602090810291909101015260010161314b565b60006131946133e5565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b7f7461726765745468726573686f6c6400000000000000000000000000000000006040518363ffffffff1660e01b8152600401612768929190614b3f565b60006131fc6133e5565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b7f69737375616e6365526174696f000000000000000000000000000000000000006040518363ffffffff1660e01b8152600401612768929190614b3f565b6000670de0b6b3a7640000613275848463ffffffff6139ac16565b8161327c57fe5b049392505050565b6002546001600160a01b031633148015906132aa57506003546001600160a01b03163314155b80156132c157506004546001600160a01b03163314155b156132d957600480546001600160a01b031916331790555b6000546004546001600160a01b039081169116146126fe5760405162461bcd60e51b815260040161069e90614c75565b6002546001600160a01b031633148061332c57506003546001600160a01b031633145b6126fe5760405162461bcd60e51b815260040161069e90614dc5565b60006108df7f52657761726473446973747269627574696f6e000000000000000000000000005b60008181526007602090815260408083205490516001600160a01b03909116918215159161339f918691016149b8565b604051602081830303815290604052906112f95760405162461bcd60e51b815260040161069e9190614c14565b60006126a883836b033b2e3c9fd0803ce8000000613a23565b60006108df7f466c657869626c6553746f72616765000000000000000000000000000000000061336f565b600061341a6133e5565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b7f65787465726e616c546f6b656e51756f746100000000000000000000000000006040518363ffffffff1660e01b8152600401612768929190614b3f565b6134806124c8565b6001600160a01b0316633562fd207f6c6173745f6665655f7769746864726177616c00000000000000000000000000846040516020016134c192919061497c565b60405160208183030381529060405280519060200120836040518363ffffffff1660e01b81526004016134f5929190614b3f565b600060405180830381600087803b15801561350f57600080fd5b505af1158015613523573d6000803e3d6000fd5b505050505050565b6000818160015b60028110156135ef576000613546826124f3565b600201549050600061355b82611507856124f3565b905080156135e45760008582106135725785613574565b815b9050613586838263ffffffff6126af16565b61358f856124f3565b600201556135a3868263ffffffff61251d16565b95506135b5858263ffffffff6126af16565b9450856135ca5784965050505050505061067a565b831580156135d85750600086115b156135e257600095505b505b505060001901613532565b509392505050565b816001600160a01b03811673feefeefeefeefeefeefeefeefeefeefeefeefeef14156136355760405162461bcd60e51b815260040161069e90614d95565b600061363f6127e3565b6001600160a01b03166357ad46636008546040518263ffffffff1660e01b815260040161366c9190614b23565b60206040518083038186803b15801561368457600080fd5b505afa158015613698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506136bc9190810190613ca4565b6040517f9dc29fac0000000000000000000000000000000000000000000000000000000081529091506001600160a01b03821690639dc29fac9061371a9073feefeefeefeefeefeefeefeefeefeefeefeefeef908790600401614a7e565b600060405180830381600087803b15801561373457600080fd5b505af1158015613748573d6000803e3d6000fd5b50506040517f867904b40000000000000000000000000000000000000000000000000000000081526001600160a01b038416925063867904b4915061303e9087908790600401614a7e565b6000818160015b60028110156135ef5760006137ce6137b1836124f3565b600401546137be846124f3565b600301549063ffffffff61251d16565b905080156138635760008482106137e557846137e7565b815b9050613806816137f6856124f3565b600401549063ffffffff6126af16565b61380f846124f3565b60040155613823858263ffffffff61251d16565b9450613835848263ffffffff6126af16565b93508461384957839550505050505061067a565b821580156138575750600085115b1561386157600094505b505b506000190161379a565b816001600160a01b03811673feefeefeefeefeefeefeefeefeefeefeefeefeef14156138ab5760405162461bcd60e51b815260040161069e90614d95565b6301dfe2006138b8613a55565b6001600160a01b0316631bb47b448585846040518463ffffffff1660e01b815260040161303e93929190614a99565b6002546040516001600160a01b039091169063907dff979061391190869086908690602001614a99565b604051602081830303815290604052600160405161392e906149a2565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261397593929160009081908190600401614b6d565b600060405180830381600087803b15801561398f57600080fd5b505af11580156139a3573d6000803e3d6000fd5b50505050505050565b6000826139bb575060006107c5565b828202828482816139c857fe5b04146126a85760405162461bcd60e51b815260040161069e90614d45565b600080600a83046139fd868663ffffffff6139ac16565b81613a0457fe5b0490506005600a825b0610613a1757600a015b600a9004949350505050565b600080613a4984613a3d87600a870263ffffffff6139ac16565b9063ffffffff613a8016565b90506005600a82613a0d565b60006108df7f526577617264457363726f77563200000000000000000000000000000000000061336f565b6000808211613aa15760405162461bcd60e51b815260040161069e90614cc5565b6000828481613aac57fe5b04949350505050565b60405180604001604052806002905b613acc613b3d565b815260200190600190039081613ac45790505090565b6040518060e00160405280600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600081526020016000815260200160008152602001600081525090565b60405180604001604052806002906020820280388339509192915050565b80356107c581614f5c565b80516107c581614f5c565b80516107c581614f70565b80516107c581614f79565b80516107c581614f82565b80356107c581614f79565b600060208284031215613baf57600080fd5b6000613bbb8484613b5b565b949350505050565b600060208284031215613bd557600080fd5b6000613bbb8484613b66565b60008060408385031215613bf457600080fd5b6000613c008585613b5b565b9250506020613c1185828601613b92565b9150509250929050565b600080600060608486031215613c3057600080fd5b6000613c3c8686613b5b565b9350506020613c4d86828701613b92565b9250506040613c5e86828701613b92565b9150509250925092565b600060208284031215613c7a57600080fd5b6000613bbb8484613b71565b600060208284031215613c9857600080fd5b6000613bbb8484613b7c565b600060208284031215613cb657600080fd5b6000613bbb8484613b87565b600060208284031215613cd457600080fd5b6000613bbb8484613b92565b60008060408385031215613cf357600080fd5b6000613cff8585613b7c565b9250506020613c1185828601613b71565b60008060408385031215613d2357600080fd5b6000613d2f8585613b7c565b9250506020613c1185828601613b7c565b600080600080600080600080610100898b031215613d5d57600080fd5b6000613d698b8b613b92565b9850506020613d7a8b828c01613b92565b9750506040613d8b8b828c01613b92565b9650506060613d9c8b828c01613b92565b9550506080613dad8b828c01613b92565b94505060a0613dbe8b828c01613b92565b93505060c0613dcf8b828c01613b92565b92505060e0613de08b828c01613b92565b9150509295985092959890939650565b6000613dfc8383613ee6565b505060400190565b6000613e108383613f3b565b505060200190565b613e2181614edc565b82525050565b613e2181614ea2565b613e21613e3c82614ea2565b614f3b565b613e4a81614e8f565b613e54818461067a565b9250613e5f826108e2565b8060005b83811015613523578151613e778782613df0565b9650613e8283614e89565b925050600101613e63565b6000613e9882614e95565b613ea28185614e99565b9350613ead83614e89565b8060005b83811015613edb578151613ec58882613e04565b9750613ed083614e89565b925050600101613eb1565b509495945050505050565b613eef81614e8f565b613ef9818461067a565b9250613f04826108e2565b8060005b83811015613523578151613f1c8782613e04565b9650613f2783614e89565b925050600101613f08565b613e2181614ead565b613e21816108e2565b613e21613f50826108e2565b6108e2565b6000613f6082614e95565b613f6a8185614e99565b9350613f7a818560208601614f0b565b613f8381614f4c565b9093019392505050565b613e2181614eb2565b613e2181614ee7565b613e2181614ef5565b6000613fb5602083614e99565b7f49737375657220616e64205065726946696e616e63655374617465206f6e6c79815260200192915050565b6000613fee601783614e99565b7f4f6e6c7920496e7465726e616c20436f6e747261637473000000000000000000815260200192915050565b6000614027603583614e99565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527f2063616e20616363657074206f776e6572736869700000000000000000000000602082015260400192915050565b6000614086602983614e99565b7f646973747269627574696e672066656520726577617264206e6f74207965742081527f617661696c61626c650000000000000000000000000000000000000000000000602082015260400192915050565b60006140e5601d83614e99565b7f546f6f206561726c7920746f20636c6f73652066656520706572696f64000000815260200192915050565b600061411e601383614e99565b7f4f776e6572206f6e6c792066756e6374696f6e00000000000000000000000000815260200192915050565b600061415760248361067a565b7f46656573436c61696d656428616464726573732c75696e743235362c75696e7481527f3235362900000000000000000000000000000000000000000000000000000000602082015260240192915050565b60006141b6603883614e99565b7f416c6c6f636174696e6720666565207265776172647320697320706f7373696281527f6c65206f6e6c79206f6e636520696e206120706572696f640000000000000000602082015260400192915050565b6000614215602783614e99565b7f616c6c6f636174696e672066656520726577617264206e6f742079657420617681527f61696c61626c6500000000000000000000000000000000000000000000000000602082015260400192915050565b600061427460378361067a565b7f49737375616e636544656274526174696f456e74727928616464726573732c7581527f696e743235362c75696e743235362c75696e7432353629000000000000000000602082015260370192915050565b60006142d3601b83614e99565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b600061430c601e83614e99565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b6000614345601a83614e99565b7f536166654d6174683a206469766973696f6e206279207a65726f000000000000815260200192915050565b600061437e604083614e99565b7f4e6f2066656573206f72207265776172647320617661696c61626c6520666f7281527f20706572696f642c206f72206665657320616c726561647920636c61696d6564602082015260400192915050565b60006143dd60118361067a565b7f4d697373696e6720616464726573733a20000000000000000000000000000000815260110192915050565b6000614416601883614e99565b7f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815260200192915050565b600061444f601f83614e99565b7f4e6f7420617070726f76656420746f20636c61696d206f6e20626568616c6600815260200192915050565b6000614488601e83614e99565b7f43616c6c6572206973206e6f742072657761726473417574686f726974790000815260200192915050565b60006144c1602f83614e99565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681527f6f726d207468697320616374696f6e0000000000000000000000000000000000602082015260400192915050565b6000614520601f83614e99565b7f432d526174696f2062656c6f772070656e616c7479207468726573686f6c6400815260200192915050565b6000614559601f83614e99565b7f412070796e7468206f722050455249207261746520697320696e76616c696400815260200192915050565b6000614592602183614e99565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f81527f7700000000000000000000000000000000000000000000000000000000000000602082015260400192915050565b60006145f1601683614e99565b7f43616e6e6f7420696d706f727420626164206461746100000000000000000000815260200192915050565b600061462a601d83614e99565b7f4578636565647320746865204645455f504552494f445f4c454e475448000000815260200192915050565b6000614663602983614e99565b7f43616e206f6e6c7920706572666f726d207468697320616374696f6e2064757281527f696e672073657475700000000000000000000000000000000000000000000000602082015260400192915050565b60006146c260198361067a565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b60006146fb601183614e99565b7f64656274206d616e61676572206f6e6c79000000000000000000000000000000815260200192915050565b6000614734601783614e99565b7f4665652061646472657373206e6f7420616c6c6f776564000000000000000000815260200192915050565b600061476d604483614e99565b7f66656520726577617264732073686f756c64206265206469737472696275746581527f64206f7220616c6c6f6361746564206265666f726520636c6f73696e6720706560208201527f72696f6400000000000000000000000000000000000000000000000000000000604082015260600192915050565b60006147f2603a83614e99565b7f446973747269627574696e6720666565207265776172647320697320706f737381527f69626c65206f6e6c79206f6e636520696e206120706572696f64000000000000602082015260400192915050565b600061485160188361067a565b7f466565506572696f64436c6f7365642875696e74323536290000000000000000815260180192915050565b600061488a601783614e99565b7f4f6e6c79207468652070726f78792063616e2063616c6c000000000000000000815260200192915050565b60006148c3602083614e99565b7f43757272656e7420706572696f64206973206e6f7420636c6f73656420796574815260200192915050565b60006148fc601b83614e99565b7f46656520506572696f64204475726174696f6e206e6f74207365740000000000815260200192915050565b6000614935602083614e99565b7f546f6c6572616e63652076616c75652063616e6e6f7420657863656564732031815260200192915050565b613e2181614f00565b613e2181614ec9565b613e2181614ed6565b60006149888285613f44565b6020820191506149988284613e30565b5060140192915050565b60006107c58261414a565b60006107c582614267565b60006149c3826143d0565b91506149cf8284613f44565b50602001919050565b60006149c3826146b5565b60006107c582614844565b602081016107c58284613e27565b602081016107c58284613e18565b60408101614a188285613e27565b6126a86020830184613e27565b60408101614a338285613e27565b6126a86020830184613f9f565b60808101614a4e8287613e27565b614a5b6020830186613f9f565b614a686040830185613f9f565b614a756060830184613f32565b95945050505050565b60408101614a8c8285613e27565b6126a86020830184613f3b565b60608101614aa78286613e27565b614ab46020830185613f3b565b613bbb6040830184613f3b565b60808101614acf8287613e27565b614adc6020830186613f3b565b614ae96040830185613f3b565b614a756060830184614961565b608081016107c58284613e41565b602080825281016126a88184613e8d565b602081016107c58284613f32565b602081016107c58284613f3b565b60408101614a188285613f3b565b60408101614a8c8285613f3b565b60408101614b5b8285613f3b565b8181036020830152613bbb8184613f55565b60c08082528101614b7e8189613f55565b9050614b8d6020830188613f9f565b614b9a6040830187613f3b565b614ba76060830186613f96565b614bb46080830185613f96565b614bc160a0830184613f96565b979650505050505050565b60c08082528101614bdd8189613f55565b9050614bec6020830188613f9f565b614bf96040830187613f3b565b614ba76060830186613f3b565b602081016107c58284613f8d565b602080825281016126a88184613f55565b6020808252810161067781613fa8565b6020808252810161067781613fe1565b602080825281016106778161401a565b6020808252810161067781614079565b60208082528101610677816140d8565b6020808252810161067781614111565b60208082528101610677816141a9565b6020808252810161067781614208565b60208082528101610677816142c6565b60208082528101610677816142ff565b6020808252810161067781614338565b6020808252810161067781614371565b6020808252810161067781614409565b6020808252810161067781614442565b602080825281016106778161447b565b60208082528101610677816144b4565b6020808252810161067781614513565b602080825281016106778161454c565b6020808252810161067781614585565b60208082528101610677816145e4565b602080825281016106778161461d565b6020808252810161067781614656565b60208082528101610677816146ee565b6020808252810161067781614727565b6020808252810161067781614760565b60208082528101610677816147e5565b602080825281016106778161487d565b60208082528101610677816148b6565b60208082528101610677816148ef565b6020808252810161067781614928565b60608101614aa78286613f3b565b60e08101614e21828a61496a565b614e2e602083018961496a565b614e3b604083018861496a565b614e486060830187613f3b565b614e556080830186613f3b565b614e6260a0830185613f3b565b614e6f60c0830184613f3b565b98975050505050505050565b602081016107c58284614973565b60200190565b50600290565b5190565b90815260200190565b600061067782614ebd565b151590565b600061067782614ea2565b6001600160a01b031690565b67ffffffffffffffff1690565b60ff1690565b600061067782614eb2565b6000610677613f50836108e2565b6000610677826108e2565b600061067782614ec9565b60005b83811015614f26578181015183820152602001614f0e565b83811115614f35576000848401525b50505050565b600061067782600061067782614f56565b601f01601f191690565b60601b90565b614f6581614ea2565b811461152757600080fd5b614f6581614ead565b614f65816108e2565b614f6581614eb256fea365627a7a72315820882079c2d3031f6a74125aae31f9cd51dec8225767dd29b17b1d172a05b79e396c6578706572696d656e74616cf564736f6c634300051000400000000000000000000000006e2eea6d56368e60f74a3f89f30b15b46bf3f7df000000000000000000000000166220468aff631290b7e1ddff7f45b052de832400000000000000000000000022f5d16097cf2396d6c893a77ea3b97234c0c114
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102f45760003560e01c80636683051b11610191578063ac834193116100e3578063d294f09311610097578063eb1edd6111610071578063eb1edd6114610578578063ec55688914610580578063fd1f498d14610588576102f4565b8063d294f09314610560578063d67bdd2514610568578063e0e6393d14610570576102f4565b8063b410a034116100c8578063b410a03414610530578063bc67f83214610538578063cff2ddad1461054b576102f4565b8063ac83419314610515578063b10090b81461051d576102f4565b806386645274116101455780638da5cb5b1161011f5780638da5cb5b146104f257806397107d6d146104fa5780639cbdaeb61461050d576102f4565b806386645274146104b75780638844578a146104ca578063899ffef4146104dd576102f4565b80636de813f1116101765780636de813f11461049f57806374185360146104a757806379ba5097146104af576102f4565b80636683051b146104845780636841e9b41461048c576102f4565b80633c41d1731161024a57806353a47bb7116101fe5780635fe47778116101d85780635fe477781461046157806362115496146104695780636466f45e14610471576102f4565b806353a47bb714610431578063569249d01461044657806359a2f19f1461044e576102f4565b80633fcd22401161022f5780633fcd2240146103fb578063446530d11461042157806346ba2d9014610429576102f4565b80633c41d173146103eb5780633ebc457a146103f3576102f4565b80631627540c116102ac578063269652671161028657806326965267146103ae5780632af64bd3146103b657806333140016146103cb576102f4565b80631627540c1461038057806322425fa41461039357806322bf55ef1461039b576102f4565b80630813071c116102dd5780630813071c146103375780630de586151461034a578063131b0ae71461036b576102f4565b806304f3bcec146102f957806307ea50cd14610317575b600080fd5b61030161059b565b60405161030e9190614c06565b60405180910390f35b61032a610325366004613b9d565b6105aa565b60405161030e9190614b23565b61032a610345366004613be1565b61067f565b61035d610358366004613b9d565b6107cb565b60405161030e929190614b3f565b61037e610379366004613b9d565b61084d565b005b61037e61038e366004613b9d565b610877565b61032a6108d5565b61037e6103a9366004613cc2565b6108e5565b61032a610a95565b6103be610a9f565b60405161030e9190614b15565b6103de6103d9366004613b9d565b610bcf565b60405161030e9190614af6565b6103be610e33565b61037e610e41565b61040e610409366004613cc2565b6111cf565b60405161030e9796959493929190614e13565b61032a611278565b61032a61127e565b610439611284565b60405161030e91906149ee565b61032a611293565b6103be61045c366004613b9d565b6112ee565b61037e611300565b61032a61152a565b6103be61047f366004613b9d565b611530565b6103be61165a565b61037e61049a366004613cc2565b611663565b61032a611906565b61037e61195b565b61037e611aad565b61037e6104c5366004613c1b565b611b49565b61037e6104d8366004613cc2565b611c89565b6104e5611d30565b60405161030e9190614b04565b610439612050565b61037e610508366004613b9d565b61205f565b6103016120b2565b61032a6120c1565b61037e61052b366004613d40565b612161565b61032a61235b565b61037e610546366004613b9d565b612365565b61055361238f565b60405161030e9190614e7b565b6103be612394565b61043961240b565b61032a61241a565b610439612424565b61030161243c565b61037e610596366004613cc2565b61244b565b6006546001600160a01b031681565b60006105b46124c8565b6001600160a01b031663bdc963d87f6c6173745f6665655f7769746864726177616c00000000000000000000000000846040516020016105f592919061497c565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004016106279190614b23565b60206040518083038186803b15801561063f57600080fd5b505afa158015610653573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106779190810190613c86565b90505b919050565b6000816106a75760405162461bcd60e51b815260040161069e90614dd5565b60405180910390fd5b600282106106c75760405162461bcd60e51b815260040161069e90614d65565b6106d3600183036124f3565b5468010000000000000000900467ffffffffffffffff166106f6575060006107c5565b60006107266001610709600186036124f3565b5468010000000000000000900467ffffffffffffffff169061251d565b9050600080610733612545565b6001600160a01b031663d29c000a87856040518363ffffffff1660e01b8152600401610760929190614a7e565b604080518083038186803b15801561077757600080fd5b505afa15801561078b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107af9190810190613d10565b90925090506107bf838383612570565b93505050505b92915050565b6000806107d6613ab5565b6107df84610bcf565b905060008060015b60028110156108405761080c8482600281106107ff57fe5b60200201515184906126af565b925061083684826002811061081d57fe5b602002015160016020020151839063ffffffff6126af16565b91506001016107e7565b509093509150505b915091565b6108556126d4565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61087f6126d4565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906108ca9083906149ee565b60405180910390a150565b60006108df612700565b90505b90565b60006108ef6127b8565b6001600160a01b0316331490506000806109076127e3565b6001600160a01b031663c9a2f3ad336040518263ffffffff1660e01b815260040161093291906149fc565b60206040518083038186803b15801561094a57600080fd5b505afa15801561095e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109829190810190613c86565b1415905060006109906127f7565b6001600160a01b0316336001600160a01b031614905060006109b0612822565b6001600160a01b031663b38988f7336040518263ffffffff1660e01b81526004016109db91906149fc565b60206040518083038186803b1580156109f357600080fd5b505afa158015610a07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a2b9190810190613c68565b90508380610a365750825b80610a3e5750815b80610a465750805b610a625760405162461bcd60e51b815260040161069e90614c35565b610a8085610a7060006124f3565b600101549063ffffffff6126af16565b610a8a60006124f3565b600101555050505050565b60006108df61284d565b60006060610aab611d30565b905060005b8151811015610bc6576000828281518110610ac757fe5b602090810291909101810151600081815260079092526040918290205460065492517f21f8a7210000000000000000000000000000000000000000000000000000000081529193506001600160a01b039081169216906321f8a72190610b31908590600401614b23565b60206040518083038186803b158015610b4957600080fd5b505afa158015610b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b819190810190613bc3565b6001600160a01b0316141580610bac57506000818152600760205260409020546001600160a01b0316155b15610bbd57600093505050506108e2565b50600101610ab0565b50600191505090565b610bd7613ab5565b6000806000610be4612545565b6040517fb326f84e0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0382169063b326f84e90610c2f908890600090600401614a25565b604080518083038186803b158015610c4657600080fd5b505afa158015610c5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c7e9190810190613d10565b909350915081158015610c8f575082155b15610ca757610c9c613ab5565b935061067a92505050565b600080610cb66000868661296c565b8751829052875160200181905290925090506000610cd3886105aa565b905060015b8015610e275760001981016000610cee826124f3565b5468010000000000000000900467ffffffffffffffff1690508015801590610d285750610d1a836124f3565b5467ffffffffffffffff1684105b15610e1c576000610d4082600163ffffffff61251d16565b6040517fd29c000a0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0389169063d29c000a90610d8a908f908590600401614a7e565b604080518083038186803b158015610da157600080fd5b505afa158015610db5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610dd99190810190613d10565b909a509850610de9848b8b61296c565b9097509550868b8560028110610dfb57fe5b602002015152858b8560028110610e0e57fe5b602002015160016020020152505b505060001901610cd8565b50505050505050919050565b601454610100900460ff1690565b610e49612a0e565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015610e8157600080fd5b505afa158015610e95573d6000803e3d6000fd5b505050506000610ea3612700565b11610ec05760405162461bcd60e51b815260040161069e90614de5565b610ec8612700565b4203610ed460006124f3565b54600160801b900467ffffffffffffffff161115610f045760405162461bcd60e51b815260040161069e90614c65565b60145460ff1680610f1c5750601454610100900460ff165b610f385760405162461bcd60e51b815260040161069e90614da5565b6000610f43816124f3565b90506000610f5160016124f3565b9050610f828260010154610f768360020154846001015461251d90919063ffffffff16565b9063ffffffff6126af16565b610f8c60006124f3565b60010155600380830154600483015491830154610fb392610f76919063ffffffff61251d16565b610fbd60006124f3565b60030155601354610ffa90600290610fee90600190610fe2908463ffffffff6126af16565b9063ffffffff61251d16565b9063ffffffff612a3916565b60138190556009906002811061100c57fe5b6005020180547fffffffffffffffff00000000000000000000000000000000000000000000000016815560006001808301829055600283018290556003830182905560049092015561107890611061816124f3565b5467ffffffffffffffff169063ffffffff6126af16565b61108260006124f3565b805467ffffffffffffffff191667ffffffffffffffff929092169190911790556110aa612a69565b6001600160a01b031663cd92eba96040518163ffffffff1660e01b815260040160206040518083038186803b1580156110e257600080fd5b505afa1580156110f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061111a9190810190613c86565b61112460006124f3565b805467ffffffffffffffff9290921668010000000000000000026fffffffffffffffff0000000000000000199092169190911790554261116460006124f3565b805467ffffffffffffffff92909216600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9092169190911790556014805461ffff191690556111cb6111bb60016124f3565b5467ffffffffffffffff16612a94565b5050565b60008060008060008060006111e2613ae2565b6111eb896124f3565b6040805160e081018252825467ffffffffffffffff808216808452680100000000000000008304821660208501819052600160801b909304909116938301849052600185015460608401819052600286015460808501819052600387015460a0860181905260049097015460c0909501859052919f929e50939c50929a5091985091965090945092505050565b60165481565b60055481565b6001546001600160a01b031681565b60008060015b60028110156112e8576112bf6112ae826124f3565b60010154839063ffffffff6126af16565b91506112de6112cd826124f3565b60020154839063ffffffff61251d16565b9150600101611299565b50905090565b60006112f982612b4c565b5092915050565b611308612d3b565b6000611312612d91565b6004546001600160a01b039081169116149050806113425760405162461bcd60e51b815260040161069e90614d85565b600061134c612700565b116113695760405162461bcd60e51b815260040161069e90614de5565b611371612700565b420361137d60006124f3565b54600160801b900467ffffffffffffffff1611156113ad5760405162461bcd60e51b815260040161069e90614c55565b60145460ff16156113d05760405162461bcd60e51b815260040161069e90614db5565b6014805460ff1916600117905560006113e761284d565b9050600081116113fc57506000601555611527565b6114046127e3565b6001600160a01b03166357ad46636008546040518263ffffffff1660e01b81526004016114319190614b23565b60206040518083038186803b15801561144957600080fd5b505afa15801561145d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114819190810190613ca4565b6001600160a01b0316639dc29fac73feefeefeefeefeefeefeefeefeefeefeefeefeef836040518363ffffffff1660e01b81526004016114c2929190614a7e565b600060405180830381600087803b1580156114dc57600080fd5b505af11580156114f0573d6000803e3d6000fd5b5050506015829055506115178161150760006124f3565b600101549063ffffffff61251d16565b61152160006124f3565b60010155505b50565b60155481565b600061153a612a0e565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b15801561157257600080fd5b505afa158015611586573d6000803e3d6000fd5b50505050611592612d3b565b61159a612e0b565b600480546040517f21f4ae570000000000000000000000000000000000000000000000000000000081526001600160a01b03938416936321f4ae57936115e593889392169101614a0a565b60206040518083038186803b1580156115fd57600080fd5b505afa158015611611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116359190810190613c68565b6116515760405162461bcd60e51b815260040161069e90614cf5565b61067782612e36565b60145460ff1690565b61166b612d3b565b6000611675612d91565b6004546001600160a01b039081169116149050806116a55760405162461bcd60e51b815260040161069e90614d85565b60006116af612700565b116116cc5760405162461bcd60e51b815260040161069e90614de5565b6116d4612700565b42036116e060006124f3565b54600160801b900467ffffffffffffffff1611156117105760405162461bcd60e51b815260040161069e90614c95565b601454610100900460ff16156117385760405162461bcd60e51b815260040161069e90614c85565b6014805461ff00191661010017905581611751576111cb565b60006117eb6117e6611761612f2b565b6001600160a01b03166302760d946040518163ffffffff1660e01b815260040160206040518083038186803b15801561179957600080fd5b505afa1580156117ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117d19190810190613c86565b6117da86612f56565b9063ffffffff612f6c16565b612f85565b90506117f56127e3565b6001600160a01b03166357ad46636008546040518263ffffffff1660e01b81526004016118229190614b23565b60206040518083038186803b15801561183a57600080fd5b505afa15801561184e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118729190810190613ca4565b6001600160a01b031663867904b473feefeefeefeefeefeefeefeefeefeefeefeefeef836040518363ffffffff1660e01b81526004016118b3929190614a7e565b600060405180830381600087803b1580156118cd57600080fd5b505af11580156118e1573d6000803e3d6000fd5b505050506118f381610a7060006124f3565b6118fd60006124f3565b60010155505050565b60008060015b60028110156112e857611932611921826124f3565b60030154839063ffffffff6126af16565b9150611951611940826124f3565b60040154839063ffffffff61251d16565b915060010161190c565b6060611965611d30565b905060005b81518110156111cb57600082828151811061198157fe5b602002602001015190506000600660009054906101000a90046001600160a01b03166001600160a01b031663dacb2d0183846040516020016119c391906149d8565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016119ef929190614b4d565b60206040518083038186803b158015611a0757600080fd5b505afa158015611a1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a3f9190810190613bc3565b6000838152600760205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa6890611a9b9084908490614b31565b60405180910390a1505060010161196a565b6001546001600160a01b03163314611ad75760405162461bcd60e51b815260040161069e90614c45565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c92611b1a926001600160a01b0391821692911690614a0a565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6000611b536127e3565b6001600160a01b0316336001600160a01b03161490506000611b73612a69565b6001600160a01b0316336001600160a01b03161490508180611b925750805b611bae5760405162461bcd60e51b815260040161069e90614c25565b611bb6612545565b6001600160a01b03166394e1a448868686611bd160006124f3565b5460405160e086901b7fffffffff00000000000000000000000000000000000000000000000000000000168152611c249493929168010000000000000000900467ffffffffffffffff1690600401614ac1565b600060405180830381600087803b158015611c3e57600080fd5b505af1158015611c52573d6000803e3d6000fd5b50505050611c82858585611c6660006124f3565b5468010000000000000000900467ffffffffffffffff16612fa7565b5050505050565b611c916126d4565b73c59ba4786ca553a4591100e97673c1cff98e5b3763907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015611cd557600080fd5b505af4158015611ce9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d0d9190810190613c86565b8110611d2b5760405162461bcd60e51b815260040161069e90614df5565b601655565b606080611d3b613076565b60408051600d8082526101c0820190925291925060609190602082016101a0803883390190505090507f53797374656d537461747573000000000000000000000000000000000000000081600081518110611d9257fe5b6020026020010181815250507f5065726946696e616e636500000000000000000000000000000000000000000081600181518110611dcc57fe5b6020026020010181815250507f466565506f6f6c5374617465000000000000000000000000000000000000000081600281518110611e0657fe5b6020026020010181815250507f466565506f6f6c457465726e616c53746f72616765000000000000000000000081600381518110611e4057fe5b6020026020010181815250507f45786368616e676572000000000000000000000000000000000000000000000081600481518110611e7a57fe5b6020026020010181815250506524b9b9bab2b960d11b81600581518110611e9d57fe5b6020026020010181815250507f5065726946696e616e636553746174650000000000000000000000000000000081600681518110611ed757fe5b6020026020010181815250507f526577617264457363726f77563200000000000000000000000000000000000081600781518110611f1157fe5b6020026020010181815250507f44656c6567617465417070726f76616c7300000000000000000000000000000081600881518110611f4b57fe5b6020026020010181815250507f4574686572436f6c6c61746572616c705553440000000000000000000000000081600981518110611f8557fe5b6020026020010181815250507f52657761726473446973747269627574696f6e0000000000000000000000000081600a81518110611fbf57fe5b6020026020010181815250507f436f6c6c61746572616c4d616e6167657200000000000000000000000000000081600b81518110611ff957fe5b6020026020010181815250507f43726f7373436861696e4d616e6167657200000000000000000000000000000081600c8151811061203357fe5b60200260200101818152505061204982826130d5565b9250505090565b6000546001600160a01b031681565b6120676126d4565b600280546001600160a01b0319166001600160a01b0383161790556040517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e906108ca9083906149fc565b6003546001600160a01b031681565b60006108df61214d6120d161318a565b73c59ba4786ca553a4591100e97673c1cff98e5b3763907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b15801561211557600080fd5b505af4158015612129573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f769190810190613c86565b6121556131f2565b9063ffffffff61325a16565b612169613284565b600554421061218a5760405162461bcd60e51b815260040161069e90614d75565b612192612a69565b6001600160a01b031663cd92eba96040518163ffffffff1660e01b815260040160206040518083038186803b1580156121ca57600080fd5b505afa1580156121de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122029190810190613c86565b8611156122215760405162461bcd60e51b815260040161069e90614d55565b6040518060e001604052808867ffffffffffffffff1681526020018767ffffffffffffffff1681526020018667ffffffffffffffff168152602001858152602001848152602001838152602001828152506009612291600260ff16610fee8c6013546126af90919063ffffffff16565b6002811061229b57fe5b82516005919091029190910180546020840151604085015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff000000000000000019166801000000000000000091851691909102177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16600160801b9390911692909202919091178155606082015160018201556080820151600282015560a0820151600382015560c0909101516004909101555050505050505050565b60006108df6131f2565b61236d613309565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b600281565b600061239e612a0e565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b1580156123d657600080fd5b505afa1580156123ea573d6000803e3d6000fd5b505050506123f6612d3b565b6004546108df906001600160a01b0316612e36565b6004546001600160a01b031681565b60006108df61318a565b73feefeefeefeefeefeefeefeefeefeefeefeefeef81565b6002546001600160a01b031681565b6000612455613348565b6004549091506001600160a01b038083169116148061247c5750336001600160a01b038216145b6124985760405162461bcd60e51b815260040161069e90614d05565b6124b6826124a660006124f3565b600301549063ffffffff6126af16565b6124c060006124f3565b600301555050565b60006108df7f466565506f6f6c457465726e616c53746f72616765000000000000000000000061336f565b60006009600260ff1683601354018161250857fe5b066002811061251357fe5b6005020192915050565b60008282111561253f5760405162461bcd60e51b815260040161069e90614cb5565b50900390565b60006108df7f466565506f6f6c5374617465000000000000000000000000000000000000000061336f565b60008061257b612a69565b905060006126a3856117da846001600160a01b03166308d95cd5886040518263ffffffff1660e01b81526004016125b29190614b23565b60206040518083038186803b1580156125ca57600080fd5b505afa1580156125de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126029190810190613c86565b6040517f08d95cd50000000000000000000000000000000000000000000000000000000081526001600160a01b038716906308d95cd590612647908d90600401614b23565b60206040518083038186803b15801561265f57600080fd5b505afa158015612673573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126979190810190613c86565b9063ffffffff6133cc16565b925050505b9392505050565b6000828201838110156126a85760405162461bcd60e51b815260040161069e90614ca5565b6000546001600160a01b031633146126fe5760405162461bcd60e51b815260040161069e90614d15565b565b600061270a6133e5565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b7f666565506572696f644475726174696f6e0000000000000000000000000000006040518363ffffffff1660e01b8152600401612768929190614b3f565b60206040518083038186803b15801561278057600080fd5b505afa158015612794573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108df9190810190613c86565b60006108df7f45786368616e676572000000000000000000000000000000000000000000000061336f565b60006108df6524b9b9bab2b960d11b61336f565b60006108df7f4574686572436f6c6c61746572616c705553440000000000000000000000000061336f565b60006108df7f436f6c6c61746572616c4d616e6167657200000000000000000000000000000061336f565b60008061294761285b612f2b565b6001600160a01b03166302760d946040518163ffffffff1660e01b815260040160206040518083038186803b15801561289357600080fd5b505afa1580156128a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506128cb9190810190613c86565b73c59ba4786ca553a4591100e97673c1cff98e5b3763d5e5e6e66040518163ffffffff1660e01b815260040160206040518083038186803b15801561290f57600080fd5b505af4158015612923573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610fe29190810190613c86565b90506129666117e6826117da61295d60006124f3565b60010154612f56565b91505090565b6000808361297f57506000905080612a06565b8385156129aa576000612999600161070960018a036124f3565b90506129a6818787612570565b9150505b60006129c9826129b9896124f3565b600101549063ffffffff61325a16565b905060006129ea836129da8a6124f3565b600301549063ffffffff61325a16565b90506129f582612f85565b6129fe82612f85565b945094505050505b935093915050565b60006108df7f53797374656d537461747573000000000000000000000000000000000000000061336f565b600081612a585760405162461bcd60e51b815260040161069e90614ce5565b818381612a6157fe5b069392505050565b60006108df7f5065726946696e616e636553746174650000000000000000000000000000000061336f565b6002546040516001600160a01b039091169063907dff9790612aba908490602001614b23565b6040516020818303038152906040526001604051612ad7906149e3565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b168252612b1e93929160009081908190600401614b6d565b600060405180830381600087803b158015612b3857600080fd5b505af1158015611c82573d6000803e3d6000fd5b6000806000612b596127e3565b6001600160a01b0316639288e7048560008060016040518563ffffffff1660e01b8152600401612b8c9493929190614a40565b60206040518083038186803b158015612ba457600080fd5b505afa158015612bb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612bdc9190810190613c86565b9050612c33612c2b60165473c59ba4786ca553a4591100e97673c1cff98e5b3763907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b15801561211557600080fd5b612155613410565b811115612c47576000809250925050610848565b600080612c526127e3565b6001600160a01b031663ae3bbbbb876040518263ffffffff1660e01b8152600401612c7d91906149ee565b604080518083038186803b158015612c9457600080fd5b505afa158015612ca8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612ccc9190810190613ce0565b915091506000612cda6131f2565b905080831015612cf35750600194509250610848915050565b6000612d10612d036120d161318a565b839063ffffffff61325a16565b905080841115612d2b57600083965096505050505050610848565b5060019550909350505050915091565b6002546001600160a01b03163314801590612d6157506003546001600160a01b03163314155b8015612d7857506004546001600160a01b03163314155b156126fe57600480546001600160a01b03191633179055565b6000612d9b612f2b565b6001600160a01b03166360b3a0336040518163ffffffff1660e01b815260040160206040518083038186803b158015612dd357600080fd5b505afa158015612de7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108df9190810190613bc3565b60006108df7f44656c6567617465417070726f76616c7300000000000000000000000000000061336f565b6000808080808080612e4788612b4c565b9150915081612e685760405162461bcd60e51b815260040161069e90614d25565b8015612e865760405162461bcd60e51b815260040161069e90614d35565b612e8f886107cb565b909450925083151580612ea25750600083115b612ebe5760405162461bcd60e51b815260040161069e90614cd5565b612edc88612ecc60016124f3565b5467ffffffffffffffff16613478565b8315612ef757612eeb8461352b565b9450612ef788866135f7565b8215612f1257612f0683613793565b9550612f12888761386d565b612f1d8886886138e7565b506001979650505050505050565b60006108df7f43726f7373436861696e4d616e6167657200000000000000000000000000000061336f565b600061067782633b9aca0063ffffffff6139ac16565b60006126a883836b033b2e3c9fd0803ce80000006139e6565b60006305f5e10082046005600a820610612f9d57600a015b600a900492915050565b6002546040516001600160a01b039091169063907dff9790612fd190869086908690602001614e05565b6040516020818303038152906040526002604051612fee906149ad565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261303e9392916001600160a01b038b16906000908190600401614bcc565b600060405180830381600087803b15801561305857600080fd5b505af115801561306c573d6000803e3d6000fd5b5050505050505050565b604080516001808252818301909252606091602080830190803883390190505090507f466c657869626c6553746f726167650000000000000000000000000000000000816000815181106130c657fe5b60200260200101818152505090565b60608151835101604051908082528060200260200182016040528015613105578160200160208202803883390190505b50905060005b83518110156131475783818151811061312057fe5b602002602001015182828151811061313457fe5b602090810291909101015260010161310b565b5060005b82518110156112f95782818151811061316057fe5b602002602001015182828651018151811061317757fe5b602090810291909101015260010161314b565b60006131946133e5565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b7f7461726765745468726573686f6c6400000000000000000000000000000000006040518363ffffffff1660e01b8152600401612768929190614b3f565b60006131fc6133e5565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b7f69737375616e6365526174696f000000000000000000000000000000000000006040518363ffffffff1660e01b8152600401612768929190614b3f565b6000670de0b6b3a7640000613275848463ffffffff6139ac16565b8161327c57fe5b049392505050565b6002546001600160a01b031633148015906132aa57506003546001600160a01b03163314155b80156132c157506004546001600160a01b03163314155b156132d957600480546001600160a01b031916331790555b6000546004546001600160a01b039081169116146126fe5760405162461bcd60e51b815260040161069e90614c75565b6002546001600160a01b031633148061332c57506003546001600160a01b031633145b6126fe5760405162461bcd60e51b815260040161069e90614dc5565b60006108df7f52657761726473446973747269627574696f6e000000000000000000000000005b60008181526007602090815260408083205490516001600160a01b03909116918215159161339f918691016149b8565b604051602081830303815290604052906112f95760405162461bcd60e51b815260040161069e9190614c14565b60006126a883836b033b2e3c9fd0803ce8000000613a23565b60006108df7f466c657869626c6553746f72616765000000000000000000000000000000000061336f565b600061341a6133e5565b6001600160a01b03166323257c2b6d53797374656d53657474696e677360901b7f65787465726e616c546f6b656e51756f746100000000000000000000000000006040518363ffffffff1660e01b8152600401612768929190614b3f565b6134806124c8565b6001600160a01b0316633562fd207f6c6173745f6665655f7769746864726177616c00000000000000000000000000846040516020016134c192919061497c565b60405160208183030381529060405280519060200120836040518363ffffffff1660e01b81526004016134f5929190614b3f565b600060405180830381600087803b15801561350f57600080fd5b505af1158015613523573d6000803e3d6000fd5b505050505050565b6000818160015b60028110156135ef576000613546826124f3565b600201549050600061355b82611507856124f3565b905080156135e45760008582106135725785613574565b815b9050613586838263ffffffff6126af16565b61358f856124f3565b600201556135a3868263ffffffff61251d16565b95506135b5858263ffffffff6126af16565b9450856135ca5784965050505050505061067a565b831580156135d85750600086115b156135e257600095505b505b505060001901613532565b509392505050565b816001600160a01b03811673feefeefeefeefeefeefeefeefeefeefeefeefeef14156136355760405162461bcd60e51b815260040161069e90614d95565b600061363f6127e3565b6001600160a01b03166357ad46636008546040518263ffffffff1660e01b815260040161366c9190614b23565b60206040518083038186803b15801561368457600080fd5b505afa158015613698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506136bc9190810190613ca4565b6040517f9dc29fac0000000000000000000000000000000000000000000000000000000081529091506001600160a01b03821690639dc29fac9061371a9073feefeefeefeefeefeefeefeefeefeefeefeefeef908790600401614a7e565b600060405180830381600087803b15801561373457600080fd5b505af1158015613748573d6000803e3d6000fd5b50506040517f867904b40000000000000000000000000000000000000000000000000000000081526001600160a01b038416925063867904b4915061303e9087908790600401614a7e565b6000818160015b60028110156135ef5760006137ce6137b1836124f3565b600401546137be846124f3565b600301549063ffffffff61251d16565b905080156138635760008482106137e557846137e7565b815b9050613806816137f6856124f3565b600401549063ffffffff6126af16565b61380f846124f3565b60040155613823858263ffffffff61251d16565b9450613835848263ffffffff6126af16565b93508461384957839550505050505061067a565b821580156138575750600085115b1561386157600094505b505b506000190161379a565b816001600160a01b03811673feefeefeefeefeefeefeefeefeefeefeefeefeef14156138ab5760405162461bcd60e51b815260040161069e90614d95565b6301dfe2006138b8613a55565b6001600160a01b0316631bb47b448585846040518463ffffffff1660e01b815260040161303e93929190614a99565b6002546040516001600160a01b039091169063907dff979061391190869086908690602001614a99565b604051602081830303815290604052600160405161392e906149a2565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16825261397593929160009081908190600401614b6d565b600060405180830381600087803b15801561398f57600080fd5b505af11580156139a3573d6000803e3d6000fd5b50505050505050565b6000826139bb575060006107c5565b828202828482816139c857fe5b04146126a85760405162461bcd60e51b815260040161069e90614d45565b600080600a83046139fd868663ffffffff6139ac16565b81613a0457fe5b0490506005600a825b0610613a1757600a015b600a9004949350505050565b600080613a4984613a3d87600a870263ffffffff6139ac16565b9063ffffffff613a8016565b90506005600a82613a0d565b60006108df7f526577617264457363726f77563200000000000000000000000000000000000061336f565b6000808211613aa15760405162461bcd60e51b815260040161069e90614cc5565b6000828481613aac57fe5b04949350505050565b60405180604001604052806002905b613acc613b3d565b815260200190600190039081613ac45790505090565b6040518060e00160405280600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600081526020016000815260200160008152602001600081525090565b60405180604001604052806002906020820280388339509192915050565b80356107c581614f5c565b80516107c581614f5c565b80516107c581614f70565b80516107c581614f79565b80516107c581614f82565b80356107c581614f79565b600060208284031215613baf57600080fd5b6000613bbb8484613b5b565b949350505050565b600060208284031215613bd557600080fd5b6000613bbb8484613b66565b60008060408385031215613bf457600080fd5b6000613c008585613b5b565b9250506020613c1185828601613b92565b9150509250929050565b600080600060608486031215613c3057600080fd5b6000613c3c8686613b5b565b9350506020613c4d86828701613b92565b9250506040613c5e86828701613b92565b9150509250925092565b600060208284031215613c7a57600080fd5b6000613bbb8484613b71565b600060208284031215613c9857600080fd5b6000613bbb8484613b7c565b600060208284031215613cb657600080fd5b6000613bbb8484613b87565b600060208284031215613cd457600080fd5b6000613bbb8484613b92565b60008060408385031215613cf357600080fd5b6000613cff8585613b7c565b9250506020613c1185828601613b71565b60008060408385031215613d2357600080fd5b6000613d2f8585613b7c565b9250506020613c1185828601613b7c565b600080600080600080600080610100898b031215613d5d57600080fd5b6000613d698b8b613b92565b9850506020613d7a8b828c01613b92565b9750506040613d8b8b828c01613b92565b9650506060613d9c8b828c01613b92565b9550506080613dad8b828c01613b92565b94505060a0613dbe8b828c01613b92565b93505060c0613dcf8b828c01613b92565b92505060e0613de08b828c01613b92565b9150509295985092959890939650565b6000613dfc8383613ee6565b505060400190565b6000613e108383613f3b565b505060200190565b613e2181614edc565b82525050565b613e2181614ea2565b613e21613e3c82614ea2565b614f3b565b613e4a81614e8f565b613e54818461067a565b9250613e5f826108e2565b8060005b83811015613523578151613e778782613df0565b9650613e8283614e89565b925050600101613e63565b6000613e9882614e95565b613ea28185614e99565b9350613ead83614e89565b8060005b83811015613edb578151613ec58882613e04565b9750613ed083614e89565b925050600101613eb1565b509495945050505050565b613eef81614e8f565b613ef9818461067a565b9250613f04826108e2565b8060005b83811015613523578151613f1c8782613e04565b9650613f2783614e89565b925050600101613f08565b613e2181614ead565b613e21816108e2565b613e21613f50826108e2565b6108e2565b6000613f6082614e95565b613f6a8185614e99565b9350613f7a818560208601614f0b565b613f8381614f4c565b9093019392505050565b613e2181614eb2565b613e2181614ee7565b613e2181614ef5565b6000613fb5602083614e99565b7f49737375657220616e64205065726946696e616e63655374617465206f6e6c79815260200192915050565b6000613fee601783614e99565b7f4f6e6c7920496e7465726e616c20436f6e747261637473000000000000000000815260200192915050565b6000614027603583614e99565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527f2063616e20616363657074206f776e6572736869700000000000000000000000602082015260400192915050565b6000614086602983614e99565b7f646973747269627574696e672066656520726577617264206e6f74207965742081527f617661696c61626c650000000000000000000000000000000000000000000000602082015260400192915050565b60006140e5601d83614e99565b7f546f6f206561726c7920746f20636c6f73652066656520706572696f64000000815260200192915050565b600061411e601383614e99565b7f4f776e6572206f6e6c792066756e6374696f6e00000000000000000000000000815260200192915050565b600061415760248361067a565b7f46656573436c61696d656428616464726573732c75696e743235362c75696e7481527f3235362900000000000000000000000000000000000000000000000000000000602082015260240192915050565b60006141b6603883614e99565b7f416c6c6f636174696e6720666565207265776172647320697320706f7373696281527f6c65206f6e6c79206f6e636520696e206120706572696f640000000000000000602082015260400192915050565b6000614215602783614e99565b7f616c6c6f636174696e672066656520726577617264206e6f742079657420617681527f61696c61626c6500000000000000000000000000000000000000000000000000602082015260400192915050565b600061427460378361067a565b7f49737375616e636544656274526174696f456e74727928616464726573732c7581527f696e743235362c75696e743235362c75696e7432353629000000000000000000602082015260370192915050565b60006142d3601b83614e99565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b600061430c601e83614e99565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b6000614345601a83614e99565b7f536166654d6174683a206469766973696f6e206279207a65726f000000000000815260200192915050565b600061437e604083614e99565b7f4e6f2066656573206f72207265776172647320617661696c61626c6520666f7281527f20706572696f642c206f72206665657320616c726561647920636c61696d6564602082015260400192915050565b60006143dd60118361067a565b7f4d697373696e6720616464726573733a20000000000000000000000000000000815260110192915050565b6000614416601883614e99565b7f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815260200192915050565b600061444f601f83614e99565b7f4e6f7420617070726f76656420746f20636c61696d206f6e20626568616c6600815260200192915050565b6000614488601e83614e99565b7f43616c6c6572206973206e6f742072657761726473417574686f726974790000815260200192915050565b60006144c1602f83614e99565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681527f6f726d207468697320616374696f6e0000000000000000000000000000000000602082015260400192915050565b6000614520601f83614e99565b7f432d526174696f2062656c6f772070656e616c7479207468726573686f6c6400815260200192915050565b6000614559601f83614e99565b7f412070796e7468206f722050455249207261746520697320696e76616c696400815260200192915050565b6000614592602183614e99565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f81527f7700000000000000000000000000000000000000000000000000000000000000602082015260400192915050565b60006145f1601683614e99565b7f43616e6e6f7420696d706f727420626164206461746100000000000000000000815260200192915050565b600061462a601d83614e99565b7f4578636565647320746865204645455f504552494f445f4c454e475448000000815260200192915050565b6000614663602983614e99565b7f43616e206f6e6c7920706572666f726d207468697320616374696f6e2064757281527f696e672073657475700000000000000000000000000000000000000000000000602082015260400192915050565b60006146c260198361067a565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b60006146fb601183614e99565b7f64656274206d616e61676572206f6e6c79000000000000000000000000000000815260200192915050565b6000614734601783614e99565b7f4665652061646472657373206e6f7420616c6c6f776564000000000000000000815260200192915050565b600061476d604483614e99565b7f66656520726577617264732073686f756c64206265206469737472696275746581527f64206f7220616c6c6f6361746564206265666f726520636c6f73696e6720706560208201527f72696f6400000000000000000000000000000000000000000000000000000000604082015260600192915050565b60006147f2603a83614e99565b7f446973747269627574696e6720666565207265776172647320697320706f737381527f69626c65206f6e6c79206f6e636520696e206120706572696f64000000000000602082015260400192915050565b600061485160188361067a565b7f466565506572696f64436c6f7365642875696e74323536290000000000000000815260180192915050565b600061488a601783614e99565b7f4f6e6c79207468652070726f78792063616e2063616c6c000000000000000000815260200192915050565b60006148c3602083614e99565b7f43757272656e7420706572696f64206973206e6f7420636c6f73656420796574815260200192915050565b60006148fc601b83614e99565b7f46656520506572696f64204475726174696f6e206e6f74207365740000000000815260200192915050565b6000614935602083614e99565b7f546f6c6572616e63652076616c75652063616e6e6f7420657863656564732031815260200192915050565b613e2181614f00565b613e2181614ec9565b613e2181614ed6565b60006149888285613f44565b6020820191506149988284613e30565b5060140192915050565b60006107c58261414a565b60006107c582614267565b60006149c3826143d0565b91506149cf8284613f44565b50602001919050565b60006149c3826146b5565b60006107c582614844565b602081016107c58284613e27565b602081016107c58284613e18565b60408101614a188285613e27565b6126a86020830184613e27565b60408101614a338285613e27565b6126a86020830184613f9f565b60808101614a4e8287613e27565b614a5b6020830186613f9f565b614a686040830185613f9f565b614a756060830184613f32565b95945050505050565b60408101614a8c8285613e27565b6126a86020830184613f3b565b60608101614aa78286613e27565b614ab46020830185613f3b565b613bbb6040830184613f3b565b60808101614acf8287613e27565b614adc6020830186613f3b565b614ae96040830185613f3b565b614a756060830184614961565b608081016107c58284613e41565b602080825281016126a88184613e8d565b602081016107c58284613f32565b602081016107c58284613f3b565b60408101614a188285613f3b565b60408101614a8c8285613f3b565b60408101614b5b8285613f3b565b8181036020830152613bbb8184613f55565b60c08082528101614b7e8189613f55565b9050614b8d6020830188613f9f565b614b9a6040830187613f3b565b614ba76060830186613f96565b614bb46080830185613f96565b614bc160a0830184613f96565b979650505050505050565b60c08082528101614bdd8189613f55565b9050614bec6020830188613f9f565b614bf96040830187613f3b565b614ba76060830186613f3b565b602081016107c58284613f8d565b602080825281016126a88184613f55565b6020808252810161067781613fa8565b6020808252810161067781613fe1565b602080825281016106778161401a565b6020808252810161067781614079565b60208082528101610677816140d8565b6020808252810161067781614111565b60208082528101610677816141a9565b6020808252810161067781614208565b60208082528101610677816142c6565b60208082528101610677816142ff565b6020808252810161067781614338565b6020808252810161067781614371565b6020808252810161067781614409565b6020808252810161067781614442565b602080825281016106778161447b565b60208082528101610677816144b4565b6020808252810161067781614513565b602080825281016106778161454c565b6020808252810161067781614585565b60208082528101610677816145e4565b602080825281016106778161461d565b6020808252810161067781614656565b60208082528101610677816146ee565b6020808252810161067781614727565b6020808252810161067781614760565b60208082528101610677816147e5565b602080825281016106778161487d565b60208082528101610677816148b6565b60208082528101610677816148ef565b6020808252810161067781614928565b60608101614aa78286613f3b565b60e08101614e21828a61496a565b614e2e602083018961496a565b614e3b604083018861496a565b614e486060830187613f3b565b614e556080830186613f3b565b614e6260a0830185613f3b565b614e6f60c0830184613f3b565b98975050505050505050565b602081016107c58284614973565b60200190565b50600290565b5190565b90815260200190565b600061067782614ebd565b151590565b600061067782614ea2565b6001600160a01b031690565b67ffffffffffffffff1690565b60ff1690565b600061067782614eb2565b6000610677613f50836108e2565b6000610677826108e2565b600061067782614ec9565b60005b83811015614f26578181015183820152602001614f0e565b83811115614f35576000848401525b50505050565b600061067782600061067782614f56565b601f01601f191690565b60601b90565b614f6581614ea2565b811461152757600080fd5b614f6581614ead565b614f65816108e2565b614f6581614eb256fea365627a7a72315820882079c2d3031f6a74125aae31f9cd51dec8225767dd29b17b1d172a05b79e396c6578706572696d656e74616cf564736f6c63430005100040
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006e2eea6d56368e60f74a3f89f30b15b46bf3f7df000000000000000000000000166220468aff631290b7e1ddff7f45b052de832400000000000000000000000022f5d16097cf2396d6c893a77ea3b97234c0c114
-----Decoded View---------------
Arg [0] : _proxy (address): 0x6e2EEa6D56368E60f74a3F89F30b15B46BF3f7DF
Arg [1] : _owner (address): 0x166220468aff631290b7E1Ddff7F45b052De8324
Arg [2] : _resolver (address): 0x22F5D16097CF2396D6C893A77Ea3b97234c0C114
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000006e2eea6d56368e60f74a3f89f30b15b46bf3f7df
Arg [1] : 000000000000000000000000166220468aff631290b7e1ddff7f45b052de8324
Arg [2] : 00000000000000000000000022f5d16097cf2396d6c893a77ea3b97234c0c114
Deployed Bytecode Sourcemap
75335:38115:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;75335:38115:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15737:31;;;:::i;:::-;;;;;;;;;;;;;;;;109601:213;;;;;;;;;:::i;:::-;;;;;;;;108421:934;;;;;;;;;:::i;100631:658::-;;;;;;;;;:::i;:::-;;;;;;;;;6633:145;;;;;;;;;:::i;:::-;;2268:141;;;;;;;;;:::i;81581:106::-;;;:::i;86882:258::-;;;;;;;;;:::i;82788:132::-;;;:::i;17432:537::-;;;:::i;:::-;;;;;;;;102992:3094;;;;;;;;;:::i;:::-;;;;;;;;82666:114;;;:::i;88039:2683::-;;;:::i;81805:727::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;76696:29;;;:::i;8019:27::-;;;:::i;2037:29::-;;;:::i;:::-;;;;;;;;99443:433;;;:::i;102660:167::-;;;;;;;;;:::i;83656:970::-;;;:::i;76649:38::-;;;:::i;91273:283::-;;;;;;;;;:::i;82540:118::-;;;:::i;84634:1043::-;;;;;;;;;:::i;99981:463::-;;;:::i;16726:657::-;;;:::i;2417:271::-;;;:::i;86239:493::-;;;;;;;;;:::i;87763:184::-;;;;;;;;;:::i;78326:1006::-;;;:::i;:::-;;;;;;;;2010:20;;;:::i;6488:137::-;;;;;;;;;:::i;5911:29::-;;;:::i;109925:173::-;;;:::i;93375:884::-;;;;;;;;;:::i;81475:98::-;;;:::i;6786:102::-;;;;;;;;;:::i;76406:43::-;;;:::i;:::-;;;;;;;;90832:125;;;:::i;6180:28::-;;;:::i;81695:102::-;;;:::i;75532:80::-;;;:::i;5886:18::-;;;:::i;87288:467::-;;;;;;;;;:::i;15737:31::-;;;-1:-1:-1;;;;;15737:31:0;;:::o;109601:213::-;109678:4;109702:23;:21;:23::i;:::-;-1:-1:-1;;;;;109702:36:0;;109766:19;109787:16;109749:55;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;109749:55:0;;;109739:66;;;;;;109702:104;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;109702:104:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;109702:104: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;109702:104:0;;;;;;;;;109695:111;;109601:213;;;;:::o;108421:934::-;108511:4;108536:11;108528:56;;;;-1:-1:-1;;;108528:56:0;;;;;;;;;;;;;;;;;76448:1;108603:26;;108595:68;;;;-1:-1:-1;;;108595:68:0;;;;;;;;;108793:36;108827:1;108818:6;:10;108793:24;:36::i;:::-;:54;;;;;;108789:73;;-1:-1:-1;108861:1:0;108854:8;;108789:73;108875:21;108899:70;108967:1;108907:36;108941:1;108932:6;:10;108907:24;:36::i;:::-;:54;;;;;;;108899:67;:70::i;:::-;108875:94;;108982:24;109017:19;109087:14;:12;:14::i;:::-;-1:-1:-1;;;;;109087:37:0;;109125:7;109134:16;109087:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;109087:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;109087:64: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;109087:64:0;;;;;;;;;109047:104;;-1:-1:-1;109047:104:0;-1:-1:-1;109264:83:0;109293:16;109047:104;;109264:28;:83::i;:::-;109257:90;;;;;108421:934;;;;;:::o;100631:658::-;100692:4;100698;100743:42;;:::i;:::-;100788:21;100801:7;100788:12;:21::i;:::-;100743:66;-1:-1:-1;100822:14:0;;100981:1;100967:175;76448:1;100984:21;;100967:175;;;101039:29;101053:8;101062:1;101053:11;;;;;;;;;;;:14;101039:9;;:13;:29::i;:::-;101027:41;;101098:32;101115:8;101124:1;101115:11;;;;;;;;;;;101127:1;101115:14;;;;101098:12;;:32;:16;:32;:::i;:::-;101083:47;-1:-1:-1;101007:3:0;;100967:175;;;-1:-1:-1;101257:9:0;;-1:-1:-1;101268:12:0;-1:-1:-1;;100631:658:0;;;;:::o;6633:145::-;2726:12;:10;:12::i;:::-;6727:16;:43;;-1:-1:-1;;;;;;6727:43:0;-1:-1:-1;;;;;6727:43:0;;;;;;;;;;6633:145::o;2268:141::-;2726:12;:10;:12::i;:::-;2340:14;:23;;-1:-1:-1;;;;;;2340:23:0;-1:-1:-1;;;;;2340:23:0;;;;;2379:22;;;;;;2340:23;;2379:22;;;;;;;;;;2268:141;:::o;81581:106::-;81633:4;81657:22;:20;:22::i;:::-;81650:29;;81581:106;;:::o;86882:258::-;110823:16;110864:11;:9;:11::i;:::-;-1:-1:-1;;;;;110842:34:0;:10;:34;;-1:-1:-1;110887:12:0;;110902:8;:6;:8::i;:::-;-1:-1:-1;;;;;110902:24:0;;110927:10;110902:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;110902:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;110902:36: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;110902:36:0;;;;;;;;;:50;;110887:65;;110963:26;111014:21;:19;:21::i;:::-;-1:-1:-1;;;;;110992:44:0;:10;-1:-1:-1;;;;;110992:44:0;;110963:73;;111047:17;111067:19;:17;:19::i;:::-;-1:-1:-1;;;;;111067:33:0;;111101:10;111067:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;111067:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;111067: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;111067:45:0;;;;;;;;;111047:65;;111133:11;:22;;;;111148:7;111133:22;:47;;;;111159:21;111133:47;:63;;;;111184:12;111133:63;111125:99;;;;-1:-1:-1;;;111125:99:0;;;;;;;;;87076:56;87125:6;87076:27;87101:1;87076:24;:27::i;:::-;:44;;;;:56;:48;:56;:::i;:::-;87029:27;87054:1;87029:24;:27::i;:::-;:44;;:103;-1:-1:-1;;;;;86882:258:0:o;82788:132::-;82854:4;82878:34;:32;:34::i;17432:537::-;17483:4;17500:34;17537:27;:25;:27::i;:::-;17500:64;-1:-1:-1;17580:6:0;17575:363;17596:17;:24;17592:1;:28;17575:363;;;17642:12;17657:17;17675:1;17657:20;;;;;;;;;;;;;;;;;;;17824:18;;;;:12;:18;;;;;;;;;17795:8;;:25;;;;;17657:20;;-1:-1:-1;;;;;;17824:18:0;;;;17795:8;;:19;;:25;;17657:20;;17795:25;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;17795:25:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;17795:25:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;17795:25:0;;;;;;;;;-1:-1:-1;;;;;17795:47:0;;;:83;;;-1:-1:-1;17876:1:0;17846:18;;;:12;:18;;;;;;-1:-1:-1;;;;;17846:18:0;:32;17795:83;17791:136;;;17906:5;17899:12;;;;;;;17791:136;-1:-1:-1;17622:3:0;;17575:363;;;;17957:4;17950:11;;;17432:537;:::o;102992:3094::-;103052:41;;:::i;:::-;103210:28;103249:19;103279:26;103308:14;:12;:14::i;:::-;103379:46;;;;;103279:43;;-1:-1:-1;;;;;;103379:34:0;;;;;:46;;103414:7;;103423:1;;103379:46;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;103379:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;103379: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;103379:46:0;;;;;;;;;103335:90;;-1:-1:-1;103335:90:0;-1:-1:-1;103728:19:0;;:51;;;;-1:-1:-1;103751:28:0;;103728:51;103724:162;;;103796:45;;:::i;:::-;103863:11;-1:-1:-1;103856:18:0;;-1:-1:-1;;;103856:18:0;103724:162;104061:19;104091:22;104162:69;104188:1;104191:23;104216:14;104162:25;:69::i;:::-;104244:10;;:30;;;104285:10;;104244;104285:13;:33;;;104124:107;;-1:-1:-1;104124:107:0;-1:-1:-1;104252:1:0;104411:29;104432:7;104411:20;:29::i;:::-;104386:54;-1:-1:-1;104653:1:0;104619:1460;104656:5;;104619:1460;;-1:-1:-1;;104695:5:0;;104683:9;104750:30;104695:5;104750:24;:30::i;:::-;:48;;;;;;;-1:-1:-1;104936:31:0;;;;;:94;;;104991:27;105016:1;104991:24;:27::i;:::-;:39;;;104971:59;;104936:94;104932:1136;;;105377:21;105401:43;105409:27;105442:1;105401:43;:40;:43;:::i;:::-;105758:63;;;;;105377:67;;-1:-1:-1;;;;;;105758:36:0;;;;;:63;;105795:7;;105377:67;;105758:63;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;105758:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;105758:63:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;105758:63:0;;;;;;;;;105714:107;;-1:-1:-1;105714:107:0;-1:-1:-1;105880:69:0;105906:1;105714:107;;105880:25;:69::i;:::-;105842:107;;-1:-1:-1;105842:107:0;-1:-1:-1;105842:107:0;105970:7;105978:1;105970:10;;;;;;;;;;;:30;106035:17;106019:7;106027:1;106019:10;;;;;;;;;;;106030:1;106019:13;;;:33;-1:-1:-1;104932:1136:0;-1:-1:-1;;;;104663:3:0;104619:1460;;;;102992:3094;;;;;;;;;:::o;82666:114::-;82748:24;;;;;;;;82666:114::o;88039:2683::-;111885:14;:12;:14::i;:::-;-1:-1:-1;;;;;111885:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;111885:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;111885:38:0;;;;88140:1;88115:22;:20;:22::i;:::-;:26;88107:66;;;;-1:-1:-1;;;88107:66:0;;;;;;;;;88240:22;:20;:22::i;:::-;88234:3;:28;88192:27;88217:1;88192:24;:27::i;:::-;:37;-1:-1:-1;;;88192:37:0;;;;:71;;88184:113;;;;-1:-1:-1;;;88184:113:0;;;;;;;;;88330:26;;;;;:54;;-1:-1:-1;88360:24:0;;;;;;;88330:54;88308:172;;;;-1:-1:-1;;;88308:172:0;;;;;;;;;88629:31;88663:47;88629:31;88663:24;:47::i;:::-;88629:81;-1:-1:-1;88721:34:0;88758:47;88803:1;88758:24;:47::i;:::-;88721:84;;89369:145;89483:13;:30;;;89369:95;89435:16;:28;;;89369:16;:47;;;:65;;:95;;;;:::i;:::-;:113;:145;:113;:145;:::i;:::-;89302:47;89327:21;89302:24;:47::i;:::-;:64;;:212;89715:33;;;;;89664:31;;;;89595:50;;;;:154;;:101;;:50;:101;:68;:101;:::i;:154::-;89525:47;89550:21;89525:24;:47::i;:::-;:67;;:224;89862:17;;:70;;76448:1;;89862:47;;89907:1;;89862:40;;76448:1;89862:40;:21;:40;:::i;:::-;:44;:47;:44;:47;:::i;:::-;:51;:70;:51;:70;:::i;:::-;89842:17;:90;;;90046:17;;:36;;;;;;;;;;90039:43;;;;;;90046:36;90039:43;;;;;;;;;;;;;;;;;;;;;;;;90257:55;;90265:27;90039:43;90265:24;:27::i;:::-;:39;;;;90257:55;:52;:55;:::i;:::-;90208:27;90233:1;90208:24;:27::i;:::-;:105;;-1:-1:-1;;90208:105:0;;;;;;;;;;;;90379:18;:16;:18::i;:::-;-1:-1:-1;;;;;90379:35:0;;:37;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;90379:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;90379:37: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;90379:37:0;;;;;;;;;90324:27;90349:1;90324:24;:27::i;:::-;:93;;;;;;;;;-1:-1:-1;;90324:93:0;;;;;;;;;90475:3;90428:27;90324:45;90428:24;:27::i;:::-;:51;;;;;;;-1:-1:-1;;;90428:51:0;;;;;;;;;;;90566:26;:34;;-1:-1:-1;;90611:32:0;;;90654:60;90674:27;-1:-1:-1;90674:24:0;:27::i;:::-;:39;;;90654:19;:60::i;:::-;111934:1;;88039:2683::o;81805:727::-;81907:18;81940:24;81979:16;82010:21;82046:16;82077:24;82116:19;82163:26;;:::i;:::-;82192:31;82217:5;82192:24;:31::i;:::-;82163:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;82163:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82163:60:0;;-1:-1:-1;82163:60:0;;-1:-1:-1;82163:60:0;;-1:-1:-1;82163:60:0;;-1:-1:-1;82163:60:0;;-1:-1:-1;81805:727:0;-1:-1:-1;;;81805:727:0:o;76696:29::-;;;;:::o;8019:27::-;;;;:::o;2037:29::-;;;-1:-1:-1;;;;;2037:29:0;;:::o;99443:433::-;99496:4;;99630:1;99616:224;76448:1;99633:21;;99616:224;;;99688:59;99702:27;99727:1;99702:24;:27::i;:::-;:44;;;99688:9;;:59;:13;:59;:::i;:::-;99676:71;;99774:54;99788:27;99813:1;99788:24;:27::i;:::-;:39;;;99774:9;;:54;:13;:54;:::i;:::-;99762:66;-1:-1:-1;99656:3:0;;99616:224;;;-1:-1:-1;99859:9:0;-1:-1:-1;99443:433:0;:::o;102660:167::-;102725:18;102776:43;102811:7;102776:34;:43::i;:::-;-1:-1:-1;102756:63:0;102660:167;-1:-1:-1;;102660:167:0:o;83656:970::-;7165:16;:14;:16::i;:::-;111577:18;111615:14;:12;:14::i;:::-;111598:13;;-1:-1:-1;;;;;111598:13:0;;;:31;;;;-1:-1:-1;111598:31:0;111640:43;;;;-1:-1:-1;;;111640:43:0;;;;;;;;;83771:1;83746:22;:20;:22::i;:::-;:26;83738:66;;;;-1:-1:-1;;;83738:66:0;;;;;;;;;83885:22;:20;:22::i;:::-;83879:3;:28;83837:27;83862:1;83837:24;:27::i;:::-;:37;-1:-1:-1;;;83837:37:0;;;;:71;;83815:162;;;;-1:-1:-1;;;83815:162:0;;;;;;;;;83998:26;;;;:35;83990:106;;;;-1:-1:-1;;;83990:106:0;;;;;;;;;84107:26;:33;;-1:-1:-1;;84107:33:0;84136:4;84107:33;;;:26;84181:34;:32;:34::i;:::-;84153:62;;84256:1;84232:20;:25;84228:106;;-1:-1:-1;84300:1:0;84274:23;:27;84316:7;;84228:106;84346:8;:6;:8::i;:::-;-1:-1:-1;;;;;84346:15:0;;84362:4;;84346:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;84346:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;84346:21: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;84346:21:0;;;;;;;;;-1:-1:-1;;;;;84346:26:0;;75570:42;84386:20;84346:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;84346:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;;84420:23:0;:46;;;-1:-1:-1;84524:94:0;84446:20;84524:27;84549:1;84524:24;:27::i;:::-;:44;;;;:94;:48;:94;:::i;:::-;84477:27;84502:1;84477:24;:27::i;:::-;:44;;:141;-1:-1:-1;111694:1:0;7192;83656:970::o;76649:38::-;;;;:::o;91273:283::-;91371:4;111885:14;:12;:14::i;:::-;-1:-1:-1;;;;;111885:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;111885:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;111885:38:0;;;;7165:16;:14;:16::i;:::-;91396:19;:17;:19::i;:::-;91448:13;;;91396:66;;;;;-1:-1:-1;;;;;91396:31:0;;;;;;:66;;91428:18;;91448:13;;;91396:66;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;91396:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;91396: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;91396:66:0;;;;;;;;;91388:110;;;;-1:-1:-1;;;91388:110:0;;;;;;;;;91518:30;91529:18;91518:10;:30::i;82540:118::-;82624:26;;;;82540:118;:::o;84634:1043::-;7165:16;:14;:16::i;:::-;111577:18;111615:14;:12;:14::i;:::-;111598:13;;-1:-1:-1;;;;;111598:13:0;;;:31;;;;-1:-1:-1;111598:31:0;111640:43;;;;-1:-1:-1;;;111640:43:0;;;;;;;;;84758:1;84733:22;:20;:22::i;:::-;:26;84725:66;;;;-1:-1:-1;;;84725:66:0;;;;;;;;;84872:22;:20;:22::i;:::-;84866:3;:28;84824:27;84849:1;84824:24;:27::i;:::-;:37;-1:-1:-1;;;84824:37:0;;;;:71;;84802:160;;;;-1:-1:-1;;;84802:160:0;;;;;;;;;84983:24;;;;;;;:33;84975:102;;;;-1:-1:-1;;;84975:102:0;;;;;;;;;85088:24;:31;;-1:-1:-1;;85088:31:0;;;;;85136:11;85132:24;;85149:7;;85132:24;85168:38;85222:192;:148;85319:19;:17;:19::i;:::-;-1:-1:-1;;;;;85319:48:0;;:50;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;85319:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;85319:50: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;85319:50:0;;;;;;;;;85222;:6;:48;:50::i;:::-;:96;:148;:96;:148;:::i;:::-;:190;:192::i;:::-;85168:246;;85427:8;:6;:8::i;:::-;-1:-1:-1;;;;;85427:15:0;;85443:4;;85427:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;85427:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;85427:21: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;85427:21:0;;;;;;;;;-1:-1:-1;;;;;85427:27:0;;75570:42;85468:33;85427:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;85427:75:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;85427:75:0;;;;85562:107;85625:33;85562:27;85587:1;85562:24;:27::i;:107::-;85515:27;85540:1;85515:24;:27::i;:::-;:44;;:154;-1:-1:-1;7192:1:0;84634:1043;:::o;99981:463::-;100037:4;;100177:1;100163:242;76448:1;100180:21;;100163:242;;;100238:65;100255:27;100280:1;100255:24;:27::i;:::-;:47;;;100238:12;;:65;:16;:65;:::i;:::-;100223:80;;100333:60;100350:27;100375:1;100350:24;:27::i;:::-;:42;;;100333:12;;:60;:16;:60;:::i;:::-;100318:75;-1:-1:-1;100203:3:0;;100163:242;;16726:657;16768:34;16805:27;:25;:27::i;:::-;16768:64;-1:-1:-1;16926:6:0;16921:455;16942:17;:24;16938:1;:28;16921:455;;;16988:12;17003:17;17021:1;17003:20;;;;;;;;;;;;;;16988:35;;17131:19;17170:8;;;;;;;;;-1:-1:-1;;;;;17170:8:0;-1:-1:-1;;;;;17170:29:0;;17200:4;17259;17213:51;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;17213:51:0;;;17170:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;17170:96:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;17170: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;17170:96:0;;;;;;;;;17281:18;;;;:12;:18;;;;;;;:32;;-1:-1:-1;;;;;;17281:32:0;-1:-1:-1;;;;;17281:32:0;;;;;17333:31;17281:32;;-1:-1:-1;17333:31:0;;;;17281:18;;:32;;17333:31;;;;;;;;;;-1:-1:-1;;16968:3:0;;16921:455;;2417:271;2486:14;;-1:-1:-1;;;;;2486:14:0;2472:10;:28;2464:94;;;;-1:-1:-1;;;2464:94:0;;;;;;;;;2587:5;;;2594:14;2574:35;;;;;;-1:-1:-1;;;;;2587:5:0;;;;2594:14;;;2574:35;;;;;;;;;;2628:14;;;;2620:22;;-1:-1:-1;;;;;;2620:22:0;;;-1:-1:-1;;;;;2628:14:0;;2620:22;;;;2653:27;;;2417:271::o;86239:493::-;111302:13;111340:8;:6;:8::i;:::-;-1:-1:-1;;;;;111318:31:0;:10;-1:-1:-1;;;;;111318:31:0;;111302:47;;111360:23;111408:18;:16;:18::i;:::-;-1:-1:-1;;;;;111386:41:0;:10;-1:-1:-1;;;;;111386:41:0;;111360:67;;111446:8;:30;;;;111458:18;111446:30;111438:75;;;;-1:-1:-1;;;111438:75:0;;;;;;;;;86414:14;:12;:14::i;:::-;-1:-1:-1;;;;;86414:42:0;;86471:7;86493:9;86517:14;86546:27;86571:1;86546:24;:27::i;:::-;:45;86414:188;;;;;;;;;;;;;;;86546:45;;;;;;86414:188;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;86414:188:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;86414:188:0;;;;86615:109;86642:7;86651:9;86662:14;86678:27;86703:1;86678:24;:27::i;:::-;:45;;;;;;86615:26;:109::i;:::-;86239:493;;;;;:::o;87763:184::-;2726:12;:10;:12::i;:::-;87846:15;:20;:22;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;87846:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;87846:22:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;87846:22:0;;;;;;;;;87839:4;:29;87831:74;;;;-1:-1:-1;;;87831:74:0;;;;;;;;;87918:14;:21;87763:184::o;78326:1006::-;78384:26;78423:34;78460:47;:45;:47::i;:::-;78550:17;;;78564:2;78550:17;;;;;;;;;78423:84;;-1:-1:-1;78518:29:0;;78550:17;;;;17:15:-1;;105:10;78550:17:0;88:34:-1;136:17;;-1:-1;78550:17:0;78518:49;;78596:21;78578:12;78591:1;78578:15;;;;;;;;;;;;;:39;;;;;78646:20;78628:12;78641:1;78628:15;;;;;;;;;;;;;:38;;;;;78695:21;78677:12;78690:1;78677:15;;;;;;;;;;;;;:39;;;;;78745:30;78727:12;78740:1;78727:15;;;;;;;;;;;;;:48;;;;;78804:18;78786:12;78799:1;78786:15;;;;;;;;;;;;;:36;;;;;-1:-1:-1;;;78833:12:0;78846:1;78833:15;;;;;;;;;;;;;:33;;;;;78895:25;78877:12;78890:1;78877:15;;;;;;;;;;;;;:43;;;;;78949:24;78931:12;78944:1;78931:15;;;;;;;;;;;;;:42;;;;;79002:26;78984:12;78997:1;78984:15;;;;;;;;;;;;;:44;;;;;79057:28;79039:12;79052:1;79039:15;;;;;;;;;;;;;:46;;;;;79115:28;79096:12;79109:2;79096:16;;;;;;;;;;;;;:47;;;;;79173:26;79154:12;79167:2;79154:16;;;;;;;;;;;;;:45;;;;;79229:26;79210:12;79223:2;79210:16;;;;;;;;;;;;;:45;;;;;79278:46;79292:17;79311:12;79278:13;:46::i;:::-;79266:58;;78326:1006;;;:::o;2010:20::-;;;-1:-1:-1;;;;;2010:20:0;;:::o;6488:137::-;2726:12;:10;:12::i;:::-;6560:5;:21;;-1:-1:-1;;;;;;6560:21:0;-1:-1:-1;;;;;6560:21:0;;;;;6597:20;;;;;;6560:21;;6597:20;;5911:29;;;-1:-1:-1;;;;;5911:29:0;;:::o;109925:173::-;109982:4;110006:84;110041:48;110068:20;:18;:20::i;:::-;110041:15;:20;:22;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;110041:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;110041:22:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;110041:22:0;;;;;;;;:48;110006:18;:16;:18::i;:::-;:34;:84;:34;:84;:::i;93375:884::-;7470:26;:24;:26::i;:::-;8337:15;;8331:3;:21;8323:75;;;;-1:-1:-1;;;8323:75:0;;;;;;;;;93733:18;:16;:18::i;:::-;-1:-1:-1;;;;;93733:35:0;;:37;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;93733:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;93733:37: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;93733:37:0;;;;;;;;;93712:17;:58;;93704:93;;;;-1:-1:-1;;;93704:93:0;;;;;;;;;93892:359;;;;;;;;93937:11;93892:359;;;;;;93990:17;93892:359;;;;;;94041:9;93892:359;;;;;;94084:16;93892:359;;;;94128:11;93892:359;;;;94175:19;93892:359;;;;94225:14;93892:359;;;93810:17;93828:60;76448:1;93828:60;;:37;93850:14;93828:17;;:21;;:37;;;;:::i;:60::-;93810:79;;;;;;;:441;;:79;;;;;;;;;:441;;;;;;;;;;-1:-1:-1;;93810:441:0;;;;;;;;-1:-1:-1;;93810:441:0;;;;;;;;;;;;-1:-1:-1;;;93810:441:0;;;;;;;;;;;;;;;;;;-1:-1:-1;93810:441:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;93375:884:0:o;81475:98::-;81523:4;81547:18;:16;:18::i;6786:102::-;6926:12;:10;:12::i;:::-;6858:13;:22;;-1:-1:-1;;;;;;6858:22:0;-1:-1:-1;;;;;6858:22:0;;;;;;;;;;6786:102::o;76406:43::-;76448:1;76406:43;:::o;90832:125::-;90900:4;111885:14;:12;:14::i;:::-;-1:-1:-1;;;;;111885:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;111885:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;111885:38:0;;;;7165:16;:14;:16::i;:::-;90935:13;;90924:25;;-1:-1:-1;;;;;90935:13:0;90924:10;:25::i;6180:28::-;;;-1:-1:-1;;;;;6180:28:0;;:::o;81695:102::-;81745:4;81769:20;:18;:20::i;75532:80::-;75570:42;75532:80;:::o;5886:18::-;;;-1:-1:-1;;;;;5886:18:0;;:::o;87288:467::-;87353:24;87388:21;:19;:21::i;:::-;87429:13;;87353:57;;-1:-1:-1;;;;;;87429:33:0;;;:13;;:33;;:67;;-1:-1:-1;87466:10:0;-1:-1:-1;;;;;87466:30:0;;;87429:67;87421:110;;;;-1:-1:-1;;;87421:110:0;;;;;;;;;87688:59;87740:6;87688:27;87713:1;87688:24;:27::i;:::-;:47;;;;:59;:51;:59;:::i;:::-;87638:27;87663:1;87638:24;:27::i;:::-;:47;;:109;-1:-1:-1;;87288:467:0:o;79796:180::-;79852:21;79915:52;79936:30;79915:20;:52::i;82928:180::-;82997:17;83034;76448:1;83052:47;;83073:5;83053:17;;:25;83052:47;;;;;;83034:66;;;;;;;;;;;82928:180;-1:-1:-1;;82928:180:0:o;31262:184::-;31320:7;31353:1;31348;:6;;31340:49;;;;-1:-1:-1;;;31340:49:0;;;;;;;;;-1:-1:-1;31412:5:0;;;31262:184::o;79644:144::-;79691:12;79736:43;79757:21;79736:20;:43::i;107724:689::-;107889:4;108032:35;108070:18;:16;:18::i;:::-;108032:56;;108099:27;108142:221;108343:19;108142:154;108251:17;-1:-1:-1;;;;;108251:28:0;;108280:14;108251:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;108251:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;108251:44: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;108251:44:0;;;;;;;;;108142:64;;;;;-1:-1:-1;;;;;108142:46:0;;;;;:64;;108189:16;;108142:64;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;108142:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;108142:64: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;108142:64:0;;;;;;;;;:108;:154;:108;:154;:::i;:221::-;108099:264;-1:-1:-1;;;107724:689:0;;;;;;:::o;30806:181::-;30864:7;30896:5;;;30920:6;;;;30912:46;;;;-1:-1:-1;;;30912:46:0;;;;;;;;2766:133;2834:5;;-1:-1:-1;;;;;2834:5:0;2820:10;:19;2812:79;;;;-1:-1:-1;;;2812:79:0;;;;;;;;;2766:133::o;25899:266::-;25954:4;26075:17;:15;:17::i;:::-;-1:-1:-1;;;;;26075:30:0;;-1:-1:-1;;;26129:27:0;26075:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26075:82:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;26075:82: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;26075:82:0;;;;;;;;79984:134;80028:10;80069:40;80090:18;80069:20;:40::i;80656:122::-;80697:7;80732:37;-1:-1:-1;;;80732:20:0;:37::i;80126:174::-;80180:20;80241:50;80262:28;80241:20;:50::i;80308:166::-;80360:18;80417:48;80438:26;80417:20;:48::i;83116:478::-;83183:34;83230:23;83256:85;83290:19;:17;:19::i;:::-;-1:-1:-1;;;;;83290:48:0;;:50;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;83290:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;83290:50: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;83290:50:0;;;;;;;;;83256:15;:27;:29;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;83256:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;83256:29: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;83256:29:0;;;;;;;;:85;83230:111;;83386:200;:160;83527:18;83386:98;:27;83411:1;83386:24;:27::i;:::-;:58;;;:96;:98::i;:200::-;83354:232;;83116:478;;:::o;106495:1221::-;106647:4;;106755:24;106751:43;;-1:-1:-1;106789:1:0;;-1:-1:-1;106789:1:0;106781:13;;106751:43;106837:19;106957:10;;106953:260;;106984:21;107008:70;107076:1;107016:36;107050:1;107041:6;:10;107016:24;:36::i;107008:70::-;106984:94;;107118:83;107147:16;107165:19;107186:14;107118:28;:83::i;:::-;107093:108;;106953:260;;107347:19;107369:89;107435:22;107369:32;107394:6;107369:24;:32::i;:::-;:49;;;;:89;:65;:89;:::i;:::-;107347:111;;107471:22;107509:92;107578:22;107509:32;107534:6;107509:24;:32::i;:::-;:52;;;;:92;:68;:92;:::i;:::-;107471:130;;107622:40;:14;:38;:40::i;:::-;107664:43;:17;:41;:43::i;:::-;107614:94;;;;;;;106495:1221;;;;;;;:::o;79340:146::-;79387:13;79434:43;79455:21;79434:20;:43::i;33425:152::-;33483:7;33511:6;33503:43;;;;-1:-1:-1;;;33503:43:0;;;;;;;;;33568:1;33564;:5;;;;;;;33425:152;-1:-1:-1;;;33425:152:0:o;80786:162::-;80837:17;80892:47;80913:25;80892:20;:47::i;112893:144::-;112960:5;;112972:23;;-1:-1:-1;;;;;112960:5:0;;;;:11;;112972:23;;112983:11;;112972:23;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;112972:23:0;;;112997:1;112847:37;;;;;;;;;;;;;;;112960:69;;;;;;;;;;;;113021:1;;;;;;112960:69;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;112960:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;101297:1355:0;101381:4;101387;101478:30;101511:8;:6;:8::i;:::-;-1:-1:-1;;;;;101511:27:0;;101539:7;101548:1;101551;101554:4;101511:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;101511:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;101511:48: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;101511:48:0;;;;;;;;;101478:81;;101616:83;101656:42;101683:14;;101656:15;:20;:22;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;101656:42:0;101616:23;:21;:23::i;:83::-;101588:25;:111;101570:189;;;101734:5;101741;101726:21;;;;;;;101570:189;101939:10;101951:21;101976:8;:6;:8::i;:::-;-1:-1:-1;;;;;101976:49:0;;102026:7;101976:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;101976:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;101976:58: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;101976:58:0;;;;;;;;;101938:96;;;;102045:16;102064:18;:16;:18::i;:::-;102045:37;;102168:11;102160:5;:19;102156:83;;;-1:-1:-1;102204:4:0;;-1:-1:-1;102210:16:0;-1:-1:-1;102196:31:0;;-1:-1:-1;;102196:31:0;102156:83;102338:20;102361:77;102389:48;102416:20;:18;:20::i;102389:48::-;102361:11;;:77;:27;:77;:::i;:::-;102338:100;;102525:15;102517:5;:23;102513:88;;;102565:5;102572:16;102557:32;;;;;;;;;;;102513:88;-1:-1:-1;102621:4:0;;-1:-1:-1;102627:16:0;;-1:-1:-1;;;;101297:1355:0;;;:::o;7209:209::-;7279:5;;-1:-1:-1;;;;;7279:5:0;7264:10;7258:26;;;;:67;;-1:-1:-1;7309:16:0;;-1:-1:-1;;;;;7309:16:0;7294:10;7288:37;;7258:67;:98;;;;-1:-1:-1;7329:13:0;;-1:-1:-1;;;;;7329:13:0;7346:10;7329:27;;7258:98;7254:157;;;7373:13;:26;;-1:-1:-1;;;;;;7373:26:0;7389:10;7373:26;;;7209:209::o;110615:115::-;110662:7;110689:19;:17;:19::i;:::-;-1:-1:-1;;;;;110689:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;110689:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;110689:33: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;110689:33:0;;;;;;;;81119:166;81171:18;81228:48;81249:26;81228:20;:48::i;91564:1698::-;91627:4;;;;;;;91968:51;92003:15;91968:34;:51::i;:::-;91922:97;;;;92040:13;92032:57;;;;-1:-1:-1;;;92032:57:0;;;;;;;;;92111:16;92110:17;92102:61;;;;-1:-1:-1;;;92102:61:0;;;;;;;;;92275:30;92289:15;92275:13;:30::i;:::-;92239:66;;-1:-1:-1;92239:66:0;-1:-1:-1;92340:17:0;;;;:41;;;92380:1;92361:16;:20;92340:41;92318:155;;;;-1:-1:-1;;;92318:155:0;;;;;;;;;92545:79;92567:15;92584:27;92609:1;92584:24;:27::i;:::-;:39;;;92545:21;:79::i;:::-;92641:17;;92637:245;;92749:32;92767:13;92749:17;:32::i;:::-;92738:43;;92835:35;92844:15;92861:8;92835;:35::i;:::-;92898:20;;92894:269;;93015:38;93036:16;93015:20;:38::i;:::-;93001:52;;93110:41;93122:15;93139:11;93110;:41::i;:::-;93175:55;93191:15;93208:8;93218:11;93175:15;:55::i;:::-;-1:-1:-1;93250:4:0;;91564:1698;-1:-1:-1;;;;;;;91564:1698:0:o;80482:166::-;80534:18;80591:48;80612:26;80591:20;:48::i;40232:143::-;40296:4;40320:47;:1;34201:42;40320:47;:5;:47;:::i;36815:149::-;36891:4;36915:41;36937:1;36940;34098:31;36915:21;:41::i;40485:298::-;40549:4;40595:45;40590:51;;40683:1;40677:2;40658:21;;:26;40654:81;;40721:2;40701:22;40654:81;40773:2;40754:21;;;;-1:-1:-1;;40485:298:0:o;112312:434::-;112498:5;;112524:65;;-1:-1:-1;;;;;112498:5:0;;;;:11;;112524:65;;112535:9;;112546:14;;112562:26;;112524:65;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;112524:65:0;;;112604:1;112235:68;;;;;;;;;;;;;;;112498:240;;;;;;;;;;;;-1:-1:-1;;;;;112669:25:0;;;112661:34;;;;112498:240;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;112498:240:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;112498:240:0;;;;112312:434;;;;:::o;23751:183::-;23860:16;;;23874:1;23860:16;;;;;;;;;23809:26;;23860:16;;;;;;105:10:-1;23860:16:0;88:34:-1;136:17;;-1:-1;23860:16:0;23848:28;;23902:24;23887:9;23897:1;23887:12;;;;;;;;;;;;;:39;;;;;23751:183;:::o;15992:458::-;16114:28;16203:6;:13;16188:5;:12;:28;16174:43;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;16174:43:0;-1:-1:-1;16160:57:0;-1:-1:-1;16235:6:0;16230:92;16251:5;:12;16247:1;:16;16230:92;;;16302:5;16308:1;16302:8;;;;;;;;;;;;;;16285:11;16297:1;16285:14;;;;;;;;;;;;;;;;;:25;16265:3;;16230:92;;;-1:-1:-1;16339:6:0;16334:109;16355:6;:13;16351:1;:17;16334:109;;;16422:6;16429:1;16422:9;;;;;;;;;;;;;;16390:11;16417:1;16402:5;:12;:16;16390:29;;;;;;;;;;;;;;;;;:41;16370:3;;16334:109;;26173:261;26226:4;26347:17;:15;:17::i;:::-;-1:-1:-1;;;;;26347:30:0;;-1:-1:-1;;;26401:24:0;26347:79;;;;;;;;;;;;;;;;;25634:257;25685:4;25806:17;:15;:17::i;:::-;-1:-1:-1;;;;;25806:30:0;;-1:-1:-1;;;25860:22:0;25806:77;;;;;;;;;;;;;;;;;34991:195;35055:4;33967:18;35163:8;:1;35169;35163:8;:5;:8;:::i;:::-;:15;;;;;;;34991:195;-1:-1:-1;;;34991:195:0:o;7578:284::-;7658:5;;-1:-1:-1;;;;;7658:5:0;7643:10;7637:26;;;;:67;;-1:-1:-1;7688:16:0;;-1:-1:-1;;;;;7688:16:0;7673:10;7667:37;;7637:67;:98;;;;-1:-1:-1;7708:13:0;;-1:-1:-1;;;;;7708:13:0;7725:10;7708:27;;7637:98;7633:157;;;7752:13;:26;;-1:-1:-1;;;;;;7752:26:0;7768:10;7752:26;;;7633:157;7825:5;;7808:13;;-1:-1:-1;;;;;7808:13:0;;;7825:5;;7808:22;7800:54;;;;-1:-1:-1;;;7800:54:0;;;;;;;;6966:157;7041:5;;-1:-1:-1;;;;;7041:5:0;7026:10;7020:26;;:67;;-1:-1:-1;7071:16:0;;-1:-1:-1;;;;;7071:16:0;7056:10;7050:37;7020:67;7012:103;;;;-1:-1:-1;;;7012:103:0;;;;;;;;81293:174;81347:20;81408:50;81429:28;18031:268;18098:7;18142:18;;;:12;:18;;;;;;;;;18215:43;;-1:-1:-1;;;;;18142:18:0;;;;18179:27;;;;18215:43;;18155:4;;18215:43;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;18215:43:0;;;18171:89;;;;;-1:-1:-1;;;18171:89:0;;;;;;;;;39981:145;40055:4;40079:39;40099:1;40102;34098:31;40079:19;:39::i;23942:158::-;23992:16;24045:46;24066:24;24045:20;:46::i;27991:171::-;28047:4;28071:17;:15;:17::i;:::-;-1:-1:-1;;;;;28071:30:0;;-1:-1:-1;;;28125:28:0;28071:83;;;;;;;;;;;;;;;;;110348:259;110444:23;:21;:23::i;:::-;-1:-1:-1;;;;;110444:36:0;;110522:19;110543:16;110505:55;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;110505:55:0;;;110495:66;;;;;;110576:12;110444:155;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;110444:155:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;110444:155:0;;;;110348:259;;:::o;94410:1669::-;94472:4;94558:10;94472:4;94864:1;94830:1214;76448:1;94867:21;;94830:1214;;;94910:23;94936:27;94961:1;94936:24;:27::i;:::-;:39;;;94910:65;;94990:10;95003:68;95052:18;95003:27;95028:1;95003:24;:27::i;:68::-;94990:81;-1:-1:-1;95092:9:0;;95088:945;;95236:19;95266;95258:5;:27;:57;;95296:19;95258:57;;;95288:5;95258:57;95236:79;-1:-1:-1;95378:38:0;:18;95236:79;95378:38;:22;:38;:::i;:::-;95336:27;95361:1;95336:24;:27::i;:::-;:39;;:80;95457:39;:19;95481:14;95457:39;:23;:39;:::i;:::-;95435:61;-1:-1:-1;95526:28:0;:8;95539:14;95526:28;:12;:28;:::i;:::-;95515:39;-1:-1:-1;95665:24:0;95661:45;;95698:8;95691:15;;;;;;;;;;95661:45;95917:6;;:33;;;;;95949:1;95927:19;:23;95917:33;95913:105;;;95997:1;95975:23;;95913:105;95088:945;;-1:-1:-1;;;;94890:3:0;94830:1214;;;-1:-1:-1;96063:8:0;94410:1669;-1:-1:-1;;;94410:1669:0:o;98180:555::-;98255:7;-1:-1:-1;;;;;111770:22:0;;75570:42;111770:22;;111762:58;;;;-1:-1:-1;;;111762:58:0;;;;;;;;;98307:16;98326:8;:6;:8::i;:::-;-1:-1:-1;;;;;98326:15:0;;98342:4;;98326:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;98326:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;98326:21: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;98326:21:0;;;;;;;;;98605:39;;;;;98307:40;;-1:-1:-1;;;;;;98605:14:0;;;;;:39;;75570:42;;98633:10;;98605:39;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;98605:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;98691:36:0;;;;;-1:-1:-1;;;;;98691:15:0;;;-1:-1:-1;98691:15:0;;-1:-1:-1;98691:36:0;;98707:7;;98716:10;;98691:36;;;;96225:1761;96290:4;96376:10;96290:4;96686:1;96652:1299;76448:1;96689:21;;96652:1299;;;96732:17;96769:95;96821:27;96846:1;96821:24;:27::i;:::-;:42;;;96769:27;96794:1;96769:24;:27::i;:::-;:47;;;;:95;:51;:95;:::i;:::-;96732:132;-1:-1:-1;96885:16:0;;96881:1059;;97036:19;97073;97058:12;:34;:71;;97110:19;97058:71;;;97095:12;97058:71;97036:93;;97195:62;97242:14;97195:27;97220:1;97195:24;:27::i;:::-;:42;;;;:62;:46;:62;:::i;:::-;97150:27;97175:1;97150:24;:27::i;:::-;:42;;:107;97298:39;:19;97322:14;97298:39;:23;:39;:::i;:::-;97276:61;-1:-1:-1;97369:30:0;:10;97384:14;97369:30;:14;:30;:::i;:::-;97356:43;-1:-1:-1;97510:24:0;97506:47;;97543:10;97536:17;;;;;;;;;97506:47;97824:6;;:33;;;;;97856:1;97834:19;:23;97824:33;97820:105;;;97904:1;97882:23;;97820:105;96881:1059;;-1:-1:-1;;;96712:3:0;96652:1299;;98950:387;99028:7;-1:-1:-1;;;;;111770:22:0;;75570:42;111770:22;;111762:58;;;;-1:-1:-1;;;111762:58:0;;;;;;;;;99115:8;99257:16;:14;:16::i;:::-;-1:-1:-1;;;;;99257:35:0;;99293:7;99302:10;99314:14;99257:72;;;;;;;;;;;;;;;;;;113222:225;113353:5;;113365:44;;-1:-1:-1;;;;;113353:5:0;;;;:11;;113365:44;;113376:7;;113385:10;;113397:11;;113365:44;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;113365:44:0;;;113411:1;113164:49;;;;;;;;;;;;;;;113353:86;;;;;;;;;;;;113431:1;;;;;;113353:86;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;113353:86:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;113353:86:0;;;;113222:225;;;:::o;31697:470::-;31755:7;31999:6;31995:47;;-1:-1:-1;32029:1:0;32022:8;;31995:47;32066:5;;;32070:1;32066;:5;:1;32090:5;;;;;:10;32082:56;;;;-1:-1:-1;;;32082:56:0;;;;;;;;35805:421;35928:4;;36081:2;36065:13;:18;36053:8;:1;36059;36053:8;:5;:8;:::i;:::-;:31;;;;;;;-1:-1:-1;36126:1:0;36120:2;36053:31;36101:21;;:26;36097:81;;36164:2;36144:22;36097:81;36216:2;36197:21;;;;-1:-1:-1;;;;35805:421:0:o;38745:328::-;38866:4;;38905:32;38935:1;38905:25;:1;38927:2;38911:18;;38905:25;:5;:25;:::i;:::-;:29;:32;:29;:32;:::i;:::-;38883:54;-1:-1:-1;38977:1:0;38971:2;38883:54;38954:19;;80956:155;81005:15;81056:46;81077:24;81056:20;:46::i;32635:333::-;32693:7;32792:1;32788;:5;32780:44;;;;-1:-1:-1;;;32780:44:0;;;;;;;;;32835:9;32851:1;32847;:5;;;;;;;32635:333;-1:-1:-1;;;;32635:333:0:o;75335:38115::-;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;75335:38115:0;;;-1:-1:-1;;75335:38115:0:o;5:130:-1:-;72:20;;97:33;72:20;97:33;;142:134;220:13;;238:33;220:13;238:33;;436:128;511:13;;529:30;511:13;529:30;;571:134;649:13;;667:33;649:13;667:33;;712:162;804:13;;822:47;804:13;822:47;;881:130;948:20;;973:33;948:20;973:33;;1159:241;;1263:2;1251:9;1242:7;1238:23;1234:32;1231:2;;;1279:1;1276;1269:12;1231:2;1314:1;1331:53;1376:7;1356:9;1331:53;;;1321:63;1225:175;-1:-1;;;;1225:175;1407:263;;1522:2;1510:9;1501:7;1497:23;1493:32;1490:2;;;1538:1;1535;1528:12;1490:2;1573:1;1590:64;1646:7;1626:9;1590:64;;1941:366;;;2062:2;2050:9;2041:7;2037:23;2033:32;2030:2;;;2078:1;2075;2068:12;2030:2;2113:1;2130:53;2175:7;2155:9;2130:53;;;2120:63;;2092:97;2220:2;2238:53;2283:7;2274:6;2263:9;2259:22;2238:53;;;2228:63;;2199:98;2024:283;;;;;;2314:491;;;;2452:2;2440:9;2431:7;2427:23;2423:32;2420:2;;;2468:1;2465;2458:12;2420:2;2503:1;2520:53;2565:7;2545:9;2520:53;;;2510:63;;2482:97;2610:2;2628:53;2673:7;2664:6;2653:9;2649:22;2628:53;;;2618:63;;2589:98;2718:2;2736:53;2781:7;2772:6;2761:9;2757:22;2736:53;;;2726:63;;2697:98;2414:391;;;;;;2812:257;;2924:2;2912:9;2903:7;2899:23;2895:32;2892:2;;;2940:1;2937;2930:12;2892:2;2975:1;2992:61;3045:7;3025:9;2992:61;;3076:263;;3191:2;3179:9;3170:7;3166:23;3162:32;3159:2;;;3207:1;3204;3197:12;3159:2;3242:1;3259:64;3315:7;3295:9;3259:64;;3346:291;;3475:2;3463:9;3454:7;3450:23;3446:32;3443:2;;;3491:1;3488;3481:12;3443:2;3526:1;3543:78;3613:7;3593:9;3543:78;;3644:241;;3748:2;3736:9;3727:7;3723:23;3719:32;3716:2;;;3764:1;3761;3754:12;3716:2;3799:1;3816:53;3861:7;3841:9;3816:53;;4162:393;;;4291:2;4279:9;4270:7;4266:23;4262:32;4259:2;;;4307:1;4304;4297:12;4259:2;4342:1;4359:64;4415:7;4395:9;4359:64;;;4349:74;;4321:108;4460:2;4478:61;4531:7;4522:6;4511:9;4507:22;4478:61;;4562:399;;;4694:2;4682:9;4673:7;4669:23;4665:32;4662:2;;;4710:1;4707;4700:12;4662:2;4745:1;4762:64;4818:7;4798:9;4762:64;;;4752:74;;4724:108;4863:2;4881:64;4937:7;4928:6;4917:9;4913:22;4881:64;;4968:1121;;;;;;;;;5191:3;5179:9;5170:7;5166:23;5162:33;5159:2;;;5208:1;5205;5198:12;5159:2;5243:1;5260:53;5305:7;5285:9;5260:53;;;5250:63;;5222:97;5350:2;5368:53;5413:7;5404:6;5393:9;5389:22;5368:53;;;5358:63;;5329:98;5458:2;5476:53;5521:7;5512:6;5501:9;5497:22;5476:53;;;5466:63;;5437:98;5566:2;5584:53;5629:7;5620:6;5609:9;5605:22;5584:53;;;5574:63;;5545:98;5674:3;5693:53;5738:7;5729:6;5718:9;5714:22;5693:53;;;5683:63;;5653:99;5783:3;5802:53;5847:7;5838:6;5827:9;5823:22;5802:53;;;5792:63;;5762:99;5892:3;5911:53;5956:7;5947:6;5936:9;5932:22;5911:53;;;5901:63;;5871:99;6001:3;6020:53;6065:7;6056:6;6045:9;6041:22;6020:53;;;6010:63;;5980:99;5153:936;;;;;;;;;;;;6097:253;;6222:88;6306:3;6298:6;6222:88;;;-1:-1;;6339:4;6330:14;;6215:135;6359:173;;6446:46;6488:3;6480:6;6446:46;;;-1:-1;;6521:4;6512:14;;6439:93;6722:142;6813:45;6852:5;6813:45;;;6808:3;6801:58;6795:69;;;6871:113;6954:24;6972:5;6954:24;;6991:152;7092:45;7112:24;7130:5;7112:24;;;7092:45;;7189:812;7360:71;7425:5;7360:71;;;7444:103;7540:6;7535:3;7444:103;;;7437:110;;7568:73;7635:5;7568:73;;;7661:7;7689:1;7674:315;7699:6;7696:1;7693:13;7674:315;;;7766:6;7760:13;7787:101;7884:3;7869:13;7787:101;;;7780:108;;7905:77;7975:6;7905:77;;;7895:87;-1:-1;;7721:1;7714:9;7674:315;;8040:690;;8185:54;8233:5;8185:54;;;8252:86;8331:6;8326:3;8252:86;;;8245:93;;8359:56;8409:5;8359:56;;;8435:7;8463:1;8448:260;8473:6;8470:1;8467:13;8448:260;;;8540:6;8534:13;8561:63;8620:3;8605:13;8561:63;;;8554:70;;8641:60;8694:6;8641:60;;;8631:70;-1:-1;;8495:1;8488:9;8448:260;;;-1:-1;8721:3;;8164:566;-1:-1;;;;;8164:566;8771:624;8890:48;8932:5;8890:48;;;8951:74;9018:6;9013:3;8951:74;;;8944:81;;9046:50;9090:5;9046:50;;;9116:7;9144:1;9129:254;9154:6;9151:1;9148:13;9129:254;;;9221:6;9215:13;9242:63;9301:3;9286:13;9242:63;;;9235:70;;9322:54;9369:6;9322:54;;;9312:64;-1:-1;;9176:1;9169:9;9129:254;;9403:104;9480:21;9495:5;9480:21;;9514:103;9587:24;9605:5;9587:24;;9744:152;9845:45;9865:24;9883:5;9865:24;;;9845:45;;9903:343;;10013:38;10045:5;10013:38;;;10063:70;10126:6;10121:3;10063:70;;;10056:77;;10138:52;10183:6;10178:3;10171:4;10164:5;10160:16;10138:52;;;10211:29;10233:6;10211:29;;;10202:39;;;;9993:253;-1:-1;;;9993:253;10253:172;10359:60;10413:5;10359:60;;10607:142;10698:45;10737:5;10698:45;;10756:142;10847:45;10886:5;10847:45;;11558:332;;11718:67;11782:2;11777:3;11718:67;;;11818:34;11798:55;;11881:2;11872:12;;11704:186;-1:-1;;11704:186;11899:323;;12059:67;12123:2;12118:3;12059:67;;;12159:25;12139:46;;12213:2;12204:12;;12045:177;-1:-1;;12045:177;12231:390;;12391:67;12455:2;12450:3;12391:67;;;12491:34;12471:55;;12560:23;12555:2;12546:12;;12539:45;12612:2;12603:12;;12377:244;-1:-1;;12377:244;12630:378;;12790:67;12854:2;12849:3;12790:67;;;12890:34;12870:55;;12959:11;12954:2;12945:12;;12938:33;12999:2;12990:12;;12776:232;-1:-1;;12776:232;13017:329;;13177:67;13241:2;13236:3;13177:67;;;13277:31;13257:52;;13337:2;13328:12;;13163:183;-1:-1;;13163:183;13355:319;;13515:67;13579:2;13574:3;13515:67;;;13615:21;13595:42;;13665:2;13656:12;;13501:173;-1:-1;;13501:173;13683:409;;13861:85;13943:2;13938:3;13861:85;;;13979:34;13959:55;;14048:6;14043:2;14034:12;;14027:28;14083:2;14074:12;;13847:245;-1:-1;;13847:245;14101:393;;14261:67;14325:2;14320:3;14261:67;;;14361:34;14341:55;;14430:26;14425:2;14416:12;;14409:48;14485:2;14476:12;;14247:247;-1:-1;;14247:247;14503:376;;14663:67;14727:2;14722:3;14663:67;;;14763:34;14743:55;;14832:9;14827:2;14818:12;;14811:31;14870:2;14861:12;;14649:230;-1:-1;;14649:230;14888:428;;15066:85;15148:2;15143:3;15066:85;;;15184:34;15164:55;;15253:25;15248:2;15239:12;;15232:47;15307:2;15298:12;;15052:264;-1:-1;;15052:264;15325:327;;15485:67;15549:2;15544:3;15485:67;;;15585:29;15565:50;;15643:2;15634:12;;15471:181;-1:-1;;15471:181;15661:330;;15821:67;15885:2;15880:3;15821:67;;;15921:32;15901:53;;15982:2;15973:12;;15807:184;-1:-1;;15807:184;16000:326;;16160:67;16224:2;16219:3;16160:67;;;16260:28;16240:49;;16317:2;16308:12;;16146:180;-1:-1;;16146:180;16335:401;;16495:67;16559:2;16554:3;16495:67;;;16595:34;16575:55;;16664:34;16659:2;16650:12;;16643:56;16727:2;16718:12;;16481:255;-1:-1;;16481:255;16745:353;;16923:85;17005:2;17000:3;16923:85;;;17041:19;17021:40;;17089:2;17080:12;;16909:189;-1:-1;;16909:189;17107:324;;17267:67;17331:2;17326:3;17267:67;;;17367:26;17347:47;;17422:2;17413:12;;17253:178;-1:-1;;17253:178;17440:331;;17600:67;17664:2;17659:3;17600:67;;;17700:33;17680:54;;17762:2;17753:12;;17586:185;-1:-1;;17586:185;17780:330;;17940:67;18004:2;17999:3;17940:67;;;18040:32;18020:53;;18101:2;18092:12;;17926:184;-1:-1;;17926:184;18119:384;;18279:67;18343:2;18338:3;18279:67;;;18379:34;18359:55;;18448:17;18443:2;18434:12;;18427:39;18494:2;18485:12;;18265:238;-1:-1;;18265:238;18512:331;;18672:67;18736:2;18731:3;18672:67;;;18772:33;18752:54;;18834:2;18825:12;;18658:185;-1:-1;;18658:185;18852:331;;19012:67;19076:2;19071:3;19012:67;;;19112:33;19092:54;;19174:2;19165:12;;18998:185;-1:-1;;18998:185;19192:370;;19352:67;19416:2;19411:3;19352:67;;;19452:34;19432:55;;19521:3;19516:2;19507:12;;19500:25;19553:2;19544:12;;19338:224;-1:-1;;19338:224;19571:322;;19731:67;19795:2;19790:3;19731:67;;;19831:24;19811:45;;19884:2;19875:12;;19717:176;-1:-1;;19717:176;19902:329;;20062:67;20126:2;20121:3;20062:67;;;20162:31;20142:52;;20222:2;20213:12;;20048:183;-1:-1;;20048:183;20240:378;;20400:67;20464:2;20459:3;20400:67;;;20500:34;20480:55;;20569:11;20564:2;20555:12;;20548:33;20609:2;20600:12;;20386:232;-1:-1;;20386:232;20627:361;;20805:85;20887:2;20882:3;20805:85;;;20923:27;20903:48;;20979:2;20970:12;;20791:197;-1:-1;;20791:197;20997:317;;21157:67;21221:2;21216:3;21157:67;;;21257:19;21237:40;;21305:2;21296:12;;21143:171;-1:-1;;21143:171;21323:323;;21483:67;21547:2;21542:3;21483:67;;;21583:25;21563:46;;21637:2;21628:12;;21469:177;-1:-1;;21469:177;21655:442;;21815:67;21879:2;21874:3;21815:67;;;21915:34;21895:55;;21984:34;21979:2;21970:12;;21963:56;22053:6;22048:2;22039:12;;22032:28;22088:2;22079:12;;21801:296;-1:-1;;21801:296;22106:395;;22266:67;22330:2;22325:3;22266:67;;;22366:34;22346:55;;22435:28;22430:2;22421:12;;22414:50;22492:2;22483:12;;22252:249;-1:-1;;22252:249;22510:360;;22688:85;22770:2;22765:3;22688:85;;;22806:26;22786:47;;22861:2;22852:12;;22674:196;-1:-1;;22674:196;22879:323;;23039:67;23103:2;23098:3;23039:67;;;23139:25;23119:46;;23193:2;23184:12;;23025:177;-1:-1;;23025:177;23211:332;;23371:67;23435:2;23430:3;23371:67;;;23471:34;23451:55;;23534:2;23525:12;;23357:186;-1:-1;;23357:186;23552:327;;23712:67;23776:2;23771:3;23712:67;;;23812:29;23792:50;;23870:2;23861:12;;23698:181;-1:-1;;23698:181;23888:332;;24048:67;24112:2;24107:3;24048:67;;;24148:34;24128:55;;24211:2;24202:12;;24034:186;-1:-1;;24034:186;24458:124;24540:36;24570:5;24540:36;;24589:110;24670:23;24687:5;24670:23;;24706:107;24785:22;24801:5;24785:22;;24820:383;;24967:75;25038:3;25029:6;24967:75;;;25064:2;25059:3;25055:12;25048:19;;25078:75;25149:3;25140:6;25078:75;;;-1:-1;25175:2;25166:12;;24955:248;-1:-1;;24955:248;25210:372;;25409:148;25553:3;25409:148;;25589:372;;25788:148;25932:3;25788:148;;25968:511;;26195:148;26339:3;26195:148;;;26188:155;;26354:75;26425:3;26416:6;26354:75;;;-1:-1;26451:2;26442:12;;26176:303;-1:-1;26176:303;26486:511;;26713:148;26857:3;26713:148;;27004:372;;27203:148;27347:3;27203:148;;27383:213;27501:2;27486:18;;27515:71;27490:9;27559:6;27515:71;;27603:229;27729:2;27714:18;;27743:79;27718:9;27795:6;27743:79;;27839:324;27985:2;27970:18;;27999:71;27974:9;28043:6;27999:71;;;28081:72;28149:2;28138:9;28134:18;28125:6;28081:72;;28170:340;28324:2;28309:18;;28338:71;28313:9;28382:6;28338:71;;;28420:80;28496:2;28485:9;28481:18;28472:6;28420:80;;28517:567;28729:3;28714:19;;28744:71;28718:9;28788:6;28744:71;;;28826:80;28902:2;28891:9;28887:18;28878:6;28826:80;;;28917;28993:2;28982:9;28978:18;28969:6;28917:80;;;29008:66;29070:2;29059:9;29055:18;29046:6;29008:66;;;28700:384;;;;;;;;29091:324;29237:2;29222:18;;29251:71;29226:9;29295:6;29251:71;;;29333:72;29401:2;29390:9;29386:18;29377:6;29333:72;;29422:435;29596:2;29581:18;;29610:71;29585:9;29654:6;29610:71;;;29692:72;29760:2;29749:9;29745:18;29736:6;29692:72;;;29775;29843:2;29832:9;29828:18;29819:6;29775:72;;29864:545;30065:3;30050:19;;30080:71;30054:9;30124:6;30080:71;;;30162:72;30230:2;30219:9;30215:18;30206:6;30162:72;;;30245;30313:2;30302:9;30298:18;30289:6;30245:72;;;30328:71;30395:2;30384:9;30380:18;30371:6;30328:71;;30416:382;30618:3;30603:19;;30633:155;30607:9;30761:6;30633:155;;30805:361;30973:2;30987:47;;;30958:18;;31048:108;30958:18;31142:6;31048:108;;31173:201;31285:2;31270:18;;31299:65;31274:9;31337:6;31299:65;;31381:213;31499:2;31484:18;;31513:71;31488:9;31557:6;31513:71;;31601:324;31747:2;31732:18;;31761:71;31736:9;31805:6;31761:71;;31932:324;32078:2;32063:18;;32092:71;32067:9;32136:6;32092:71;;32263:412;32429:2;32414:18;;32443:71;32418:9;32487:6;32443:71;;;32562:9;32556:4;32552:20;32547:2;32536:9;32532:18;32525:48;32587:78;32660:4;32651:6;32587:78;;33013:919;33321:3;33336:47;;;33306:19;;33397:76;33306:19;33459:6;33397:76;;;33389:84;;33484:80;33560:2;33549:9;33545:18;33536:6;33484:80;;;33575:72;33643:2;33632:9;33628:18;33619:6;33575:72;;;33658:80;33734:2;33723:9;33719:18;33710:6;33658:80;;;33749:81;33825:3;33814:9;33810:19;33801:6;33749:81;;;33841;33917:3;33906:9;33902:19;33893:6;33841:81;;;33292:640;;;;;;;;;;33939:903;34239:3;34254:47;;;34224:19;;34315:76;34224:19;34377:6;34315:76;;;34307:84;;34402:80;34478:2;34467:9;34463:18;34454:6;34402:80;;;34493:72;34561:2;34550:9;34546:18;34537:6;34493:72;;;34576;34644:2;34633:9;34629:18;34620:6;34576:72;;34849:259;34990:2;34975:18;;35004:94;34979:9;35071:6;35004:94;;35377:301;35515:2;35529:47;;;35500:18;;35590:78;35500:18;35654:6;35590:78;;35685:407;35876:2;35890:47;;;35861:18;;35951:131;35861:18;35951:131;;36099:407;36290:2;36304:47;;;36275:18;;36365:131;36275:18;36365:131;;36513:407;36704:2;36718:47;;;36689:18;;36779:131;36689:18;36779:131;;36927:407;37118:2;37132:47;;;37103:18;;37193:131;37103:18;37193:131;;37341:407;37532:2;37546:47;;;37517:18;;37607:131;37517:18;37607:131;;37755:407;37946:2;37960:47;;;37931:18;;38021:131;37931:18;38021:131;;38169:407;38360:2;38374:47;;;38345:18;;38435:131;38345:18;38435:131;;38583:407;38774:2;38788:47;;;38759:18;;38849:131;38759:18;38849:131;;38997:407;39188:2;39202:47;;;39173:18;;39263:131;39173:18;39263:131;;39411:407;39602:2;39616:47;;;39587:18;;39677:131;39587:18;39677:131;;39825:407;40016:2;40030:47;;;40001:18;;40091:131;40001:18;40091:131;;40239:407;40430:2;40444:47;;;40415:18;;40505:131;40415:18;40505:131;;40653:407;40844:2;40858:47;;;40829:18;;40919:131;40829:18;40919:131;;41067:407;41258:2;41272:47;;;41243:18;;41333:131;41243:18;41333:131;;41481:407;41672:2;41686:47;;;41657:18;;41747:131;41657:18;41747:131;;41895:407;42086:2;42100:47;;;42071:18;;42161:131;42071:18;42161:131;;42309:407;42500:2;42514:47;;;42485:18;;42575:131;42485:18;42575:131;;42723:407;42914:2;42928:47;;;42899:18;;42989:131;42899:18;42989:131;;43137:407;43328:2;43342:47;;;43313:18;;43403:131;43313:18;43403:131;;43551:407;43742:2;43756:47;;;43727:18;;43817:131;43727:18;43817:131;;43965:407;44156:2;44170:47;;;44141:18;;44231:131;44141:18;44231:131;;44379:407;44570:2;44584:47;;;44555:18;;44645:131;44555:18;44645:131;;44793:407;44984:2;44998:47;;;44969:18;;45059:131;44969:18;45059:131;;45207:407;45398:2;45412:47;;;45383:18;;45473:131;45383:18;45473:131;;45621:407;45812:2;45826:47;;;45797:18;;45887:131;45797:18;45887:131;;46035:407;46226:2;46240:47;;;46211:18;;46301:131;46211:18;46301:131;;46449:407;46640:2;46654:47;;;46625:18;;46715:131;46625:18;46715:131;;46863:407;47054:2;47068:47;;;47039:18;;47129:131;47039:18;47129:131;;47277:407;47468:2;47482:47;;;47453:18;;47543:131;47453:18;47543:131;;47691:407;47882:2;47896:47;;;47867:18;;47957:131;47867:18;47957:131;;48656:435;48830:2;48815:18;;48844:71;48819:9;48888:6;48844:71;;49098:871;49378:3;49363:19;;49393:69;49367:9;49435:6;49393:69;;;49473:70;49539:2;49528:9;49524:18;49515:6;49473:70;;;49554;49620:2;49609:9;49605:18;49596:6;49554:70;;;49635:72;49703:2;49692:9;49688:18;49679:6;49635:72;;;49718:73;49786:3;49775:9;49771:19;49762:6;49718:73;;;49802;49870:3;49859:9;49855:19;49846:6;49802:73;;;49886;49954:3;49943:9;49939:19;49930:6;49886:73;;;49349:620;;;;;;;;;;;49976:205;50090:2;50075:18;;50104:67;50079:9;50144:6;50104:67;;50311:151;50435:4;50426:14;;50383:79;50569:127;-1:-1;50682:4;;50660:36;50703:137;50806:12;;50777:63;51740:178;51858:19;;;51907:4;51898:14;;51851:67;52562:91;;52624:24;52642:5;52624:24;;52766:85;52832:13;52825:21;;52808:43;52937:105;;53013:24;53031:5;53013:24;;53136:121;-1:-1;;;;;53198:54;;53181:76;53343:96;53415:18;53404:30;;53387:52;53446:81;53517:4;53506:16;;53489:38;53534:129;;53621:37;53652:5;53621:37;;54272:138;;54359:46;54372:32;54398:5;54372:32;;54417:116;;54504:24;54522:5;54504:24;;55029:106;;55107:23;55124:5;55107:23;;55143:268;55208:1;55215:101;55229:6;55226:1;55223:13;55215:101;;;55296:11;;;55290:18;55277:11;;;55270:39;55251:2;55244:10;55215:101;;;55331:6;55328:1;55325:13;55322:2;;;55396:1;55387:6;55382:3;55378:16;55371:27;55322:2;55192:219;;;;;55419:95;;55483:26;55503:5;55602:89;55666:20;55680:5;55666:20;;55698:97;55786:2;55766:14;-1:-1;;55762:28;;55746:49;55903:94;55977:2;55973:14;;55945:52;56005:117;56074:24;56092:5;56074:24;;;56067:5;56064:35;56054:2;;56113:1;56110;56103:12;56269:111;56335:21;56350:5;56335:21;;56387:117;56456:24;56474:5;56456:24;;56511:145;56594:38;56626:5;56594:38;
Swarm Source
bzzr://882079c2d3031f6a74125aae31f9cd51dec8225767dd29b17b1d172a05b79e39
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.