Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
107553128 | 539 days ago | 0 ETH | ||||
107553128 | 539 days ago | 0 ETH | ||||
107553128 | 539 days ago | 0 ETH | ||||
107553128 | 539 days ago | 0 ETH | ||||
107553128 | 539 days ago | 0 ETH | ||||
107553110 | 539 days ago | 0 ETH | ||||
107553110 | 539 days ago | 0 ETH | ||||
107553110 | 539 days ago | 0 ETH | ||||
107553110 | 539 days ago | 0 ETH | ||||
107553110 | 539 days ago | 0 ETH | ||||
107553110 | 539 days ago | 0 ETH | ||||
107553110 | 539 days ago | 0 ETH | ||||
107553110 | 539 days ago | 0 ETH | ||||
107553110 | 539 days ago | 0 ETH | ||||
107553110 | 539 days ago | 0 ETH | ||||
107553110 | 539 days ago | 0 ETH | ||||
107552861 | 539 days ago | 0 ETH | ||||
107552861 | 539 days ago | 0 ETH | ||||
107552833 | 539 days ago | 0 ETH | ||||
107552833 | 539 days ago | 0 ETH | ||||
107552833 | 539 days ago | 0 ETH | ||||
107552833 | 539 days ago | 0 ETH | ||||
107552833 | 539 days ago | 0 ETH | ||||
107552833 | 539 days ago | 0 ETH | ||||
107551377 | 539 days ago | 0 ETH |
Loading...
Loading
Contract Name:
PoolAccountant
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 500 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../dependencies/openzeppelin/contracts/proxy/utils/Initializable.sol"; import "../dependencies/openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../dependencies/openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "../dependencies/openzeppelin/contracts/utils/Context.sol"; import "../Errors.sol"; import "../interfaces/vesper/IVesperPool.sol"; import "./PoolAccountantStorage.sol"; /// @title Accountant for Vesper pools which keep records of strategies. contract PoolAccountant is Initializable, Context, PoolAccountantStorageV2 { using SafeERC20 for IERC20; string public constant VERSION = "5.1.0"; uint256 public constant MAX_BPS = 10_000; event EarningReported( address indexed strategy, uint256 profit, uint256 loss, uint256 payback, uint256 strategyDebt, uint256 poolDebt, uint256 creditLine ); event LossReported(address indexed strategy, uint256 loss); event StrategyAdded(address indexed strategy, uint256 debtRatio, uint256 externalDepositFee); event StrategyRemoved(address indexed strategy); event StrategyMigrated(address indexed oldStrategy, address indexed newStrategy); event UpdatedExternalDepositFee(address indexed strategy, uint256 oldFee, uint256 newFee); event UpdatedPoolExternalDepositFee(uint256 oldFee, uint256 newFee); event UpdatedStrategyDebtRatio(address indexed strategy, uint256 oldDebtRatio, uint256 newDebtRatio); /** * @dev This init function meant to be called after proxy deployment. * @dev DO NOT CALL it with proxy deploy * @param pool_ Address of Vesper pool proxy */ function init(address pool_) public initializer { require(pool_ != address(0), Errors.INPUT_ADDRESS_IS_ZERO); pool = pool_; } modifier onlyGovernor() { require(IVesperPool(pool).governor() == _msgSender(), "not-the-governor"); _; } modifier onlyKeeper() { require( IVesperPool(pool).governor() == _msgSender() || IVesperPool(pool).isKeeper(_msgSender()), "not-a-keeper" ); _; } modifier onlyMaintainer() { require( IVesperPool(pool).governor() == _msgSender() || IVesperPool(pool).isMaintainer(_msgSender()), "not-a-maintainer" ); _; } modifier onlyPool() { require(pool == _msgSender(), "not-a-pool"); _; } /** * @notice Get available credit limit of strategy. This is the amount strategy can borrow from pool * @dev Available credit limit is calculated based on current debt of pool and strategy, current debt limit of pool and strategy. * credit available = min(pool's debt limit, strategy's debt limit, max debt per rebalance) * when some strategy do not pay back outstanding debt, this impact credit line of other strategy if totalDebt of pool >= debtLimit of pool * @param strategy_ Strategy address */ function availableCreditLimit(address strategy_) external view returns (uint256) { return _availableCreditLimit(strategy_); } /** * @notice Debt above current debt limit * @param strategy_ Address of strategy */ function excessDebt(address strategy_) external view returns (uint256) { return _excessDebt(strategy_); } /// @notice Return strategies array function getStrategies() external view returns (address[] memory) { return strategies; } /// @notice Return withdrawQueue function getWithdrawQueue() external view returns (address[] memory) { return withdrawQueue; } /** * @notice Get total debt of given strategy * @param strategy_ Strategy address */ function totalDebtOf(address strategy_) external view returns (uint256) { return strategy[strategy_].totalDebt; } function _availableCreditLimit(address strategy_) internal view returns (uint256) { if (IVesperPool(pool).stopEverything()) { return 0; } uint256 _totalValue = IVesperPool(pool).totalValue(); uint256 _maxDebt = (strategy[strategy_].debtRatio * _totalValue) / MAX_BPS; uint256 _currentDebt = strategy[strategy_].totalDebt; if (_currentDebt >= _maxDebt) { return 0; } uint256 _poolDebtLimit = (totalDebtRatio * _totalValue) / MAX_BPS; if (totalDebt >= _poolDebtLimit) { return 0; } uint256 _available = _maxDebt - _currentDebt; _available = _min(_min(IVesperPool(pool).tokensHere(), _available), _poolDebtLimit - totalDebt); return _available; } function _excessDebt(address strategy_) internal view returns (uint256) { uint256 _currentDebt = strategy[strategy_].totalDebt; if (IVesperPool(pool).stopEverything()) { return _currentDebt; } uint256 _maxDebt = (strategy[strategy_].debtRatio * IVesperPool(pool).totalValue()) / MAX_BPS; return _currentDebt > _maxDebt ? (_currentDebt - _maxDebt) : 0; } function _min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /// @notice Recalculate pool external deposit fee. /// @dev As it uses state variables for calculation, make sure to call it only after updating state variables. function _recalculatePoolExternalDepositFee() internal { uint256 _len = strategies.length; uint256 _externalDepositFee; // calculate poolExternalDepositFee and weightedFee for each strategy if (totalDebtRatio > 0) { for (uint256 i; i < _len; i++) { _externalDepositFee += (strategy[strategies[i]].externalDepositFee * strategy[strategies[i]].debtRatio) / totalDebtRatio; } } // Update externalDepositFee and emit event emit UpdatedPoolExternalDepositFee(externalDepositFee, externalDepositFee = _externalDepositFee); } /** * @dev When strategy report loss, its debtRatio decreases to get fund back quickly. * Reduction is debt ratio is reduction in credit limit */ function _reportLoss(address strategy_, uint256 loss_) internal { require(strategy[strategy_].totalDebt >= loss_, Errors.LOSS_TOO_HIGH); strategy[strategy_].totalLoss += loss_; strategy[strategy_].totalDebt -= loss_; totalDebt -= loss_; uint256 _deltaDebtRatio = _min( (loss_ * MAX_BPS) / IVesperPool(pool).totalValue(), strategy[strategy_].debtRatio ); strategy[strategy_].debtRatio -= _deltaDebtRatio; totalDebtRatio -= _deltaDebtRatio; } /************************************************************************************************ * Authorized function * ***********************************************************************************************/ ////////////////////////////// Only Governor ////////////////////////////// /** * @notice Add strategy. Once strategy is added it can call rebalance and * borrow fund from pool and invest that fund in provider/lender. * @dev Recalculate pool level external deposit fee after all state variables are updated. * @param strategy_ Strategy address * @param debtRatio_ Pool fund allocation to this strategy * @param externalDepositFee_ External deposit fee of strategy */ function addStrategy(address strategy_, uint256 debtRatio_, uint256 externalDepositFee_) public onlyGovernor { require(strategy_ != address(0), Errors.INPUT_ADDRESS_IS_ZERO); require(!strategy[strategy_].active, Errors.STRATEGY_IS_ACTIVE); totalDebtRatio = totalDebtRatio + debtRatio_; require(totalDebtRatio <= MAX_BPS, Errors.DEBT_RATIO_LIMIT_REACHED); require(externalDepositFee_ <= MAX_BPS, Errors.FEE_LIMIT_REACHED); StrategyConfig memory newStrategy = StrategyConfig({ active: true, interestFee: 0, // Obsolete debtRate: 0, // Obsolete lastRebalance: block.timestamp, totalDebt: 0, totalLoss: 0, totalProfit: 0, debtRatio: debtRatio_, externalDepositFee: externalDepositFee_ }); strategy[strategy_] = newStrategy; strategies.push(strategy_); withdrawQueue.push(strategy_); emit StrategyAdded(strategy_, debtRatio_, externalDepositFee_); // Recalculate pool level externalDepositFee. This should be called at the end of function _recalculatePoolExternalDepositFee(); } /** * @notice Remove strategy and recalculate pool level external deposit fee. * @dev Revoke and remove strategy from array. Update withdraw queue. * Withdraw queue order should not change after remove. * Strategy can be removed only after it has paid all debt. * Use migrate strategy if debt is not paid and want to upgrade strategy. */ function removeStrategy(uint256 index_) external onlyGovernor { address _strategy = strategies[index_]; require(strategy[_strategy].active, Errors.STRATEGY_IS_NOT_ACTIVE); require(strategy[_strategy].totalDebt == 0, Errors.TOTAL_DEBT_IS_NOT_ZERO); // Adjust totalDebtRatio totalDebtRatio -= strategy[_strategy].debtRatio; // Remove strategy delete strategy[_strategy]; strategies[index_] = strategies[strategies.length - 1]; strategies.pop(); address[] memory _withdrawQueue = new address[](strategies.length); uint256 j; // After above update, withdrawQueue.length > strategies.length for (uint256 i; i < withdrawQueue.length; i++) { if (withdrawQueue[i] != _strategy) { _withdrawQueue[j] = withdrawQueue[i]; j++; } } withdrawQueue = _withdrawQueue; emit StrategyRemoved(_strategy); // Recalculate pool level externalDepositFee. _recalculatePoolExternalDepositFee(); } /** * @notice Update external deposit fee of strategy and recalculate pool level external deposit fee. * @param strategy_ Strategy address for which external deposit fee is being updated * @param externalDepositFee_ New external deposit fee */ function updateExternalDepositFee(address strategy_, uint256 externalDepositFee_) external onlyGovernor { require(strategy[strategy_].active, Errors.STRATEGY_IS_NOT_ACTIVE); require(externalDepositFee_ <= MAX_BPS, Errors.FEE_LIMIT_REACHED); uint256 _oldExternalDepositFee = strategy[strategy_].externalDepositFee; // Write to storage strategy[strategy_].externalDepositFee = externalDepositFee_; emit UpdatedExternalDepositFee(strategy_, _oldExternalDepositFee, externalDepositFee_); // Recalculate pool level externalDepositFee. _recalculatePoolExternalDepositFee(); } ///////////////////////////// Only Keeper ///////////////////////////// /** * @notice Recalculate pool external deposit fee. It is calculated using debtRatio and external deposit fee of each strategy. * @dev Whenever debtRatio changes recalculation is required. DebtRatio changes if strategy reports loss and in that case an * off chain application can watch for it and take action accordingly. * @dev This function is gas heavy hence we do not want to call during reportLoss. */ function recalculatePoolExternalDepositFee() external onlyKeeper { _recalculatePoolExternalDepositFee(); } /** * @dev Transfer given ERC20 token to pool * @param fromToken_ Token address to sweep */ function sweep(address fromToken_) external virtual onlyKeeper { IERC20(fromToken_).safeTransfer(pool, IERC20(fromToken_).balanceOf(address(this))); } ///////////////////////////// Only Maintainer ///////////////////////////// /** * @notice Update debt ratio. * @dev A strategy is retired when debtRatio is 0 * @dev As debtRatio impacts pool level external deposit fee hence recalculate it after updating debtRatio. * @param strategy_ Strategy address for which debt ratio is being updated * @param debtRatio_ New debt ratio */ function updateDebtRatio(address strategy_, uint256 debtRatio_) external onlyMaintainer { require(strategy[strategy_].active, Errors.STRATEGY_IS_NOT_ACTIVE); // Update totalDebtRatio totalDebtRatio = (totalDebtRatio - strategy[strategy_].debtRatio) + debtRatio_; require(totalDebtRatio <= MAX_BPS, Errors.DEBT_RATIO_LIMIT_REACHED); emit UpdatedStrategyDebtRatio(strategy_, strategy[strategy_].debtRatio, debtRatio_); // Write to storage strategy[strategy_].debtRatio = debtRatio_; // Recalculate pool level externalDepositFee. _recalculatePoolExternalDepositFee(); } /** * @notice Update withdraw queue. Withdraw queue is list of strategy in the order in which * funds should be withdrawn. * @dev Pool always keep some buffer amount to satisfy withdrawal request, any withdrawal * request higher than buffer will withdraw from withdraw queue. So withdrawQueue[0] will * be the first strategy where withdrawal request will be send. * @param withdrawQueue_ Ordered list of strategy. */ function updateWithdrawQueue(address[] memory withdrawQueue_) external onlyMaintainer { uint256 _length = withdrawQueue_.length; require(_length == withdrawQueue.length && _length == strategies.length, Errors.INPUT_LENGTH_MISMATCH); for (uint256 i; i < _length; i++) { require(strategy[withdrawQueue_[i]].active, Errors.STRATEGY_IS_NOT_ACTIVE); } withdrawQueue = withdrawQueue_; } //////////////////////////////// Only Pool //////////////////////////////// /** * @notice Decrease debt of strategy, also decrease totalDebt * @dev In case of withdraw from strategy, pool will decrease debt by amount withdrawn * @param strategy_ Strategy Address * @param decreaseBy_ Amount by which strategy debt will be decreased */ function decreaseDebt(address strategy_, uint256 decreaseBy_) external onlyPool { // A strategy may send more than its debt. This should never fail decreaseBy_ = _min(strategy[strategy_].totalDebt, decreaseBy_); strategy[strategy_].totalDebt -= decreaseBy_; totalDebt -= decreaseBy_; } /** * @notice Migrate existing strategy to new strategy. * @dev Migrating strategy aka old and new strategy should be of same type. * @dev New strategy will replace old strategy in strategy mapping, * strategies array, withdraw queue. * @param old_ Address of strategy being migrated * @param new_ Address of new strategy */ function migrateStrategy(address old_, address new_) external onlyPool { require(strategy[old_].active, Errors.STRATEGY_IS_NOT_ACTIVE); require(!strategy[new_].active, Errors.STRATEGY_IS_ACTIVE); StrategyConfig memory _newStrategy = StrategyConfig({ active: true, interestFee: 0, // Obsolete debtRate: 0, // Obsolete lastRebalance: strategy[old_].lastRebalance, totalDebt: strategy[old_].totalDebt, totalLoss: 0, totalProfit: 0, debtRatio: strategy[old_].debtRatio, externalDepositFee: strategy[old_].externalDepositFee }); delete strategy[old_]; strategy[new_] = _newStrategy; // Strategies and withdrawQueue has same length but we still want // to iterate over them in different loop. for (uint256 i; i < strategies.length; i++) { if (strategies[i] == old_) { strategies[i] = new_; break; } } for (uint256 i; i < withdrawQueue.length; i++) { if (withdrawQueue[i] == old_) { withdrawQueue[i] = new_; break; } } emit StrategyMigrated(old_, new_); } /** * @dev Strategy call this in regular interval. * @param profit_ yield generated by strategy. Strategy get performance fee on this amount * @param loss_ Reduce debt ,also reduce debtRatio, increase loss in record. * @param payback_ strategy willing to payback outstanding above debtLimit. no performance fee on this amount. * when governance has reduced debtRatio of strategy, strategy will report profit and payback amount separately. */ function reportEarning( address strategy_, uint256 profit_, uint256 loss_, uint256 payback_ ) external onlyPool returns (uint256 _actualPayback, uint256 _creditLine) { require(strategy[strategy_].active, Errors.STRATEGY_IS_NOT_ACTIVE); require(IVesperPool(pool).token().balanceOf(strategy_) >= (profit_ + payback_), Errors.INSUFFICIENT_BALANCE); if (loss_ > 0) { _reportLoss(strategy_, loss_); } uint256 _overLimitDebt = _excessDebt(strategy_); _actualPayback = _min(_overLimitDebt, payback_); if (_actualPayback > 0) { strategy[strategy_].totalDebt -= _actualPayback; totalDebt -= _actualPayback; } _creditLine = _availableCreditLimit(strategy_); if (_creditLine > 0) { strategy[strategy_].totalDebt += _creditLine; totalDebt += _creditLine; } if (profit_ > 0) { strategy[strategy_].totalProfit += profit_; } strategy[strategy_].lastRebalance = block.timestamp; emit EarningReported( strategy_, profit_, loss_, _actualPayback, strategy[strategy_].totalDebt, totalDebt, _creditLine ); return (_actualPayback, _creditLine); } /** * @notice Update strategy loss. * @param strategy_ Strategy which incur loss * @param loss_ Loss of strategy */ function reportLoss(address strategy_, uint256 loss_) external onlyPool { require(strategy[strategy_].active, Errors.STRATEGY_IS_NOT_ACTIVE); _reportLoss(strategy_, loss_); emit LossReported(strategy_, loss_); } /////////////////////////////////////////////////////////////////////////// }
// SPDX-License-Identifier: MIT // solhint-disable-next-line compiler-version pragma solidity ^0.8.0; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract 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 protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ 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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.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 IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { 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)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ 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) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _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. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "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"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @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) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @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]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with 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. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; /// @title Errors library library Errors { string public constant INVALID_COLLATERAL_AMOUNT = "1"; // Collateral must be greater than 0 or > defined limit string public constant INVALID_SHARE_AMOUNT = "2"; // Share must be greater than 0 string public constant INVALID_INPUT_LENGTH = "3"; // Input array length must be greater than 0 string public constant INPUT_LENGTH_MISMATCH = "4"; // Input array length mismatch with another array length string public constant NOT_WHITELISTED_ADDRESS = "5"; // Caller is not whitelisted to withdraw without fee string public constant MULTI_TRANSFER_FAILED = "6"; // Multi transfer of tokens has failed string public constant FEE_COLLECTOR_NOT_SET = "7"; // Fee Collector is not set string public constant NOT_ALLOWED_TO_SWEEP = "8"; // Token is not allowed to sweep string public constant INSUFFICIENT_BALANCE = "9"; // Insufficient balance to performs operations to follow string public constant INPUT_ADDRESS_IS_ZERO = "10"; // Input address is zero string public constant FEE_LIMIT_REACHED = "11"; // Fee must be less than MAX_BPS string public constant ALREADY_INITIALIZED = "12"; // Data structure, contract, or logic already initialized and can not be called again string public constant ADD_IN_LIST_FAILED = "13"; // Cannot add address in address list string public constant REMOVE_FROM_LIST_FAILED = "14"; // Cannot remove address from address list string public constant STRATEGY_IS_ACTIVE = "15"; // Strategy is already active, an inactive strategy is required string public constant STRATEGY_IS_NOT_ACTIVE = "16"; // Strategy is not active, an active strategy is required string public constant INVALID_STRATEGY = "17"; // Given strategy is not a strategy of this pool string public constant DEBT_RATIO_LIMIT_REACHED = "18"; // Debt ratio limit reached. It must be less than MAX_BPS string public constant TOTAL_DEBT_IS_NOT_ZERO = "19"; // Strategy total debt must be 0 string public constant LOSS_TOO_HIGH = "20"; // Strategy reported loss must be less than current debt string public constant INVALID_MAX_BORROW_LIMIT = "21"; // Max borrow limit is beyond range. string public constant MAX_LIMIT_LESS_THAN_MIN = "22"; // Max limit should be greater than min limit. string public constant INVALID_SLIPPAGE = "23"; // Slippage should be less than MAX_BPS string public constant WRONG_RECEIPT_TOKEN = "24"; // Wrong receipt token address string public constant AAVE_FLASH_LOAN_NOT_ACTIVE = "25"; // aave flash loan is not active string public constant DYDX_FLASH_LOAN_NOT_ACTIVE = "26"; // DYDX flash loan is not active string public constant INVALID_FLASH_LOAN = "27"; // invalid-flash-loan string public constant INVALID_INITIATOR = "28"; // "invalid-initiator" string public constant INCORRECT_WITHDRAW_AMOUNT = "29"; // withdrawn amount is not correct string public constant NO_MARKET_ID_FOUND = "30"; // dydx flash loan no marketId found for token string public constant SAME_AS_PREVIOUS = "31"; // Input should not be same as previous value. string public constant INVALID_INPUT = "32"; // Generic invalid input error code }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; /** * @notice Governable interface */ interface IGovernable { function governor() external view returns (address _governor); function transferGovernorship(address _proposedGovernor) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; /** * @notice Pausable interface */ interface IPausable { function paused() external view returns (bool); function stopEverything() external view returns (bool); function pause() external; function unpause() external; function shutdown() external; function open() external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../../dependencies/openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "./IGovernable.sol"; import "./IPausable.sol"; interface IVesperPool is IGovernable, IPausable, IERC20Metadata { function calculateUniversalFee(uint256 profit_) external view returns (uint256 _fee); function deposit(uint256 collateralAmount_) external; function excessDebt(address strategy_) external view returns (uint256); function poolAccountant() external view returns (address); function poolRewards() external view returns (address); function reportEarning(uint256 profit_, uint256 loss_, uint256 payback_) external; function reportLoss(uint256 loss_) external; function sweepERC20(address fromToken_) external; function withdraw(uint256 share_) external; function keepers() external view returns (address[] memory); function isKeeper(address address_) external view returns (bool); function maintainers() external view returns (address[] memory); function isMaintainer(address address_) external view returns (bool); function pricePerShare() external view returns (uint256); function strategy( address strategy_ ) external view returns ( bool _active, uint256 _interestFee, // Obsolete uint256 _debtRate, // Obsolete uint256 _lastRebalance, uint256 _totalDebt, uint256 _totalLoss, uint256 _totalProfit, uint256 _debtRatio, uint256 _externalDepositFee ); function token() external view returns (IERC20); function tokensHere() external view returns (uint256); function totalDebtOf(address strategy_) external view returns (uint256); function totalValue() external view returns (uint256); function totalDebt() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; abstract contract PoolAccountantStorageV1 { address public pool; // Address of Vesper pool uint256 public totalDebtRatio; // Total debt ratio. This will keep some buffer amount in pool uint256 public totalDebt; // Total debt. Sum of debt of all strategies. address[] public strategies; // Array of strategies address[] public withdrawQueue; // Array of strategy in the order in which funds should be withdrawn. } abstract contract PoolAccountantStorageV2 is PoolAccountantStorageV1 { struct StrategyConfig { bool active; uint256 interestFee; // Obsolete in favor of universal fee uint256 debtRate; // Obsolete uint256 lastRebalance; // Timestamp of last rebalance. It is used in universal fee calculation uint256 totalDebt; // Total outstanding debt strategy has uint256 totalLoss; // Total loss that strategy has realized uint256 totalProfit; // Total gain that strategy has realized uint256 debtRatio; // % of asset allocation uint256 externalDepositFee; // External deposit fee of strategy } mapping(address => StrategyConfig) public strategy; // Strategy address to its configuration uint256 public externalDepositFee; // External deposit fee of Vesper pool }
{ "optimizer": { "enabled": true, "runs": 500 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"profit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"loss","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"payback","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"strategyDebt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"poolDebt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"creditLine","type":"uint256"}],"name":"EarningReported","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"loss","type":"uint256"}],"name":"LossReported","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"debtRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"externalDepositFee","type":"uint256"}],"name":"StrategyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldStrategy","type":"address"},{"indexed":true,"internalType":"address","name":"newStrategy","type":"address"}],"name":"StrategyMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"}],"name":"StrategyRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"UpdatedExternalDepositFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"UpdatedPoolExternalDepositFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldDebtRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDebtRatio","type":"uint256"}],"name":"UpdatedStrategyDebtRatio","type":"event"},{"inputs":[],"name":"MAX_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"strategy_","type":"address"},{"internalType":"uint256","name":"debtRatio_","type":"uint256"},{"internalType":"uint256","name":"externalDepositFee_","type":"uint256"}],"name":"addStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategy_","type":"address"}],"name":"availableCreditLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"strategy_","type":"address"},{"internalType":"uint256","name":"decreaseBy_","type":"uint256"}],"name":"decreaseDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategy_","type":"address"}],"name":"excessDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"externalDepositFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStrategies","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawQueue","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool_","type":"address"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"old_","type":"address"},{"internalType":"address","name":"new_","type":"address"}],"name":"migrateStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"recalculatePoolExternalDepositFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index_","type":"uint256"}],"name":"removeStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategy_","type":"address"},{"internalType":"uint256","name":"profit_","type":"uint256"},{"internalType":"uint256","name":"loss_","type":"uint256"},{"internalType":"uint256","name":"payback_","type":"uint256"}],"name":"reportEarning","outputs":[{"internalType":"uint256","name":"_actualPayback","type":"uint256"},{"internalType":"uint256","name":"_creditLine","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategy_","type":"address"},{"internalType":"uint256","name":"loss_","type":"uint256"}],"name":"reportLoss","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"strategies","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"strategy","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"interestFee","type":"uint256"},{"internalType":"uint256","name":"debtRate","type":"uint256"},{"internalType":"uint256","name":"lastRebalance","type":"uint256"},{"internalType":"uint256","name":"totalDebt","type":"uint256"},{"internalType":"uint256","name":"totalLoss","type":"uint256"},{"internalType":"uint256","name":"totalProfit","type":"uint256"},{"internalType":"uint256","name":"debtRatio","type":"uint256"},{"internalType":"uint256","name":"externalDepositFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken_","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"strategy_","type":"address"}],"name":"totalDebtOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDebtRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"strategy_","type":"address"},{"internalType":"uint256","name":"debtRatio_","type":"uint256"}],"name":"updateDebtRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategy_","type":"address"},{"internalType":"uint256","name":"externalDepositFee_","type":"uint256"}],"name":"updateExternalDepositFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"withdrawQueue_","type":"address[]"}],"name":"updateWithdrawQueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawQueue","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506130f1806100206000396000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c8063854f4d80116100ee578063c0cbbca611610097578063fa34d61111610071578063fa34d61114610423578063fc7b9c1814610436578063fd967f471461043f578063ffa1ad741461044857600080fd5b8063c0cbbca6146103ea578063d53ddc26146103fd578063d574ea3d1461041057600080fd5b8063a066654b116100c8578063a066654b146103a7578063b49a60bb146103cf578063b64321ec146103d757600080fd5b8063854f4d80146103555780638f88d18c146103685780639f2b28331461037b57600080fd5b80632df9eab91161015b578063346162d511610135578063346162d51461031357806362518ddf1461031c5780636cb56d191461032f5780637f13086e1461034257600080fd5b80632df9eab9146102d65780632fb9ba31146102ed57806332b77a761461030057600080fd5b806319ab453c1161018c57806319ab453c14610217578063228bfd9f1461022a5780632a1f6ec1146102ce57600080fd5b806301681a62146101b357806311183052146101c857806316f0115b146101e6575b600080fd5b6101c66101c1366004612ce8565b610479565b005b6101d0610677565b6040516101dd9190612d05565b60405180910390f35b6000546101ff906201000090046001600160a01b031681565b6040516001600160a01b0390911681526020016101dd565b6101c6610225366004612ce8565b6106d9565b610288610238366004612ce8565b600560208190526000918252604090912080546001820154600283015460038401546004850154958501546006860154600787015460089097015460ff9096169794969395929493919290919089565b604080519915158a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c084015260e0830152610100820152610120016101dd565b6101c661080c565b6102df60015481565b6040519081526020016101dd565b6101c66102fb366004612d52565b610972565b6101c661030e366004612d52565b610a38565b6102df60065481565b6101ff61032a366004612d7e565b610c01565b6101c661033d366004612d97565b610c2b565b6101c6610350366004612d52565b6110ac565b6101c6610363366004612de6565b6111a2565b6101c6610376366004612d52565b611409565b6102df610389366004612ce8565b6001600160a01b031660009081526005602052604090206004015490565b6103ba6103b5366004612eab565b6116b2565b604080519283526020830191909152016101dd565b6101d0611a30565b6102df6103e5366004612ce8565b611a90565b6101c66103f8366004612d7e565b611aa1565b6102df61040b366004612ce8565b611ee3565b6101ff61041e366004612d7e565b611eee565b6101c6610431366004612ee6565b611efe565b6102df60025481565b6102df61271081565b61046c604051806040016040528060058152602001640352e312e360dc1b81525081565b6040516101dd9190612f47565b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b1580156104c357600080fd5b505afa1580156104d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104fb9190612f7a565b6001600160a01b0316148061059a57506000546201000090046001600160a01b0316636ba42aaa336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b15801561056257600080fd5b505afa158015610576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a9190612f97565b6105da5760405162461bcd60e51b815260206004820152600c60248201526b3737ba16b096b5b2b2b832b960a11b60448201526064015b60405180910390fd5b6000546040516370a0823160e01b8152306004820152610674916201000090046001600160a01b0390811691908416906370a082319060240160206040518083038186803b15801561062b57600080fd5b505afa15801561063f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106639190612fb9565b6001600160a01b03841691906122bb565b50565b606060048054806020026020016040519081016040528092919081815260200182805480156106cf57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116106b1575b5050505050905090565b600054610100900460ff16806106f2575060005460ff16155b6107645760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105d1565b600054610100900460ff16158015610786576000805461ffff19166101011790555b604080518082019091526002815261031360f41b60208201526001600160a01b0383166107c65760405162461bcd60e51b81526004016105d19190612f47565b506000805475ffffffffffffffffffffffffffffffffffffffff00001916620100006001600160a01b038516021790558015610808576000805461ff00191690555b5050565b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b15801561085657600080fd5b505afa15801561086a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088e9190612f7a565b6001600160a01b0316148061092d57506000546201000090046001600160a01b0316636ba42aaa336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b1580156108f557600080fd5b505afa158015610909573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092d9190612f97565b6109685760405162461bcd60e51b815260206004820152600c60248201526b3737ba16b096b5b2b2b832b960a11b60448201526064016105d1565b610970612322565b565b6000546001600160a01b03620100009091041633146109c05760405162461bcd60e51b815260206004820152600a6024820152691b9bdd0b584b5c1bdbdb60b21b60448201526064016105d1565b6001600160a01b0382166000908152600560205260409020600401546109e6908261244f565b6001600160a01b038316600090815260056020526040812060040180549293508392909190610a16908490612fe8565b925050819055508060026000828254610a2f9190612fe8565b90915550505050565b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b158015610a8257600080fd5b505afa158015610a96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aba9190612f7a565b6001600160a01b031614610b035760405162461bcd60e51b815260206004820152601060248201526f3737ba16ba343296b3b7bb32b93737b960811b60448201526064016105d1565b6001600160a01b0382166000908152600560209081526040918290205482518084019093526002835261189b60f11b9183019190915260ff16610b595760405162461bcd60e51b81526004016105d19190612f47565b50604080518082019091526002815261313160f01b6020820152612710821115610b965760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b038216600081815260056020908152604091829020600801805490859055825181815291820185905292917f3e57eabb1906726caa174b6716b34373026dfd25dbae17ba47ec46e8a9ced9ee910160405180910390a2610bfc612322565b505050565b60048181548110610c1157600080fd5b6000918252602090912001546001600160a01b0316905081565b6000546001600160a01b0362010000909104163314610c795760405162461bcd60e51b815260206004820152600a6024820152691b9bdd0b584b5c1bdbdb60b21b60448201526064016105d1565b6001600160a01b0382166000908152600560209081526040918290205482518084019093526002835261189b60f11b9183019190915260ff16610ccf5760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b0381166000908152600560209081526040918290205482518084019093526002835261313560f01b9183019190915260ff1615610d275760405162461bcd60e51b81526004016105d19190612f47565b506000604051806101200160405280600115158152602001600081526020016000815260200160056000866001600160a01b03166001600160a01b0316815260200190815260200160002060030154815260200160056000866001600160a01b03166001600160a01b03168152602001908152602001600020600401548152602001600081526020016000815260200160056000866001600160a01b03166001600160a01b0316815260200190815260200160002060070154815260200160056000866001600160a01b03166001600160a01b0316815260200190815260200160002060080154815250905060056000846001600160a01b03166001600160a01b03168152602001908152602001600020600080820160006101000a81549060ff02191690556001820160009055600282016000905560038201600090556004820160009055600582016000905560068201600090556007820160009055600882016000905550508060056000846001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070155610100820151816008015590505060005b600354811015610fc757836001600160a01b031660038281548110610f5357610f53612fff565b6000918252602090912001546001600160a01b03161415610fb5578260038281548110610f8257610f82612fff565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610fc7565b80610fbf81613015565b915050610f2c565b5060005b60045481101561106657836001600160a01b031660048281548110610ff257610ff2612fff565b6000918252602090912001546001600160a01b0316141561105457826004828154811061102157611021612fff565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550611066565b8061105e81613015565b915050610fcb565b50816001600160a01b0316836001600160a01b03167f100b69bb6b504e1252e36b375233158edee64d071b399e2f81473a695fd1b02160405160405180910390a3505050565b6000546001600160a01b03620100009091041633146110fa5760405162461bcd60e51b815260206004820152600a6024820152691b9bdd0b584b5c1bdbdb60b21b60448201526064016105d1565b6001600160a01b0382166000908152600560209081526040918290205482518084019093526002835261189b60f11b9183019190915260ff166111505760405162461bcd60e51b81526004016105d19190612f47565b5061115b8282612467565b816001600160a01b03167f3ffa9beb41b46c88b16758ef6c236ebd4d07cdfd4d22471030eb6b2d662482d98260405161119691815260200190565b60405180910390a25050565b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b1580156111ec57600080fd5b505afa158015611200573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112249190612f7a565b6001600160a01b031614806112c357506000546201000090046001600160a01b031663dd57366a336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b15801561128b57600080fd5b505afa15801561129f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c39190612f97565b6113025760405162461bcd60e51b815260206004820152601060248201526f3737ba16b096b6b0b4b73a30b4b732b960811b60448201526064016105d1565b805160045481148015611316575060035481145b604051806040016040528060018152602001600d60fa1b8152509061134e5760405162461bcd60e51b81526004016105d19190612f47565b5060005b818110156113f5576005600084838151811061137057611370612fff565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060000160009054906101000a900460ff1660405180604001604052806002815260200161189b60f11b815250906113e25760405162461bcd60e51b81526004016105d19190612f47565b50806113ed81613015565b915050611352565b508151610bfc906004906020850190612c3c565b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b15801561145357600080fd5b505afa158015611467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148b9190612f7a565b6001600160a01b0316148061152a57506000546201000090046001600160a01b031663dd57366a336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b1580156114f257600080fd5b505afa158015611506573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152a9190612f97565b6115695760405162461bcd60e51b815260206004820152601060248201526f3737ba16b096b6b0b4b73a30b4b732b960811b60448201526064016105d1565b6001600160a01b0382166000908152600560209081526040918290205482518084019093526002835261189b60f11b9183019190915260ff166115bf5760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b03821660009081526005602052604090206007015460015482916115ea91612fe8565b6115f49190613030565b6001819055604080518082019091526002815261062760f31b60208201529061271010156116355760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b0382166000818152600560209081526040918290206007015482519081529081018490527fab9990442b7ef5dfed05018d2d947ceb38710eda84b3e3b32940cbb28867ee0e910160405180910390a26001600160a01b0382166000908152600560205260409020600701819055610808612322565b6000805481906001600160a01b03620100009091041633146117035760405162461bcd60e51b815260206004820152600a6024820152691b9bdd0b584b5c1bdbdb60b21b60448201526064016105d1565b6001600160a01b0386166000908152600560209081526040918290205482518084019093526002835261189b60f11b9183019190915260ff166117595760405162461bcd60e51b81526004016105d19190612f47565b506117648386613030565b600060029054906101000a90046001600160a01b03166001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117b257600080fd5b505afa1580156117c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ea9190612f7a565b6040516370a0823160e01b81526001600160a01b03898116600483015291909116906370a082319060240160206040518083038186803b15801561182d57600080fd5b505afa158015611841573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118659190612fb9565b1015604051806040016040528060018152602001603960f81b8152509061189f5760405162461bcd60e51b81526004016105d19190612f47565b5083156118b0576118b08685612467565b60006118bb8761265d565b90506118c7818561244f565b92508215611919576001600160a01b038716600090815260056020526040812060040180548592906118fa908490612fe8565b9250508190555082600260008282546119139190612fe8565b90915550505b611922876127f9565b91508115611974576001600160a01b03871660009081526005602052604081206004018054849290611955908490613030565b92505081905550816002600082825461196e9190613030565b90915550505b85156119ab576001600160a01b038716600090815260056020526040812060060180548892906119a5908490613030565b90915550505b6001600160a01b0387166000818152600560209081526040918290204260038201556004015460025483518b81529283018a90529282018790526060820152608081019190915260a081018490527f29c6c60e040fcd722949346bda66341e8859b20b9a2124a625326ad10373391b9060c00160405180910390a25094509492505050565b606060038054806020026020016040519081016040528092919081815260200182805480156106cf576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116106b1575050505050905090565b6000611a9b826127f9565b92915050565b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b158015611aeb57600080fd5b505afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190612f7a565b6001600160a01b031614611b6c5760405162461bcd60e51b815260206004820152601060248201526f3737ba16ba343296b3b7bb32b93737b960811b60448201526064016105d1565b600060038281548110611b8157611b81612fff565b60009182526020808320909101546001600160a01b0316808352600582526040928390205483518085019094526002845261189b60f11b92840192909252925060ff16611be15760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b0381166000908152600560209081526040918290206004015482518084019093526002835261313960f01b9183019190915215611c395760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b0381166000908152600560205260408120600701546001805491929091611c69908490612fe8565b90915550506001600160a01b03811660009081526005602081905260408220805460ff19168155600180820184905560028201849055600380830185905560048301859055928201849055600682018490556007820184905560089091019290925580549091611cd891612fe8565b81548110611ce857611ce8612fff565b600091825260209091200154600380546001600160a01b039092169184908110611d1457611d14612fff565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506003805480611d5357611d53613048565b6000828152602081208201600019908101805473ffffffffffffffffffffffffffffffffffffffff1916905590910190915560035467ffffffffffffffff811115611da057611da0612dd0565b604051908082528060200260200182016040528015611dc9578160200160208202803683370190505b5090506000805b600454811015611e8c57836001600160a01b031660048281548110611df757611df7612fff565b6000918252602090912001546001600160a01b031614611e7a5760048181548110611e2457611e24612fff565b9060005260206000200160009054906101000a90046001600160a01b0316838381518110611e5457611e54612fff565b6001600160a01b039092166020928302919091019091015281611e7681613015565b9250505b80611e8481613015565b915050611dd0565b508151611ea0906004906020850190612c3c565b506040516001600160a01b038416907f09a1db4b80c32706328728508c941a6b954f31eb5affd32f236c1fd405f8fea490600090a2611edd612322565b50505050565b6000611a9b8261265d565b60038181548110610c1157600080fd5b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b158015611f4857600080fd5b505afa158015611f5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f809190612f7a565b6001600160a01b031614611fc95760405162461bcd60e51b815260206004820152601060248201526f3737ba16ba343296b3b7bb32b93737b960811b60448201526064016105d1565b604080518082019091526002815261031360f41b60208201526001600160a01b0384166120095760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b0383166000908152600560209081526040918290205482518084019093526002835261313560f01b9183019190915260ff16156120615760405162461bcd60e51b81526004016105d19190612f47565b50816001546120709190613030565b6001819055604080518082019091526002815261062760f31b60208201529061271010156120b15760405162461bcd60e51b81526004016105d19190612f47565b50604080518082019091526002815261313160f01b60208201526127108211156120ee5760405162461bcd60e51b81526004016105d19190612f47565b50600060405180610120016040528060011515815260200160008152602001600081526020014281526020016000815260200160008152602001600081526020018481526020018381525090508060056000866001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e0820151816007015561010082015181600801559050506003849080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b031602179055506004849080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b03160217905550836001600160a01b03167f45bb3eed5cd098efb0a286413fb1f3c11841762610cefbabae6a772963e916ba84846040516122ab929190918252602082015260400190565b60405180910390a2611edd612322565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b179052610bfc908490612a6f565b6003546001546000901561240a5760005b8281101561240857600154600560006003848154811061235557612355612fff565b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000206007015460056000600385815481106123ae576123ae612fff565b60009182526020808320909101546001600160a01b031683528201929092526040019020600801546123e0919061305e565b6123ea919061307d565b6123f49083613030565b91508061240081613015565b915050612333565b505b600680549082905560408051918252602082018390527f2d6a5770d560080bb77885132eea46b6db3b15e70e6e5e73087ea7bcd138fcf0910160405180910390a15050565b600081831061245e5781612460565b825b9392505050565b8060056000846001600160a01b03166001600160a01b0316815260200190815260200160002060040154101560405180604001604052806002815260200161032360f41b815250906124cc5760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b038216600090815260056020819052604082200180548392906124f8908490613030565b90915550506001600160a01b03821660009081526005602052604081206004018054839290612528908490612fe8565b9250508190555080600260008282546125419190612fe8565b92505081905550600061260a600060029054906101000a90046001600160a01b03166001600160a01b031663d4c3eea06040518163ffffffff1660e01b815260040160206040518083038186803b15801561259b57600080fd5b505afa1580156125af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d39190612fb9565b6125df6127108561305e565b6125e9919061307d565b6001600160a01b03851660009081526005602052604090206007015461244f565b6001600160a01b03841660009081526005602052604081206007018054929350839290919061263a908490612fe8565b9250508190555080600160008282546126539190612fe8565b9091555050505050565b60008060056000846001600160a01b03166001600160a01b03168152602001908152602001600020600401549050600060029054906101000a90046001600160a01b03166001600160a01b0316634938649a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156126d957600080fd5b505afa1580156126ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127119190612f97565b1561271c5792915050565b6000612710600060029054906101000a90046001600160a01b03166001600160a01b031663d4c3eea06040518163ffffffff1660e01b815260040160206040518083038186803b15801561276f57600080fd5b505afa158015612783573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a79190612fb9565b6001600160a01b0386166000908152600560205260409020600701546127cd919061305e565b6127d7919061307d565b90508082116127e75760006127f1565b6127f18183612fe8565b949350505050565b60008060029054906101000a90046001600160a01b03166001600160a01b0316634938649a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561284857600080fd5b505afa15801561285c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128809190612f97565b1561288d57506000919050565b60008060029054906101000a90046001600160a01b03166001600160a01b031663d4c3eea06040518163ffffffff1660e01b815260040160206040518083038186803b1580156128dc57600080fd5b505afa1580156128f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129149190612fb9565b6001600160a01b038416600090815260056020526040812060070154919250906127109061294390849061305e565b61294d919061307d565b6001600160a01b03851660009081526005602052604090206004015490915081811061297e57506000949350505050565b600061271084600154612991919061305e565b61299b919061307d565b905080600254106129b25750600095945050505050565b60006129be8385612fe8565b9050612a64612a52600060029054906101000a90046001600160a01b03166001600160a01b031663b8cb343d6040518163ffffffff1660e01b815260040160206040518083038186803b158015612a1457600080fd5b505afa158015612a28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4c9190612fb9565b8361244f565b600254612a5f9085612fe8565b61244f565b979650505050505050565b6000612ac4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612b419092919063ffffffff16565b805190915015610bfc5780806020019051810190612ae29190612f97565b610bfc5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105d1565b60606127f1848460008585843b612b9a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105d1565b600080866001600160a01b03168587604051612bb6919061309f565b60006040518083038185875af1925050503d8060008114612bf3576040519150601f19603f3d011682016040523d82523d6000602084013e612bf8565b606091505b5091509150612a6482828660608315612c12575081612460565b825115612c225782518084602001fd5b8160405162461bcd60e51b81526004016105d19190612f47565b828054828255906000526020600020908101928215612c9e579160200282015b82811115612c9e578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190612c5c565b50612caa929150612cae565b5090565b5b80821115612caa5760008155600101612caf565b6001600160a01b038116811461067457600080fd5b8035612ce381612cc3565b919050565b600060208284031215612cfa57600080fd5b813561246081612cc3565b6020808252825182820181905260009190848201906040850190845b81811015612d465783516001600160a01b031683529284019291840191600101612d21565b50909695505050505050565b60008060408385031215612d6557600080fd5b8235612d7081612cc3565b946020939093013593505050565b600060208284031215612d9057600080fd5b5035919050565b60008060408385031215612daa57600080fd5b8235612db581612cc3565b91506020830135612dc581612cc3565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60006020808385031215612df957600080fd5b823567ffffffffffffffff80821115612e1157600080fd5b818501915085601f830112612e2557600080fd5b813581811115612e3757612e37612dd0565b8060051b604051601f19603f83011681018181108582111715612e5c57612e5c612dd0565b604052918252848201925083810185019188831115612e7a57600080fd5b938501935b82851015612e9f57612e9085612cd8565b84529385019392850192612e7f565b98975050505050505050565b60008060008060808587031215612ec157600080fd5b8435612ecc81612cc3565b966020860135965060408601359560600135945092505050565b600080600060608486031215612efb57600080fd5b8335612f0681612cc3565b95602085013595506040909401359392505050565b60005b83811015612f36578181015183820152602001612f1e565b83811115611edd5750506000910152565b6020815260008251806020840152612f66816040850160208701612f1b565b601f01601f19169190910160400192915050565b600060208284031215612f8c57600080fd5b815161246081612cc3565b600060208284031215612fa957600080fd5b8151801515811461246057600080fd5b600060208284031215612fcb57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015612ffa57612ffa612fd2565b500390565b634e487b7160e01b600052603260045260246000fd5b600060001982141561302957613029612fd2565b5060010190565b6000821982111561304357613043612fd2565b500190565b634e487b7160e01b600052603160045260246000fd5b600081600019048311821515161561307857613078612fd2565b500290565b60008261309a57634e487b7160e01b600052601260045260246000fd5b500490565b600082516130b1818460208701612f1b565b919091019291505056fea26469706673582212203678b2a39cfa651d5adc7bdce7acf7898228010e33ba2bfd11d258c25b906e1a64736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101ae5760003560e01c8063854f4d80116100ee578063c0cbbca611610097578063fa34d61111610071578063fa34d61114610423578063fc7b9c1814610436578063fd967f471461043f578063ffa1ad741461044857600080fd5b8063c0cbbca6146103ea578063d53ddc26146103fd578063d574ea3d1461041057600080fd5b8063a066654b116100c8578063a066654b146103a7578063b49a60bb146103cf578063b64321ec146103d757600080fd5b8063854f4d80146103555780638f88d18c146103685780639f2b28331461037b57600080fd5b80632df9eab91161015b578063346162d511610135578063346162d51461031357806362518ddf1461031c5780636cb56d191461032f5780637f13086e1461034257600080fd5b80632df9eab9146102d65780632fb9ba31146102ed57806332b77a761461030057600080fd5b806319ab453c1161018c57806319ab453c14610217578063228bfd9f1461022a5780632a1f6ec1146102ce57600080fd5b806301681a62146101b357806311183052146101c857806316f0115b146101e6575b600080fd5b6101c66101c1366004612ce8565b610479565b005b6101d0610677565b6040516101dd9190612d05565b60405180910390f35b6000546101ff906201000090046001600160a01b031681565b6040516001600160a01b0390911681526020016101dd565b6101c6610225366004612ce8565b6106d9565b610288610238366004612ce8565b600560208190526000918252604090912080546001820154600283015460038401546004850154958501546006860154600787015460089097015460ff9096169794969395929493919290919089565b604080519915158a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c084015260e0830152610100820152610120016101dd565b6101c661080c565b6102df60015481565b6040519081526020016101dd565b6101c66102fb366004612d52565b610972565b6101c661030e366004612d52565b610a38565b6102df60065481565b6101ff61032a366004612d7e565b610c01565b6101c661033d366004612d97565b610c2b565b6101c6610350366004612d52565b6110ac565b6101c6610363366004612de6565b6111a2565b6101c6610376366004612d52565b611409565b6102df610389366004612ce8565b6001600160a01b031660009081526005602052604090206004015490565b6103ba6103b5366004612eab565b6116b2565b604080519283526020830191909152016101dd565b6101d0611a30565b6102df6103e5366004612ce8565b611a90565b6101c66103f8366004612d7e565b611aa1565b6102df61040b366004612ce8565b611ee3565b6101ff61041e366004612d7e565b611eee565b6101c6610431366004612ee6565b611efe565b6102df60025481565b6102df61271081565b61046c604051806040016040528060058152602001640352e312e360dc1b81525081565b6040516101dd9190612f47565b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b1580156104c357600080fd5b505afa1580156104d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104fb9190612f7a565b6001600160a01b0316148061059a57506000546201000090046001600160a01b0316636ba42aaa336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b15801561056257600080fd5b505afa158015610576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a9190612f97565b6105da5760405162461bcd60e51b815260206004820152600c60248201526b3737ba16b096b5b2b2b832b960a11b60448201526064015b60405180910390fd5b6000546040516370a0823160e01b8152306004820152610674916201000090046001600160a01b0390811691908416906370a082319060240160206040518083038186803b15801561062b57600080fd5b505afa15801561063f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106639190612fb9565b6001600160a01b03841691906122bb565b50565b606060048054806020026020016040519081016040528092919081815260200182805480156106cf57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116106b1575b5050505050905090565b600054610100900460ff16806106f2575060005460ff16155b6107645760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105d1565b600054610100900460ff16158015610786576000805461ffff19166101011790555b604080518082019091526002815261031360f41b60208201526001600160a01b0383166107c65760405162461bcd60e51b81526004016105d19190612f47565b506000805475ffffffffffffffffffffffffffffffffffffffff00001916620100006001600160a01b038516021790558015610808576000805461ff00191690555b5050565b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b15801561085657600080fd5b505afa15801561086a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088e9190612f7a565b6001600160a01b0316148061092d57506000546201000090046001600160a01b0316636ba42aaa336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b1580156108f557600080fd5b505afa158015610909573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092d9190612f97565b6109685760405162461bcd60e51b815260206004820152600c60248201526b3737ba16b096b5b2b2b832b960a11b60448201526064016105d1565b610970612322565b565b6000546001600160a01b03620100009091041633146109c05760405162461bcd60e51b815260206004820152600a6024820152691b9bdd0b584b5c1bdbdb60b21b60448201526064016105d1565b6001600160a01b0382166000908152600560205260409020600401546109e6908261244f565b6001600160a01b038316600090815260056020526040812060040180549293508392909190610a16908490612fe8565b925050819055508060026000828254610a2f9190612fe8565b90915550505050565b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b158015610a8257600080fd5b505afa158015610a96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aba9190612f7a565b6001600160a01b031614610b035760405162461bcd60e51b815260206004820152601060248201526f3737ba16ba343296b3b7bb32b93737b960811b60448201526064016105d1565b6001600160a01b0382166000908152600560209081526040918290205482518084019093526002835261189b60f11b9183019190915260ff16610b595760405162461bcd60e51b81526004016105d19190612f47565b50604080518082019091526002815261313160f01b6020820152612710821115610b965760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b038216600081815260056020908152604091829020600801805490859055825181815291820185905292917f3e57eabb1906726caa174b6716b34373026dfd25dbae17ba47ec46e8a9ced9ee910160405180910390a2610bfc612322565b505050565b60048181548110610c1157600080fd5b6000918252602090912001546001600160a01b0316905081565b6000546001600160a01b0362010000909104163314610c795760405162461bcd60e51b815260206004820152600a6024820152691b9bdd0b584b5c1bdbdb60b21b60448201526064016105d1565b6001600160a01b0382166000908152600560209081526040918290205482518084019093526002835261189b60f11b9183019190915260ff16610ccf5760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b0381166000908152600560209081526040918290205482518084019093526002835261313560f01b9183019190915260ff1615610d275760405162461bcd60e51b81526004016105d19190612f47565b506000604051806101200160405280600115158152602001600081526020016000815260200160056000866001600160a01b03166001600160a01b0316815260200190815260200160002060030154815260200160056000866001600160a01b03166001600160a01b03168152602001908152602001600020600401548152602001600081526020016000815260200160056000866001600160a01b03166001600160a01b0316815260200190815260200160002060070154815260200160056000866001600160a01b03166001600160a01b0316815260200190815260200160002060080154815250905060056000846001600160a01b03166001600160a01b03168152602001908152602001600020600080820160006101000a81549060ff02191690556001820160009055600282016000905560038201600090556004820160009055600582016000905560068201600090556007820160009055600882016000905550508060056000846001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070155610100820151816008015590505060005b600354811015610fc757836001600160a01b031660038281548110610f5357610f53612fff565b6000918252602090912001546001600160a01b03161415610fb5578260038281548110610f8257610f82612fff565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610fc7565b80610fbf81613015565b915050610f2c565b5060005b60045481101561106657836001600160a01b031660048281548110610ff257610ff2612fff565b6000918252602090912001546001600160a01b0316141561105457826004828154811061102157611021612fff565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550611066565b8061105e81613015565b915050610fcb565b50816001600160a01b0316836001600160a01b03167f100b69bb6b504e1252e36b375233158edee64d071b399e2f81473a695fd1b02160405160405180910390a3505050565b6000546001600160a01b03620100009091041633146110fa5760405162461bcd60e51b815260206004820152600a6024820152691b9bdd0b584b5c1bdbdb60b21b60448201526064016105d1565b6001600160a01b0382166000908152600560209081526040918290205482518084019093526002835261189b60f11b9183019190915260ff166111505760405162461bcd60e51b81526004016105d19190612f47565b5061115b8282612467565b816001600160a01b03167f3ffa9beb41b46c88b16758ef6c236ebd4d07cdfd4d22471030eb6b2d662482d98260405161119691815260200190565b60405180910390a25050565b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b1580156111ec57600080fd5b505afa158015611200573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112249190612f7a565b6001600160a01b031614806112c357506000546201000090046001600160a01b031663dd57366a336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b15801561128b57600080fd5b505afa15801561129f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c39190612f97565b6113025760405162461bcd60e51b815260206004820152601060248201526f3737ba16b096b6b0b4b73a30b4b732b960811b60448201526064016105d1565b805160045481148015611316575060035481145b604051806040016040528060018152602001600d60fa1b8152509061134e5760405162461bcd60e51b81526004016105d19190612f47565b5060005b818110156113f5576005600084838151811061137057611370612fff565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060000160009054906101000a900460ff1660405180604001604052806002815260200161189b60f11b815250906113e25760405162461bcd60e51b81526004016105d19190612f47565b50806113ed81613015565b915050611352565b508151610bfc906004906020850190612c3c565b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b15801561145357600080fd5b505afa158015611467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148b9190612f7a565b6001600160a01b0316148061152a57506000546201000090046001600160a01b031663dd57366a336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b1580156114f257600080fd5b505afa158015611506573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152a9190612f97565b6115695760405162461bcd60e51b815260206004820152601060248201526f3737ba16b096b6b0b4b73a30b4b732b960811b60448201526064016105d1565b6001600160a01b0382166000908152600560209081526040918290205482518084019093526002835261189b60f11b9183019190915260ff166115bf5760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b03821660009081526005602052604090206007015460015482916115ea91612fe8565b6115f49190613030565b6001819055604080518082019091526002815261062760f31b60208201529061271010156116355760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b0382166000818152600560209081526040918290206007015482519081529081018490527fab9990442b7ef5dfed05018d2d947ceb38710eda84b3e3b32940cbb28867ee0e910160405180910390a26001600160a01b0382166000908152600560205260409020600701819055610808612322565b6000805481906001600160a01b03620100009091041633146117035760405162461bcd60e51b815260206004820152600a6024820152691b9bdd0b584b5c1bdbdb60b21b60448201526064016105d1565b6001600160a01b0386166000908152600560209081526040918290205482518084019093526002835261189b60f11b9183019190915260ff166117595760405162461bcd60e51b81526004016105d19190612f47565b506117648386613030565b600060029054906101000a90046001600160a01b03166001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117b257600080fd5b505afa1580156117c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ea9190612f7a565b6040516370a0823160e01b81526001600160a01b03898116600483015291909116906370a082319060240160206040518083038186803b15801561182d57600080fd5b505afa158015611841573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118659190612fb9565b1015604051806040016040528060018152602001603960f81b8152509061189f5760405162461bcd60e51b81526004016105d19190612f47565b5083156118b0576118b08685612467565b60006118bb8761265d565b90506118c7818561244f565b92508215611919576001600160a01b038716600090815260056020526040812060040180548592906118fa908490612fe8565b9250508190555082600260008282546119139190612fe8565b90915550505b611922876127f9565b91508115611974576001600160a01b03871660009081526005602052604081206004018054849290611955908490613030565b92505081905550816002600082825461196e9190613030565b90915550505b85156119ab576001600160a01b038716600090815260056020526040812060060180548892906119a5908490613030565b90915550505b6001600160a01b0387166000818152600560209081526040918290204260038201556004015460025483518b81529283018a90529282018790526060820152608081019190915260a081018490527f29c6c60e040fcd722949346bda66341e8859b20b9a2124a625326ad10373391b9060c00160405180910390a25094509492505050565b606060038054806020026020016040519081016040528092919081815260200182805480156106cf576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116106b1575050505050905090565b6000611a9b826127f9565b92915050565b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b158015611aeb57600080fd5b505afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190612f7a565b6001600160a01b031614611b6c5760405162461bcd60e51b815260206004820152601060248201526f3737ba16ba343296b3b7bb32b93737b960811b60448201526064016105d1565b600060038281548110611b8157611b81612fff565b60009182526020808320909101546001600160a01b0316808352600582526040928390205483518085019094526002845261189b60f11b92840192909252925060ff16611be15760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b0381166000908152600560209081526040918290206004015482518084019093526002835261313960f01b9183019190915215611c395760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b0381166000908152600560205260408120600701546001805491929091611c69908490612fe8565b90915550506001600160a01b03811660009081526005602081905260408220805460ff19168155600180820184905560028201849055600380830185905560048301859055928201849055600682018490556007820184905560089091019290925580549091611cd891612fe8565b81548110611ce857611ce8612fff565b600091825260209091200154600380546001600160a01b039092169184908110611d1457611d14612fff565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506003805480611d5357611d53613048565b6000828152602081208201600019908101805473ffffffffffffffffffffffffffffffffffffffff1916905590910190915560035467ffffffffffffffff811115611da057611da0612dd0565b604051908082528060200260200182016040528015611dc9578160200160208202803683370190505b5090506000805b600454811015611e8c57836001600160a01b031660048281548110611df757611df7612fff565b6000918252602090912001546001600160a01b031614611e7a5760048181548110611e2457611e24612fff565b9060005260206000200160009054906101000a90046001600160a01b0316838381518110611e5457611e54612fff565b6001600160a01b039092166020928302919091019091015281611e7681613015565b9250505b80611e8481613015565b915050611dd0565b508151611ea0906004906020850190612c3c565b506040516001600160a01b038416907f09a1db4b80c32706328728508c941a6b954f31eb5affd32f236c1fd405f8fea490600090a2611edd612322565b50505050565b6000611a9b8261265d565b60038181548110610c1157600080fd5b6000546040805163030d028960e21b8152905133926201000090046001600160a01b031691630c340a24916004808301926020929190829003018186803b158015611f4857600080fd5b505afa158015611f5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f809190612f7a565b6001600160a01b031614611fc95760405162461bcd60e51b815260206004820152601060248201526f3737ba16ba343296b3b7bb32b93737b960811b60448201526064016105d1565b604080518082019091526002815261031360f41b60208201526001600160a01b0384166120095760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b0383166000908152600560209081526040918290205482518084019093526002835261313560f01b9183019190915260ff16156120615760405162461bcd60e51b81526004016105d19190612f47565b50816001546120709190613030565b6001819055604080518082019091526002815261062760f31b60208201529061271010156120b15760405162461bcd60e51b81526004016105d19190612f47565b50604080518082019091526002815261313160f01b60208201526127108211156120ee5760405162461bcd60e51b81526004016105d19190612f47565b50600060405180610120016040528060011515815260200160008152602001600081526020014281526020016000815260200160008152602001600081526020018481526020018381525090508060056000866001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e0820151816007015561010082015181600801559050506003849080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b031602179055506004849080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b03160217905550836001600160a01b03167f45bb3eed5cd098efb0a286413fb1f3c11841762610cefbabae6a772963e916ba84846040516122ab929190918252602082015260400190565b60405180910390a2611edd612322565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b179052610bfc908490612a6f565b6003546001546000901561240a5760005b8281101561240857600154600560006003848154811061235557612355612fff565b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000206007015460056000600385815481106123ae576123ae612fff565b60009182526020808320909101546001600160a01b031683528201929092526040019020600801546123e0919061305e565b6123ea919061307d565b6123f49083613030565b91508061240081613015565b915050612333565b505b600680549082905560408051918252602082018390527f2d6a5770d560080bb77885132eea46b6db3b15e70e6e5e73087ea7bcd138fcf0910160405180910390a15050565b600081831061245e5781612460565b825b9392505050565b8060056000846001600160a01b03166001600160a01b0316815260200190815260200160002060040154101560405180604001604052806002815260200161032360f41b815250906124cc5760405162461bcd60e51b81526004016105d19190612f47565b506001600160a01b038216600090815260056020819052604082200180548392906124f8908490613030565b90915550506001600160a01b03821660009081526005602052604081206004018054839290612528908490612fe8565b9250508190555080600260008282546125419190612fe8565b92505081905550600061260a600060029054906101000a90046001600160a01b03166001600160a01b031663d4c3eea06040518163ffffffff1660e01b815260040160206040518083038186803b15801561259b57600080fd5b505afa1580156125af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d39190612fb9565b6125df6127108561305e565b6125e9919061307d565b6001600160a01b03851660009081526005602052604090206007015461244f565b6001600160a01b03841660009081526005602052604081206007018054929350839290919061263a908490612fe8565b9250508190555080600160008282546126539190612fe8565b9091555050505050565b60008060056000846001600160a01b03166001600160a01b03168152602001908152602001600020600401549050600060029054906101000a90046001600160a01b03166001600160a01b0316634938649a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156126d957600080fd5b505afa1580156126ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127119190612f97565b1561271c5792915050565b6000612710600060029054906101000a90046001600160a01b03166001600160a01b031663d4c3eea06040518163ffffffff1660e01b815260040160206040518083038186803b15801561276f57600080fd5b505afa158015612783573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a79190612fb9565b6001600160a01b0386166000908152600560205260409020600701546127cd919061305e565b6127d7919061307d565b90508082116127e75760006127f1565b6127f18183612fe8565b949350505050565b60008060029054906101000a90046001600160a01b03166001600160a01b0316634938649a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561284857600080fd5b505afa15801561285c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128809190612f97565b1561288d57506000919050565b60008060029054906101000a90046001600160a01b03166001600160a01b031663d4c3eea06040518163ffffffff1660e01b815260040160206040518083038186803b1580156128dc57600080fd5b505afa1580156128f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129149190612fb9565b6001600160a01b038416600090815260056020526040812060070154919250906127109061294390849061305e565b61294d919061307d565b6001600160a01b03851660009081526005602052604090206004015490915081811061297e57506000949350505050565b600061271084600154612991919061305e565b61299b919061307d565b905080600254106129b25750600095945050505050565b60006129be8385612fe8565b9050612a64612a52600060029054906101000a90046001600160a01b03166001600160a01b031663b8cb343d6040518163ffffffff1660e01b815260040160206040518083038186803b158015612a1457600080fd5b505afa158015612a28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4c9190612fb9565b8361244f565b600254612a5f9085612fe8565b61244f565b979650505050505050565b6000612ac4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612b419092919063ffffffff16565b805190915015610bfc5780806020019051810190612ae29190612f97565b610bfc5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105d1565b60606127f1848460008585843b612b9a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105d1565b600080866001600160a01b03168587604051612bb6919061309f565b60006040518083038185875af1925050503d8060008114612bf3576040519150601f19603f3d011682016040523d82523d6000602084013e612bf8565b606091505b5091509150612a6482828660608315612c12575081612460565b825115612c225782518084602001fd5b8160405162461bcd60e51b81526004016105d19190612f47565b828054828255906000526020600020908101928215612c9e579160200282015b82811115612c9e578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190612c5c565b50612caa929150612cae565b5090565b5b80821115612caa5760008155600101612caf565b6001600160a01b038116811461067457600080fd5b8035612ce381612cc3565b919050565b600060208284031215612cfa57600080fd5b813561246081612cc3565b6020808252825182820181905260009190848201906040850190845b81811015612d465783516001600160a01b031683529284019291840191600101612d21565b50909695505050505050565b60008060408385031215612d6557600080fd5b8235612d7081612cc3565b946020939093013593505050565b600060208284031215612d9057600080fd5b5035919050565b60008060408385031215612daa57600080fd5b8235612db581612cc3565b91506020830135612dc581612cc3565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60006020808385031215612df957600080fd5b823567ffffffffffffffff80821115612e1157600080fd5b818501915085601f830112612e2557600080fd5b813581811115612e3757612e37612dd0565b8060051b604051601f19603f83011681018181108582111715612e5c57612e5c612dd0565b604052918252848201925083810185019188831115612e7a57600080fd5b938501935b82851015612e9f57612e9085612cd8565b84529385019392850192612e7f565b98975050505050505050565b60008060008060808587031215612ec157600080fd5b8435612ecc81612cc3565b966020860135965060408601359560600135945092505050565b600080600060608486031215612efb57600080fd5b8335612f0681612cc3565b95602085013595506040909401359392505050565b60005b83811015612f36578181015183820152602001612f1e565b83811115611edd5750506000910152565b6020815260008251806020840152612f66816040850160208701612f1b565b601f01601f19169190910160400192915050565b600060208284031215612f8c57600080fd5b815161246081612cc3565b600060208284031215612fa957600080fd5b8151801515811461246057600080fd5b600060208284031215612fcb57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015612ffa57612ffa612fd2565b500390565b634e487b7160e01b600052603260045260246000fd5b600060001982141561302957613029612fd2565b5060010190565b6000821982111561304357613043612fd2565b500190565b634e487b7160e01b600052603160045260246000fd5b600081600019048311821515161561307857613078612fd2565b500290565b60008261309a57634e487b7160e01b600052601260045260246000fd5b500490565b600082516130b1818460208701612f1b565b919091019291505056fea26469706673582212203678b2a39cfa651d5adc7bdce7acf7898228010e33ba2bfd11d258c25b906e1a64736f6c63430008090033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.