My Name Tag:
Not Available, login to update
ContractCreator:
GENESIS at txn GENESIS_47ee58801c1ac44e54ff2651ae50525c5cfc66d0
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Latest 25 Deposits
[ Download CSV Export ]
Contract Source Code Verified (Genesis Bytecode Match Only)
Contract Name:
ImportableRewardEscrowV2
Compiler Version
v0.5.16
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Optimistic.Etherscan.io on 2021-08-25 */ /* ____ __ __ __ _ / __/__ __ ___ / /_ / / ___ / /_ (_)__ __ _\ \ / // // _ \/ __// _ \/ -_)/ __// / \ \ / /___/ \_, //_//_/\__//_//_/\__/ \__//_/ /_\_\ /___/ * Synthetix: ImportableRewardEscrowV2.sol * * Latest source (may be newer): https://github.com/Synthetixio/synthetix/blob/master/contracts/ImportableRewardEscrowV2.sol * Docs: https://docs.synthetix.io/contracts/ImportableRewardEscrowV2 * * Contract Dependencies: * - BaseRewardEscrowV2 * - IAddressResolver * - Owned * Libraries: * - SafeDecimalMath * - SafeMath * - VestingEntries * * MIT License * =========== * * Copyright (c) 2021 Synthetix * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity ^0.5.16; // https://docs.synthetix.io/contracts/source/contracts/owned contract Owned { address public owner; address public nominatedOwner; constructor(address _owner) public { require(_owner != address(0), "Owner address cannot be 0"); owner = _owner; emit OwnerChanged(address(0), _owner); } function nominateNewOwner(address _owner) external onlyOwner { nominatedOwner = _owner; emit OwnerNominated(_owner); } function acceptOwnership() external { require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership"); emit OwnerChanged(owner, nominatedOwner); owner = nominatedOwner; nominatedOwner = address(0); } modifier onlyOwner { _onlyOwner(); _; } function _onlyOwner() private view { require(msg.sender == owner, "Only the contract owner may perform this action"); } event OwnerNominated(address newOwner); event OwnerChanged(address oldOwner, address newOwner); } // https://docs.synthetix.io/contracts/source/interfaces/iaddressresolver interface IAddressResolver { function getAddress(bytes32 name) external view returns (address); function getSynth(bytes32 key) external view returns (address); function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address); } // https://docs.synthetix.io/contracts/source/interfaces/isynth interface ISynth { // Views function currencyKey() external view returns (bytes32); function transferableSynths(address account) external view returns (uint); // Mutative functions function transferAndSettle(address to, uint value) external returns (bool); function transferFromAndSettle( address from, address to, uint value ) external returns (bool); // Restricted: used internally to Synthetix function burn(address account, uint amount) external; function issue(address account, uint amount) external; } // https://docs.synthetix.io/contracts/source/interfaces/iissuer interface IIssuer { // Views function anySynthOrSNXRateIsInvalid() external view returns (bool anyRateInvalid); function availableCurrencyKeys() external view returns (bytes32[] memory); function availableSynthCount() external view returns (uint); function availableSynths(uint index) external view returns (ISynth); function canBurnSynths(address account) external view returns (bool); function collateral(address account) external view returns (uint); function collateralisationRatio(address issuer) external view returns (uint); function collateralisationRatioAndAnyRatesInvalid(address _issuer) external view returns (uint cratio, bool anyRateIsInvalid); function debtBalanceOf(address issuer, bytes32 currencyKey) external view returns (uint debtBalance); function issuanceRatio() external view returns (uint); function lastIssueEvent(address account) external view returns (uint); function maxIssuableSynths(address issuer) external view returns (uint maxIssuable); function minimumStakeTime() external view returns (uint); function remainingIssuableSynths(address issuer) external view returns ( uint maxIssuable, uint alreadyIssued, uint totalSystemDebt ); function synths(bytes32 currencyKey) external view returns (ISynth); function getSynths(bytes32[] calldata currencyKeys) external view returns (ISynth[] memory); function synthsByAddress(address synthAddress) external view returns (bytes32); function totalIssuedSynths(bytes32 currencyKey, bool excludeOtherCollateral) external view returns (uint); function transferableSynthetixAndAnyRateIsInvalid(address account, uint balance) external view returns (uint transferable, bool anyRateIsInvalid); // Restricted: used internally to Synthetix function issueSynths(address from, uint amount) external; function issueSynthsOnBehalf( address issueFor, address from, uint amount ) external; function issueMaxSynths(address from) external; function issueMaxSynthsOnBehalf(address issueFor, address from) external; function burnSynths(address from, uint amount) external; function burnSynthsOnBehalf( address burnForAddress, address from, uint amount ) external; function burnSynthsToTarget(address from) external; function burnSynthsToTargetOnBehalf(address burnForAddress, address from) external; function burnForRedemption( ISynth deprecatedSynth, address account, uint balance ) external; function liquidateDelinquentAccount( address account, uint susdAmount, address liquidator ) external returns (uint totalRedeemed, uint amountToLiquidate); } // Inheritance // Internal references // https://docs.synthetix.io/contracts/source/contracts/addressresolver contract AddressResolver is Owned, IAddressResolver { mapping(bytes32 => address) public repository; constructor(address _owner) public Owned(_owner) {} /* ========== RESTRICTED FUNCTIONS ========== */ function importAddresses(bytes32[] calldata names, address[] calldata destinations) external onlyOwner { require(names.length == destinations.length, "Input lengths must match"); for (uint i = 0; i < names.length; i++) { bytes32 name = names[i]; address destination = destinations[i]; repository[name] = destination; emit AddressImported(name, destination); } } /* ========= PUBLIC FUNCTIONS ========== */ function rebuildCaches(MixinResolver[] calldata destinations) external { for (uint i = 0; i < destinations.length; i++) { destinations[i].rebuildCache(); } } /* ========== VIEWS ========== */ function areAddressesImported(bytes32[] calldata names, address[] calldata destinations) external view returns (bool) { for (uint i = 0; i < names.length; i++) { if (repository[names[i]] != destinations[i]) { return false; } } return true; } function getAddress(bytes32 name) external view returns (address) { return repository[name]; } function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address) { address _foundAddress = repository[name]; require(_foundAddress != address(0), reason); return _foundAddress; } function getSynth(bytes32 key) external view returns (address) { IIssuer issuer = IIssuer(repository["Issuer"]); require(address(issuer) != address(0), "Cannot find Issuer address"); return address(issuer.synths(key)); } /* ========== EVENTS ========== */ event AddressImported(bytes32 name, address destination); } // Internal references // https://docs.synthetix.io/contracts/source/contracts/mixinresolver contract MixinResolver { AddressResolver public resolver; mapping(bytes32 => address) private addressCache; constructor(address _resolver) internal { resolver = AddressResolver(_resolver); } /* ========== INTERNAL FUNCTIONS ========== */ function combineArrays(bytes32[] memory first, bytes32[] memory second) internal pure returns (bytes32[] memory combination) { combination = new bytes32[](first.length + second.length); for (uint i = 0; i < first.length; i++) { combination[i] = first[i]; } for (uint j = 0; j < second.length; j++) { combination[first.length + j] = second[j]; } } /* ========== PUBLIC FUNCTIONS ========== */ // Note: this function is public not external in order for it to be overridden and invoked via super in subclasses function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {} function rebuildCache() public { bytes32[] memory requiredAddresses = resolverAddressesRequired(); // The resolver must call this function whenver it updates its state for (uint i = 0; i < requiredAddresses.length; i++) { bytes32 name = requiredAddresses[i]; // Note: can only be invoked once the resolver has all the targets needed added address destination = resolver.requireAndGetAddress(name, string(abi.encodePacked("Resolver missing target: ", name))); addressCache[name] = destination; emit CacheUpdated(name, destination); } } /* ========== VIEWS ========== */ function isResolverCached() external view returns (bool) { bytes32[] memory requiredAddresses = resolverAddressesRequired(); for (uint i = 0; i < requiredAddresses.length; i++) { bytes32 name = requiredAddresses[i]; // false if our cache is invalid or if the resolver doesn't have the required address if (resolver.getAddress(name) != addressCache[name] || addressCache[name] == address(0)) { return false; } } return true; } /* ========== INTERNAL FUNCTIONS ========== */ function requireAndGetAddress(bytes32 name) internal view returns (address) { address _foundAddress = addressCache[name]; require(_foundAddress != address(0), string(abi.encodePacked("Missing address: ", name))); return _foundAddress; } /* ========== EVENTS ========== */ event CacheUpdated(bytes32 name, address destination); } // https://docs.synthetix.io/contracts/source/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"); _; } } pragma experimental ABIEncoderV2; library VestingEntries { struct VestingEntry { uint64 endTime; uint256 escrowAmount; } struct VestingEntryWithID { uint64 endTime; uint256 escrowAmount; uint256 entryID; } } interface IRewardEscrowV2 { // Views function balanceOf(address account) external view returns (uint); function numVestingEntries(address account) external view returns (uint); function totalEscrowedAccountBalance(address account) external view returns (uint); function totalVestedAccountBalance(address account) external view returns (uint); function getVestingQuantity(address account, uint256[] calldata entryIDs) external view returns (uint); function getVestingSchedules( address account, uint256 index, uint256 pageSize ) external view returns (VestingEntries.VestingEntryWithID[] memory); function getAccountVestingEntryIDs( address account, uint256 index, uint256 pageSize ) external view returns (uint256[] memory); function getVestingEntryClaimable(address account, uint256 entryID) external view returns (uint); function getVestingEntry(address account, uint256 entryID) external view returns (uint64, uint256); // Mutative functions function vest(uint256[] calldata entryIDs) external; function createEscrowEntry( address beneficiary, uint256 deposit, uint256 duration ) external; function appendVestingEntry( address account, uint256 quantity, uint256 duration ) external; function migrateVestingSchedule(address _addressToMigrate) external; function migrateAccountEscrowBalances( address[] calldata accounts, uint256[] calldata escrowBalances, uint256[] calldata vestedBalances ) external; // Account Merging function startMergingWindow() external; function mergeAccount(address accountToMerge, uint256[] calldata entryIDs) external; function nominateAccountToMerge(address account) external; function accountMergingIsOpen() external view returns (bool); // L2 Migration function importVestingEntries( address account, uint256 escrowedAmount, VestingEntries.VestingEntry[] calldata vestingEntries ) external; // Return amount of SNX transfered to SynthetixBridgeToOptimism deposit contract function burnForMigration(address account, uint256[] calldata entryIDs) external returns (uint256 escrowedAccountBalance, VestingEntries.VestingEntry[] memory vestingEntries); } /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // Libraries // https://docs.synthetix.io/contracts/source/libraries/safedecimalmath library SafeDecimalMath { using SafeMath for uint; /* Number of decimal places in the representations. */ uint8 public constant decimals = 18; uint8 public constant highPrecisionDecimals = 27; /* The number representing 1.0. */ uint public constant UNIT = 10**uint(decimals); /* The number representing 1.0 for higher fidelity numbers. */ uint public constant PRECISE_UNIT = 10**uint(highPrecisionDecimals); uint private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR = 10**uint(highPrecisionDecimals - decimals); /** * @return Provides an interface to UNIT. */ function unit() external pure returns (uint) { return UNIT; } /** * @return Provides an interface to PRECISE_UNIT. */ function preciseUnit() external pure returns (uint) { return PRECISE_UNIT; } /** * @return The result of multiplying x and y, interpreting the operands as fixed-point * decimals. * * @dev A unit factor is divided out after the product of x and y is evaluated, * so that product must be less than 2**256. As this is an integer division, * the internal division always rounds down. This helps save on gas. Rounding * is more expensive on gas. */ function multiplyDecimal(uint x, uint y) internal pure returns (uint) { /* Divide by UNIT to remove the extra factor introduced by the product. */ return x.mul(y) / UNIT; } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of the specified precision unit. * * @dev The operands should be in the form of a the specified unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function _multiplyDecimalRound( uint x, uint y, uint precisionUnit ) private pure returns (uint) { /* Divide by UNIT to remove the extra factor introduced by the product. */ uint quotientTimesTen = x.mul(y) / (precisionUnit / 10); if (quotientTimesTen % 10 >= 5) { quotientTimesTen += 10; } return quotientTimesTen / 10; } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of a precise unit. * * @dev The operands should be in the precise unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function multiplyDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) { return _multiplyDecimalRound(x, y, PRECISE_UNIT); } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of a standard unit. * * @dev The operands should be in the standard unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function multiplyDecimalRound(uint x, uint y) internal pure returns (uint) { return _multiplyDecimalRound(x, y, UNIT); } /** * @return The result of safely dividing x and y. The return value is a high * precision decimal. * * @dev y is divided after the product of x and the standard precision unit * is evaluated, so the product of x and UNIT must be less than 2**256. As * this is an integer division, the result is always rounded down. * This helps save on gas. Rounding is more expensive on gas. */ function divideDecimal(uint x, uint y) internal pure returns (uint) { /* Reintroduce the UNIT factor that will be divided out by y. */ return x.mul(UNIT).div(y); } /** * @return The result of safely dividing x and y. The return value is as a rounded * decimal in the precision unit specified in the parameter. * * @dev y is divided after the product of x and the specified precision unit * is evaluated, so the product of x and the specified precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function _divideDecimalRound( uint x, uint y, uint precisionUnit ) private pure returns (uint) { uint resultTimesTen = x.mul(precisionUnit * 10).div(y); if (resultTimesTen % 10 >= 5) { resultTimesTen += 10; } return resultTimesTen / 10; } /** * @return The result of safely dividing x and y. The return value is as a rounded * standard precision decimal. * * @dev y is divided after the product of x and the standard precision unit * is evaluated, so the product of x and the standard precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function divideDecimalRound(uint x, uint y) internal pure returns (uint) { return _divideDecimalRound(x, y, UNIT); } /** * @return The result of safely dividing x and y. The return value is as a rounded * high precision decimal. * * @dev y is divided after the product of x and the high precision unit * is evaluated, so the product of x and the high precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function divideDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) { return _divideDecimalRound(x, y, PRECISE_UNIT); } /** * @dev Convert a standard decimal representation to a high precision one. */ function decimalToPreciseDecimal(uint i) internal pure returns (uint) { return i.mul(UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR); } /** * @dev Convert a high precision decimal to a standard decimal representation. */ function preciseDecimalToDecimal(uint i) internal pure returns (uint) { uint quotientTimesTen = i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10); if (quotientTimesTen % 10 >= 5) { quotientTimesTen += 10; } return quotientTimesTen / 10; } // Computes `a - b`, setting the value to 0 if b > a. function floorsub(uint a, uint b) internal pure returns (uint) { return b >= a ? 0 : a - b; } } // https://docs.synthetix.io/contracts/source/interfaces/ierc20 interface IERC20 { // ERC20 Optional Views function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); // Views function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); // Mutative functions function transfer(address to, uint value) external returns (bool); function approve(address spender, uint value) external returns (bool); function transferFrom( address from, address to, uint value ) external returns (bool); // Events event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); } // https://docs.synthetix.io/contracts/source/interfaces/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); // Mutative Functions function claimFees() external returns (bool); function claimOnBehalf(address claimingForAddress) external returns (bool); function closeCurrentFeePeriod() external; // Restricted: used internally to Synthetix function appendAccountIssuanceRecord( address account, uint lockedAmount, uint debtEntryIndex ) external; function recordFeePaid(uint sUSDAmount) external; function setRewardsToDistribute(uint amount) external; } interface IVirtualSynth { // Views function balanceOfUnderlying(address account) external view returns (uint); function rate() external view returns (uint); function readyToSettle() external view returns (bool); function secsLeftInWaitingPeriod() external view returns (uint); function settled() external view returns (bool); function synth() external view returns (ISynth); // Mutative functions function settle(address account) external; } // https://docs.synthetix.io/contracts/source/interfaces/isynthetix interface ISynthetix { // Views function anySynthOrSNXRateIsInvalid() external view returns (bool anyRateInvalid); function availableCurrencyKeys() external view returns (bytes32[] memory); function availableSynthCount() external view returns (uint); function availableSynths(uint index) external view returns (ISynth); function collateral(address account) external view returns (uint); function collateralisationRatio(address issuer) external view returns (uint); function debtBalanceOf(address issuer, bytes32 currencyKey) external view returns (uint); function isWaitingPeriod(bytes32 currencyKey) external view returns (bool); function maxIssuableSynths(address issuer) external view returns (uint maxIssuable); function remainingIssuableSynths(address issuer) external view returns ( uint maxIssuable, uint alreadyIssued, uint totalSystemDebt ); function synths(bytes32 currencyKey) external view returns (ISynth); function synthsByAddress(address synthAddress) external view returns (bytes32); function totalIssuedSynths(bytes32 currencyKey) external view returns (uint); function totalIssuedSynthsExcludeOtherCollateral(bytes32 currencyKey) external view returns (uint); function transferableSynthetix(address account) external view returns (uint transferable); // Mutative Functions function burnSynths(uint amount) external; function burnSynthsOnBehalf(address burnForAddress, uint amount) external; function burnSynthsToTarget() external; function burnSynthsToTargetOnBehalf(address burnForAddress) external; function exchange( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external returns (uint amountReceived); function exchangeOnBehalf( address exchangeForAddress, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external returns (uint amountReceived); function exchangeWithTracking( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address rewardAddress, bytes32 trackingCode ) external returns (uint amountReceived); function exchangeWithTrackingForInitiator( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address rewardAddress, bytes32 trackingCode ) external returns (uint amountReceived); function exchangeOnBehalfWithTracking( address exchangeForAddress, bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, address rewardAddress, bytes32 trackingCode ) external returns (uint amountReceived); function exchangeWithVirtual( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, bytes32 trackingCode ) external returns (uint amountReceived, IVirtualSynth vSynth); function issueMaxSynths() external; function issueMaxSynthsOnBehalf(address issueForAddress) external; function issueSynths(uint amount) external; function issueSynthsOnBehalf(address issueForAddress, uint amount) external; function mint() external returns (bool); function settle(bytes32 currencyKey) external returns ( uint reclaimed, uint refunded, uint numEntries ); // Liquidations function liquidateDelinquentAccount(address account, uint susdAmount) external returns (bool); // Restricted Functions function mintSecondary(address account, uint amount) external; function mintSecondaryRewards(uint amount) external; function burnSecondary(address account, uint amount) external; } // Inheritance // Libraries // Internal references // https://docs.synthetix.io/contracts/RewardEscrow contract BaseRewardEscrowV2 is Owned, IRewardEscrowV2, LimitedSetup(8 weeks), MixinResolver { using SafeMath for uint; using SafeDecimalMath for uint; mapping(address => mapping(uint256 => VestingEntries.VestingEntry)) public vestingSchedules; mapping(address => uint256[]) public accountVestingEntryIDs; /*Counter for new vesting entry ids. */ uint256 public nextEntryId; /* An account's total escrowed synthetix balance to save recomputing this for fee extraction purposes. */ mapping(address => uint256) public totalEscrowedAccountBalance; /* An account's total vested reward synthetix. */ mapping(address => uint256) public totalVestedAccountBalance; /* Mapping of nominated address to recieve account merging */ mapping(address => address) public nominatedReceiver; /* The total remaining escrowed balance, for verifying the actual synthetix balance of this contract against. */ uint256 public totalEscrowedBalance; /* Max escrow duration */ uint public max_duration = 2 * 52 weeks; // Default max 2 years duration /* Max account merging duration */ uint public maxAccountMergingDuration = 4 weeks; // Default 4 weeks is max /* ========== ACCOUNT MERGING CONFIGURATION ========== */ uint public accountMergingDuration = 1 weeks; uint public accountMergingStartTime; /* ========== ADDRESS RESOLVER CONFIGURATION ========== */ bytes32 private constant CONTRACT_SYNTHETIX = "Synthetix"; bytes32 private constant CONTRACT_ISSUER = "Issuer"; bytes32 private constant CONTRACT_FEEPOOL = "FeePool"; /* ========== CONSTRUCTOR ========== */ constructor(address _owner, address _resolver) public Owned(_owner) MixinResolver(_resolver) { nextEntryId = 1; } /* ========== VIEWS ======================= */ function feePool() internal view returns (IFeePool) { return IFeePool(requireAndGetAddress(CONTRACT_FEEPOOL)); } function synthetix() internal view returns (ISynthetix) { return ISynthetix(requireAndGetAddress(CONTRACT_SYNTHETIX)); } function issuer() internal view returns (IIssuer) { return IIssuer(requireAndGetAddress(CONTRACT_ISSUER)); } function _notImplemented() internal pure { revert("Cannot be run on this layer"); } /* ========== VIEW FUNCTIONS ========== */ // Note: use public visibility so that it can be invoked in a subclass function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { addresses = new bytes32[](3); addresses[0] = CONTRACT_SYNTHETIX; addresses[1] = CONTRACT_FEEPOOL; addresses[2] = CONTRACT_ISSUER; } /** * @notice A simple alias to totalEscrowedAccountBalance: provides ERC20 balance integration. */ function balanceOf(address account) public view returns (uint) { return totalEscrowedAccountBalance[account]; } /** * @notice The number of vesting dates in an account's schedule. */ function numVestingEntries(address account) external view returns (uint) { return accountVestingEntryIDs[account].length; } /** * @notice Get a particular schedule entry for an account. * @return The vesting entry object and rate per second emission. */ function getVestingEntry(address account, uint256 entryID) external view returns (uint64 endTime, uint256 escrowAmount) { endTime = vestingSchedules[account][entryID].endTime; escrowAmount = vestingSchedules[account][entryID].escrowAmount; } function getVestingSchedules( address account, uint256 index, uint256 pageSize ) external view returns (VestingEntries.VestingEntryWithID[] memory) { uint256 endIndex = index + pageSize; // If index starts after the endIndex return no results if (endIndex <= index) { return new VestingEntries.VestingEntryWithID[](0); } // If the page extends past the end of the accountVestingEntryIDs, truncate it. if (endIndex > accountVestingEntryIDs[account].length) { endIndex = accountVestingEntryIDs[account].length; } uint256 n = endIndex - index; VestingEntries.VestingEntryWithID[] memory vestingEntries = new VestingEntries.VestingEntryWithID[](n); for (uint256 i; i < n; i++) { uint256 entryID = accountVestingEntryIDs[account][i + index]; VestingEntries.VestingEntry memory entry = vestingSchedules[account][entryID]; vestingEntries[i] = VestingEntries.VestingEntryWithID({ endTime: uint64(entry.endTime), escrowAmount: entry.escrowAmount, entryID: entryID }); } return vestingEntries; } function getAccountVestingEntryIDs( address account, uint256 index, uint256 pageSize ) external view returns (uint256[] memory) { uint256 endIndex = index + pageSize; // If the page extends past the end of the accountVestingEntryIDs, truncate it. if (endIndex > accountVestingEntryIDs[account].length) { endIndex = accountVestingEntryIDs[account].length; } if (endIndex <= index) { return new uint256[](0); } uint256 n = endIndex - index; uint256[] memory page = new uint256[](n); for (uint256 i; i < n; i++) { page[i] = accountVestingEntryIDs[account][i + index]; } return page; } function getVestingQuantity(address account, uint256[] calldata entryIDs) external view returns (uint total) { for (uint i = 0; i < entryIDs.length; i++) { VestingEntries.VestingEntry memory entry = vestingSchedules[account][entryIDs[i]]; /* Skip entry if escrowAmount == 0 */ if (entry.escrowAmount != 0) { uint256 quantity = _claimableAmount(entry); /* add quantity to total */ total = total.add(quantity); } } } function getVestingEntryClaimable(address account, uint256 entryID) external view returns (uint) { VestingEntries.VestingEntry memory entry = vestingSchedules[account][entryID]; return _claimableAmount(entry); } function _claimableAmount(VestingEntries.VestingEntry memory _entry) internal view returns (uint256) { uint256 quantity; if (_entry.escrowAmount != 0) { /* Escrow amounts claimable if block.timestamp equal to or after entry endTime */ quantity = block.timestamp >= _entry.endTime ? _entry.escrowAmount : 0; } return quantity; } /* ========== MUTATIVE FUNCTIONS ========== */ /** * Vest escrowed amounts that are claimable * Allows users to vest their vesting entries based on msg.sender */ function vest(uint256[] calldata entryIDs) external { uint256 total; for (uint i = 0; i < entryIDs.length; i++) { VestingEntries.VestingEntry storage entry = vestingSchedules[msg.sender][entryIDs[i]]; /* Skip entry if escrowAmount == 0 already vested */ if (entry.escrowAmount != 0) { uint256 quantity = _claimableAmount(entry); /* update entry to remove escrowAmount */ if (quantity > 0) { entry.escrowAmount = 0; } /* add quantity to total */ total = total.add(quantity); } } /* Transfer vested tokens. Will revert if total > totalEscrowedAccountBalance */ if (total != 0) { _transferVestedTokens(msg.sender, total); } } /** * @notice Create an escrow entry to lock SNX for a given duration in seconds * @dev This call expects that the depositor (msg.sender) has already approved the Reward escrow contract to spend the the amount being escrowed. */ function createEscrowEntry( address beneficiary, uint256 deposit, uint256 duration ) external { require(beneficiary != address(0), "Cannot create escrow with address(0)"); /* Transfer SNX from msg.sender */ require(IERC20(address(synthetix())).transferFrom(msg.sender, address(this), deposit), "token transfer failed"); /* Append vesting entry for the beneficiary address */ _appendVestingEntry(beneficiary, deposit, duration); } /** * @notice Add a new vesting entry at a given time and quantity to an account's schedule. * @dev A call to this should accompany a previous successful call to synthetix.transfer(rewardEscrow, amount), * to ensure that when the funds are withdrawn, there is enough balance. * @param account The account to append a new vesting entry to. * @param quantity The quantity of SNX that will be escrowed. * @param duration The duration that SNX will be emitted. */ function appendVestingEntry( address account, uint256 quantity, uint256 duration ) external onlyFeePool { _appendVestingEntry(account, quantity, duration); } /* Transfer vested tokens and update totalEscrowedAccountBalance, totalVestedAccountBalance */ function _transferVestedTokens(address _account, uint256 _amount) internal { _reduceAccountEscrowBalances(_account, _amount); totalVestedAccountBalance[_account] = totalVestedAccountBalance[_account].add(_amount); IERC20(address(synthetix())).transfer(_account, _amount); emit Vested(_account, block.timestamp, _amount); } function _reduceAccountEscrowBalances(address _account, uint256 _amount) internal { // Reverts if amount being vested is greater than the account's existing totalEscrowedAccountBalance totalEscrowedBalance = totalEscrowedBalance.sub(_amount); totalEscrowedAccountBalance[_account] = totalEscrowedAccountBalance[_account].sub(_amount); } /* ========== ACCOUNT MERGING ========== */ function accountMergingIsOpen() public view returns (bool) { return accountMergingStartTime.add(accountMergingDuration) > block.timestamp; } function startMergingWindow() external onlyOwner { accountMergingStartTime = block.timestamp; emit AccountMergingStarted(accountMergingStartTime, accountMergingStartTime.add(accountMergingDuration)); } function setAccountMergingDuration(uint256 duration) external onlyOwner { require(duration <= maxAccountMergingDuration, "exceeds max merging duration"); accountMergingDuration = duration; emit AccountMergingDurationUpdated(duration); } function setMaxAccountMergingWindow(uint256 duration) external onlyOwner { maxAccountMergingDuration = duration; emit MaxAccountMergingDurationUpdated(duration); } function setMaxEscrowDuration(uint256 duration) external onlyOwner { max_duration = duration; emit MaxEscrowDurationUpdated(duration); } /* Nominate an account to merge escrow and vesting schedule */ function nominateAccountToMerge(address account) external { require(account != msg.sender, "Cannot nominate own account to merge"); require(accountMergingIsOpen(), "Account merging has ended"); require(issuer().debtBalanceOf(msg.sender, "sUSD") == 0, "Cannot merge accounts with debt"); nominatedReceiver[msg.sender] = account; emit NominateAccountToMerge(msg.sender, account); } function mergeAccount(address accountToMerge, uint256[] calldata entryIDs) external { require(accountMergingIsOpen(), "Account merging has ended"); require(issuer().debtBalanceOf(accountToMerge, "sUSD") == 0, "Cannot merge accounts with debt"); require(nominatedReceiver[accountToMerge] == msg.sender, "Address is not nominated to merge"); uint256 totalEscrowAmountMerged; for (uint i = 0; i < entryIDs.length; i++) { // retrieve entry VestingEntries.VestingEntry memory entry = vestingSchedules[accountToMerge][entryIDs[i]]; /* ignore vesting entries with zero escrowAmount */ if (entry.escrowAmount != 0) { /* copy entry to msg.sender (destination address) */ vestingSchedules[msg.sender][entryIDs[i]] = entry; /* Add the escrowAmount of entry to the totalEscrowAmountMerged */ totalEscrowAmountMerged = totalEscrowAmountMerged.add(entry.escrowAmount); /* append entryID to list of entries for account */ accountVestingEntryIDs[msg.sender].push(entryIDs[i]); /* Delete entry from accountToMerge */ delete vestingSchedules[accountToMerge][entryIDs[i]]; } } /* update totalEscrowedAccountBalance for merged account and accountToMerge */ totalEscrowedAccountBalance[accountToMerge] = totalEscrowedAccountBalance[accountToMerge].sub( totalEscrowAmountMerged ); totalEscrowedAccountBalance[msg.sender] = totalEscrowedAccountBalance[msg.sender].add(totalEscrowAmountMerged); emit AccountMerged(accountToMerge, msg.sender, totalEscrowAmountMerged, entryIDs, block.timestamp); } /* Internal function for importing vesting entry and creating new entry for escrow liquidations */ function _addVestingEntry(address account, VestingEntries.VestingEntry memory entry) internal returns (uint) { uint entryID = nextEntryId; vestingSchedules[account][entryID] = entry; /* append entryID to list of entries for account */ accountVestingEntryIDs[account].push(entryID); /* Increment the next entry id. */ nextEntryId = nextEntryId.add(1); return entryID; } /* ========== MIGRATION OLD ESCROW ========== */ function migrateVestingSchedule(address) external { _notImplemented(); } function migrateAccountEscrowBalances( address[] calldata, uint256[] calldata, uint256[] calldata ) external { _notImplemented(); } /* ========== L2 MIGRATION ========== */ function burnForMigration(address, uint[] calldata) external returns (uint256, VestingEntries.VestingEntry[] memory) { _notImplemented(); } function importVestingEntries( address, uint256, VestingEntries.VestingEntry[] calldata ) external { _notImplemented(); } /* ========== INTERNALS ========== */ function _appendVestingEntry( address account, uint256 quantity, uint256 duration ) internal { /* No empty or already-passed vesting entries allowed. */ require(quantity != 0, "Quantity cannot be zero"); require(duration > 0 && duration <= max_duration, "Cannot escrow with 0 duration OR above max_duration"); /* There must be enough balance in the contract to provide for the vesting entry. */ totalEscrowedBalance = totalEscrowedBalance.add(quantity); require( totalEscrowedBalance <= IERC20(address(synthetix())).balanceOf(address(this)), "Must be enough balance in the contract to provide for the vesting entry" ); /* Escrow the tokens for duration. */ uint endTime = block.timestamp + duration; /* Add quantity to account's escrowed balance */ totalEscrowedAccountBalance[account] = totalEscrowedAccountBalance[account].add(quantity); uint entryID = nextEntryId; vestingSchedules[account][entryID] = VestingEntries.VestingEntry({endTime: uint64(endTime), escrowAmount: quantity}); accountVestingEntryIDs[account].push(entryID); /* Increment the next entry id. */ nextEntryId = nextEntryId.add(1); emit VestingEntryCreated(account, block.timestamp, quantity, duration, entryID); } /* ========== MODIFIERS ========== */ modifier onlyFeePool() { require(msg.sender == address(feePool()), "Only the FeePool can perform this action"); _; } /* ========== EVENTS ========== */ event Vested(address indexed beneficiary, uint time, uint value); event VestingEntryCreated(address indexed beneficiary, uint time, uint value, uint duration, uint entryID); event MaxEscrowDurationUpdated(uint newDuration); event MaxAccountMergingDurationUpdated(uint newDuration); event AccountMergingDurationUpdated(uint newDuration); event AccountMergingStarted(uint time, uint endTime); event AccountMerged( address indexed accountToMerge, address destinationAddress, uint escrowAmountMerged, uint[] entryIDs, uint time ); event NominateAccountToMerge(address indexed account, address destination); } // Inheritance // https://docs.synthetix.io/contracts/RewardEscrow contract ImportableRewardEscrowV2 is BaseRewardEscrowV2 { /* ========== ADDRESS RESOLVER CONFIGURATION ========== */ bytes32 private constant CONTRACT_SYNTHETIX_BRIDGE_BASE = "SynthetixBridgeToBase"; /* ========== CONSTRUCTOR ========== */ constructor(address _owner, address _resolver) public BaseRewardEscrowV2(_owner, _resolver) {} /* ========== VIEWS ======================= */ function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { bytes32[] memory existingAddresses = BaseRewardEscrowV2.resolverAddressesRequired(); bytes32[] memory newAddresses = new bytes32[](1); newAddresses[0] = CONTRACT_SYNTHETIX_BRIDGE_BASE; return combineArrays(existingAddresses, newAddresses); } function synthetixBridgeToBase() internal view returns (address) { return requireAndGetAddress(CONTRACT_SYNTHETIX_BRIDGE_BASE); } /* ========== MUTATIVE FUNCTIONS ========== */ function importVestingEntries( address account, uint256 escrowedAmount, VestingEntries.VestingEntry[] calldata vestingEntries ) external onlySynthetixBridge { // There must be enough balance in the contract to provide for the escrowed balance. totalEscrowedBalance = totalEscrowedBalance.add(escrowedAmount); require( totalEscrowedBalance <= IERC20(address(synthetix())).balanceOf(address(this)), "Insufficient balance in the contract to provide for escrowed balance" ); /* Add escrowedAmount to account's escrowed balance */ totalEscrowedAccountBalance[account] = totalEscrowedAccountBalance[account].add(escrowedAmount); for (uint i = 0; i < vestingEntries.length; i++) { _importVestingEntry(account, vestingEntries[i]); } } function _importVestingEntry(address account, VestingEntries.VestingEntry memory entry) internal { uint entryID = nextEntryId; vestingSchedules[account][entryID] = entry; /* append entryID to list of entries for account */ accountVestingEntryIDs[account].push(entryID); /* Increment the next entry id. */ nextEntryId = nextEntryId.add(1); } modifier onlySynthetixBridge() { require(msg.sender == synthetixBridgeToBase(), "Can only be invoked by SynthetixBridgeToBase contract"); _; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_resolver","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"accountToMerge","type":"address"},{"indexed":false,"internalType":"address","name":"destinationAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"escrowAmountMerged","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"entryIDs","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"AccountMerged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"AccountMergingDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"}],"name":"AccountMergingStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"name","type":"bytes32"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"CacheUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"MaxAccountMergingDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"MaxEscrowDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"NominateAccountToMerge","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":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Vested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"entryID","type":"uint256"}],"name":"VestingEntryCreated","type":"event"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"accountMergingDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"accountMergingIsOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"accountMergingStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"accountVestingEntryIDs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"appendVestingEntry","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"name":"burnForMigration","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"components":[{"internalType":"uint64","name":"endTime","type":"uint64"},{"internalType":"uint256","name":"escrowAmount","type":"uint256"}],"internalType":"struct VestingEntries.VestingEntry[]","name":"","type":"tuple[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"createEscrowEntry","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"pageSize","type":"uint256"}],"name":"getAccountVestingEntryIDs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"entryID","type":"uint256"}],"name":"getVestingEntry","outputs":[{"internalType":"uint64","name":"endTime","type":"uint64"},{"internalType":"uint256","name":"escrowAmount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"entryID","type":"uint256"}],"name":"getVestingEntryClaimable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"entryIDs","type":"uint256[]"}],"name":"getVestingQuantity","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"pageSize","type":"uint256"}],"name":"getVestingSchedules","outputs":[{"components":[{"internalType":"uint64","name":"endTime","type":"uint64"},{"internalType":"uint256","name":"escrowAmount","type":"uint256"},{"internalType":"uint256","name":"entryID","type":"uint256"}],"internalType":"struct VestingEntries.VestingEntryWithID[]","name":"","type":"tuple[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"escrowedAmount","type":"uint256"},{"components":[{"internalType":"uint64","name":"endTime","type":"uint64"},{"internalType":"uint256","name":"escrowAmount","type":"uint256"}],"internalType":"struct VestingEntries.VestingEntry[]","name":"vestingEntries","type":"tuple[]"}],"name":"importVestingEntries","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isResolverCached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxAccountMergingDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"max_duration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"accountToMerge","type":"address"},{"internalType":"uint256[]","name":"entryIDs","type":"uint256[]"}],"name":"mergeAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"name":"migrateAccountEscrowBalances","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"migrateVestingSchedule","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"nextEntryId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"nominateAccountToMerge","outputs":[],"payable":false,"stateMutability":"nonpayable","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":[{"internalType":"address","name":"","type":"address"}],"name":"nominatedReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"numVestingEntries","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"rebuildCache","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"resolver","outputs":[{"internalType":"contract AddressResolver","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"resolverAddressesRequired","outputs":[{"internalType":"bytes32[]","name":"addresses","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"setAccountMergingDuration","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"setMaxAccountMergingWindow","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"setMaxEscrowDuration","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":false,"inputs":[],"name":"startMergingWindow","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalEscrowedAccountBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalEscrowedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalVestedAccountBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256[]","name":"entryIDs","type":"uint256[]"}],"name":"vest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"vestingSchedules","outputs":[{"internalType":"uint64","name":"endTime","type":"uint64"},{"internalType":"uint256","name":"escrowAmount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
80604052348015610019576000806100166128ae565b50505b506004361061025c5760003560e01c80636dc05bd31161014f57806380d46f58116100cc578063ae58254911610090578063ae582549146104d3578063b95375bd146104e6578063cd7b43dd146104f9578063e6b2cf6c1461050c578063eac6248914610514578063f0b882ba146105345761025c565b806380d46f581461047a578063899ffef41461049b5780638da5cb5b146104b0578063910a326d146104b8578063a0416ed3146104c05761025c565b8063773ab39f11610113578063773ab39f146104195780637839b92f146104395780637993e6991461044c57806379ba50971461045f5780637cc1d756146104675761025c565b80636dc05bd3146103d057806370a08231146103e357806371e780f3146103f657806373307e40146103fe57806374185360146104115761025c565b806330104c5f116101dd57806345626bd6116101a157806345626bd61461037757806346ba2d901461039857806353a47bb7146103a05780635eb8cf25146103b55780636154c343146103bd5761025c565b806330104c5f14610323578063326a3cfb1461033657806334c7fec91461034957806337088ffc1461035c5780634525aabc146103645761025c565b8063178c565511610224578063178c5655146102da5780631bb47b44146102e2578063204b676a146102f5578063227d517a146103085780632af64bd31461031b5761025c565b8063018c6c551461026a57806304f3bcec1461027f578063056629861461029d5780630fcdefb7146102b25780631627540c146102c7575b6000806102676128ae565b50505b61027d610278366004613105565b610547565b005b610287610598565b6040516102949190613afd565b60405180910390f35b6102a56105b7565b6040516102949190613ab3565b6102ba6105ec565b6040516102949190613ac1565b61027d6102d5366004612ddb565b6105f9565b61027d610662565b61027d6102f0366004612f4c565b6106d1565b6102ba610303366004612ddb565b610733565b6102ba610316366004612ddb565b61075b565b6102a5610773565b6102ba610331366004612e90565b6108f4565b6102ba610344366004612ddb565b610977565b61027d610357366004613064565b61098f565b6102ba610a99565b61027d610372366004613105565b610aa3565b61038a610385366004612e90565b610ae9565b604051610294929190613ca8565b6102ba610b34565b6103a8610b3e565b604051610294919061399d565b6102ba610b4a565b61038a6103cb366004612e90565b610b54565b6102ba6103de366004612e29565b610be1565b6102ba6103f1366004612ddb565b610cab565b6102ba610ccb565b6103a861040c366004612ddb565b610cd5565b61027d610cef565b61042c610427366004612f4c565b610e86565b6040516102949190613a91565b61027d610447366004612ddb565b611074565b61027d61045a366004613105565b61107f565b61027d611100565b61027d610475366004612ddb565b61125b565b61048d610488366004612e29565b611465565b604051610294929190613c3c565b6104a3611479565b6040516102949190613a80565b6103a86114f9565b6102ba611504565b61027d6104ce366004612f4c565b61150e565b6102ba6104e1366004612e90565b611670565b61027d6104f4366004612fa2565b6116a6565b61027d610507366004612ed3565b6116b6565b6102ba6118ee565b610527610522366004612f4c565b6118f8565b6040516102949190613aa2565b61027d610542366004612e29565b611a22565b61054f611f10565b8080600d61055b612919565b5050507fe829efae5d8a2f7163f46c23a8190bf14625c1e446561ca0f5cf279ab7c8015e8160405161058d9190613ac1565b60405180910390a150565b600060036105a4612976565b906101000a90046001600160a01b031681565b60005a6105c26129c2565b6105e5600e6105cf612976565b600f6105d9612976565b9063ffffffff611f7416565b1190505b90565b600f6105f6612976565b81565b610601611f10565b806001808061060e612976565b816001600160a01b0302191690836001600160a01b0316021790610630612919565b5050507f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce228160405161058d919061399d565b61066a611f10565b5a6106736129c2565b80600f61067e612919565b5050507fceade2b9bc02350b17075c94bb699508b89ed2752f501ea42024b1bb5fd34445600f6106ac612976565b6106b9600e6105cf612976565b6040516106c7929190613c5c565b60405180910390a1565b6106d9611fb1565b6001600160a01b03165a6106eb612a08565b6001600160a01b0316146107235760405162461bcd60e51b815260040161071190613c0c565b604051809103906107206128ae565b50505b61072e838383611fcb565b505050565b6001600160a01b038116600090815260066020526040812080610754612976565b9392505050565b600960205280600052604060002090506105f6612976565b6000606061077f611479565b905060005b81518110156108eb57600082828151811061079b57fe5b602002602001015160008181526004602052909150604090206000906107bf612976565b6001600160a01b036101009290920a900416600060036107dd612976565b906101000a90046001600160a01b03166001600160a01b03166321f8a721836040518263ffffffff1660e01b81526004016108189190613ac1565b602060405180830381868061082b612a4e565b1580156108405760008061083d6128ae565b50505b505a61084a612a9a565b5050505050158015610869573d6000803e3d60006108666128ae565b50505b50505050604051601f3d908101601f1916820160405261088c9190810190612e02565b6001600160a01b03161415806108d1575060008181526004602052604081206000906108b6612976565b906101000a90046001600160a01b03166001600160a01b0316145b156108e257600093505050506105e9565b50600101610784565b50600191505090565b60006108fe612b85565b6001600160a01b038416600090815260056020526040902060008481526020919091526040902060405160408082019052908160008261093c612976565b6001600160401b036101009290920a90041681526020016001820161095f612976565b905250905061096d8161234f565b9150505b92915050565b600860205280600052604060002090506105f6612976565b6000805b82811015610a80576000600560005a6109aa612a08565b6001600160a01b03166001600160a01b0316815260200190815260200160002060008686858181106109d857fe5b9050602002013581526020019081526020016000209050806001016109fb612976565b15610a77576000610a4882604051604080820190529081600082610a1d612976565b6001600160401b036101009290920a900416815260200160018201610a40612976565b90525061234f565b90508015610a635760008060018401610a5f612919565b5050505b610a73848263ffffffff611f7416565b9350505b50600101610993565b50801561072e5761072e5a610a93612a08565b82612389565b600d6105f6612976565b610aab611f10565b8080600c610ab7612919565b5050507f6b92bd20c4b2e6861047ba7209ddc78d538419aae187d0df46716b827b8997a48160405161058d9190613ac1565b600560205281600052604060002060205280600052604060002091506000905081610b12612976565b906101000a90046001600160401b03169080600101610b2f612976565b905082565b60026105f6612976565b600060016105a4612976565b600c6105f6612976565b6001600160a01b038216600090815260056020528060408120600084815260209190915260409020600090610b87612976565b906101000a90046001600160401b0316915060056000856001600160a01b03166001600160a01b03168152602001908152602001600020600084815260209190915260409020600101610bd8612976565b90509250929050565b6000805b82811015610ca357610bf5612b85565b6001600160a01b03861660009081526005602052604090206000868685818110610c1b57fe5b905060200201358152602001908152602001600020604051604080820190529081600082610c47612976565b6001600160401b036101009290920a900416815260200160018201610c6a612976565b9052509050602081015115610c9a576000610c848261234f565b9050610c96848263ffffffff611f7416565b9350505b50600101610be5565b509392505050565b6001600160a01b0381166000908152600860205260408120610971612976565b600b6105f6612976565b600a602052806000526040600020600091506105a4612976565b6060610cf9611479565b905060005b8151811015610e82576000828281518110610d1557fe5b602002602001015190506000806003610d2c612976565b906101000a90046001600160a01b03166001600160a01b031663dacb2d018384604051602001610d5c9190613992565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401610d88929190613add565b6020604051808303818680610d9b612a4e565b158015610db057600080610dad6128ae565b50505b505a610dba612a9a565b5050505050158015610dd9573d6000803e3d6000610dd66128ae565b50505b50505050604051601f3d908101601f19168201604052610dfc9190810190612e02565b60008381526004602052909150819060409020600181610e1a612976565b816001600160a01b0302191690836001600160a01b0316021790610e3c612919565b5050507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa688282604051610e70929190613acf565b60405180910390a15050600101610cfe565b5050565b6060828201838111610ed6576000604051908082528060200260200182016040528015610ecd57816020015b610eba612b9c565b815260200190600190039081610eb25790505b50915050610754565b6001600160a01b038516600090815260066020526040902080610ef7612976565b9050811115610f25576001600160a01b038516600090815260066020526040902080610f21612976565b9150505b838103606081604051908082528060200260200182016040528015610f6457816020015b610f51612b9c565b815260200190600190039081610f495790505b50905060005b82811015611069576001600160a01b038816600090815260066020526040812088830181610f96612976565b8110610f9e57fe5b90600052602060002001610fb0612976565b9050610fba612b85565b6001600160a01b038a166000908152600560205260409020600083815260209190915260409020604051604080820190529081600082610ff8612976565b6001600160401b036101009290920a90041681526020016001820161101b612976565b9052509050604051606081016040528082516001600160401b031681526020018260200151815260200183905284848151811061105457fe5b60209081029190910101525050600101610f6a565b509695505050505050565b61107c6124da565b50565b611087611f10565b600d611091612976565b8111156110c25760405162461bcd60e51b81526004016110b090613bfc565b604051809103906110bf6128ae565b50505b8080600e6110ce612919565b5050507f723c43349da7aeae47190396f2e2fbe6bedb46b9e9705bc5b908d65bc7a1e0e68160405161058d9190613ac1565b6000600161110c612976565b906101000a90046001600160a01b03166001600160a01b03165a61112e612a08565b6001600160a01b0316146111665760405162461bcd60e51b815260040161115490613b1c565b604051809103906111636128ae565b50505b7fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c600080611192612976565b906101000a90046001600160a01b031660016000906111af612976565b906101000a90046001600160a01b03166040516111cd929190613a3c565b60405180910390a1600060016111e1612976565b906101000a90046001600160a01b03166000806101000a81611201612976565b816001600160a01b0302191690836001600160a01b0316021790611223612919565b5050506000600160006101000a81611239612976565b816001600160a01b0302191690836001600160a01b031602179061072e612919565b5a611264612a08565b6001600160a01b0316816001600160a01b031614156112a75760405162461bcd60e51b815260040161129590613bcc565b604051809103906112a46128ae565b50505b6112af6105b7565b6112dd5760405162461bcd60e51b81526004016112cb90613bac565b604051809103906112da6128ae565b50505b6112e56124f2565b6001600160a01b031663d37c4d8b5a6112fc612a08565b6040518263ffffffff1660e01b815260040161131891906139db565b602060405180830381868061132b612a4e565b1580156113405760008061133d6128ae565b50505b505a61134a612a9a565b5050505050158015611369573d6000803e3d60006113666128ae565b50505b50505050604051601f3d908101601f1916820160405261138c919081019061312c565b156113bb5760405162461bcd60e51b81526004016113a990613c2c565b604051809103906113b86128ae565b50505b80600a60005a6113c9612a08565b6001600160a01b03166001600160a01b031681526020019081526020016000206001816113f4612976565b816001600160a01b0302191690836001600160a01b0316021790611416612919565b5050505a611422612a08565b6001600160a01b03167fcf51776bb16e5780edcca2e64a9ba8a9c7d5d00a6699cbd7606e465361ba48528260405161145a919061399d565b60405180910390a250565b600060606114716124da565b935093915050565b606080611484612506565b9050606060016040519080825280602002602001820160405280156114b3578160200160208202803883390190505b5090507453796e746865746978427269646765546f4261736560581b816000815181106114dc57fe5b6020026020010181815250506114f282826125a6565b9250505090565b6000806105a4612976565b600e6105f6612976565b6001600160a01b0383166115465760405162461bcd60e51b815260040161153490613b4c565b604051809103906115436128ae565b50505b61154e612662565b6001600160a01b03166323b872dd5a611565612a08565b5a63996d79a5598160e01b8152602081600483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b8051925060005b60408110156115bb576000828201526020016115a4565b505050856040518463ffffffff1660e01b81526004016115dd939291906139ab565b602060405180830381600087806115f2612a4e565b158015611607576000806116046128ae565b50505b505a611611612bbb565b505050505050158015611631573d6000803e3d600061162e6128ae565b50505b50505050604051601f3d908101601f1916820160405261165491908101906130b7565b6107235760405162461bcd60e51b815260040161071190613bbc565b60066020528160005260406000208181611688612976565b811061169057fe5b9060005260206000200191506105f69050612976565b6116ae6124da565b505050505050565b6116be612679565b6001600160a01b03165a6116d0612a08565b6001600160a01b0316146117085760405162461bcd60e51b81526004016116f690613b5c565b604051809103906117056128ae565b50505b61171683600b6105d9612976565b80600b611721612919565b50505061172c612662565b6001600160a01b03166370a082315a63996d79a5598160e01b8152602081600483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b8051925060005b604081101561179057600082820152602001611779565b5050506040518263ffffffff1660e01b81526004016117af919061399d565b60206040518083038186806117c2612a4e565b1580156117d7576000806117d46128ae565b50505b505a6117e1612a9a565b5050505050158015611800573d6000803e3d60006117fd6128ae565b50505b50505050604051601f3d908101601f19168201604052611823919081019061312c565b600b61182d612976565b111561185d5760405162461bcd60e51b815260040161184b90613c1c565b6040518091039061185a6128ae565b50505b6001600160a01b03841660009081526008602052611883908490604090206105d9612976565b6001600160a01b038516600090815260086020526040902081906118a5612919565b5060009150505b818110156118e7576118df858484848181106118c457fe5b9050604002018036036118da91908101906130de565b61269c565b6001016118ac565b5050505050565b60076105f6612976565b6001600160a01b03831660009081526006602052606090838301906040902080611920612976565b905081111561194e576001600160a01b03851660009081526006602052604090208061194a612976565b9150505b838111611988576000604051908082528060200260200182016040528015610ecd5781602001602082028038833901905050915050610754565b8381036060816040519080825280602002602001820160405280156119b7578160200160208202803883390190505b50905060005b82811015611069576001600160a01b0388166000908152600660205260409020878201816119e9612976565b81106119f157fe5b90600052602060002001611a03612976565b828281518110611a0f57fe5b60209081029190910101526001016119bd565b611a2a6105b7565b611a585760405162461bcd60e51b8152600401611a4690613bac565b60405180910390611a556128ae565b50505b611a606124f2565b6001600160a01b031663d37c4d8b846040518263ffffffff1660e01b8152600401611a8b9190613a57565b6020604051808303818680611a9e612a4e565b158015611ab357600080611ab06128ae565b50505b505a611abd612a9a565b5050505050158015611adc573d6000803e3d6000611ad96128ae565b50505b50505050604051601f3d908101601f19168201604052611aff919081019061312c565b15611b2e5760405162461bcd60e51b8152600401611b1c90613c2c565b60405180910390611b2b6128ae565b50505b5a611b37612a08565b6001600160a01b038481166000908152600a60205291169060409020600090611b5e612976565b906101000a90046001600160a01b03166001600160a01b031614611ba65760405162461bcd60e51b8152600401611b9490613bec565b60405180910390611ba36128ae565b50505b6000805b82811015611de657611bba612b85565b6001600160a01b03861660009081526005602052604090206000868685818110611be057fe5b905060200201358152602001908152602001600020604051604080820190529081600082611c0c612976565b6001600160401b036101009290920a900416815260200160018201611c2f612976565b9052509050602081015115611ddd5780600560005a611c4c612a08565b6001600160a01b03166001600160a01b031681526020019081526020016000206000878786818110611c7a57fe5b905060200201358152602001908152602001600020815181600181611c9d612976565b816001600160401b0302191690836001600160401b0316021790611cbf612919565b505050602082015181600101611cd3612919565b5050905050611ced8160200151849063ffffffff611f7416565b9250600660005a611cfc612a08565b6001600160a01b03166001600160a01b03168152602001908152602001600020858584818110611d2857fe5b905060200201359080600181611d3c612976565b018082611d47612919565b5050600092835291600019830191506020902091929101611d66612919565b5050506001600160a01b03861660009081526005602052604090206000868685818110611d8f57fe5b905060200201358152602001908152602001600020600081600181611db2612976565b906001600160401b0302191690611dc7612919565b505060018201600090611dd8612919565b505050505b50600101611baa565b506001600160a01b03841660009081526008602052611e1990829060409020611e0d612976565b9063ffffffff61278916565b6001600160a01b03851660009081526008602052604090208190611e3b612919565b505050611e7781600860005a611e4f612a08565b6001600160a01b03166001600160a01b031681526020019081526020016000206105d9612976565b600860005a611e84612a08565b6001600160a01b03166001600160a01b031681526020019081526020016000208190611eae612919565b505050836001600160a01b03167f48d567deaa7db90f8a443344e519ca8906521ffe118e1df43e89a3c257963f7c5a611ee5612a08565b8386865a611ef16129c2565b604051611f029594939291906139f5565b60405180910390a250505050565b600080611f1b612976565b906101000a90046001600160a01b03166001600160a01b03165a611f3d612a08565b6001600160a01b031614611f725760405162461bcd60e51b8152600401611f6390613bdc565b60405180910390610e826128ae565b565b6000828201838110156107545760405162461bcd60e51b8152600401611f9990613b2c565b60405180910390611fa86128ae565b50509392505050565b6000611fc666119959541bdbdb60ca1b6127c3565b905090565b81611ffa5760405162461bcd60e51b8152600401611fe890613b8c565b60405180910390611ff76128ae565b50505b6000811180156120135750600c61200f612976565b8111155b6120415760405162461bcd60e51b815260040161202f90613b3c565b6040518091039061203e6128ae565b50505b61204f82600b6105d9612976565b80600b61205a612919565b505050612065612662565b6001600160a01b03166370a082315a63996d79a5598160e01b8152602081600483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b8051925060005b60408110156120c9576000828201526020016120b2565b5050506040518263ffffffff1660e01b81526004016120e8919061399d565b60206040518083038186806120fb612a4e565b1580156121105760008061210d6128ae565b50505b505a61211a612a9a565b5050505050158015612139573d6000803e3d60006121366128ae565b50505b50505050604051601f3d908101601f1916820160405261215c919081019061312c565b600b612166612976565b11156121965760405162461bcd60e51b815260040161218490613b9c565b604051809103906121936128ae565b50505b6000815a6121a26129c2565b6001600160a01b03861660009081526008602052910191506121cc908490604090206105d9612976565b6001600160a01b038516600090815260086020526040902081906121ee612919565b505050600060076121fd612976565b9050604051604080820181526001600160401b038416825260208083018790526001600160a01b038816600090815260059091522060008381526020919091526040902081518160018161224f612976565b816001600160401b0302191690836001600160401b0316021790612271612919565b505050602082015181600101612285612919565b5050506001600160a01b0386166000908152600660205260409150208190806001816122af612976565b0180826122ba612919565b50506000928352916000198301915060209020919291016122d9612919565b5050506122eb600160076105d9612976565b8060076122f6612919565b505050846001600160a01b03167f2cc016694185d38abbe28d9e9baea2e9d95a321ae43475e5ea7b643756840bc05a61232d6129c2565b8686856040516123409493929190613c6a565b60405180910390a25050505050565b6000808260200151156109715782516001600160401b03165a6123706129c2565b101561237d576000610754565b82602001519392505050565b612393828261284a565b6001600160a01b038216600090815260096020526123b9908290604090206105d9612976565b6001600160a01b038316600090815260096020526040902081906123db612919565b5050506123e6612662565b6001600160a01b031663a9059cbb83836040518363ffffffff1660e01b8152600401612413929190613a65565b60206040518083038160008780612428612a4e565b15801561243d5760008061243a6128ae565b50505b505a612447612bbb565b505050505050158015612467573d6000803e3d60006124646128ae565b50505b50505050604051601f3d908101601f1916820160405261248a91908101906130b7565b50816001600160a01b03167ffbeff59d2bfda0d79ea8a29f8c57c66d48c7a13eabbdb90908d9115ec41c9dc65a6124bf6129c2565b836040516124ce929190613c5c565b60405180910390a25050565b60405162461bcd60e51b8152600401611f6390613b7c565b6000611fc66524b9b9bab2b960d11b6127c3565b60606003604051908082528060200260200182016040528015612533578160200160208202803883390190505b509050680a6f2dce8d0cae8d2f60bb1b8160008151811061255057fe5b60200260200101818152505066119959541bdbdb60ca1b8160018151811061257457fe5b6020026020010181815250506524b9b9bab2b960d11b8160028151811061259757fe5b60200260200101818152505090565b606081518351016040519080825280602002602001820160405280156125d6578160200160208202803883390190505b50905060005b8351811015612618578381815181106125f157fe5b602002602001015182828151811061260557fe5b60209081029190910101526001016125dc565b5060005b825181101561265b5782818151811061263157fe5b602002602001015182828651018151811061264857fe5b602090810291909101015260010161261c565b5092915050565b6000611fc6680a6f2dce8d0cae8d2f60bb1b6127c3565b6000611fc67453796e746865746978427269646765546f4261736560581b6127c3565b600060076126a8612976565b6001600160a01b038416600090815260056020529091508290604090206000838152602091909152604090208151816001816126e2612976565b816001600160401b0302191690836001600160401b0316021790612704612919565b505050602082015181600101612718612919565b5050506001600160a01b038416600090815260066020526040915020819080600181612742612976565b01808261274d612919565b505060009283529160001983019150602090209192910161276c612919565b50505061277e600160076105d9612976565b8060076116ae612919565b6000828211156127bd5760405162461bcd60e51b81526004016127ab90613b6c565b604051809103906127ba6128ae565b50505b50900390565b6000818152600460205280604081206000906127dd612976565b6001600160a01b036101009290920a9004169050801515836040516020016128059190613972565b6040516020818303038152906040529061265b5760405162461bcd60e51b81526004016128329190613b0b565b604051809103906128416128ae565b50505092915050565b61285881600b611e0d612976565b80600b612863612919565b5050506001600160a01b0382166000908152600860205261288c90829060409020611e0d612976565b6001600160a01b038316600090815260086020526040902081906118e7612919565b632a2a7adb598160e01b8152600481016020815285602082015260005b868110156128e65780860151828201604001526020016128cb565b506020828760640184336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b505050565b6322bd64c0598160e01b8152836004820152846024820152600081604483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b60005b604081101561072e5760008282015260200161295f565b6303daa959598160e01b8152836004820152602081602483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b8051600082529350602061295f565b63bdbf8c36598160e01b8152602081600483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b8051600082529350602061295f565b6373509064598160e01b8152602081600483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b8051600082529350602061295f565b638435035b598160e01b8152836004820152602081602483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b8051600082529350602061295f565b638540661f598160e01b8152612acb565b8080831115610971575090919050565b8080831015610971575090919050565b836004820152846024820152606060448201528660648201526084810160005b88811015612b03578088015182820152602001612aeb565b506060828960a40184336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b815160408301513d6000853e8b8b82606087013350600060045af15059612b588d3d612abb565b8c01612b648187612aab565b5b82811015612b795760008152602001612b65565b50929c50505050505050565b604051604080820190526000808252602082015290565b6040516060810160409081526000808352602083018190529082015290565b6385979f76598160e01b8152836004820152846024820152606060448201528760648201526084810160005b89811015612bff578089015182820152602001612be7565b506060828a60a40184336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b815160408301513d6000853e8c8c82606087013350600060045af15059612c548e3d612abb565b8d01612c608187612aab565b5b82811015612c755760008152602001612c61565b50929d50505050505050565b803561097181613d83565b60008151905061097181613d83565b60008083601f840112612cb657600080612cb36128ae565b50505b5081356001600160401b03811115612cd657600080612cd36128ae565b50505b602083019150836020820283011115612cf757600080612cf46128ae565b50505b9250929050565b60008083601f840112612d1957600080612d166128ae565b50505b5081356001600160401b03811115612d3957600080612d366128ae565b50505b602083019150836040820283011115612cf757600080612cf46128ae565b60008151905061097181613d9d565b600060408284031215612d8157600080612d7e6128ae565b50505b612d8b6040613cb6565b90506000612d998484612dd0565b8252506020612daa84848301612db6565b60208301525092915050565b803561097181613da6565b60008151905061097181613da6565b803561097181613daf565b600060208284031215612df657600080612df36128ae565b50505b600061096d8484612c81565b600060208284031215612e1d57600080612e1a6128ae565b50505b600061096d8484612c8c565b600080600060408486031215612e4757600080612e446128ae565b50505b6000612e538686612c81565b93505060208401356001600160401b03811115612e7857600080612e756128ae565b50505b612e8486828701612c9b565b92509250509250925092565b60008060408385031215612eac57600080612ea96128ae565b50505b6000612eb88585612c81565b9250506020612ec985828601612db6565b9150509250929050565b60008060008060608587031215612ef257600080612eef6128ae565b50505b6000612efe8787612c81565b9450506020612f0f87828801612db6565b93505060408501356001600160401b03811115612f3457600080612f316128ae565b50505b612f4087828801612cfe565b95989497509550505050565b600080600060608486031215612f6a57600080612f676128ae565b50505b6000612f768686612c81565b9350506020612f8786828701612db6565b9250506040612f9886828701612db6565b9150509250925092565b60008060008060008060608789031215612fc457600080612fc16128ae565b50505b86356001600160401b03811115612fe357600080612fe06128ae565b50505b612fef89828a01612c9b565b965096505060208701356001600160401b03811115613016576000806130136128ae565b50505b61302289828a01612c9b565b945094505060408701356001600160401b03811115613049576000806130466128ae565b50505b61305589828a01612c9b565b92509250509295509295509295565b600080602083850312156130805760008061307d6128ae565b50505b82356001600160401b0381111561309f5760008061309c6128ae565b50505b6130ab85828601612c9b565b92509250509250929050565b6000602082840312156130d2576000806130cf6128ae565b50505b600061096d8484612d57565b6000604082840312156130f9576000806130f66128ae565b50505b600061096d8484612d66565b6000602082840312156131205760008061311d6128ae565b50505b600061096d8484612db6565b600060208284031215613147576000806131446128ae565b50505b600061096d8484612dc1565b600061315f8383613335565b505060200190565b6000613173838361390a565b505060600190565b60006131878383613946565b505060400190565b61319881613d2f565b82525050565b61319881613d07565b60006131b282613cef565b6131bc8185613cf9565b93506131c783613ce9565b8060005b838110156131f55781516131df8882613153565b97506131ea83613ce9565b9250506001016131cb565b509495945050505050565b600061320b82613cef565b6132158185613cf9565b935061322083613ce9565b8060005b838110156131f55781516132388882613167565b975061324383613ce9565b925050600101613224565b600061325982613cef565b6132638185613cf9565b935061326e83613ce9565b8060005b838110156131f5578151613286888261317b565b975061329183613ce9565b925050600101613272565b60006132a88385613cf9565b93506001600160fb1b038311156132c7576000806132c46128ae565b50505b6020830292506132d8838584613d41565b50500190565b60006132e982613cef565b6132f38185613cf9565b93506132fe83613ce9565b8060005b838110156131f55781516133168882613153565b975061332183613ce9565b925050600101613302565b61319881613d12565b613198816105e9565b61319861334a826105e9565b6105e9565b61319881613d36565b600061336382613cef565b61336d8185613cf9565b935061337d818560208601613d4d565b61338681613d79565b9093019392505050565b600061339d603583613cf9565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527402063616e20616363657074206f776e65727368697605c1b602082015260400192915050565b60006133f4601b83613cf9565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b600061342d603383613cf9565b7f43616e6e6f7420657363726f7720776974682030206475726174696f6e204f528152721030b137bb329036b0bc2fb23ab930ba34b7b760691b602082015260400192915050565b6000613482602483613cf9565b7f43616e6e6f742063726561746520657363726f772077697468206164647265738152637328302960e01b602082015260400192915050565b60006134c8603583613cf9565b7f43616e206f6e6c7920626520696e766f6b65642062792053796e746865746978815274109c9a5919d9551bd0985cd94818dbdb9d1c9858dd605a1b602082015260400192915050565b600061351f601e83613cf9565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b6000613558601b83613cf9565b7f43616e6e6f742062652072756e206f6e2074686973206c617965720000000000815260200192915050565b6000613591601183613d02565b70026b4b9b9b4b7339030b2323932b9b99d1607d1b815260110192915050565b60006135be601783613cf9565b7f5175616e746974792063616e6e6f74206265207a65726f000000000000000000815260200192915050565b60006135f7604783613cf9565b7f4d75737420626520656e6f7567682062616c616e636520696e2074686520636f81527f6e747261637420746f2070726f7669646520666f72207468652076657374696e6020820152666720656e74727960c81b604082015260600192915050565b6000613666601983613cf9565b7f4163636f756e74206d657267696e672068617320656e64656400000000000000815260200192915050565b600061369f601583613cf9565b741d1bdad95b881d1c985b9cd9995c8819985a5b1959605a1b815260200192915050565b60006136d0602483613cf9565b7f43616e6e6f74206e6f6d696e617465206f776e206163636f756e7420746f206d8152636572676560e01b602082015260400192915050565b6000613716602f83613cf9565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681526e37b936903a3434b99030b1ba34b7b760891b602082015260400192915050565b631cd554d160e21b9052565b6000613773602183613cf9565b7f41646472657373206973206e6f74206e6f6d696e6174656420746f206d6572678152606560f81b602082015260400192915050565b60006137b6601c83613cf9565b7f65786365656473206d6178206d657267696e67206475726174696f6e00000000815260200192915050565b60006137ef601983613d02565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b6000613828602883613cf9565b7f4f6e6c792074686520466565506f6f6c2063616e20706572666f726d20746869815267399030b1ba34b7b760c11b602082015260400192915050565b6000613872604483613cf9565b7f496e73756666696369656e742062616c616e636520696e2074686520636f6e7481527f7261637420746f2070726f7669646520666f7220657363726f7765642062616c602082015263616e636560e01b604082015260600192915050565b60006138de601f83613cf9565b7f43616e6e6f74206d65726765206163636f756e74732077697468206465627400815260200192915050565b60608201815161391a8482613969565b50602082015161392d6020850182613335565b5060408201516139406040850182613335565b50505050565b6040820181516139568482613969565b5060208201516139406020850182613335565b61319881613d23565b600061397d82613584565b9150613989828461333e565b50602001919050565b600061397d826137e2565b60208101610971828461319e565b606081016139b9828661318f565b6139c6602083018561319e565b6139d36040830184613335565b949350505050565b604081016139e9828461318f565b6109716020830161375a565b60808101613a03828861318f565b613a106020830187613335565b8181036040830152613a2381858761329c565b9050613a326060830184613335565b9695505050505050565b60408101613a4a828561319e565b610754602083018461319e565b604081016139e9828461319e565b60408101613a73828561319e565b6107546020830184613335565b6020808252810161075481846131a7565b602080825281016107548184613200565b6020808252810161075481846132de565b60208101610971828461332c565b602081016109718284613335565b60408101613a4a8285613335565b60408101613aeb8285613335565b81810360208301526139d38184613358565b60208101610971828461334f565b602080825281016107548184613358565b6020808252810161097181613390565b60208082528101610971816133e7565b6020808252810161097181613420565b6020808252810161097181613475565b60208082528101610971816134bb565b6020808252810161097181613512565b602080825281016109718161354b565b60208082528101610971816135b1565b60208082528101610971816135ea565b6020808252810161097181613659565b6020808252810161097181613692565b60208082528101610971816136c3565b6020808252810161097181613709565b6020808252810161097181613766565b60208082528101610971816137a9565b602080825281016109718161381b565b6020808252810161097181613865565b60208082528101610971816138d1565b60408101613c4a8285613335565b81810360208301526139d3818461324e565b60408101613a738285613335565b60808101613c788287613335565b613c856020830186613335565b613c926040830185613335565b613c9f6060830184613335565b95945050505050565b60408101613a738285613969565b600060405190508181018181106001600160401b0382111715613ce157600080613cde6128ae565b50505b604052919050565b60200190565b6000815192915050565b90815260200190565b919050565b600061097182613d17565b151590565b6001600160a01b031690565b6001600160401b031690565b6000610971825b600061097182613d07565b82818337506000910152565b60005b83811015613d68578082015183820152602001613d50565b838111156139405750506000910152565b601f01601f191690565b613d8c81613d07565b811461107c5760008061072e6128ae565b613d8c81613d12565b613d8c816105e9565b613d8c81613d2356
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102535760003560e01c80636dc05bd31161014657806380d46f58116100c3578063ae58254911610087578063ae582549146104c1578063b95375bd146104d4578063cd7b43dd146104e7578063e6b2cf6c146104fa578063eac6248914610502578063f0b882ba1461052257610253565b806380d46f5814610468578063899ffef4146104895780638da5cb5b1461049e578063910a326d146104a6578063a0416ed3146104ae57610253565b8063773ab39f1161010a578063773ab39f146104075780637839b92f146104275780637993e6991461043a57806379ba50971461044d5780637cc1d7561461045557610253565b80636dc05bd3146103be57806370a08231146103d157806371e780f3146103e457806373307e40146103ec57806374185360146103ff57610253565b806330104c5f116101d457806345626bd61161019857806345626bd61461036557806346ba2d901461038657806353a47bb71461038e5780635eb8cf25146103a35780636154c343146103ab57610253565b806330104c5f14610311578063326a3cfb1461032457806334c7fec91461033757806337088ffc1461034a5780634525aabc1461035257610253565b8063178c56551161021b578063178c5655146102c85780631bb47b44146102d0578063204b676a146102e3578063227d517a146102f65780632af64bd31461030957610253565b8063018c6c551461025857806304f3bcec1461026d578063056629861461028b5780630fcdefb7146102a05780631627540c146102b5575b600080fd5b61026b61026636600461223b565b610535565b005b61027561057d565b6040516102829190612c1a565b60405180910390f35b61029361058c565b6040516102829190612bd0565b6102a86105ad565b6040516102829190612bde565b61026b6102c3366004611fa1565b6105b3565b61026b610606565b61026b6102de3660046120d3565b610663565b6102a86102f1366004611fa1565b6106b4565b6102a8610304366004611fa1565b6106cf565b6102936106e1565b6102a861031f366004612032565b6107f8565b6102a8610332366004611fa1565b610857565b61026b6103453660046121be565b610869565b6102a861091f565b61026b61036036600461223b565b610925565b610378610373366004612032565b610962565b604051610282929190612dc5565b6102a8610992565b610396610998565b6040516102829190612aba565b6102a86109a7565b6103786103b9366004612032565b6109ad565b6102a86103cc366004611fdd565b6109e7565b6102a86103df366004611fa1565b610a94565b6102a8610aaf565b6103966103fa366004611fa1565b610ab5565b61026b610ad0565b61041a6104153660046120d3565b610c26565b6040516102829190612bae565b61026b610435366004611fa1565b610dc6565b61026b61044836600461223b565b610dd1565b61026b610e30565b61026b610463366004611fa1565b610ecc565b61047b610476366004611fdd565b61101c565b604051610282929190612d59565b610491611030565b6040516102829190612b9d565b6103966110a4565b6102a86110b3565b61026b6104bc3660046120d3565b6110b9565b6102a86104cf366004612032565b611184565b61026b6104e2366004612120565b6111b2565b61026b6104f536600461206c565b6111c2565b6102a861133c565b6105156105103660046120d3565b611342565b6040516102829190612bbf565b61026b610530366004611fdd565b61142e565b61053d61176a565b600d8190556040517fe829efae5d8a2f7163f46c23a8190bf14625c1e446561ca0f5cf279ab7c8015e90610572908390612bde565b60405180910390a150565b6003546001600160a01b031681565b6000426105a6600e54600f5461179690919063ffffffff16565b1190505b90565b600f5481565b6105bb61176a565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290610572908390612aba565b61060e61176a565b42600f819055600e547fceade2b9bc02350b17075c94bb699508b89ed2752f501ea42024b1bb5fd34445919061064b90829063ffffffff61179616565b604051610659929190612d79565b60405180910390a1565b61066b6117bb565b6001600160a01b0316336001600160a01b0316146106a45760405162461bcd60e51b815260040161069b90612d29565b60405180910390fd5b6106af8383836117d5565b505050565b6001600160a01b031660009081526006602052604090205490565b60096020526000908152604090205481565b600060606106ed611030565b905060005b81518110156107ef57600082828151811061070957fe5b60209081029190910181015160008181526004928390526040908190205460035491516321f8a72160e01b81529294506001600160a01b03908116939116916321f8a7219161075a91869101612bde565b60206040518083038186803b15801561077257600080fd5b505afa158015610786573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107aa9190810190611fbf565b6001600160a01b03161415806107d557506000818152600460205260409020546001600160a01b0316155b156107e657600093505050506105aa565b506001016106f2565b50600191505090565b6000610802611e4e565b506001600160a01b0383166000908152600560209081526040808320858452825291829020825180840190935280546001600160401b03168352600101549082015261084d816119ed565b9150505b92915050565b60086020526000908152604090205481565b6000805b8281101561090e573360009081526005602052604081208186868581811061089157fe5b90506020020135815260200190815260200160002090508060010154600014610905576040805180820190915281546001600160401b03168152600182015460208201526000906108e1906119ed565b905080156108f157600060018301555b610901848263ffffffff61179616565b9350505b5060010161086d565b5080156106af576106af3382611a1e565b600d5481565b61092d61176a565b600c8190556040517f6b92bd20c4b2e6861047ba7209ddc78d538419aae187d0df46716b827b8997a490610572908390612bde565b6005602090815260009283526040808420909152908252902080546001909101546001600160401b039091169082565b60025481565b6001546001600160a01b031681565b600c5481565b6001600160a01b039190911660009081526005602090815260408083209383529290522080546001909101546001600160401b0390911691565b6000805b82811015610a8c576109fb611e4e565b6001600160a01b038616600090815260056020526040812090868685818110610a2057fe5b60209081029290920135835250818101929092526040908101600020815180830190925280546001600160401b0316825260010154918101829052915015610a83576000610a6d826119ed565b9050610a7f848263ffffffff61179616565b9350505b506001016109eb565b509392505050565b6001600160a01b031660009081526008602052604090205490565b600b5481565b600a602052600090815260409020546001600160a01b031681565b6060610ada611030565b905060005b8151811015610c22576000828281518110610af657fe5b602002602001015190506000600360009054906101000a90046001600160a01b03166001600160a01b031663dacb2d018384604051602001610b389190612aaf565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401610b64929190612bfa565b60206040518083038186803b158015610b7c57600080fd5b505afa158015610b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610bb49190810190611fbf565b6000838152600460205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa6890610c109084908490612bec565b60405180910390a15050600101610adf565b5050565b6060828201838111610c6c576040805160008082526020820190925290610c63565b610c50611e65565b815260200190600190039081610c485790505b50915050610dbf565b6001600160a01b038516600090815260066020526040902054811115610ca757506001600160a01b0384166000908152600660205260409020545b604080518583038082526020808202830101909252606090828015610ce657816020015b610cd3611e65565b815260200190600190039081610ccb5790505b50905060005b82811015610db9576001600160a01b03881660009081526006602052604081208054838a01908110610d1a57fe5b90600052602060002001549050610d2f611e4e565b506001600160a01b03891660009081526005602090815260408083208484528252918290208251808401845281546001600160401b03908116825260019092015481840190815284516060810186528251909316835251928201929092529182018390528451909190859085908110610da457fe5b60209081029190910101525050600101610cec565b50925050505b9392505050565b610dce611b39565b50565b610dd961176a565b600d54811115610dfb5760405162461bcd60e51b815260040161069b90612d19565b600e8190556040517f723c43349da7aeae47190396f2e2fbe6bedb46b9e9705bc5b908d65bc7a1e0e690610572908390612bde565b6001546001600160a01b03163314610e5a5760405162461bcd60e51b815260040161069b90612c39565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c92610e9d926001600160a01b0391821692911690612b59565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6001600160a01b038116331415610ef55760405162461bcd60e51b815260040161069b90612ce9565b610efd61058c565b610f195760405162461bcd60e51b815260040161069b90612cc9565b610f21611b51565b6001600160a01b031663d37c4d8b336040518263ffffffff1660e01b8152600401610f4c9190612af8565b60206040518083038186803b158015610f6457600080fd5b505afa158015610f78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f9c9190810190612259565b15610fb95760405162461bcd60e51b815260040161069b90612d49565b336000818152600a60205260409081902080546001600160a01b0319166001600160a01b038516179055517fcf51776bb16e5780edcca2e64a9ba8a9c7d5d00a6699cbd7606e465361ba485290611011908490612aba565b60405180910390a250565b60006060611028611b39565b935093915050565b60608061103b611b65565b60408051600180825281830190925291925060609190602080830190803883390190505090507453796e746865746978427269646765546f4261736560581b8160008151811061108757fe5b60200260200101818152505061109d8282611bf7565b9250505090565b6000546001600160a01b031681565b600e5481565b6001600160a01b0383166110df5760405162461bcd60e51b815260040161069b90612c69565b6110e7611cb3565b6001600160a01b03166323b872dd3330856040518463ffffffff1660e01b815260040161111693929190612ac8565b602060405180830381600087803b15801561113057600080fd5b505af1158015611144573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061116891908101906121ff565b6106a45760405162461bcd60e51b815260040161069b90612cd9565b6006602052816000526040600020818154811061119d57fe5b90600052602060002001600091509150505481565b6111ba611b39565b505050505050565b6111ca611cca565b6001600160a01b0316336001600160a01b0316146111fa5760405162461bcd60e51b815260040161069b90612c79565b600b5461120d908463ffffffff61179616565b600b55611218611cb3565b6001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016112439190612aba565b60206040518083038186803b15801561125b57600080fd5b505afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112939190810190612259565b600b5411156112b45760405162461bcd60e51b815260040161069b90612d39565b6001600160a01b0384166000908152600860205260409020546112dd908463ffffffff61179616565b6001600160a01b0385166000908152600860205260408120919091555b818110156113355761132d8584848481811061131257fe5b905060400201803603611328919081019061221d565b611ced565b6001016112fa565b5050505050565b60075481565b6001600160a01b0383166000908152600660205260409020546060908383019081111561138457506001600160a01b0384166000908152600660205260409020545b8381116113a1576040805160008082526020820190925290610c63565b6040805185830380825260208082028301019092526060908280156113d0578160200160208202803883390190505b50905060005b82811015610db9576001600160a01b0388166000908152600660205260409020805482890190811061140457fe5b906000526020600020015482828151811061141b57fe5b60209081029190910101526001016113d6565b61143661058c565b6114525760405162461bcd60e51b815260040161069b90612cc9565b61145a611b51565b6001600160a01b031663d37c4d8b846040518263ffffffff1660e01b81526004016114859190612b74565b60206040518083038186803b15801561149d57600080fd5b505afa1580156114b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114d59190810190612259565b156114f25760405162461bcd60e51b815260040161069b90612d49565b6001600160a01b038381166000908152600a602052604090205416331461152b5760405162461bcd60e51b815260040161069b90612d09565b6000805b828110156116aa5761153f611e4e565b6001600160a01b03861660009081526005602052604081209086868581811061156457fe5b60209081029290920135835250818101929092526040908101600020815180830190925280546001600160401b03168252600101549181018290529150156116a15733600090815260056020526040812082918787868181106115c357fe5b60209081029290920135835250818101929092526040016000208251815467ffffffffffffffff19166001600160401b0390911617815591810151600190920191909155810151611615908490611796565b33600090815260066020526040902090935085858481811061163357fe5b8354600181018555600094855260208086209281029490940135910155506001600160a01b038816825260059052604081209086868581811061167257fe5b602090810292909201358352508101919091526040016000908120805467ffffffffffffffff19168155600101555b5060010161152f565b506001600160a01b0384166000908152600860205260409020546116d4908263ffffffff611d6a16565b6001600160a01b038516600090815260086020526040808220929092553381522054611706908263ffffffff61179616565b33600081815260086020526040908190209290925590516001600160a01b038616917f48d567deaa7db90f8a443344e519ca8906521ffe118e1df43e89a3c257963f7c9161175c91908590889088904290612b12565b60405180910390a250505050565b6000546001600160a01b031633146117945760405162461bcd60e51b815260040161069b90612cf9565b565b600082820183811015610dbf5760405162461bcd60e51b815260040161069b90612c49565b60006117d066119959541bdbdb60ca1b611d92565b905090565b816117f25760405162461bcd60e51b815260040161069b90612ca9565b6000811180156118045750600c548111155b6118205760405162461bcd60e51b815260040161069b90612c59565b600b54611833908363ffffffff61179616565b600b5561183e611cb3565b6001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016118699190612aba565b60206040518083038186803b15801561188157600080fd5b505afa158015611895573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118b99190810190612259565b600b5411156118da5760405162461bcd60e51b815260040161069b90612cb9565b6001600160a01b03831660009081526008602052604090205442820190611907908463ffffffff61179616565b6001600160a01b03851660008181526008602090815260408083209490945560078054855180870187526001600160401b0388811682528185018b81528787526005865288872084885286528887209251835467ffffffffffffffff1916921691909117825551600191820155948452600683529483208054808601825590845291909220018390555461199a91611796565b6007556040516001600160a01b038616907f2cc016694185d38abbe28d9e9baea2e9d95a321ae43475e5ea7b643756840bc0906119de904290889088908790612d87565b60405180910390a25050505050565b60008082602001516000146108515782516001600160401b0316421015611a15576000610dbf565b50506020015190565b611a288282611def565b6001600160a01b038216600090815260096020526040902054611a51908263ffffffff61179616565b6001600160a01b038316600090815260096020526040902055611a72611cb3565b6001600160a01b031663a9059cbb83836040518363ffffffff1660e01b8152600401611a9f929190612b82565b602060405180830381600087803b158015611ab957600080fd5b505af1158015611acd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611af191908101906121ff565b50816001600160a01b03167ffbeff59d2bfda0d79ea8a29f8c57c66d48c7a13eabbdb90908d9115ec41c9dc64283604051611b2d929190612d79565b60405180910390a25050565b60405162461bcd60e51b815260040161069b90612c99565b60006117d06524b9b9bab2b960d11b611d92565b60408051600380825260808201909252606091602082018380388339019050509050680a6f2dce8d0cae8d2f60bb1b81600081518110611ba157fe5b60200260200101818152505066119959541bdbdb60ca1b81600181518110611bc557fe5b6020026020010181815250506524b9b9bab2b960d11b81600281518110611be857fe5b60200260200101818152505090565b60608151835101604051908082528060200260200182016040528015611c27578160200160208202803883390190505b50905060005b8351811015611c6957838181518110611c4257fe5b6020026020010151828281518110611c5657fe5b6020908102919091010152600101611c2d565b5060005b8251811015611cac57828181518110611c8257fe5b6020026020010151828286510181518110611c9957fe5b6020908102919091010152600101611c6d565b5092915050565b60006117d0680a6f2dce8d0cae8d2f60bb1b611d92565b60006117d07453796e746865746978427269646765546f4261736560581b611d92565b600780546001600160a01b038416600081815260056020908152604080832085845282528083208751815467ffffffffffffffff19166001600160401b03909116178155878301516001918201559383526006825282208054808501825590835291200182905591549091611d629190611796565b600755505050565b600082821115611d8c5760405162461bcd60e51b815260040161069b90612c89565b50900390565b60008181526004602090815260408083205490516001600160a01b039091169182151591611dc291869101612a8f565b60405160208183030381529060405290611cac5760405162461bcd60e51b815260040161069b9190612c28565b600b54611e02908263ffffffff611d6a16565b600b556001600160a01b038216600090815260086020526040902054611e2e908263ffffffff611d6a16565b6001600160a01b0390921660009081526008602052604090209190915550565b604080518082019091526000808252602082015290565b604051806060016040528060006001600160401b0316815260200160008152602001600081525090565b803561085181612e8d565b805161085181612e8d565b60008083601f840112611eb757600080fd5b5081356001600160401b03811115611ece57600080fd5b602083019150836020820283011115611ee657600080fd5b9250929050565b60008083601f840112611eff57600080fd5b5081356001600160401b03811115611f1657600080fd5b602083019150836040820283011115611ee657600080fd5b805161085181612ea1565b600060408284031215611f4b57600080fd5b611f556040612dd3565b90506000611f638484611f96565b8252506020611f7484848301611f80565b60208301525092915050565b803561085181612eaa565b805161085181612eaa565b803561085181612eb3565b600060208284031215611fb357600080fd5b600061084d8484611e8f565b600060208284031215611fd157600080fd5b600061084d8484611e9a565b600080600060408486031215611ff257600080fd5b6000611ffe8686611e8f565b93505060208401356001600160401b0381111561201a57600080fd5b61202686828701611ea5565b92509250509250925092565b6000806040838503121561204557600080fd5b60006120518585611e8f565b925050602061206285828601611f80565b9150509250929050565b6000806000806060858703121561208257600080fd5b600061208e8787611e8f565b945050602061209f87828801611f80565b93505060408501356001600160401b038111156120bb57600080fd5b6120c787828801611eed565b95989497509550505050565b6000806000606084860312156120e857600080fd5b60006120f48686611e8f565b935050602061210586828701611f80565b925050604061211686828701611f80565b9150509250925092565b6000806000806000806060878903121561213957600080fd5b86356001600160401b0381111561214f57600080fd5b61215b89828a01611ea5565b965096505060208701356001600160401b0381111561217957600080fd5b61218589828a01611ea5565b945094505060408701356001600160401b038111156121a357600080fd5b6121af89828a01611ea5565b92509250509295509295509295565b600080602083850312156121d157600080fd5b82356001600160401b038111156121e757600080fd5b6121f385828601611ea5565b92509250509250929050565b60006020828403121561221157600080fd5b600061084d8484611f2e565b60006040828403121561222f57600080fd5b600061084d8484611f39565b60006020828403121561224d57600080fd5b600061084d8484611f80565b60006020828403121561226b57600080fd5b600061084d8484611f8b565b60006122838383612450565b505060200190565b60006122978383612a25565b505060600190565b60006122ab8383612a62565b505060400190565b6122bc81612e39565b82525050565b6122bc81612e11565b60006122d682612dff565b6122e08185612e03565b93506122eb83612df9565b8060005b838110156123195781516123038882612277565b975061230e83612df9565b9250506001016122ef565b509495945050505050565b600061232f82612dff565b6123398185612e03565b935061234483612df9565b8060005b8381101561231957815161235c888261228b565b975061236783612df9565b925050600101612348565b600061237d82612dff565b6123878185612e03565b935061239283612df9565b8060005b838110156123195781516123aa888261229f565b97506123b583612df9565b925050600101612396565b60006123cc8385612e03565b93506001600160fb1b038311156123e257600080fd5b6020830292506123f3838584612e4b565b50500190565b600061240482612dff565b61240e8185612e03565b935061241983612df9565b8060005b838110156123195781516124318882612277565b975061243c83612df9565b92505060010161241d565b6122bc81612e1c565b6122bc816105aa565b6122bc612465826105aa565b6105aa565b6122bc81612e40565b600061247e82612dff565b6124888185612e03565b9350612498818560208601612e57565b6124a181612e83565b9093019392505050565b60006124b8603583612e03565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527402063616e20616363657074206f776e65727368697605c1b602082015260400192915050565b600061250f601b83612e03565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000612548603383612e03565b7f43616e6e6f7420657363726f7720776974682030206475726174696f6e204f528152721030b137bb329036b0bc2fb23ab930ba34b7b760691b602082015260400192915050565b600061259d602483612e03565b7f43616e6e6f742063726561746520657363726f772077697468206164647265738152637328302960e01b602082015260400192915050565b60006125e3603583612e03565b7f43616e206f6e6c7920626520696e766f6b65642062792053796e746865746978815274109c9a5919d9551bd0985cd94818dbdb9d1c9858dd605a1b602082015260400192915050565b600061263a601e83612e03565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b6000612673601b83612e03565b7f43616e6e6f742062652072756e206f6e2074686973206c617965720000000000815260200192915050565b60006126ac601183612e0c565b70026b4b9b9b4b7339030b2323932b9b99d1607d1b815260110192915050565b60006126d9601783612e03565b7f5175616e746974792063616e6e6f74206265207a65726f000000000000000000815260200192915050565b6000612712604783612e03565b7f4d75737420626520656e6f7567682062616c616e636520696e2074686520636f81527f6e747261637420746f2070726f7669646520666f72207468652076657374696e6020820152666720656e74727960c81b604082015260600192915050565b6000612781601983612e03565b7f4163636f756e74206d657267696e672068617320656e64656400000000000000815260200192915050565b60006127ba601583612e03565b741d1bdad95b881d1c985b9cd9995c8819985a5b1959605a1b815260200192915050565b60006127eb602483612e03565b7f43616e6e6f74206e6f6d696e617465206f776e206163636f756e7420746f206d8152636572676560e01b602082015260400192915050565b6000612831602f83612e03565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681526e37b936903a3434b99030b1ba34b7b760891b602082015260400192915050565b631cd554d160e21b9052565b600061288e602183612e03565b7f41646472657373206973206e6f74206e6f6d696e6174656420746f206d6572678152606560f81b602082015260400192915050565b60006128d1601c83612e03565b7f65786365656473206d6178206d657267696e67206475726174696f6e00000000815260200192915050565b600061290a601983612e0c565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b6000612943602883612e03565b7f4f6e6c792074686520466565506f6f6c2063616e20706572666f726d20746869815267399030b1ba34b7b760c11b602082015260400192915050565b600061298d604483612e03565b7f496e73756666696369656e742062616c616e636520696e2074686520636f6e7481527f7261637420746f2070726f7669646520666f7220657363726f7765642062616c602082015263616e636560e01b604082015260600192915050565b60006129f9601f83612e03565b7f43616e6e6f74206d65726765206163636f756e74732077697468206465627400815260200192915050565b80516060830190612a368482612a86565b506020820151612a496020850182612450565b506040820151612a5c6040850182612450565b50505050565b80516040830190612a738482612a86565b506020820151612a5c6020850182612450565b6122bc81612e2d565b6000612a9a8261269f565b9150612aa68284612459565b50602001919050565b6000612a9a826128fd565b6020810161085182846122c2565b60608101612ad682866122b3565b612ae360208301856122c2565b612af06040830184612450565b949350505050565b60408101612b0682846122b3565b61085160208301612875565b60808101612b2082886122b3565b612b2d6020830187612450565b8181036040830152612b408185876123c0565b9050612b4f6060830184612450565b9695505050505050565b60408101612b6782856122c2565b610dbf60208301846122c2565b60408101612b0682846122c2565b60408101612b9082856122c2565b610dbf6020830184612450565b60208082528101610dbf81846122cb565b60208082528101610dbf8184612324565b60208082528101610dbf81846123f9565b602081016108518284612447565b602081016108518284612450565b60408101612b678285612450565b60408101612c088285612450565b8181036020830152612af08184612473565b60208101610851828461246a565b60208082528101610dbf8184612473565b60208082528101610851816124ab565b6020808252810161085181612502565b602080825281016108518161253b565b6020808252810161085181612590565b60208082528101610851816125d6565b602080825281016108518161262d565b6020808252810161085181612666565b60208082528101610851816126cc565b6020808252810161085181612705565b6020808252810161085181612774565b60208082528101610851816127ad565b60208082528101610851816127de565b6020808252810161085181612824565b6020808252810161085181612881565b60208082528101610851816128c4565b6020808252810161085181612936565b6020808252810161085181612980565b60208082528101610851816129ec565b60408101612d678285612450565b8181036020830152612af08184612372565b60408101612b908285612450565b60808101612d958287612450565b612da26020830186612450565b612daf6040830185612450565b612dbc6060830184612450565b95945050505050565b60408101612b908285612a86565b6040518181016001600160401b0381118282101715612df157600080fd5b604052919050565b60200190565b5190565b90815260200190565b919050565b600061085182612e21565b151590565b6001600160a01b031690565b6001600160401b031690565b6000610851825b600061085182612e11565b82818337506000910152565b60005b83811015612e72578181015183820152602001612e5a565b83811115612a5c5750506000910152565b601f01601f191690565b612e9681612e11565b8114610dce57600080fd5b612e9681612e1c565b612e96816105aa565b612e9681612e2d56fea365627a7a723158203d8121fe1dfd4ca5397ab064ec601be38b07d31688ce715cf12e8c4c7b544f646c6578706572696d656e74616cf564736f6c63430005100040
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.