Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Vault
Compiler Version
v0.5.16+commit.9c3226ce
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity 0.5.16; import "@openzeppelin/contracts-ethereum-package/contracts/math/Math.sol"; import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/SafeERC20.sol"; import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Detailed.sol"; import "@openzeppelin/contracts-ethereum-package/contracts/utils/ReentrancyGuard.sol"; import "./interfaces/IStrategy.sol"; import "./interfaces/IController.sol"; import "./interfaces/IVault.sol"; import "./interfaces/IUpgradeSource.sol"; import "./ControllableInit.sol"; import "./VaultStorage.sol"; contract Vault is ERC20, ERC20Detailed, IVault, IUpgradeSource, ControllableInit, VaultStorage, ReentrancyGuard { using SafeERC20 for IERC20; using Address for address; using SafeMath for uint256; event Withdraw(address indexed beneficiary, uint256 amount); event Deposit(address indexed beneficiary, uint256 amount); event Invest(uint256 amount); event StrategyAnnounced(address newStrategy, uint256 time); event StrategyChanged(address newStrategy, address oldStrategy); modifier whenStrategyDefined() { require(address(strategy()) != address(0), "Strategy must be defined"); _; } // Only smart contracts will be affected by this modifier modifier defense() { require( (msg.sender == tx.origin) || // If it is a normal user and not smart contract, // then the requirement will pass IController(controller()).whiteList(msg.sender), "Access denied for caller" ); _; } // the function is name differently to not cause inheritance clash in truffle and allows tests function initializeVault( address _storage, address _underlying, uint256 _toInvestNumerator, uint256 _toInvestDenominator, uint256 _withdrawFee, uint256 _maxDepositCap ) public initializer { require( _toInvestNumerator <= _toInvestDenominator, "cannot invest more than 100%" ); require(_toInvestDenominator != 0, "cannot divide by 0"); ERC20Detailed.initialize( string( abi.encodePacked("FORCE_", ERC20Detailed(_underlying).symbol()) ), string(abi.encodePacked("x", ERC20Detailed(_underlying).symbol())), ERC20Detailed(_underlying).decimals() ); ControllableInit.initialize(_storage); ReentrancyGuard.initialize(); uint256 underlyingUnit = 10**uint256(ERC20Detailed(address(_underlying)).decimals()); uint256 implementationDelay = 12 hours; uint256 strategyChangeDelay = 12 hours; VaultStorage.initialize( _underlying, _toInvestNumerator, _toInvestDenominator, underlyingUnit, _withdrawFee, _maxDepositCap, implementationDelay, strategyChangeDelay ); } function strategy() public view returns (address) { return _strategy(); } function underlying() public view returns (address) { return _underlying(); } function underlyingUnit() public view returns (uint256) { return _underlyingUnit(); } function vaultFractionToInvestNumerator() public view returns (uint256) { return _vaultFractionToInvestNumerator(); } function vaultFractionToInvestDenominator() public view returns (uint256) { return _vaultFractionToInvestDenominator(); } function withdrawFee() public view returns (uint256) { return _withdrawFee(); } function totalDeposits() public view returns (uint256) { return _totalDeposits(); } function maxDepositCap() public view returns (uint256) { return _maxDepositCap(); } function nextImplementation() public view returns (address) { return _nextImplementation(); } function nextImplementationTimestamp() public view returns (uint256) { return _nextImplementationTimestamp(); } function nextImplementationDelay() public view returns (uint256) { return _nextImplementationDelay(); } /** * Chooses the best strategy and re-invests. If the strategy did not change, it just calls * forceUnleashed on the current strategy. Call this through controller to claim galactic rewards. */ function forceUnleashed() external whenStrategyDefined onlyControllerOrGovernance { // ensure that new funds are invested too invest(); IStrategy(strategy()).forceUnleashed(); } /* * Returns the cash balance across all users in this contract. */ function underlyingBalanceInVault() public view returns (uint256) { return IERC20(underlying()).balanceOf(address(this)); } /* Returns the current underlying (e.g., DAI's) balance together with * the invested amount (if DAI is invested elsewhere by the strategy). */ function underlyingBalanceWithInvestment() public view returns (uint256) { if (address(strategy()) == address(0)) { // initial state, when not set return underlyingBalanceInVault(); } return underlyingBalanceInVault().add( IStrategy(strategy()).investedUnderlyingBalance() ); } function getPricePerFullShare() public view returns (uint256) { return totalSupply() == 0 ? underlyingUnit() : underlyingUnit().mul(underlyingBalanceWithInvestment()).div( totalSupply() ); } /* get the user's share (in underlying) */ function underlyingBalanceWithInvestmentForHolder(address holder) external view returns (uint256) { if (totalSupply() == 0) { return 0; } return underlyingBalanceWithInvestment().mul(balanceOf(holder)).div( totalSupply() ); } function futureStrategy() public view returns (address) { return _futureStrategy(); } function strategyUpdateTime() public view returns (uint256) { return _strategyUpdateTime(); } function strategyTimeLock() public view returns (uint256) { return _strategyTimeLock(); } function canUpdateStrategy(address _strategy) public view returns (bool) { return strategy() == address(0) || // no strategy was set yet (_strategy == futureStrategy() && block.timestamp > strategyUpdateTime() && strategyUpdateTime() > 0); // or the timelock has passed } /** * Indicates that the strategy update will happen in the future */ function announceStrategyUpdate(address _strategy) public onlyControllerOrGovernance { // records a new timestamp uint256 when = block.timestamp.add(strategyTimeLock()); _setStrategyUpdateTime(when); _setFutureStrategy(_strategy); emit StrategyAnnounced(_strategy, when); } /** * Finalizes (or cancels) the strategy update by resetting the data */ function finalizeStrategyUpdate() public onlyControllerOrGovernance { _setStrategyUpdateTime(0); _setFutureStrategy(address(0)); } function setStrategy(address _strategy) public onlyControllerOrGovernance { require( canUpdateStrategy(_strategy), "The strategy exists and switch timelock did not elapse yet" ); require(_strategy != address(0), "new _strategy cannot be empty"); require( IStrategy(_strategy).underlying() == address(underlying()), "Vault underlying must match Strategy underlying" ); require( IStrategy(_strategy).vault() == address(this), "the strategy does not belong to this vault" ); emit StrategyChanged(_strategy, strategy()); if (address(_strategy) != address(strategy())) { if (address(strategy()) != address(0)) { // if the original strategy (no underscore) is defined IERC20(underlying()).safeApprove(address(strategy()), 0); IStrategy(strategy()).withdrawAllToVault(); } _setStrategy(_strategy); IERC20(underlying()).safeApprove(address(strategy()), 0); IERC20(underlying()).safeApprove(address(strategy()), uint256(~0)); } finalizeStrategyUpdate(); } function setVaultFractionToInvest(uint256 numerator, uint256 denominator) external onlyGovernance { require(denominator > 0, "denominator must be greater than 0"); require( numerator <= denominator, "denominator must be greater than or equal to the numerator" ); _setVaultFractionToInvestNumerator(numerator); _setVaultFractionToInvestDenominator(denominator); } function setWithdrawFee(uint256 value) external onlyGovernance { return _setWithdrawFee(value); } function setMaxDepositCap(uint256 value) external onlyGovernance { return _setMaxDepositCap(value); } function rebalance() external onlyControllerOrGovernance { withdrawAll(); invest(); } function availableToInvestOut() public view returns (uint256) { uint256 wantInvestInTotal = underlyingBalanceWithInvestment() .mul(vaultFractionToInvestNumerator()) .div(vaultFractionToInvestDenominator()); uint256 alreadyInvested = IStrategy(strategy()).investedUnderlyingBalance(); if (alreadyInvested >= wantInvestInTotal) { return 0; } else { uint256 remainingToInvest = wantInvestInTotal.sub(alreadyInvested); return remainingToInvest <= underlyingBalanceInVault() // TODO: we think that the "else" branch of the ternary operation is not // going to get hit ? remainingToInvest : underlyingBalanceInVault(); } } function invest() internal whenStrategyDefined { uint256 availableAmount = availableToInvestOut(); if (availableAmount > 0) { IERC20(underlying()).safeTransfer( address(strategy()), availableAmount ); emit Invest(availableAmount); } } /* * Allows for depositing the underlying asset in exchange for shares. * Approval is assumed. */ function deposit(uint256 amount) external defense { _deposit(amount, msg.sender, msg.sender); } /* * Allows for depositing the underlying asset in exchange for shares * assigned to the holder. * This facilitates depositing for someone else (using DepositHelper) */ function depositFor(uint256 amount, address holder) public defense { _deposit(amount, msg.sender, holder); } function withdrawAll() public onlyControllerOrGovernance whenStrategyDefined { IStrategy(strategy()).withdrawAllToVault(); } function withdraw(uint256 numberOfShares) external defense nonReentrant { require(totalSupply() > 0, "Vault has no shares"); require(numberOfShares > 0, "numberOfShares must be greater than 0"); uint256 totalSupply = totalSupply(); _burn(msg.sender, numberOfShares); uint256 underlyingAmountToWithdraw = underlyingBalanceWithInvestment().mul(numberOfShares).div( totalSupply ); uint256 originalDepositsToWithdraw = _totalDeposits().mul(numberOfShares).div(totalSupply); if (underlyingAmountToWithdraw > underlyingBalanceInVault()) { // withdraw everything from the strategy to accurately check the share value if (numberOfShares == totalSupply) { IStrategy(strategy()).withdrawAllToVault(); } else { uint256 missing = underlyingAmountToWithdraw.sub(underlyingBalanceInVault()); IStrategy(strategy()).withdrawToVault(missing); } // recalculate to improve accuracy underlyingAmountToWithdraw = Math.min( underlyingBalanceWithInvestment().mul(numberOfShares).div( totalSupply ), underlyingBalanceInVault() ); } uint256 fee = underlyingAmountToWithdraw.mul(withdrawFee()).div(1000); IERC20(underlying()).safeTransfer( msg.sender, underlyingAmountToWithdraw.sub(fee) ); _setTotalDeposits(_totalDeposits().sub(originalDepositsToWithdraw)); if (fee > 0) { IERC20(underlying()).safeTransfer( IController(controller()).treasury(), fee ); } // update the withdrawal amount for the holder emit Withdraw(msg.sender, underlyingAmountToWithdraw); } function _deposit( uint256 amount, address sender, address beneficiary ) internal nonReentrant { require(amount > 0, "Cannot deposit 0"); require(beneficiary != address(0), "holder must be defined"); require( maxDepositCap() == 0 || totalDeposits().add(amount) <= maxDepositCap(), "Cannot deposit more than cap" ); if (address(strategy()) != address(0)) { require(IStrategy(strategy()).depositArbCheck(), "Too much arb"); } uint256 toMint = totalSupply() == 0 ? amount : amount.mul(totalSupply()).div( underlyingBalanceWithInvestment() ); _mint(beneficiary, toMint); IERC20(underlying()).safeTransferFrom(sender, address(this), amount); _setTotalDeposits(_totalDeposits().add(amount)); // update the contribution amount for the beneficiary emit Deposit(beneficiary, amount); } /** * Schedules an upgrade for this vault's proxy. */ function scheduleUpgrade(address impl) public onlyGovernance { _setNextImplementation(impl); _setNextImplementationTimestamp( block.timestamp.add(nextImplementationDelay()) ); } function shouldUpgrade() external view returns (bool, address) { return ( nextImplementationTimestamp() != 0 && block.timestamp > nextImplementationTimestamp() && nextImplementation() != address(0), nextImplementation() ); } function finalizeUpgrade() external onlyGovernance { _setNextImplementation(address(0)); _setNextImplementationTimestamp(0); } }
pragma solidity 0.5.16; import "./GovernableInit.sol"; // A clone of Governable supporting the Initializable interface and pattern contract ControllableInit is GovernableInit { constructor() public {} function initialize(address _storage) public initializer { GovernableInit.initialize(_storage); } modifier onlyController() { require( Storage(_storage()).isController(msg.sender), "Not a controller" ); _; } modifier onlyControllerOrGovernance() { require( (Storage(_storage()).isController(msg.sender) || Storage(_storage()).isGovernance(msg.sender)), "The caller must be controller or governance" ); _; } function controller() public view returns (address) { return Storage(_storage()).controller(); } }
pragma solidity 0.5.16; import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "./Storage.sol"; // A clone of Governable supporting the Initializable interface and pattern contract GovernableInit is Initializable { bytes32 internal constant _STORAGE_SLOT = 0xa7ec62784904ff31cbcc32d09932a58e7f1e4476e1d041995b37c917990b16dc; modifier onlyGovernance() { require(Storage(_storage()).isGovernance(msg.sender), "Not governance"); _; } constructor() public { assert( _STORAGE_SLOT == bytes32( uint256(keccak256("eip1967.governableInit.storage")) - 1 ) ); } function initialize(address _store) public initializer { _setStorage(_store); } function _setStorage(address newStorage) private { bytes32 slot = _STORAGE_SLOT; // solhint-disable-next-line no-inline-assembly assembly { sstore(slot, newStorage) } } function setStorage(address _store) public onlyGovernance { require(_store != address(0), "new storage shouldn't be empty"); _setStorage(_store); } function _storage() internal view returns (address str) { bytes32 slot = _STORAGE_SLOT; // solhint-disable-next-line no-inline-assembly assembly { str := sload(slot) } } function governance() public view returns (address) { return Storage(_storage()).governance(); } }
pragma solidity 0.5.16; contract Storage { address public governance; address public controller; constructor() public { governance = msg.sender; } modifier onlyGovernance() { require(isGovernance(msg.sender), "Not governance"); _; } function setGovernance(address _governance) public onlyGovernance { require(_governance != address(0), "new governance shouldn't be empty"); governance = _governance; } function setController(address _controller) public onlyGovernance { require(_controller != address(0), "new controller shouldn't be empty"); controller = _controller; } function isGovernance(address account) public view returns (bool) { return account == governance; } function isController(address account) public view returns (bool) { return account == controller; } }
pragma solidity 0.5.16; import "@openzeppelin/upgrades/contracts/Initializable.sol"; contract VaultStorage is Initializable { bytes32 internal constant _STRATEGY_SLOT = 0xf1a169aa0f736c2813818fdfbdc5755c31e0839c8f49831a16543496b28574ea; bytes32 internal constant _UNDERLYING_SLOT = 0x1994607607e11d53306ef62e45e3bd85762c58d9bf38b5578bc4a258a26a7371; bytes32 internal constant _UNDERLYING_UNIT_SLOT = 0xa66bc57d4b4eed7c7687876ca77997588987307cb13ecc23f5e52725192e5fff; bytes32 internal constant _VAULT_FRACTION_TO_INVEST_NUMERATOR_SLOT = 0x39122c9adfb653455d0c05043bd52fcfbc2be864e832efd3abc72ce5a3d7ed5a; bytes32 internal constant _VAULT_FRACTION_TO_INVEST_DENOMINATOR_SLOT = 0x469a3bad2fab7b936c45eecd1f5da52af89cead3e2ed7f732b6f3fc92ed32308; bytes32 internal constant _NEXT_IMPLEMENTATION_SLOT = 0xb1acf527cd7cd1668b30e5a9a1c0d845714604de29ce560150922c9d8c0937df; bytes32 internal constant _NEXT_IMPLEMENTATION_TIMESTAMP_SLOT = 0x3bc747f4b148b37be485de3223c90b4468252967d2ea7f9fcbd8b6e653f434c9; bytes32 internal constant _NEXT_IMPLEMENTATION_DELAY_SLOT = 0x82ddc3be3f0c1a6870327f78f4979a0b37b21b16736ef5be6a7a7a35e530bcf0; bytes32 internal constant _STRATEGY_TIME_LOCK_SLOT = 0x6d02338b2e4c913c0f7d380e2798409838a48a2c4d57d52742a808c82d713d8b; bytes32 internal constant _FUTURE_STRATEGY_SLOT = 0xb441b53a4e42c2ca9182bc7ede99bedba7a5d9360d9dfbd31fa8ee2dc8590610; bytes32 internal constant _STRATEGY_UPDATE_TIME_SLOT = 0x56e7c0e75875c6497f0de657009613a32558904b5c10771a825cc330feff7e72; bytes32 internal constant _WITHDRAW_FEE = 0x3405c96d34f8f0e36eac648034ca7e687437f795bbdbdc2cb7db90a89d519f57; bytes32 internal constant _TOTAL_DEPOSITS = 0xaf765835ed5af0d235b6c686724ad31fa90e06b3daf1c074d6cc398b8fcef213; bytes32 internal constant _MAX_DEPOSIT_CAP = 0x0df75d4bdb87be8e3e04e1dc08ec1c98ed6c4147138e5789f0bd448c5c8e1e28; constructor() public { assert( _STRATEGY_SLOT == bytes32(uint256(keccak256("eip1967.vaultStorage.strategy")) - 1) ); assert( _UNDERLYING_SLOT == bytes32( uint256(keccak256("eip1967.vaultStorage.underlying")) - 1 ) ); assert( _UNDERLYING_UNIT_SLOT == bytes32( uint256(keccak256("eip1967.vaultStorage.underlyingUnit")) - 1 ) ); assert( _VAULT_FRACTION_TO_INVEST_NUMERATOR_SLOT == bytes32( uint256( keccak256( "eip1967.vaultStorage.vaultFractionToInvestNumerator" ) ) - 1 ) ); assert( _VAULT_FRACTION_TO_INVEST_DENOMINATOR_SLOT == bytes32( uint256( keccak256( "eip1967.vaultStorage.vaultFractionToInvestDenominator" ) ) - 1 ) ); assert( _NEXT_IMPLEMENTATION_SLOT == bytes32( uint256( keccak256("eip1967.vaultStorage.nextImplementation") ) - 1 ) ); assert( _NEXT_IMPLEMENTATION_TIMESTAMP_SLOT == bytes32( uint256( keccak256( "eip1967.vaultStorage.nextImplementationTimestamp" ) ) - 1 ) ); assert( _NEXT_IMPLEMENTATION_DELAY_SLOT == bytes32( uint256( keccak256( "eip1967.vaultStorage.nextImplementationDelay" ) ) - 1 ) ); assert( _STRATEGY_TIME_LOCK_SLOT == bytes32( uint256( keccak256("eip1967.vaultStorage.strategyTimeLock") ) - 1 ) ); assert( _FUTURE_STRATEGY_SLOT == bytes32( uint256(keccak256("eip1967.vaultStorage.futureStrategy")) - 1 ) ); assert( _STRATEGY_UPDATE_TIME_SLOT == bytes32( uint256( keccak256("eip1967.vaultStorage.strategyUpdateTime") ) - 1 ) ); assert( _WITHDRAW_FEE == bytes32( uint256(keccak256("eip1967.vaultStorage.withdrawFee")) - 1 ) ); assert( _TOTAL_DEPOSITS == bytes32( uint256(keccak256("eip1967.vaultStorage.totalDeposits")) - 1 ) ); assert( _MAX_DEPOSIT_CAP == bytes32( uint256(keccak256("eip1967.vaultStorage.maxDepositCap")) - 1 ) ); } function initialize( address _underlying, uint256 _toInvestNumerator, uint256 _toInvestDenominator, uint256 _underlyingUnit, uint256 _withdrawFee_, uint256 _maxDepositCap_, uint256 _implementationChangeDelay, uint256 _strategyChangeDelay ) public initializer { _setUnderlying(_underlying); _setVaultFractionToInvestNumerator(_toInvestNumerator); _setVaultFractionToInvestDenominator(_toInvestDenominator); _setWithdrawFee(_withdrawFee_); _setMaxDepositCap(_maxDepositCap_); _setUnderlyingUnit(_underlyingUnit); _setNextImplementationDelay(_implementationChangeDelay); _setStrategyTimeLock(_strategyChangeDelay); _setStrategyUpdateTime(0); _setFutureStrategy(address(0)); } function _setStrategy(address _address) internal { setAddress(_STRATEGY_SLOT, _address); } function _strategy() internal view returns (address) { return getAddress(_STRATEGY_SLOT); } function _setUnderlying(address _address) internal { setAddress(_UNDERLYING_SLOT, _address); } function _underlying() internal view returns (address) { return getAddress(_UNDERLYING_SLOT); } function _setUnderlyingUnit(uint256 _value) internal { setUint256(_UNDERLYING_UNIT_SLOT, _value); } function _underlyingUnit() internal view returns (uint256) { return getUint256(_UNDERLYING_UNIT_SLOT); } function _setVaultFractionToInvestNumerator(uint256 _value) internal { setUint256(_VAULT_FRACTION_TO_INVEST_NUMERATOR_SLOT, _value); } function _vaultFractionToInvestNumerator() internal view returns (uint256) { return getUint256(_VAULT_FRACTION_TO_INVEST_NUMERATOR_SLOT); } function _setVaultFractionToInvestDenominator(uint256 _value) internal { setUint256(_VAULT_FRACTION_TO_INVEST_DENOMINATOR_SLOT, _value); } function _vaultFractionToInvestDenominator() internal view returns (uint256) { return getUint256(_VAULT_FRACTION_TO_INVEST_DENOMINATOR_SLOT); } function _setWithdrawFee(uint256 _value) internal { setUint256(_WITHDRAW_FEE, _value); } function _withdrawFee() internal view returns (uint256) { return getUint256(_WITHDRAW_FEE); } function _setTotalDeposits(uint256 _value) internal { setUint256(_TOTAL_DEPOSITS, _value); } function _totalDeposits() internal view returns (uint256) { return getUint256(_TOTAL_DEPOSITS); } function _setMaxDepositCap(uint256 _value) internal { setUint256(_MAX_DEPOSIT_CAP, _value); } function _maxDepositCap() internal view returns (uint256) { return getUint256(_MAX_DEPOSIT_CAP); } function _setNextImplementation(address _address) internal { setAddress(_NEXT_IMPLEMENTATION_SLOT, _address); } function _nextImplementation() internal view returns (address) { return getAddress(_NEXT_IMPLEMENTATION_SLOT); } function _setNextImplementationTimestamp(uint256 _value) internal { setUint256(_NEXT_IMPLEMENTATION_TIMESTAMP_SLOT, _value); } function _nextImplementationTimestamp() internal view returns (uint256) { return getUint256(_NEXT_IMPLEMENTATION_TIMESTAMP_SLOT); } function _setNextImplementationDelay(uint256 _value) internal { setUint256(_NEXT_IMPLEMENTATION_DELAY_SLOT, _value); } function _nextImplementationDelay() internal view returns (uint256) { return getUint256(_NEXT_IMPLEMENTATION_DELAY_SLOT); } function _setStrategyTimeLock(uint256 _value) internal { setUint256(_STRATEGY_TIME_LOCK_SLOT, _value); } function _strategyTimeLock() internal view returns (uint256) { return getUint256(_STRATEGY_TIME_LOCK_SLOT); } function _setFutureStrategy(address _value) internal { setAddress(_FUTURE_STRATEGY_SLOT, _value); } function _futureStrategy() internal view returns (address) { return getAddress(_FUTURE_STRATEGY_SLOT); } function _setStrategyUpdateTime(uint256 _value) internal { setUint256(_STRATEGY_UPDATE_TIME_SLOT, _value); } function _strategyUpdateTime() internal view returns (uint256) { return getUint256(_STRATEGY_UPDATE_TIME_SLOT); } function setAddress(bytes32 slot, address _address) private { // solhint-disable-next-line no-inline-assembly assembly { sstore(slot, _address) } } function setUint256(bytes32 slot, uint256 _value) private { // solhint-disable-next-line no-inline-assembly assembly { sstore(slot, _value) } } function getAddress(bytes32 slot) private view returns (address str) { // solhint-disable-next-line no-inline-assembly assembly { str := sload(slot) } } function getUint256(bytes32 slot) private view returns (uint256 str) { // solhint-disable-next-line no-inline-assembly assembly { str := sload(slot) } } uint256[50] private ______gap; }
pragma solidity 0.5.16; interface IController { function whiteList(address _target) external view returns (bool); function addVaultAndStrategy(address _vault, address _strategy) external; function forceUnleashed(address _vault) external; function hasVault(address _vault) external returns (bool); function salvage(address _token, uint256 amount) external; function salvageStrategy( address _strategy, address _token, uint256 amount ) external; function notifyFee(address _underlying, uint256 fee) external; function profitSharingNumerator() external view returns (uint256); function profitSharingDenominator() external view returns (uint256); function treasury() external view returns (address); }
pragma solidity 0.5.16; interface IStrategy { function unsalvagableTokens(address tokens) external view returns (bool); function governance() external view returns (address); function controller() external view returns (address); function underlying() external view returns (address); function vault() external view returns (address); function withdrawAllToVault() external; function withdrawToVault(uint256 amount) external; function investedUnderlyingBalance() external view returns (uint256); // itsNotMuch() // should only be called by controller function salvage( address recipient, address token, uint256 amount ) external; function forceUnleashed() external; function depositArbCheck() external view returns (bool); }
pragma solidity 0.5.16; interface IUpgradeSource { function shouldUpgrade() external view returns (bool, address); function finalizeUpgrade() external; }
pragma solidity 0.5.16; interface IVault { function underlyingBalanceInVault() external view returns (uint256); function underlyingBalanceWithInvestment() external view returns (uint256); function governance() external view returns (address); function controller() external view returns (address); function underlying() external view returns (address); function strategy() external view returns (address); function setStrategy(address _strategy) external; function setVaultFractionToInvest(uint256 numerator, uint256 denominator) external; function deposit(uint256 amountWei) external; function depositFor(uint256 amountWei, address holder) external; function withdrawAll() external; function withdraw(uint256 numberOfShares) external; function getPricePerFullShare() external view returns (uint256); function underlyingBalanceWithInvestmentForHolder(address holder) external view returns (uint256); // force unleash should be callable only by the controller (by the force unleasher) or by governance function forceUnleashed() external; function rebalance() external; }
pragma solidity ^0.5.0; import "@openzeppelin/upgrades/contracts/Initializable.sol"; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ contract Context is Initializable { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor () internal { } // solhint-disable-previous-line no-empty-blocks function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
pragma solidity ^0.5.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } }
pragma solidity ^0.5.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
pragma solidity ^0.5.0; import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "../../GSN/Context.sol"; import "./IERC20.sol"; import "../../math/SafeMath.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20Mintable}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Initializable, Context, IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for `sender`'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal { require(account != address(0), "ERC20: mint to the zero address"); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal { require(account != address(0), "ERC20: burn from the zero address"); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * This is internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Destroys `amount` tokens from `account`.`amount` is then deducted * from the caller's allowance. * * See {_burn} and {_approve}. */ function _burnFrom(address account, uint256 amount) internal { _burn(account, amount); _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance")); } uint256[50] private ______gap; }
pragma solidity ^0.5.0; import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "./IERC20.sol"; /** * @dev Optional functions from the ERC20 standard. */ contract ERC20Detailed is Initializable, IERC20 { string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of * these values are immutable: they can only be set once during * construction. */ function initialize(string memory name, string memory symbol, uint8 decimals) public initializer { _name = name; _symbol = symbol; _decimals = decimals; } /** * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view returns (uint8) { return _decimals; } uint256[50] private ______gap; }
pragma solidity ^0.5.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see {ERC20Detailed}. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
pragma solidity ^0.5.0; import "./IERC20.sol"; import "../../math/SafeMath.sol"; import "../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. // A Solidity high level call has three parts: // 1. The target address is checked to verify it contains contract code // 2. The call itself is made, and success asserted // 3. The return value is decoded, which in turn checks the size of the returned data. // solhint-disable-next-line max-line-length require(address(token).isContract(), "SafeERC20: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
pragma solidity ^0.5.5; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Converts an `address` into `address payable`. Note that this is * simply a type cast: the actual underlying value is not changed. * * _Available since v2.4.0._ */ function toPayable(address account) internal pure returns (address payable) { return address(uint160(account)); } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. * * _Available since v2.4.0._ */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-call-value (bool success, ) = recipient.call.value(amount)(""); require(success, "Address: unable to send value, recipient may have reverted"); } }
pragma solidity ^0.5.0; import "@openzeppelin/upgrades/contracts/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. */ contract ReentrancyGuard is Initializable { // counter to allow mutex lock with only one SSTORE operation uint256 private _guardCounter; function initialize() public initializer { // The counter starts at one to prevent changing it from zero to a non-zero // value, which is a more expensive operation. _guardCounter = 1; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { _guardCounter += 1; uint256 localCounter = _guardCounter; _; require(localCounter == _guardCounter, "ReentrancyGuard: reentrant call"); } uint256[50] private ______gap; }
pragma solidity >=0.4.24 <0.7.0; /** * @title Initializable * * @dev Helper contract to support initializer functions. To use it, replace * the constructor with a function that has the `initializer` modifier. * WARNING: Unlike constructors, initializer functions must be manually * invoked. This applies both to deploying an Initializable contract, as well * as extending an Initializable contract via inheritance. * WARNING: When used with inheritance, manual care must be taken to not invoke * a parent initializer twice, or ensure that all initializers are idempotent, * because this is not dealt with automatically as with constructors. */ contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private initializing; /** * @dev Modifier to use in the initializer function of a contract. */ modifier initializer() { require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); bool isTopLevelCall = !initializing; if (isTopLevelCall) { initializing = true; initialized = true; } _; if (isTopLevelCall) { initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function isConstructor() private view returns (bool) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. address self = address(this); uint256 cs; assembly { cs := extcodesize(self) } return cs == 0; } // Reserved storage space to allow for layout changes in the future. uint256[50] private ______gap; }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "istanbul", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Invest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStrategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"StrategyAnnounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStrategy","type":"address"},{"indexed":false,"internalType":"address","name":"oldStrategy","type":"address"}],"name":"StrategyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"announceStrategyUpdate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"availableToInvestOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","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":true,"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"canUpdateStrategy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"holder","type":"address"}],"name":"depositFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"finalizeStrategyUpdate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"finalizeUpgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"forceUnleashed","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"futureStrategy","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getPricePerFullShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_underlying","type":"address"},{"internalType":"uint256","name":"_toInvestNumerator","type":"uint256"},{"internalType":"uint256","name":"_toInvestDenominator","type":"uint256"},{"internalType":"uint256","name":"_underlyingUnit","type":"uint256"},{"internalType":"uint256","name":"_withdrawFee_","type":"uint256"},{"internalType":"uint256","name":"_maxDepositCap_","type":"uint256"},{"internalType":"uint256","name":"_implementationChangeDelay","type":"uint256"},{"internalType":"uint256","name":"_strategyChangeDelay","type":"uint256"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_storage","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_storage","type":"address"},{"internalType":"address","name":"_underlying","type":"address"},{"internalType":"uint256","name":"_toInvestNumerator","type":"uint256"},{"internalType":"uint256","name":"_toInvestDenominator","type":"uint256"},{"internalType":"uint256","name":"_withdrawFee","type":"uint256"},{"internalType":"uint256","name":"_maxDepositCap","type":"uint256"}],"name":"initializeVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"maxDepositCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nextImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nextImplementationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nextImplementationTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"rebalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"impl","type":"address"}],"name":"scheduleUpgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setMaxDepositCap","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_store","type":"address"}],"name":"setStorage","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"setStrategy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"setVaultFractionToInvest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setWithdrawFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"shouldUpgrade","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"strategy","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"strategyTimeLock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"strategyUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"underlying","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"underlyingBalanceInVault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"underlyingBalanceWithInvestment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"holder","type":"address"}],"name":"underlyingBalanceWithInvestmentForHolder","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"underlyingUnit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vaultFractionToInvestDenominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vaultFractionToInvestNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"numberOfShares","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"withdrawFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
608060408190527f656970313936372e7661756c7453746f726167652e756e6465726c79696e6700815260019080602362004ff382396023019050604051809103902060001c0360001b7fa66bc57d4b4eed7c7687876ca77997588987307cb13ecc23f5e52725192e5fff60001b146200007557fe5b6001604051808062004ee3603391396033019050604051809103902060001c0360001b7f39122c9adfb653455d0c05043bd52fcfbc2be864e832efd3abc72ce5a3d7ed5a60001b14620000c457fe5b6001604051808062004f46603591396035019050604051809103902060001c0360001b7f469a3bad2fab7b936c45eecd1f5da52af89cead3e2ed7f732b6f3fc92ed3230860001b146200011357fe5b6001604051808062005038602791396027019050604051809103902060001c0360001b7fb1acf527cd7cd1668b30e5a9a1c0d845714604de29ce560150922c9d8c0937df60001b146200016257fe5b6001604051808062004f16603091396030019050604051809103902060001c0360001b7f3bc747f4b148b37be485de3223c90b4468252967d2ea7f9fcbd8b6e653f434c960001b14620001b157fe5b6001604051808062004fc7602c9139602c019050604051809103902060001c0360001b7f82ddc3be3f0c1a6870327f78f4979a0b37b21b16736ef5be6a7a7a35e530bcf060001b146200020057fe5b6001604051808062004fa2602591396025019050604051809103902060001c0360001b7f6d02338b2e4c913c0f7d380e2798409838a48a2c4d57d52742a808c82d713d8b60001b146200024f57fe5b600160405180806200505f602391396023019050604051809103902060001c0360001b7fb441b53a4e42c2ca9182bc7ede99bedba7a5d9360d9dfbd31fa8ee2dc859061060001b146200029e57fe5b6001604051808062004f7b602791396027019050604051809103902060001c0360001b7f56e7c0e75875c6497f0de657009613a32558904b5c10771a825cc330feff7e7260001b14620002ed57fe5b604080517f656970313936372e7661756c7453746f726167652e7769746864726177466565815290519081900360200190207f3405c96d34f8f0e36eac648034ca7e687437f795bbdbdc2cb7db90a89d519f57600019909101146200034e57fe5b6001604051808062005016602291396022019050604051809103902060001c0360001b7faf765835ed5af0d235b6c686724ad31fa90e06b3daf1c074d6cc398b8fcef21360001b146200039d57fe5b6001604051808062004ec1602291396022019050604051809103902060001c0360001b7f0df75d4bdb87be8e3e04e1dc08ec1c98ed6c4147138e5789f0bd448c5c8e1e2860001b14620003ec57fe5b614ac580620003fc6000396000f3fe608060405234801561001057600080fd5b50600436106103425760003560e01c8063853828b6116101b8578063aa04462511610104578063dd62ed3e116100a2578063eda199aa1161007c578063eda199aa146109c1578063f0cf91e7146109c9578063f2768c1e146109ef578063f77c4791146109f757610342565b8063dd62ed3e1461096e578063dfed91601461099c578063e941fa78146109b957610342565b8063b6b55f25116100de578063b6b55f251461091b578063c2baf35614610938578063c4d66de814610940578063cca7f4751461096657610342565b8063aa044625146108ee578063b592c390146108f6578063b6ac642a146108fe57610342565b80639a508c8e11610171578063a5b1a24d1161014b578063a5b1a24d1461088f578063a8365693146108b2578063a8c62e76146108ba578063a9059cbb146108c257610342565b80639a508c8e146108305780639d16acfd14610838578063a457c2d71461086357610342565b8063853828b614610784578063871de9fd1461078c5780638cb1d67f146107d45780639137c1a7146107fa5780639546cc531461082057806395d89b411461082857610342565b806336efd16f1161029257806370a08231116102305780637d7c2a1c1161020a5780637d7c2a1c146107645780637d8820971461076c5780638129fc1c1461077457806382de9c1b1461077c57610342565b806370a08231146106e557806377c7b8fc1461070b5780637ca5fc9d1461071357610342565b806353ceb01c1161026c57806353ceb01c146106c55780635aa6e675146106cd5780635fe51e6d146106d55780636f307dc3146106dd57610342565b806336efd16f1461066557806339509351146106915780634af1758b146106bd57610342565b80631624f6c6116102ff57806323b872dd116102d957806323b872dd146105ce5780632e1a7d4d14610604578063313ce5671461062157806333a100ca1461063f57610342565b80631624f6c61461049057806318160ddd146105be5780631bf8e7be146105c657610342565b806306fdde0314610347578063095ea7b3146103c457806309ff18f0146104045780630a6bbeb3146104285780630ad2239d146104505780630c80447a1461046a575b600080fd5b61034f6109ff565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610389578181015183820152602001610371565b50505050905090810190601f1680156103b65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103f0600480360360408110156103da57600080fd5b506001600160a01b038135169060200135610a96565b604080519115158252519081900360200190f35b61040c610ab4565b604080516001600160a01b039092168252519081900360200190f35b61044e6004803603602081101561043e57600080fd5b50356001600160a01b0316610ac3565b005b610458610c8d565b60408051918252519081900360200190f35b61044e6004803603602081101561048057600080fd5b50356001600160a01b0316610c97565b61044e600480360360608110156104a657600080fd5b810190602081018135600160201b8111156104c057600080fd5b8201836020820111156104d257600080fd5b803590602001918460018302840111600160201b831117156104f357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561054557600080fd5b82018360208201111561055757600080fd5b803590602001918460018302840111600160201b8311171561057857600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050903560ff169150610d819050565b610458610e5d565b610458610e63565b6103f0600480360360608110156105e457600080fd5b506001600160a01b03813581169160208101359091169060400135610f0f565b61044e6004803603602081101561061a57600080fd5b5035610f9c565b61062961140f565b6040805160ff9092168252519081900360200190f35b61044e6004803603602081101561065557600080fd5b50356001600160a01b0316611418565b61044e6004803603604081101561067b57600080fd5b50803590602001356001600160a01b03166118b9565b6103f0600480360360408110156106a757600080fd5b506001600160a01b0381351690602001356119a3565b6104586119f7565b610458611a01565b61040c611a0b565b61040c611a7e565b61040c611a88565b610458600480360360208110156106fb57600080fd5b50356001600160a01b0316611a92565b610458611ab1565b61044e600480360361010081101561072a57600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a08101359060c08101359060e00135611aeb565b61044e611bf1565b610458611d57565b61044e611d61565b610458611e07565b61044e611e11565b61044e600480360360c08110156107a257600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060808101359060a0013561201c565b610458600480360360208110156107ea57600080fd5b50356001600160a01b0316612595565b61044e6004803603602081101561081057600080fd5b50356001600160a01b03166125ca565b6104586126f9565b61034f612703565b61044e612764565b610840612843565b6040805192151583526001600160a01b0390911660208301528051918290030190f35b6103f06004803603604081101561087957600080fd5b506001600160a01b03813516906020013561288f565b61044e600480360360408110156108a557600080fd5b50803590602001356128fd565b610458612a58565b61040c612a62565b6103f0600480360360408110156108d857600080fd5b506001600160a01b038135169060200135612a6c565b610458612a80565b610458612a8a565b61044e6004803603602081101561091457600080fd5b5035612b63565b61044e6004803603602081101561093157600080fd5b5035612c37565b610458612d21565b61044e6004803603602081101561095657600080fd5b50356001600160a01b0316612d80565b61044e612e2b565b6104586004803603604081101561098457600080fd5b506001600160a01b038135811691602001351661302a565b61044e600480360360208110156109b257600080fd5b5035613055565b610458613129565b61044e613133565b6103f0600480360360208110156109df57600080fd5b50356001600160a01b031661329b565b6104586132fc565b61040c613306565b60688054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a8b5780601f10610a6057610100808354040283529160200191610a8b565b820191906000526020600020905b815481529060010190602001808311610a6e57829003601f168201915b505050505090505b90565b6000610aaa610aa3613348565b848461334c565b5060015b92915050565b6000610abe613438565b905090565b610acb613463565b6001600160a01b031663b429afeb336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610b2057600080fd5b505afa158015610b34573d6000803e3d6000fd5b505050506040513d6020811015610b4a57600080fd5b505180610bdc5750610b5a613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610baf57600080fd5b505afa158015610bc3573d6000803e3d6000fd5b505050506040513d6020811015610bd957600080fd5b50515b610c175760405162461bcd60e51b815260040180806020018281038252602b81526020018061475f602b913960400191505060405180910390fd5b6000610c31610c24610c8d565b429063ffffffff61348816565b9050610c3c816134e9565b610c4582613513565b604080516001600160a01b03841681526020810183905281517f7d5e1cfe55788983acd19d248da36a27c9413e8e43445ed36a76ae0e741a04ed929181900390910190a15050565b6000610abe61353d565b610c9f613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610cf457600080fd5b505afa158015610d08573d6000803e3d6000fd5b505050506040513d6020811015610d1e57600080fd5b5051610d62576040805162461bcd60e51b815260206004820152600e60248201526d4e6f7420676f7665726e616e636560901b604482015290519081900360640190fd5b610d6b81613568565b610d7e610d79610c24612a58565b613592565b50565b600054610100900460ff1680610d9a5750610d9a6135bc565b80610da8575060005460ff16155b610de35760405162461bcd60e51b815260040180806020018281038252602e815260200180614915602e913960400191505060405180910390fd5b600054610100900460ff16158015610e0e576000805460ff1961ff0019909116610100171660011790555b8351610e219060689060208701906146c6565b508251610e359060699060208601906146c6565b50606a805460ff191660ff84161790558015610e57576000805461ff00191690555b50505050565b60355490565b600080610e6e612a62565b6001600160a01b03161415610e8c57610e85612d21565b9050610a93565b610abe610e97612a62565b6001600160a01b03166345d01e4a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ecf57600080fd5b505afa158015610ee3573d6000803e3d6000fd5b505050506040513d6020811015610ef957600080fd5b5051610f03612d21565b9063ffffffff61348816565b6000610f1c8484846135c2565b610f9284610f28613348565b610f8d856040518060600160405280602881526020016148ed602891396001600160a01b038a16600090815260346020526040812090610f66613348565b6001600160a01b03168152602081019190915260400160002054919063ffffffff61372016565b61334c565b5060019392505050565b3332148061102f5750610fad613306565b6001600160a01b031663372c12b1336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561100257600080fd5b505afa158015611016573d6000803e3d6000fd5b505050506040513d602081101561102c57600080fd5b50515b61107b576040805162461bcd60e51b815260206004820152601860248201527720b1b1b2b9b9903232b734b2b2103337b91031b0b63632b960411b604482015290519081900360640190fd5b60cf8054600101908190556000611090610e5d565b116110d8576040805162461bcd60e51b81526020600482015260136024820152725661756c7420686173206e6f2073686172657360681b604482015290519081900360640190fd5b600082116111175760405162461bcd60e51b815260040180806020018281038252602581526020018061497d6025913960400191505060405180910390fd5b6000611121610e5d565b905061112d33846137b7565b60006111578261114b8661113f610e63565b9063ffffffff6138b316565b9063ffffffff61390c16565b9050600061116b8361114b8761113f61394e565b9050611175612d21565b82111561128957828514156111e35761118c612a62565b6001600160a01b031663bfd131f16040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156111c657600080fd5b505af11580156111da573d6000803e3d6000fd5b50505050611266565b60006111fd6111f0612d21565b849063ffffffff61397916565b9050611207612a62565b6001600160a01b031663ce8c42e8826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561124c57600080fd5b505af1158015611260573d6000803e3d6000fd5b50505050505b6112866112798461114b8861113f610e63565b611281612d21565b6139bb565b91505b60006112a96103e861114b61129c613129565b869063ffffffff6138b316565b90506112dd336112bf858463ffffffff61397916565b6112c7611a88565b6001600160a01b0316919063ffffffff6139d116565b6112fd6112f8836112ec61394e565b9063ffffffff61397916565b613a28565b801561137b5761137b61130e613306565b6001600160a01b03166361d027b36040518163ffffffff1660e01b815260040160206040518083038186803b15801561134657600080fd5b505afa15801561135a573d6000803e3d6000fd5b505050506040513d602081101561137057600080fd5b5051826112c7611a88565b60408051848152905133917f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364919081900360200190a25050505060cf54811461140b576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b5050565b606a5460ff1690565b611420613463565b6001600160a01b031663b429afeb336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561147557600080fd5b505afa158015611489573d6000803e3d6000fd5b505050506040513d602081101561149f57600080fd5b50518061153157506114af613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561150457600080fd5b505afa158015611518573d6000803e3d6000fd5b505050506040513d602081101561152e57600080fd5b50515b61156c5760405162461bcd60e51b815260040180806020018281038252602b81526020018061475f602b913960400191505060405180910390fd5b6115758161329b565b6115b05760405162461bcd60e51b815260040180806020018281038252603a815260200180614943603a913960400191505060405180910390fd5b6001600160a01b03811661160b576040805162461bcd60e51b815260206004820152601d60248201527f6e6577205f73747261746567792063616e6e6f7420626520656d707479000000604482015290519081900360640190fd5b611613611a88565b6001600160a01b0316816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561165557600080fd5b505afa158015611669573d6000803e3d6000fd5b505050506040513d602081101561167f57600080fd5b50516001600160a01b0316146116c65760405162461bcd60e51b815260040180806020018281038252602f81526020018061489d602f913960400191505060405180910390fd5b306001600160a01b0316816001600160a01b031663fbfa77cf6040518163ffffffff1660e01b815260040160206040518083038186803b15801561170957600080fd5b505afa15801561171d573d6000803e3d6000fd5b505050506040513d602081101561173357600080fd5b50516001600160a01b03161461177a5760405162461bcd60e51b815260040180806020018281038252602a815260200180614813602a913960400191505060405180910390fd5b7f254c88e7a2ea123aeeb89b7cc413fb949188fefcdb7584c4f3d493294daf65c5816117a4612a62565b604080516001600160a01b03938416815291909216602082015281519081900390910190a16117d1612a62565b6001600160a01b0316816001600160a01b0316146118b15760006117f3612a62565b6001600160a01b0316146118875761182c61180c612a62565b6000611816611a88565b6001600160a01b0316919063ffffffff613a5216565b611834612a62565b6001600160a01b031663bfd131f16040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561186e57600080fd5b505af1158015611882573d6000803e3d6000fd5b505050505b61189081613b65565b61189b61180c612a62565b6118b16118a6612a62565b600019611816611a88565b610d7e613133565b3332148061194c57506118ca613306565b6001600160a01b031663372c12b1336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561191f57600080fd5b505afa158015611933573d6000803e3d6000fd5b505050506040513d602081101561194957600080fd5b50515b611998576040805162461bcd60e51b815260206004820152601860248201527720b1b1b2b9b9903232b734b2b2103337b91031b0b63632b960411b604482015290519081900360640190fd5b61140b823383613b8f565b6000610aaa6119b0613348565b84610f8d85603460006119c1613348565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff61348816565b6000610abe613e7d565b6000610abe613ea8565b6000611a15613463565b6001600160a01b0316635aa6e6756040518163ffffffff1660e01b815260040160206040518083038186803b158015611a4d57600080fd5b505afa158015611a61573d6000803e3d6000fd5b505050506040513d6020811015611a7757600080fd5b5051905090565b6000610abe613ed3565b6000610abe613efe565b6001600160a01b0381166000908152603360205260409020545b919050565b6000611abb610e5d565b15611ae357611ade611acb610e5d565b61114b611ad6610e63565b61113f611a01565b610abe565b610abe611a01565b600054610100900460ff1680611b045750611b046135bc565b80611b12575060005460ff16155b611b4d5760405162461bcd60e51b815260040180806020018281038252602e815260200180614915602e913960400191505060405180910390fd5b600054610100900460ff16158015611b78576000805460ff1961ff0019909116610100171660011790555b611b8189613f29565b611b8a88613f53565b611b9387613f7d565b611b9c85613fa7565b611ba584613fd1565b611bae86613ffb565b611bb783614025565b611bc08261404f565b611bca60006134e9565b611bd46000613513565b8015611be6576000805461ff00191690555b505050505050505050565b611bf9613463565b6001600160a01b031663b429afeb336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611c4e57600080fd5b505afa158015611c62573d6000803e3d6000fd5b505050506040513d6020811015611c7857600080fd5b505180611d0a5750611c88613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611cdd57600080fd5b505afa158015611cf1573d6000803e3d6000fd5b505050506040513d6020811015611d0757600080fd5b50515b611d455760405162461bcd60e51b815260040180806020018281038252602b81526020018061475f602b913960400191505060405180910390fd5b611d4d611e11565b611d55614079565b565b6000610abe61394e565b600054610100900460ff1680611d7a5750611d7a6135bc565b80611d88575060005460ff16155b611dc35760405162461bcd60e51b815260040180806020018281038252602e815260200180614915602e913960400191505060405180910390fd5b600054610100900460ff16158015611dee576000805460ff1961ff0019909116610100171660011790555b600160cf558015610d7e576000805461ff001916905550565b6000610abe614136565b611e19613463565b6001600160a01b031663b429afeb336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611e6e57600080fd5b505afa158015611e82573d6000803e3d6000fd5b505050506040513d6020811015611e9857600080fd5b505180611f2a5750611ea8613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611efd57600080fd5b505afa158015611f11573d6000803e3d6000fd5b505050506040513d6020811015611f2757600080fd5b50515b611f655760405162461bcd60e51b815260040180806020018281038252602b81526020018061475f602b913960400191505060405180910390fd5b6000611f6f612a62565b6001600160a01b03161415611fc6576040805162461bcd60e51b815260206004820152601860248201527714dd1c985d1959de481b5d5cdd081899481919599a5b995960421b604482015290519081900360640190fd5b611fce612a62565b6001600160a01b031663bfd131f16040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561200857600080fd5b505af1158015610e57573d6000803e3d6000fd5b600054610100900460ff168061203557506120356135bc565b80612043575060005460ff16155b61207e5760405162461bcd60e51b815260040180806020018281038252602e815260200180614915602e913960400191505060405180910390fd5b600054610100900460ff161580156120a9576000805460ff1961ff0019909116610100171660011790555b838511156120fe576040805162461bcd60e51b815260206004820152601c60248201527f63616e6e6f7420696e76657374206d6f7265207468616e203130302500000000604482015290519081900360640190fd5b83612145576040805162461bcd60e51b8152602060048201526012602482015271063616e6e6f742064697669646520627920360741b604482015290519081900360640190fd5b6124e3866001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561218157600080fd5b505afa158015612195573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156121be57600080fd5b8101908080516040519392919084600160201b8211156121dd57600080fd5b9083019060208201858111156121f257600080fd5b8251600160201b81118282018810171561220b57600080fd5b82525081516020918201929091019080838360005b83811015612238578181015183820152602001612220565b50505050905090810190601f1680156122655780820380516001836020036101000a031916815260200191505b50604052505050604051602001808065464f5243455f60d01b81525060060182805190602001908083835b602083106122af5780518252601f199092019160209182019101612290565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052876001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561231c57600080fd5b505afa158015612330573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561235957600080fd5b8101908080516040519392919084600160201b82111561237857600080fd5b90830190602082018581111561238d57600080fd5b8251600160201b8111828201881017156123a657600080fd5b82525081516020918201929091019080838360005b838110156123d35781810151838201526020016123bb565b50505050905090810190601f1680156124005780820380516001836020036101000a031916815260200191505b506040525050506040516020018080600f60fb1b81525060010182805190602001908083835b602083106124455780518252601f199092019160209182019101612426565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052886001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156124b257600080fd5b505afa1580156124c6573d6000803e3d6000fd5b505050506040513d60208110156124dc57600080fd5b5051610d81565b6124ec87612d80565b6124f4611d61565b6000866001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561252f57600080fd5b505afa158015612543573d6000803e3d6000fd5b505050506040513d602081101561255957600080fd5b505160ff16600a0a905061a8c080612577898989868a8a8780611aeb565b505050801561258c576000805461ff00191690555b50505050505050565b600061259f610e5d565b6125ab57506000611aac565b610aae6125b6610e5d565b61114b6125c285611a92565b61113f610e63565b6125d2613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561262757600080fd5b505afa15801561263b573d6000803e3d6000fd5b505050506040513d602081101561265157600080fd5b5051612695576040805162461bcd60e51b815260206004820152600e60248201526d4e6f7420676f7665726e616e636560901b604482015290519081900360640190fd5b6001600160a01b0381166126f0576040805162461bcd60e51b815260206004820152601e60248201527f6e65772073746f726167652073686f756c646e277420626520656d7074790000604482015290519081900360640190fd5b610d7e81614161565b6000610abe614185565b60698054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a8b5780601f10610a6057610100808354040283529160200191610a8b565b61276c613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156127c157600080fd5b505afa1580156127d5573d6000803e3d6000fd5b505050506040513d60208110156127eb57600080fd5b505161282f576040805162461bcd60e51b815260206004820152600e60248201526d4e6f7420676f7665726e616e636560901b604482015290519081900360640190fd5b6128396000613568565b611d556000613592565b60008061284e611e07565b15801590612862575061285f611e07565b42115b801561287f57506000612873610ab4565b6001600160a01b031614155b612887610ab4565b915091509091565b6000610aaa61289c613348565b84610f8d85604051806060016040528060258152602001614a6c60259139603460006128c6613348565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61372016565b612905613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561295a57600080fd5b505afa15801561296e573d6000803e3d6000fd5b505050506040513d602081101561298457600080fd5b50516129c8576040805162461bcd60e51b815260206004820152600e60248201526d4e6f7420676f7665726e616e636560901b604482015290519081900360640190fd5b60008111612a075760405162461bcd60e51b81526004018080602001828103825260228152602001806147ad6022913960400191505060405180910390fd5b80821115612a465760405162461bcd60e51b815260040180806020018281038252603a81526020018061483d603a913960400191505060405180910390fd5b612a4f82613f53565b61140b81613f7d565b6000610abe6141b0565b6000610abe6141db565b6000610aaa612a79613348565b84846135c2565b6000610abe614206565b600080612aa3612a986132fc565b61114b6125c26119f7565b90506000612aaf612a62565b6001600160a01b03166345d01e4a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ae757600080fd5b505afa158015612afb573d6000803e3d6000fd5b505050506040513d6020811015612b1157600080fd5b50519050818110612b2757600092505050610a93565b6000612b39838363ffffffff61397916565b9050612b43612d21565b811115612b5757612b52612d21565b612b59565b805b9350505050610a93565b612b6b613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612bc057600080fd5b505afa158015612bd4573d6000803e3d6000fd5b505050506040513d6020811015612bea57600080fd5b5051612c2e576040805162461bcd60e51b815260206004820152600e60248201526d4e6f7420676f7665726e616e636560901b604482015290519081900360640190fd5b610d7e81613fa7565b33321480612cca5750612c48613306565b6001600160a01b031663372c12b1336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612c9d57600080fd5b505afa158015612cb1573d6000803e3d6000fd5b505050506040513d6020811015612cc757600080fd5b50515b612d16576040805162461bcd60e51b815260206004820152601860248201527720b1b1b2b9b9903232b734b2b2103337b91031b0b63632b960411b604482015290519081900360640190fd5b610d7e813333613b8f565b6000612d2b611a88565b6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611a4d57600080fd5b600054610100900460ff1680612d995750612d996135bc565b80612da7575060005460ff16155b612de25760405162461bcd60e51b815260040180806020018281038252602e815260200180614915602e913960400191505060405180910390fd5b600054610100900460ff16158015612e0d576000805460ff1961ff0019909116610100171660011790555b612e1682614231565b801561140b576000805461ff00191690555050565b6000612e35612a62565b6001600160a01b03161415612e8c576040805162461bcd60e51b815260206004820152601860248201527714dd1c985d1959de481b5d5cdd081899481919599a5b995960421b604482015290519081900360640190fd5b612e94613463565b6001600160a01b031663b429afeb336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612ee957600080fd5b505afa158015612efd573d6000803e3d6000fd5b505050506040513d6020811015612f1357600080fd5b505180612fa55750612f23613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612f7857600080fd5b505afa158015612f8c573d6000803e3d6000fd5b505050506040513d6020811015612fa257600080fd5b50515b612fe05760405162461bcd60e51b815260040180806020018281038252602b81526020018061475f602b913960400191505060405180910390fd5b612fe8614079565b612ff0612a62565b6001600160a01b031663cca7f4756040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561200857600080fd5b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b61305d613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156130b257600080fd5b505afa1580156130c6573d6000803e3d6000fd5b505050506040513d60208110156130dc57600080fd5b5051613120576040805162461bcd60e51b815260206004820152600e60248201526d4e6f7420676f7665726e616e636560901b604482015290519081900360640190fd5b610d7e81613fd1565b6000610abe6142c7565b61313b613463565b6001600160a01b031663b429afeb336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561319057600080fd5b505afa1580156131a4573d6000803e3d6000fd5b505050506040513d60208110156131ba57600080fd5b50518061324c57506131ca613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561321f57600080fd5b505afa158015613233573d6000803e3d6000fd5b505050506040513d602081101561324957600080fd5b50515b6132875760405162461bcd60e51b815260040180806020018281038252602b81526020018061475f602b913960400191505060405180910390fd5b61329160006134e9565b611d556000613513565b6000806132a6612a62565b6001600160a01b03161480610aae57506132be611a7e565b6001600160a01b0316826001600160a01b03161480156132e457506132e1612a80565b42115b8015610aae575060006132f5612a80565b1192915050565b6000610abe6142f2565b6000613310613463565b6001600160a01b031663f77c47916040518163ffffffff1660e01b815260040160206040518083038186803b158015611a4d57600080fd5b3390565b6001600160a01b0383166133915760405162461bcd60e51b81526004018080602001828103825260248152602001806149e86024913960400191505060405180910390fd5b6001600160a01b0382166133d65760405162461bcd60e51b81526004018080602001828103825260228152602001806147f16022913960400191505060405180910390fd5b6001600160a01b03808416600081815260346020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6000610abe7fb1acf527cd7cd1668b30e5a9a1c0d845714604de29ce560150922c9d8c0937df614319565b7fa7ec62784904ff31cbcc32d09932a58e7f1e4476e1d041995b37c917990b16dc5490565b6000828201838110156134e2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b610d7e7f56e7c0e75875c6497f0de657009613a32558904b5c10771a825cc330feff7e728261431d565b610d7e7fb441b53a4e42c2ca9182bc7ede99bedba7a5d9360d9dfbd31fa8ee2dc85906108261431d565b6000610abe7f6d02338b2e4c913c0f7d380e2798409838a48a2c4d57d52742a808c82d713d8b614319565b610d7e7fb1acf527cd7cd1668b30e5a9a1c0d845714604de29ce560150922c9d8c0937df8261431d565b610d7e7f3bc747f4b148b37be485de3223c90b4468252967d2ea7f9fcbd8b6e653f434c98261431d565b303b1590565b6001600160a01b0383166136075760405162461bcd60e51b81526004018080602001828103825260258152602001806149c36025913960400191505060405180910390fd5b6001600160a01b03821661364c5760405162461bcd60e51b815260040180806020018281038252602381526020018061478a6023913960400191505060405180910390fd5b61368f81604051806060016040528060268152602001614877602691396001600160a01b038616600090815260336020526040902054919063ffffffff61372016565b6001600160a01b0380851660009081526033602052604080822093909355908416815220546136c4908263ffffffff61348816565b6001600160a01b0380841660008181526033602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156137af5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561377457818101518382015260200161375c565b50505050905090810190601f1680156137a15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6001600160a01b0382166137fc5760405162461bcd60e51b81526004018080602001828103825260218152602001806149a26021913960400191505060405180910390fd5b61383f816040518060600160405280602281526020016147cf602291396001600160a01b038516600090815260336020526040902054919063ffffffff61372016565b6001600160a01b03831660009081526033602052604090205560355461386b908263ffffffff61397916565b6035556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6000826138c257506000610aae565b828202828482816138cf57fe5b04146134e25760405162461bcd60e51b81526004018080602001828103825260218152602001806148cc6021913960400191505060405180910390fd5b60006134e283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614321565b6000610abe7faf765835ed5af0d235b6c686724ad31fa90e06b3daf1c074d6cc398b8fcef213614319565b60006134e283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613720565b60008183106139ca57816134e2565b5090919050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052613a23908490614386565b505050565b610d7e7faf765835ed5af0d235b6c686724ad31fa90e06b3daf1c074d6cc398b8fcef2138261431d565b801580613ad8575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015613aaa57600080fd5b505afa158015613abe573d6000803e3d6000fd5b505050506040513d6020811015613ad457600080fd5b5051155b613b135760405162461bcd60e51b8152600401808060200182810382526036815260200180614a366036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052613a23908490614386565b610d7e7ff1a169aa0f736c2813818fdfbdc5755c31e0839c8f49831a16543496b28574ea8261431d565b60cf80546001019081905583613bdf576040805162461bcd60e51b815260206004820152601060248201526f043616e6e6f74206465706f73697420360841b604482015290519081900360640190fd5b6001600160a01b038216613c33576040805162461bcd60e51b81526020600482015260166024820152751a1bdb19195c881b5d5cdd081899481919599a5b995960521b604482015290519081900360640190fd5b613c3b6126f9565b1580613c595750613c4a6126f9565b613c5685610f03611d57565b11155b613caa576040805162461bcd60e51b815260206004820152601c60248201527f43616e6e6f74206465706f736974206d6f7265207468616e2063617000000000604482015290519081900360640190fd5b6000613cb4612a62565b6001600160a01b031614613d6e57613cca612a62565b6001600160a01b031663c2a2a07b6040518163ffffffff1660e01b815260040160206040518083038186803b158015613d0257600080fd5b505afa158015613d16573d6000803e3d6000fd5b505050506040513d6020811015613d2c57600080fd5b5051613d6e576040805162461bcd60e51b815260206004820152600c60248201526b2a37b79036bab1b41030b93160a11b604482015290519081900360640190fd5b6000613d78610e5d565b15613da557613da0613d88610e63565b61114b613d93610e5d565b889063ffffffff6138b316565b613da7565b845b9050613db3838261453e565b613dd8843087613dc1611a88565b6001600160a01b031692919063ffffffff61463016565b613de76112f886610f0361394e565b6040805186815290516001600160a01b038516917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a25060cf548114610e57576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6000610abe7f39122c9adfb653455d0c05043bd52fcfbc2be864e832efd3abc72ce5a3d7ed5a614319565b6000610abe7fa66bc57d4b4eed7c7687876ca77997588987307cb13ecc23f5e52725192e5fff614319565b6000610abe7fb441b53a4e42c2ca9182bc7ede99bedba7a5d9360d9dfbd31fa8ee2dc8590610614319565b6000610abe7f1994607607e11d53306ef62e45e3bd85762c58d9bf38b5578bc4a258a26a7371614319565b610d7e7f1994607607e11d53306ef62e45e3bd85762c58d9bf38b5578bc4a258a26a73718261431d565b610d7e7f39122c9adfb653455d0c05043bd52fcfbc2be864e832efd3abc72ce5a3d7ed5a8261431d565b610d7e7f469a3bad2fab7b936c45eecd1f5da52af89cead3e2ed7f732b6f3fc92ed323088261431d565b610d7e7f3405c96d34f8f0e36eac648034ca7e687437f795bbdbdc2cb7db90a89d519f578261431d565b610d7e7f0df75d4bdb87be8e3e04e1dc08ec1c98ed6c4147138e5789f0bd448c5c8e1e288261431d565b610d7e7fa66bc57d4b4eed7c7687876ca77997588987307cb13ecc23f5e52725192e5fff8261431d565b610d7e7f82ddc3be3f0c1a6870327f78f4979a0b37b21b16736ef5be6a7a7a35e530bcf08261431d565b610d7e7f6d02338b2e4c913c0f7d380e2798409838a48a2c4d57d52742a808c82d713d8b8261431d565b6000614083612a62565b6001600160a01b031614156140da576040805162461bcd60e51b815260206004820152601860248201527714dd1c985d1959de481b5d5cdd081899481919599a5b995960421b604482015290519081900360640190fd5b60006140e4612a8a565b90508015610d7e576141006140f7612a62565b826112c7611a88565b6040805182815290517fa09b7ae452b7bffb9e204c3a016e80caeecf46f554d112644f36fa114dac6ffa9181900360200190a150565b6000610abe7f3bc747f4b148b37be485de3223c90b4468252967d2ea7f9fcbd8b6e653f434c9614319565b7fa7ec62784904ff31cbcc32d09932a58e7f1e4476e1d041995b37c917990b16dc55565b6000610abe7f0df75d4bdb87be8e3e04e1dc08ec1c98ed6c4147138e5789f0bd448c5c8e1e28614319565b6000610abe7f82ddc3be3f0c1a6870327f78f4979a0b37b21b16736ef5be6a7a7a35e530bcf0614319565b6000610abe7ff1a169aa0f736c2813818fdfbdc5755c31e0839c8f49831a16543496b28574ea614319565b6000610abe7f56e7c0e75875c6497f0de657009613a32558904b5c10771a825cc330feff7e72614319565b600054610100900460ff168061424a575061424a6135bc565b80614258575060005460ff16155b6142935760405162461bcd60e51b815260040180806020018281038252602e815260200180614915602e913960400191505060405180910390fd5b600054610100900460ff161580156142be576000805460ff1961ff0019909116610100171660011790555b612e1682614161565b6000610abe7f3405c96d34f8f0e36eac648034ca7e687437f795bbdbdc2cb7db90a89d519f57614319565b6000610abe7f469a3bad2fab7b936c45eecd1f5da52af89cead3e2ed7f732b6f3fc92ed323085b5490565b9055565b600081836143705760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561377457818101518382015260200161375c565b50600083858161437c57fe5b0495945050505050565b614398826001600160a01b031661468a565b6143e9576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106144275780518252601f199092019160209182019101614408565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614489576040519150601f19603f3d011682016040523d82523d6000602084013e61448e565b606091505b5091509150816144e5576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610e575780806020019051602081101561450157600080fd5b5051610e575760405162461bcd60e51b815260040180806020018281038252602a815260200180614a0c602a913960400191505060405180910390fd5b6001600160a01b038216614599576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6035546145ac908263ffffffff61348816565b6035556001600160a01b0382166000908152603360205260409020546145d8908263ffffffff61348816565b6001600160a01b03831660008181526033602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610e57908590614386565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906146be57508115155b949350505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061470757805160ff1916838001178555614734565b82800160010185558215614734579182015b82811115614734578251825591602001919060010190614719565b50614740929150614744565b5090565b610a9391905b80821115614740576000815560010161474a56fe5468652063616c6c6572206d75737420626520636f6e74726f6c6c6572206f7220676f7665726e616e636545524332303a207472616e7366657220746f20746865207a65726f206164647265737364656e6f6d696e61746f72206d7573742062652067726561746572207468616e203045524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737374686520737472617465677920646f6573206e6f742062656c6f6e6720746f2074686973207661756c7464656e6f6d696e61746f72206d7573742062652067726561746572207468616e206f7220657175616c20746f20746865206e756d657261746f7245524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e63655661756c7420756e6465726c79696e67206d757374206d6174636820537472617465677920756e6465726c79696e67536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65645468652073747261746567792065786973747320616e64207377697463682074696d656c6f636b20646964206e6f7420656c61707365207965746e756d6265724f66536861726573206d7573742062652067726561746572207468616e203045524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a72315820b639d37bc996244d20a0a966c47be0246bbcced3531f861e417fda2889085f2664736f6c63430005100032656970313936372e7661756c7453746f726167652e6d61784465706f736974436170656970313936372e7661756c7453746f726167652e7661756c744672616374696f6e546f496e766573744e756d657261746f72656970313936372e7661756c7453746f726167652e6e657874496d706c656d656e746174696f6e54696d657374616d70656970313936372e7661756c7453746f726167652e7661756c744672616374696f6e546f496e7665737444656e6f6d696e61746f72656970313936372e7661756c7453746f726167652e737472617465677955706461746554696d65656970313936372e7661756c7453746f726167652e737472617465677954696d654c6f636b656970313936372e7661756c7453746f726167652e6e657874496d706c656d656e746174696f6e44656c6179656970313936372e7661756c7453746f726167652e756e6465726c79696e67556e6974656970313936372e7661756c7453746f726167652e746f74616c4465706f73697473656970313936372e7661756c7453746f726167652e6e657874496d706c656d656e746174696f6e656970313936372e7661756c7453746f726167652e6675747572655374726174656779
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103425760003560e01c8063853828b6116101b8578063aa04462511610104578063dd62ed3e116100a2578063eda199aa1161007c578063eda199aa146109c1578063f0cf91e7146109c9578063f2768c1e146109ef578063f77c4791146109f757610342565b8063dd62ed3e1461096e578063dfed91601461099c578063e941fa78146109b957610342565b8063b6b55f25116100de578063b6b55f251461091b578063c2baf35614610938578063c4d66de814610940578063cca7f4751461096657610342565b8063aa044625146108ee578063b592c390146108f6578063b6ac642a146108fe57610342565b80639a508c8e11610171578063a5b1a24d1161014b578063a5b1a24d1461088f578063a8365693146108b2578063a8c62e76146108ba578063a9059cbb146108c257610342565b80639a508c8e146108305780639d16acfd14610838578063a457c2d71461086357610342565b8063853828b614610784578063871de9fd1461078c5780638cb1d67f146107d45780639137c1a7146107fa5780639546cc531461082057806395d89b411461082857610342565b806336efd16f1161029257806370a08231116102305780637d7c2a1c1161020a5780637d7c2a1c146107645780637d8820971461076c5780638129fc1c1461077457806382de9c1b1461077c57610342565b806370a08231146106e557806377c7b8fc1461070b5780637ca5fc9d1461071357610342565b806353ceb01c1161026c57806353ceb01c146106c55780635aa6e675146106cd5780635fe51e6d146106d55780636f307dc3146106dd57610342565b806336efd16f1461066557806339509351146106915780634af1758b146106bd57610342565b80631624f6c6116102ff57806323b872dd116102d957806323b872dd146105ce5780632e1a7d4d14610604578063313ce5671461062157806333a100ca1461063f57610342565b80631624f6c61461049057806318160ddd146105be5780631bf8e7be146105c657610342565b806306fdde0314610347578063095ea7b3146103c457806309ff18f0146104045780630a6bbeb3146104285780630ad2239d146104505780630c80447a1461046a575b600080fd5b61034f6109ff565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610389578181015183820152602001610371565b50505050905090810190601f1680156103b65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103f0600480360360408110156103da57600080fd5b506001600160a01b038135169060200135610a96565b604080519115158252519081900360200190f35b61040c610ab4565b604080516001600160a01b039092168252519081900360200190f35b61044e6004803603602081101561043e57600080fd5b50356001600160a01b0316610ac3565b005b610458610c8d565b60408051918252519081900360200190f35b61044e6004803603602081101561048057600080fd5b50356001600160a01b0316610c97565b61044e600480360360608110156104a657600080fd5b810190602081018135600160201b8111156104c057600080fd5b8201836020820111156104d257600080fd5b803590602001918460018302840111600160201b831117156104f357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561054557600080fd5b82018360208201111561055757600080fd5b803590602001918460018302840111600160201b8311171561057857600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050903560ff169150610d819050565b610458610e5d565b610458610e63565b6103f0600480360360608110156105e457600080fd5b506001600160a01b03813581169160208101359091169060400135610f0f565b61044e6004803603602081101561061a57600080fd5b5035610f9c565b61062961140f565b6040805160ff9092168252519081900360200190f35b61044e6004803603602081101561065557600080fd5b50356001600160a01b0316611418565b61044e6004803603604081101561067b57600080fd5b50803590602001356001600160a01b03166118b9565b6103f0600480360360408110156106a757600080fd5b506001600160a01b0381351690602001356119a3565b6104586119f7565b610458611a01565b61040c611a0b565b61040c611a7e565b61040c611a88565b610458600480360360208110156106fb57600080fd5b50356001600160a01b0316611a92565b610458611ab1565b61044e600480360361010081101561072a57600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a08101359060c08101359060e00135611aeb565b61044e611bf1565b610458611d57565b61044e611d61565b610458611e07565b61044e611e11565b61044e600480360360c08110156107a257600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060808101359060a0013561201c565b610458600480360360208110156107ea57600080fd5b50356001600160a01b0316612595565b61044e6004803603602081101561081057600080fd5b50356001600160a01b03166125ca565b6104586126f9565b61034f612703565b61044e612764565b610840612843565b6040805192151583526001600160a01b0390911660208301528051918290030190f35b6103f06004803603604081101561087957600080fd5b506001600160a01b03813516906020013561288f565b61044e600480360360408110156108a557600080fd5b50803590602001356128fd565b610458612a58565b61040c612a62565b6103f0600480360360408110156108d857600080fd5b506001600160a01b038135169060200135612a6c565b610458612a80565b610458612a8a565b61044e6004803603602081101561091457600080fd5b5035612b63565b61044e6004803603602081101561093157600080fd5b5035612c37565b610458612d21565b61044e6004803603602081101561095657600080fd5b50356001600160a01b0316612d80565b61044e612e2b565b6104586004803603604081101561098457600080fd5b506001600160a01b038135811691602001351661302a565b61044e600480360360208110156109b257600080fd5b5035613055565b610458613129565b61044e613133565b6103f0600480360360208110156109df57600080fd5b50356001600160a01b031661329b565b6104586132fc565b61040c613306565b60688054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a8b5780601f10610a6057610100808354040283529160200191610a8b565b820191906000526020600020905b815481529060010190602001808311610a6e57829003601f168201915b505050505090505b90565b6000610aaa610aa3613348565b848461334c565b5060015b92915050565b6000610abe613438565b905090565b610acb613463565b6001600160a01b031663b429afeb336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610b2057600080fd5b505afa158015610b34573d6000803e3d6000fd5b505050506040513d6020811015610b4a57600080fd5b505180610bdc5750610b5a613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610baf57600080fd5b505afa158015610bc3573d6000803e3d6000fd5b505050506040513d6020811015610bd957600080fd5b50515b610c175760405162461bcd60e51b815260040180806020018281038252602b81526020018061475f602b913960400191505060405180910390fd5b6000610c31610c24610c8d565b429063ffffffff61348816565b9050610c3c816134e9565b610c4582613513565b604080516001600160a01b03841681526020810183905281517f7d5e1cfe55788983acd19d248da36a27c9413e8e43445ed36a76ae0e741a04ed929181900390910190a15050565b6000610abe61353d565b610c9f613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610cf457600080fd5b505afa158015610d08573d6000803e3d6000fd5b505050506040513d6020811015610d1e57600080fd5b5051610d62576040805162461bcd60e51b815260206004820152600e60248201526d4e6f7420676f7665726e616e636560901b604482015290519081900360640190fd5b610d6b81613568565b610d7e610d79610c24612a58565b613592565b50565b600054610100900460ff1680610d9a5750610d9a6135bc565b80610da8575060005460ff16155b610de35760405162461bcd60e51b815260040180806020018281038252602e815260200180614915602e913960400191505060405180910390fd5b600054610100900460ff16158015610e0e576000805460ff1961ff0019909116610100171660011790555b8351610e219060689060208701906146c6565b508251610e359060699060208601906146c6565b50606a805460ff191660ff84161790558015610e57576000805461ff00191690555b50505050565b60355490565b600080610e6e612a62565b6001600160a01b03161415610e8c57610e85612d21565b9050610a93565b610abe610e97612a62565b6001600160a01b03166345d01e4a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ecf57600080fd5b505afa158015610ee3573d6000803e3d6000fd5b505050506040513d6020811015610ef957600080fd5b5051610f03612d21565b9063ffffffff61348816565b6000610f1c8484846135c2565b610f9284610f28613348565b610f8d856040518060600160405280602881526020016148ed602891396001600160a01b038a16600090815260346020526040812090610f66613348565b6001600160a01b03168152602081019190915260400160002054919063ffffffff61372016565b61334c565b5060019392505050565b3332148061102f5750610fad613306565b6001600160a01b031663372c12b1336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561100257600080fd5b505afa158015611016573d6000803e3d6000fd5b505050506040513d602081101561102c57600080fd5b50515b61107b576040805162461bcd60e51b815260206004820152601860248201527720b1b1b2b9b9903232b734b2b2103337b91031b0b63632b960411b604482015290519081900360640190fd5b60cf8054600101908190556000611090610e5d565b116110d8576040805162461bcd60e51b81526020600482015260136024820152725661756c7420686173206e6f2073686172657360681b604482015290519081900360640190fd5b600082116111175760405162461bcd60e51b815260040180806020018281038252602581526020018061497d6025913960400191505060405180910390fd5b6000611121610e5d565b905061112d33846137b7565b60006111578261114b8661113f610e63565b9063ffffffff6138b316565b9063ffffffff61390c16565b9050600061116b8361114b8761113f61394e565b9050611175612d21565b82111561128957828514156111e35761118c612a62565b6001600160a01b031663bfd131f16040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156111c657600080fd5b505af11580156111da573d6000803e3d6000fd5b50505050611266565b60006111fd6111f0612d21565b849063ffffffff61397916565b9050611207612a62565b6001600160a01b031663ce8c42e8826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561124c57600080fd5b505af1158015611260573d6000803e3d6000fd5b50505050505b6112866112798461114b8861113f610e63565b611281612d21565b6139bb565b91505b60006112a96103e861114b61129c613129565b869063ffffffff6138b316565b90506112dd336112bf858463ffffffff61397916565b6112c7611a88565b6001600160a01b0316919063ffffffff6139d116565b6112fd6112f8836112ec61394e565b9063ffffffff61397916565b613a28565b801561137b5761137b61130e613306565b6001600160a01b03166361d027b36040518163ffffffff1660e01b815260040160206040518083038186803b15801561134657600080fd5b505afa15801561135a573d6000803e3d6000fd5b505050506040513d602081101561137057600080fd5b5051826112c7611a88565b60408051848152905133917f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364919081900360200190a25050505060cf54811461140b576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b5050565b606a5460ff1690565b611420613463565b6001600160a01b031663b429afeb336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561147557600080fd5b505afa158015611489573d6000803e3d6000fd5b505050506040513d602081101561149f57600080fd5b50518061153157506114af613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561150457600080fd5b505afa158015611518573d6000803e3d6000fd5b505050506040513d602081101561152e57600080fd5b50515b61156c5760405162461bcd60e51b815260040180806020018281038252602b81526020018061475f602b913960400191505060405180910390fd5b6115758161329b565b6115b05760405162461bcd60e51b815260040180806020018281038252603a815260200180614943603a913960400191505060405180910390fd5b6001600160a01b03811661160b576040805162461bcd60e51b815260206004820152601d60248201527f6e6577205f73747261746567792063616e6e6f7420626520656d707479000000604482015290519081900360640190fd5b611613611a88565b6001600160a01b0316816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561165557600080fd5b505afa158015611669573d6000803e3d6000fd5b505050506040513d602081101561167f57600080fd5b50516001600160a01b0316146116c65760405162461bcd60e51b815260040180806020018281038252602f81526020018061489d602f913960400191505060405180910390fd5b306001600160a01b0316816001600160a01b031663fbfa77cf6040518163ffffffff1660e01b815260040160206040518083038186803b15801561170957600080fd5b505afa15801561171d573d6000803e3d6000fd5b505050506040513d602081101561173357600080fd5b50516001600160a01b03161461177a5760405162461bcd60e51b815260040180806020018281038252602a815260200180614813602a913960400191505060405180910390fd5b7f254c88e7a2ea123aeeb89b7cc413fb949188fefcdb7584c4f3d493294daf65c5816117a4612a62565b604080516001600160a01b03938416815291909216602082015281519081900390910190a16117d1612a62565b6001600160a01b0316816001600160a01b0316146118b15760006117f3612a62565b6001600160a01b0316146118875761182c61180c612a62565b6000611816611a88565b6001600160a01b0316919063ffffffff613a5216565b611834612a62565b6001600160a01b031663bfd131f16040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561186e57600080fd5b505af1158015611882573d6000803e3d6000fd5b505050505b61189081613b65565b61189b61180c612a62565b6118b16118a6612a62565b600019611816611a88565b610d7e613133565b3332148061194c57506118ca613306565b6001600160a01b031663372c12b1336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561191f57600080fd5b505afa158015611933573d6000803e3d6000fd5b505050506040513d602081101561194957600080fd5b50515b611998576040805162461bcd60e51b815260206004820152601860248201527720b1b1b2b9b9903232b734b2b2103337b91031b0b63632b960411b604482015290519081900360640190fd5b61140b823383613b8f565b6000610aaa6119b0613348565b84610f8d85603460006119c1613348565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff61348816565b6000610abe613e7d565b6000610abe613ea8565b6000611a15613463565b6001600160a01b0316635aa6e6756040518163ffffffff1660e01b815260040160206040518083038186803b158015611a4d57600080fd5b505afa158015611a61573d6000803e3d6000fd5b505050506040513d6020811015611a7757600080fd5b5051905090565b6000610abe613ed3565b6000610abe613efe565b6001600160a01b0381166000908152603360205260409020545b919050565b6000611abb610e5d565b15611ae357611ade611acb610e5d565b61114b611ad6610e63565b61113f611a01565b610abe565b610abe611a01565b600054610100900460ff1680611b045750611b046135bc565b80611b12575060005460ff16155b611b4d5760405162461bcd60e51b815260040180806020018281038252602e815260200180614915602e913960400191505060405180910390fd5b600054610100900460ff16158015611b78576000805460ff1961ff0019909116610100171660011790555b611b8189613f29565b611b8a88613f53565b611b9387613f7d565b611b9c85613fa7565b611ba584613fd1565b611bae86613ffb565b611bb783614025565b611bc08261404f565b611bca60006134e9565b611bd46000613513565b8015611be6576000805461ff00191690555b505050505050505050565b611bf9613463565b6001600160a01b031663b429afeb336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611c4e57600080fd5b505afa158015611c62573d6000803e3d6000fd5b505050506040513d6020811015611c7857600080fd5b505180611d0a5750611c88613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611cdd57600080fd5b505afa158015611cf1573d6000803e3d6000fd5b505050506040513d6020811015611d0757600080fd5b50515b611d455760405162461bcd60e51b815260040180806020018281038252602b81526020018061475f602b913960400191505060405180910390fd5b611d4d611e11565b611d55614079565b565b6000610abe61394e565b600054610100900460ff1680611d7a5750611d7a6135bc565b80611d88575060005460ff16155b611dc35760405162461bcd60e51b815260040180806020018281038252602e815260200180614915602e913960400191505060405180910390fd5b600054610100900460ff16158015611dee576000805460ff1961ff0019909116610100171660011790555b600160cf558015610d7e576000805461ff001916905550565b6000610abe614136565b611e19613463565b6001600160a01b031663b429afeb336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611e6e57600080fd5b505afa158015611e82573d6000803e3d6000fd5b505050506040513d6020811015611e9857600080fd5b505180611f2a5750611ea8613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611efd57600080fd5b505afa158015611f11573d6000803e3d6000fd5b505050506040513d6020811015611f2757600080fd5b50515b611f655760405162461bcd60e51b815260040180806020018281038252602b81526020018061475f602b913960400191505060405180910390fd5b6000611f6f612a62565b6001600160a01b03161415611fc6576040805162461bcd60e51b815260206004820152601860248201527714dd1c985d1959de481b5d5cdd081899481919599a5b995960421b604482015290519081900360640190fd5b611fce612a62565b6001600160a01b031663bfd131f16040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561200857600080fd5b505af1158015610e57573d6000803e3d6000fd5b600054610100900460ff168061203557506120356135bc565b80612043575060005460ff16155b61207e5760405162461bcd60e51b815260040180806020018281038252602e815260200180614915602e913960400191505060405180910390fd5b600054610100900460ff161580156120a9576000805460ff1961ff0019909116610100171660011790555b838511156120fe576040805162461bcd60e51b815260206004820152601c60248201527f63616e6e6f7420696e76657374206d6f7265207468616e203130302500000000604482015290519081900360640190fd5b83612145576040805162461bcd60e51b8152602060048201526012602482015271063616e6e6f742064697669646520627920360741b604482015290519081900360640190fd5b6124e3866001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561218157600080fd5b505afa158015612195573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156121be57600080fd5b8101908080516040519392919084600160201b8211156121dd57600080fd5b9083019060208201858111156121f257600080fd5b8251600160201b81118282018810171561220b57600080fd5b82525081516020918201929091019080838360005b83811015612238578181015183820152602001612220565b50505050905090810190601f1680156122655780820380516001836020036101000a031916815260200191505b50604052505050604051602001808065464f5243455f60d01b81525060060182805190602001908083835b602083106122af5780518252601f199092019160209182019101612290565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052876001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561231c57600080fd5b505afa158015612330573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561235957600080fd5b8101908080516040519392919084600160201b82111561237857600080fd5b90830190602082018581111561238d57600080fd5b8251600160201b8111828201881017156123a657600080fd5b82525081516020918201929091019080838360005b838110156123d35781810151838201526020016123bb565b50505050905090810190601f1680156124005780820380516001836020036101000a031916815260200191505b506040525050506040516020018080600f60fb1b81525060010182805190602001908083835b602083106124455780518252601f199092019160209182019101612426565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052886001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156124b257600080fd5b505afa1580156124c6573d6000803e3d6000fd5b505050506040513d60208110156124dc57600080fd5b5051610d81565b6124ec87612d80565b6124f4611d61565b6000866001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561252f57600080fd5b505afa158015612543573d6000803e3d6000fd5b505050506040513d602081101561255957600080fd5b505160ff16600a0a905061a8c080612577898989868a8a8780611aeb565b505050801561258c576000805461ff00191690555b50505050505050565b600061259f610e5d565b6125ab57506000611aac565b610aae6125b6610e5d565b61114b6125c285611a92565b61113f610e63565b6125d2613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561262757600080fd5b505afa15801561263b573d6000803e3d6000fd5b505050506040513d602081101561265157600080fd5b5051612695576040805162461bcd60e51b815260206004820152600e60248201526d4e6f7420676f7665726e616e636560901b604482015290519081900360640190fd5b6001600160a01b0381166126f0576040805162461bcd60e51b815260206004820152601e60248201527f6e65772073746f726167652073686f756c646e277420626520656d7074790000604482015290519081900360640190fd5b610d7e81614161565b6000610abe614185565b60698054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a8b5780601f10610a6057610100808354040283529160200191610a8b565b61276c613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156127c157600080fd5b505afa1580156127d5573d6000803e3d6000fd5b505050506040513d60208110156127eb57600080fd5b505161282f576040805162461bcd60e51b815260206004820152600e60248201526d4e6f7420676f7665726e616e636560901b604482015290519081900360640190fd5b6128396000613568565b611d556000613592565b60008061284e611e07565b15801590612862575061285f611e07565b42115b801561287f57506000612873610ab4565b6001600160a01b031614155b612887610ab4565b915091509091565b6000610aaa61289c613348565b84610f8d85604051806060016040528060258152602001614a6c60259139603460006128c6613348565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61372016565b612905613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561295a57600080fd5b505afa15801561296e573d6000803e3d6000fd5b505050506040513d602081101561298457600080fd5b50516129c8576040805162461bcd60e51b815260206004820152600e60248201526d4e6f7420676f7665726e616e636560901b604482015290519081900360640190fd5b60008111612a075760405162461bcd60e51b81526004018080602001828103825260228152602001806147ad6022913960400191505060405180910390fd5b80821115612a465760405162461bcd60e51b815260040180806020018281038252603a81526020018061483d603a913960400191505060405180910390fd5b612a4f82613f53565b61140b81613f7d565b6000610abe6141b0565b6000610abe6141db565b6000610aaa612a79613348565b84846135c2565b6000610abe614206565b600080612aa3612a986132fc565b61114b6125c26119f7565b90506000612aaf612a62565b6001600160a01b03166345d01e4a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ae757600080fd5b505afa158015612afb573d6000803e3d6000fd5b505050506040513d6020811015612b1157600080fd5b50519050818110612b2757600092505050610a93565b6000612b39838363ffffffff61397916565b9050612b43612d21565b811115612b5757612b52612d21565b612b59565b805b9350505050610a93565b612b6b613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612bc057600080fd5b505afa158015612bd4573d6000803e3d6000fd5b505050506040513d6020811015612bea57600080fd5b5051612c2e576040805162461bcd60e51b815260206004820152600e60248201526d4e6f7420676f7665726e616e636560901b604482015290519081900360640190fd5b610d7e81613fa7565b33321480612cca5750612c48613306565b6001600160a01b031663372c12b1336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612c9d57600080fd5b505afa158015612cb1573d6000803e3d6000fd5b505050506040513d6020811015612cc757600080fd5b50515b612d16576040805162461bcd60e51b815260206004820152601860248201527720b1b1b2b9b9903232b734b2b2103337b91031b0b63632b960411b604482015290519081900360640190fd5b610d7e813333613b8f565b6000612d2b611a88565b6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611a4d57600080fd5b600054610100900460ff1680612d995750612d996135bc565b80612da7575060005460ff16155b612de25760405162461bcd60e51b815260040180806020018281038252602e815260200180614915602e913960400191505060405180910390fd5b600054610100900460ff16158015612e0d576000805460ff1961ff0019909116610100171660011790555b612e1682614231565b801561140b576000805461ff00191690555050565b6000612e35612a62565b6001600160a01b03161415612e8c576040805162461bcd60e51b815260206004820152601860248201527714dd1c985d1959de481b5d5cdd081899481919599a5b995960421b604482015290519081900360640190fd5b612e94613463565b6001600160a01b031663b429afeb336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612ee957600080fd5b505afa158015612efd573d6000803e3d6000fd5b505050506040513d6020811015612f1357600080fd5b505180612fa55750612f23613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612f7857600080fd5b505afa158015612f8c573d6000803e3d6000fd5b505050506040513d6020811015612fa257600080fd5b50515b612fe05760405162461bcd60e51b815260040180806020018281038252602b81526020018061475f602b913960400191505060405180910390fd5b612fe8614079565b612ff0612a62565b6001600160a01b031663cca7f4756040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561200857600080fd5b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b61305d613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156130b257600080fd5b505afa1580156130c6573d6000803e3d6000fd5b505050506040513d60208110156130dc57600080fd5b5051613120576040805162461bcd60e51b815260206004820152600e60248201526d4e6f7420676f7665726e616e636560901b604482015290519081900360640190fd5b610d7e81613fd1565b6000610abe6142c7565b61313b613463565b6001600160a01b031663b429afeb336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561319057600080fd5b505afa1580156131a4573d6000803e3d6000fd5b505050506040513d60208110156131ba57600080fd5b50518061324c57506131ca613463565b6001600160a01b031663dee1f0e4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561321f57600080fd5b505afa158015613233573d6000803e3d6000fd5b505050506040513d602081101561324957600080fd5b50515b6132875760405162461bcd60e51b815260040180806020018281038252602b81526020018061475f602b913960400191505060405180910390fd5b61329160006134e9565b611d556000613513565b6000806132a6612a62565b6001600160a01b03161480610aae57506132be611a7e565b6001600160a01b0316826001600160a01b03161480156132e457506132e1612a80565b42115b8015610aae575060006132f5612a80565b1192915050565b6000610abe6142f2565b6000613310613463565b6001600160a01b031663f77c47916040518163ffffffff1660e01b815260040160206040518083038186803b158015611a4d57600080fd5b3390565b6001600160a01b0383166133915760405162461bcd60e51b81526004018080602001828103825260248152602001806149e86024913960400191505060405180910390fd5b6001600160a01b0382166133d65760405162461bcd60e51b81526004018080602001828103825260228152602001806147f16022913960400191505060405180910390fd5b6001600160a01b03808416600081815260346020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6000610abe7fb1acf527cd7cd1668b30e5a9a1c0d845714604de29ce560150922c9d8c0937df614319565b7fa7ec62784904ff31cbcc32d09932a58e7f1e4476e1d041995b37c917990b16dc5490565b6000828201838110156134e2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b610d7e7f56e7c0e75875c6497f0de657009613a32558904b5c10771a825cc330feff7e728261431d565b610d7e7fb441b53a4e42c2ca9182bc7ede99bedba7a5d9360d9dfbd31fa8ee2dc85906108261431d565b6000610abe7f6d02338b2e4c913c0f7d380e2798409838a48a2c4d57d52742a808c82d713d8b614319565b610d7e7fb1acf527cd7cd1668b30e5a9a1c0d845714604de29ce560150922c9d8c0937df8261431d565b610d7e7f3bc747f4b148b37be485de3223c90b4468252967d2ea7f9fcbd8b6e653f434c98261431d565b303b1590565b6001600160a01b0383166136075760405162461bcd60e51b81526004018080602001828103825260258152602001806149c36025913960400191505060405180910390fd5b6001600160a01b03821661364c5760405162461bcd60e51b815260040180806020018281038252602381526020018061478a6023913960400191505060405180910390fd5b61368f81604051806060016040528060268152602001614877602691396001600160a01b038616600090815260336020526040902054919063ffffffff61372016565b6001600160a01b0380851660009081526033602052604080822093909355908416815220546136c4908263ffffffff61348816565b6001600160a01b0380841660008181526033602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156137af5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561377457818101518382015260200161375c565b50505050905090810190601f1680156137a15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6001600160a01b0382166137fc5760405162461bcd60e51b81526004018080602001828103825260218152602001806149a26021913960400191505060405180910390fd5b61383f816040518060600160405280602281526020016147cf602291396001600160a01b038516600090815260336020526040902054919063ffffffff61372016565b6001600160a01b03831660009081526033602052604090205560355461386b908263ffffffff61397916565b6035556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6000826138c257506000610aae565b828202828482816138cf57fe5b04146134e25760405162461bcd60e51b81526004018080602001828103825260218152602001806148cc6021913960400191505060405180910390fd5b60006134e283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614321565b6000610abe7faf765835ed5af0d235b6c686724ad31fa90e06b3daf1c074d6cc398b8fcef213614319565b60006134e283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613720565b60008183106139ca57816134e2565b5090919050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052613a23908490614386565b505050565b610d7e7faf765835ed5af0d235b6c686724ad31fa90e06b3daf1c074d6cc398b8fcef2138261431d565b801580613ad8575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015613aaa57600080fd5b505afa158015613abe573d6000803e3d6000fd5b505050506040513d6020811015613ad457600080fd5b5051155b613b135760405162461bcd60e51b8152600401808060200182810382526036815260200180614a366036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052613a23908490614386565b610d7e7ff1a169aa0f736c2813818fdfbdc5755c31e0839c8f49831a16543496b28574ea8261431d565b60cf80546001019081905583613bdf576040805162461bcd60e51b815260206004820152601060248201526f043616e6e6f74206465706f73697420360841b604482015290519081900360640190fd5b6001600160a01b038216613c33576040805162461bcd60e51b81526020600482015260166024820152751a1bdb19195c881b5d5cdd081899481919599a5b995960521b604482015290519081900360640190fd5b613c3b6126f9565b1580613c595750613c4a6126f9565b613c5685610f03611d57565b11155b613caa576040805162461bcd60e51b815260206004820152601c60248201527f43616e6e6f74206465706f736974206d6f7265207468616e2063617000000000604482015290519081900360640190fd5b6000613cb4612a62565b6001600160a01b031614613d6e57613cca612a62565b6001600160a01b031663c2a2a07b6040518163ffffffff1660e01b815260040160206040518083038186803b158015613d0257600080fd5b505afa158015613d16573d6000803e3d6000fd5b505050506040513d6020811015613d2c57600080fd5b5051613d6e576040805162461bcd60e51b815260206004820152600c60248201526b2a37b79036bab1b41030b93160a11b604482015290519081900360640190fd5b6000613d78610e5d565b15613da557613da0613d88610e63565b61114b613d93610e5d565b889063ffffffff6138b316565b613da7565b845b9050613db3838261453e565b613dd8843087613dc1611a88565b6001600160a01b031692919063ffffffff61463016565b613de76112f886610f0361394e565b6040805186815290516001600160a01b038516917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a25060cf548114610e57576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6000610abe7f39122c9adfb653455d0c05043bd52fcfbc2be864e832efd3abc72ce5a3d7ed5a614319565b6000610abe7fa66bc57d4b4eed7c7687876ca77997588987307cb13ecc23f5e52725192e5fff614319565b6000610abe7fb441b53a4e42c2ca9182bc7ede99bedba7a5d9360d9dfbd31fa8ee2dc8590610614319565b6000610abe7f1994607607e11d53306ef62e45e3bd85762c58d9bf38b5578bc4a258a26a7371614319565b610d7e7f1994607607e11d53306ef62e45e3bd85762c58d9bf38b5578bc4a258a26a73718261431d565b610d7e7f39122c9adfb653455d0c05043bd52fcfbc2be864e832efd3abc72ce5a3d7ed5a8261431d565b610d7e7f469a3bad2fab7b936c45eecd1f5da52af89cead3e2ed7f732b6f3fc92ed323088261431d565b610d7e7f3405c96d34f8f0e36eac648034ca7e687437f795bbdbdc2cb7db90a89d519f578261431d565b610d7e7f0df75d4bdb87be8e3e04e1dc08ec1c98ed6c4147138e5789f0bd448c5c8e1e288261431d565b610d7e7fa66bc57d4b4eed7c7687876ca77997588987307cb13ecc23f5e52725192e5fff8261431d565b610d7e7f82ddc3be3f0c1a6870327f78f4979a0b37b21b16736ef5be6a7a7a35e530bcf08261431d565b610d7e7f6d02338b2e4c913c0f7d380e2798409838a48a2c4d57d52742a808c82d713d8b8261431d565b6000614083612a62565b6001600160a01b031614156140da576040805162461bcd60e51b815260206004820152601860248201527714dd1c985d1959de481b5d5cdd081899481919599a5b995960421b604482015290519081900360640190fd5b60006140e4612a8a565b90508015610d7e576141006140f7612a62565b826112c7611a88565b6040805182815290517fa09b7ae452b7bffb9e204c3a016e80caeecf46f554d112644f36fa114dac6ffa9181900360200190a150565b6000610abe7f3bc747f4b148b37be485de3223c90b4468252967d2ea7f9fcbd8b6e653f434c9614319565b7fa7ec62784904ff31cbcc32d09932a58e7f1e4476e1d041995b37c917990b16dc55565b6000610abe7f0df75d4bdb87be8e3e04e1dc08ec1c98ed6c4147138e5789f0bd448c5c8e1e28614319565b6000610abe7f82ddc3be3f0c1a6870327f78f4979a0b37b21b16736ef5be6a7a7a35e530bcf0614319565b6000610abe7ff1a169aa0f736c2813818fdfbdc5755c31e0839c8f49831a16543496b28574ea614319565b6000610abe7f56e7c0e75875c6497f0de657009613a32558904b5c10771a825cc330feff7e72614319565b600054610100900460ff168061424a575061424a6135bc565b80614258575060005460ff16155b6142935760405162461bcd60e51b815260040180806020018281038252602e815260200180614915602e913960400191505060405180910390fd5b600054610100900460ff161580156142be576000805460ff1961ff0019909116610100171660011790555b612e1682614161565b6000610abe7f3405c96d34f8f0e36eac648034ca7e687437f795bbdbdc2cb7db90a89d519f57614319565b6000610abe7f469a3bad2fab7b936c45eecd1f5da52af89cead3e2ed7f732b6f3fc92ed323085b5490565b9055565b600081836143705760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561377457818101518382015260200161375c565b50600083858161437c57fe5b0495945050505050565b614398826001600160a01b031661468a565b6143e9576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106144275780518252601f199092019160209182019101614408565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614489576040519150601f19603f3d011682016040523d82523d6000602084013e61448e565b606091505b5091509150816144e5576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610e575780806020019051602081101561450157600080fd5b5051610e575760405162461bcd60e51b815260040180806020018281038252602a815260200180614a0c602a913960400191505060405180910390fd5b6001600160a01b038216614599576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6035546145ac908263ffffffff61348816565b6035556001600160a01b0382166000908152603360205260409020546145d8908263ffffffff61348816565b6001600160a01b03831660008181526033602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610e57908590614386565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906146be57508115155b949350505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061470757805160ff1916838001178555614734565b82800160010185558215614734579182015b82811115614734578251825591602001919060010190614719565b50614740929150614744565b5090565b610a9391905b80821115614740576000815560010161474a56fe5468652063616c6c6572206d75737420626520636f6e74726f6c6c6572206f7220676f7665726e616e636545524332303a207472616e7366657220746f20746865207a65726f206164647265737364656e6f6d696e61746f72206d7573742062652067726561746572207468616e203045524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737374686520737472617465677920646f6573206e6f742062656c6f6e6720746f2074686973207661756c7464656e6f6d696e61746f72206d7573742062652067726561746572207468616e206f7220657175616c20746f20746865206e756d657261746f7245524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e63655661756c7420756e6465726c79696e67206d757374206d6174636820537472617465677920756e6465726c79696e67536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65645468652073747261746567792065786973747320616e64207377697463682074696d656c6f636b20646964206e6f7420656c61707365207965746e756d6265724f66536861726573206d7573742062652067726561746572207468616e203045524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a72315820b639d37bc996244d20a0a966c47be0246bbcced3531f861e417fda2889085f2664736f6c63430005100032
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.