Overview
FTM Balance
0 FTM
FTM Value
$0.00More Info
Private Name Tags
ContractCreator:
Sponsored
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 25455085 | 830 days ago | IN | Create: ContractReader | 0 FTM | 1.34530151 |
Latest 1 internal transaction
Parent Txn Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
25455085 | 830 days ago | Contract Creation | 0 FTM |
Loading...
Loading
Contract Name:
ContractReader
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 150 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; import "../base/governance/Controllable.sol"; import "../base/interface/IBookkeeper.sol"; import "../base/interface/ISmartVault.sol"; import "../base/interface/IStrategy.sol"; import "../infrastructure/price/IPriceCalculator.sol"; /// @title View data reader for using on website UI and other integrations /// @author belbix contract ContractReader is Initializable, Controllable { using SafeMath for uint256; string public constant VERSION = "1.0.4"; uint256 constant public PRECISION = 1e18; mapping(bytes32 => address) internal tools; function initialize(address _controller, address _calculator) external initializer { Controllable.initializeControllable(_controller); tools[keccak256(abi.encodePacked("calculator"))] = _calculator; } event ToolAddressUpdated(address newValue); struct VaultInfo { address addr; string name; uint256 created; bool active; uint256 tvl; uint256 tvlUsdc; uint256 decimals; address underlying; address[] rewardTokens; uint256[] rewardTokensBal; uint256[] rewardTokensBalUsdc; uint256 duration; uint256[] rewardsApr; uint256 ppfsApr; uint256 users; // strategy address strategy; uint256 strategyCreated; IStrategy.Platform platform; address[] assets; address[] strategyRewards; bool strategyOnPause; uint256 earned; } struct VaultInfoLight { address addr; uint256 created; bool active; uint256 tvl; uint256 tvlUsdc; address underlying; address[] rewardTokens; uint256[] rewardsApr; uint256 ppfsApr; IStrategy.Platform platform; address[] assets; uint256 earned; } struct UserInfo { address wallet; address vault; uint256 underlyingBalance; uint256 underlyingBalanceUsdc; uint256 depositedUnderlying; uint256 depositedUnderlyingUsdc; uint256 depositedShare; address[] rewardTokens; uint256[] rewards; uint256[] rewardsUsdc; uint256[] rewardsBoost; uint256[] rewardsBoostUsdc; } struct UserInfoLight { uint256 depositedUnderlying; uint256 depositedUnderlyingUsdc; uint256 depositedShare; } struct VaultWithUserInfo { VaultInfo vault; UserInfo user; } struct VaultWithUserInfoLight { VaultInfoLight vault; UserInfoLight user; } // ************************************************************** // HEAVY QUERIES //*************************************************************** function vaultInfo(address vault) public view returns (VaultInfo memory) { address strategy = ISmartVault(vault).strategy(); VaultInfo memory v = VaultInfo( vault, vaultName(vault), vaultCreated(vault), vaultActive(vault), vaultTvl(vault), vaultTvlUsdc(vault), vaultDecimals(vault), vaultUnderlying(vault), vaultRewardTokens(vault), vaultRewardTokensBal(vault), vaultRewardTokensBalUsdc(vault), vaultDuration(vault), vaultRewardsApr(vault), vaultPpfsApr(vault), vaultUsers(vault), strategy, strategyCreated(strategy), strategyPlatform(strategy), strategyAssets(strategy), strategyRewardTokens(strategy), strategyPausedInvesting(strategy), strategyEarned(strategy) ); return v; } function vaultInfoLight(address vault) public view returns (VaultInfoLight memory) { address strategy = ISmartVault(vault).strategy(); VaultInfoLight memory v = VaultInfoLight( vault, vaultCreated(vault), vaultActive(vault), vaultTvl(vault), vaultTvlUsdc(vault), vaultUnderlying(vault), vaultRewardTokens(vault), vaultRewardsApr(vault), vaultPpfsApr(vault), strategyPlatform(strategy), strategyAssets(strategy), strategyEarned(strategy) ); return v; } function vaultInfos(address[] memory _vaults) external view returns (VaultInfo[] memory){ VaultInfo[] memory result = new VaultInfo[](_vaults.length); for (uint256 i = 0; i < _vaults.length; i++) { result[i] = vaultInfo(_vaults[i]); } return result; } function vaultInfosLight(address[] memory _vaults) external view returns (VaultInfoLight[] memory){ VaultInfoLight[] memory result = new VaultInfoLight[](_vaults.length); for (uint256 i = 0; i < _vaults.length; i++) { result[i] = vaultInfoLight(_vaults[i]); } return result; } function userInfo(address _user, address _vault) public view returns (UserInfo memory) { address[] memory rewardTokens = ISmartVault(_vault).rewardTokens(); uint256[] memory rewardsEarned = new uint256[](rewardTokens.length); for (uint256 i = 0; i < rewardTokens.length; i++) { rewardsEarned[i] = ISmartVault(_vault).earned(rewardTokens[i], _user); } return UserInfo( _user, _vault, userUnderlyingBalance(_user, _vault), userUnderlyingBalanceUsdc(_user, _vault), userDepositedUnderlying(_user, _vault), userDepositedUnderlyingUsdc(_user, _vault), userDepositedShare(_user, _vault), rewardTokens, userRewards(_user, _vault), userRewardsUsdc(_user, _vault), userRewardsBoost(_user, _vault), userRewardsBoostUsdc(_user, _vault) ); } function userInfoLight(address _user, address _vault) public view returns (UserInfoLight memory) { return UserInfoLight( userDepositedUnderlying(_user, _vault), userDepositedUnderlyingUsdc(_user, _vault), userDepositedShare(_user, _vault) ); } function userInfosLight(address _user, address[] memory _vaults) external view returns (UserInfoLight[] memory) { UserInfoLight[] memory result = new UserInfoLight[](_vaults.length); for (uint256 i = 0; i < _vaults.length; i++) { result[i] = userInfoLight(_user, _vaults[i]); } return result; } function vaultWithUserInfos(address _user, address[] memory _vaults) external view returns (VaultWithUserInfo[] memory){ VaultWithUserInfo[] memory result = new VaultWithUserInfo[](_vaults.length); for (uint256 i = 0; i < _vaults.length; i++) { result[i] = VaultWithUserInfo( vaultInfo(_vaults[i]), userInfo(_user, _vaults[i]) ); } return result; } function vaultWithUserInfosLight(address _user, address[] memory _vaults) external view returns (VaultWithUserInfoLight[] memory){ VaultWithUserInfoLight[] memory result = new VaultWithUserInfoLight[](_vaults.length); for (uint256 i = 0; i < _vaults.length; i++) { result[i] = VaultWithUserInfoLight( vaultInfoLight(_vaults[i]), userInfoLight(_user, _vaults[i]) ); } return result; } function vaultWithUserInfoPages(address _user, uint256 page, uint256 pageSize) external view returns (VaultWithUserInfo[] memory){ uint256 size = vaults().length; require(size > 0, "empty vaults"); uint256 totalPages = size / pageSize; if (totalPages * pageSize < size) { totalPages++; } if (page > totalPages) { page = totalPages; } uint256 start = Math.min(page * pageSize, size - 1); uint256 end = Math.min((start + pageSize), size); VaultWithUserInfo[] memory result = new VaultWithUserInfo[](end - start); for (uint256 i = start; i < end; i++) { result[i - start] = VaultWithUserInfo( vaultInfo(vaults()[i]), userInfo(_user, vaults()[i]) ); } return result; } function vaultWithUserInfoPagesLight(address _user, uint256 page, uint256 pageSize) external view returns (VaultWithUserInfoLight[] memory){ uint256 size = vaults().length; require(size > 0, "empty vaults"); uint256 totalPages = size / pageSize; if (totalPages * pageSize < size) { totalPages++; } if (page > totalPages) { page = totalPages; } uint256 start = Math.min(page * pageSize, size - 1); uint256 end = Math.min((start + pageSize), size); VaultWithUserInfoLight[] memory result = new VaultWithUserInfoLight[](end - start); for (uint256 i = start; i < end; i++) { result[i - start] = VaultWithUserInfoLight( vaultInfoLight(vaults()[i]), userInfoLight(_user, vaults()[i]) ); } return result; } function tetuTokenValues() external view returns (uint256[] memory){ uint256 price = getPrice(IController(controller()).rewardToken()); uint256 mCap = ERC20(IController(controller()).rewardToken()).totalSupply() .mul(price).div(1e18); uint256[] memory result = new uint256[](2); result[0] = price; result[1] = mCap; return result; } function totalTvlUsdc(address[] memory _vaults) external view returns (uint256) { uint256 result = 0; for (uint256 i = 0; i < _vaults.length; i++) { result += vaultTvlUsdc(_vaults[i]); } return result; } function totalTetuBoughBack(address[] memory _vaults) external view returns (uint256) { uint256 result = 0; for (uint256 i = 0; i < _vaults.length; i++) { result += strategyEarned(ISmartVault(_vaults[i]).strategy()); } return result; } function totalTetuBoughBack2(address[] memory _strategies) external view returns (uint256) { uint256 result = 0; for (uint256 i = 0; i < _strategies.length; i++) { result += strategyEarned(_strategies[i]); } return result; } function totalUsers(address[] memory _vaults) external view returns (uint256) { uint256 result = 0; for (uint256 i = 0; i < _vaults.length; i++) { result += vaultUsers(_vaults[i]); } return result; } function totalUsersForAllVaults() external view returns (uint256) { address[] memory _vaults = vaults(); uint256 result = 0; for (uint256 i = 0; i < _vaults.length; i++) { result += vaultUsers(_vaults[i]); } return result; } // ********************** FIELDS *********************** // no decimals function vaultUsers(address _vault) public view returns (uint256){ return IBookkeeper(bookkeeper()).vaultUsersQuantity(_vault); } function vaultName(address _vault) public view returns (string memory){ return ERC20(_vault).name(); } function vaultPlatform(address _vault) public view returns (IStrategy.Platform){ return IStrategy(ISmartVault(_vault).strategy()).platform(); } // no decimals function vaultCreated(address _vault) public view returns (uint256){ return Controllable(_vault).created(); } function vaultActive(address _vault) public view returns (bool){ return ISmartVault(_vault).active(); } // normalized precision function vaultTvl(address _vault) public view returns (uint256){ return normalizePrecision(ISmartVault(_vault).underlyingBalanceWithInvestment(), vaultDecimals(_vault)); } // normalized precision function vaultTvlUsdc(address _vault) public view returns (uint256){ uint256 underlyingPrice = getPrice(vaultUnderlying(_vault)); return vaultTvl(_vault).mul(underlyingPrice).div(PRECISION); } function vaultDecimals(address _vault) public view returns (uint256){ return uint256(ERC20(_vault).decimals()); } function vaultUnderlying(address _vault) public view returns (address){ return ISmartVault(_vault).underlying(); } // no decimals function vaultDuration(address _vault) public view returns (uint256){ return ISmartVault(_vault).duration(); } function vaultRewardTokens(address _vault) public view returns (address[] memory){ return ISmartVault(_vault).rewardTokens(); } // normalized precision function vaultRewardTokensBal(address _vault) public view returns (uint256[] memory){ uint256[] memory result = new uint256[](vaultRewardTokens(_vault).length); for (uint256 i = 0; i < vaultRewardTokens(_vault).length; i++) { address rt = vaultRewardTokens(_vault)[i]; result[i] = normalizePrecision(ERC20(rt).balanceOf(_vault), ERC20(rt).decimals()); } return result; } // normalized precision function vaultRewardTokensBalUsdc(address _vault) public view returns (uint256[] memory){ uint256[] memory result = new uint256[](vaultRewardTokens(_vault).length); for (uint256 i = 0; i < vaultRewardTokens(_vault).length; i++) { address rt = vaultRewardTokens(_vault)[i]; uint256 rtPrice = getPrice(rt); uint256 bal = ERC20(rt).balanceOf(_vault).mul(rtPrice).div(PRECISION); result[i] = normalizePrecision(bal, ERC20(rt).decimals()); } return result; } // normalized precision function vaultRewardsApr(address _vault) public view returns (uint256[] memory){ ISmartVault vault = ISmartVault(_vault); uint256[] memory result = new uint256[](vault.rewardTokens().length); for (uint256 i = 0; i < vault.rewardTokens().length; i++) { result[i] = computeRewardApr(_vault, vault.rewardTokens()[i]); } return result; } // normalized precision function computeRewardApr(address _vault, address rt) public view returns (uint256) { uint256 periodFinish = ISmartVault(_vault).periodFinishForToken(rt); // already normalized precision uint256 tvlUsd = vaultTvlUsdc(_vault); uint256 rtPrice = getPrice(rt); uint256 rewardsForFullPeriod = ISmartVault(_vault).rewardRateForToken(rt) .mul(ISmartVault(_vault).duration()); // keep precision numbers if (tvlUsd != 0 && rewardsForFullPeriod != 0 && periodFinish > block.timestamp) { uint256 currentPeriod = periodFinish.sub(block.timestamp); uint256 periodRatio = currentPeriod.mul(PRECISION).div(ISmartVault(_vault).duration()); uint256 rtBalanceUsd = rewardsForFullPeriod .mul(periodRatio) .mul(rtPrice) .div(1e36); // amounts should have the same decimals rtBalanceUsd = normalizePrecision(rtBalanceUsd, ERC20(rt).decimals()); return computeApr(tvlUsd, rtBalanceUsd, currentPeriod); } else { return 0; } } // https://www.investopedia.com/terms/a/apr.asp // TVL and rewards should be in the same currency and with the same decimals function computeApr(uint256 tvl, uint256 rewards, uint256 duration) public pure returns (uint256) { uint256 rewardsPerTvlRatio = rewards.mul(PRECISION).div(tvl).mul(PRECISION); return rewardsPerTvlRatio.mul(PRECISION).div(duration.mul(PRECISION).div(1 days)) .mul(uint256(365)).mul(uint256(100)).div(PRECISION); } // normalized precision function vaultPpfs(address _vault) public view returns (uint256){ return normalizePrecision(ISmartVault(_vault).getPricePerFullShare(), vaultDecimals(_vault)); } // normalized precision function vaultPpfsApr(address _vault) public view returns (uint256){ return normalizePrecision(computePpfsApr( ISmartVault(_vault).getPricePerFullShare(), 10 ** vaultDecimals(_vault), block.timestamp, vaultCreated(_vault) ), vaultDecimals(_vault)); } // it is an experimental metric and shows very volatile value // normalized precision function vaultPpfsLastApr(address _vault) external view returns (uint256){ IBookkeeper.PpfsChange memory lastPpfsChange = IBookkeeper(bookkeeper()).lastPpfsChange(_vault); // skip fresh vault if (lastPpfsChange.time == 0) { return 0; } return normalizePrecision(computePpfsApr( lastPpfsChange.value, lastPpfsChange.oldValue, lastPpfsChange.time, lastPpfsChange.oldTime ), vaultDecimals(_vault)); } function computePpfsApr(uint256 ppfs, uint256 startPpfs, uint256 curTime, uint256 startTime) internal pure returns (uint256) { if (ppfs <= startPpfs) { return 0; } uint256 ppfsChange = ppfs.sub(startPpfs); uint256 timeChange = Math.max(curTime.sub(startTime), 1); return ppfsChange.mul(PRECISION).div(timeChange) .mul(uint256(1 days * 365)).mul(uint256(100)).div(PRECISION); } // no decimals function strategyCreated(address _strategy) public view returns (uint256){ return Controllable(_strategy).created(); } function strategyPlatform(address _strategy) public view returns (IStrategy.Platform){ return IStrategy(_strategy).platform(); } function strategyAssets(address _strategy) public view returns (address[] memory){ return IStrategy(_strategy).assets(); } function strategyRewardTokens(address _strategy) public view returns (address[] memory){ return IStrategy(_strategy).rewardTokens(); } function strategyPausedInvesting(address _strategy) public view returns (bool){ return IStrategy(_strategy).pausedInvesting(); } // normalized precision function strategyEarned(address _strategy) public view returns (uint256){ address targetToken = IController(controller()).rewardToken(); return normalizePrecision( IBookkeeper(bookkeeper()).targetTokenEarned(_strategy), ERC20(targetToken).decimals() ); } // normalized precision function userUnderlyingBalance(address _user, address _vault) public view returns (uint256) { return normalizePrecision(IERC20(vaultUnderlying(_vault)).balanceOf(_user), vaultDecimals(_vault)); } // normalized precision function userUnderlyingBalanceUsdc(address _user, address _vault) public view returns (uint256) { uint256 underlyingPrice = getPrice(vaultUnderlying(_vault)); return userUnderlyingBalance(_user, _vault).mul(underlyingPrice).div(PRECISION); } // normalized precision function userDepositedUnderlying(address _user, address _vault) public view returns (uint256) { return normalizePrecision( ISmartVault(_vault).underlyingBalanceWithInvestmentForHolder(_user), vaultDecimals(_vault) ); } function userDepositedUnderlyingUsdc(address _user, address _vault) public view returns (uint256) { uint256 underlyingPrice = getPrice(vaultUnderlying(_vault)); return userDepositedUnderlying(_user, _vault).mul(underlyingPrice).div(PRECISION); } // normalized precision function userDepositedShare(address _user, address _vault) public view returns (uint256) { return normalizePrecision(IERC20(_vault).balanceOf(_user), vaultDecimals(_vault)); } // normalized precision function userRewards(address _user, address _vault) public view returns (uint256[] memory) { address[] memory rewardTokens = ISmartVault(_vault).rewardTokens(); uint256[] memory rewards = new uint256[](rewardTokens.length); for (uint256 i = 0; i < rewardTokens.length; i++) { rewards[i] = normalizePrecision( ISmartVault(_vault).earned(rewardTokens[i], _user), ERC20(rewardTokens[i]).decimals() ); } return rewards; } // normalized precision function userRewardsBoost(address _user, address _vault) public view returns (uint256[] memory) { address[] memory rewardTokens = ISmartVault(_vault).rewardTokens(); uint256[] memory rewards = new uint256[](rewardTokens.length); for (uint256 i = 0; i < rewardTokens.length; i++) { rewards[i] = normalizePrecision( ISmartVault(_vault).earnedWithBoost(rewardTokens[i], _user), ERC20(rewardTokens[i]).decimals() ); } return rewards; } // normalized precision function userRewardsUsdc(address _user, address _vault) public view returns (uint256[] memory) { address[] memory rewardTokens = ISmartVault(_vault).rewardTokens(); uint256[] memory rewards = new uint256[](rewardTokens.length); for (uint256 i = 0; i < rewardTokens.length; i++) { uint256 price = getPrice(rewardTokens[i]); rewards[i] = normalizePrecision( ISmartVault(_vault).earned(rewardTokens[i], _user).mul(price).div(PRECISION), ERC20(rewardTokens[i]).decimals() ); } return rewards; } // normalized precision function userRewardsBoostUsdc(address _user, address _vault) public view returns (uint256[] memory) { address[] memory rewardTokens = ISmartVault(_vault).rewardTokens(); uint256[] memory rewards = new uint256[](rewardTokens.length); for (uint256 i = 0; i < rewardTokens.length; i++) { uint256 price = getPrice(rewardTokens[i]); rewards[i] = normalizePrecision( ISmartVault(_vault).earnedWithBoost(rewardTokens[i], _user).mul(price).div(PRECISION), ERC20(rewardTokens[i]).decimals() ); } return rewards; } function vaults() public view returns (address[] memory){ return IBookkeeper(bookkeeper()).vaults(); } function vaultsLength() public view returns (uint256){ return IBookkeeper(bookkeeper()).vaults().length; } function strategies() public view returns (address[] memory){ return IBookkeeper(bookkeeper()).strategies(); } function strategiesLength() public view returns (uint256){ return IBookkeeper(bookkeeper()).strategies().length; } function priceCalculator() public view returns (address) { return tools[keccak256(abi.encodePacked("calculator"))]; } function bookkeeper() public view returns (address) { return IController(controller()).bookkeeper(); } // normalized precision //noinspection NoReturn function getPrice(address _token) public view returns (uint256) { //slither-disable-next-line unused-return,variable-scope,uninitialized-local try IPriceCalculator(priceCalculator()).getPriceWithDefaultOutput(_token) returns (uint256 price){ return price; } catch { return 0; } } function normalizePrecision(uint256 amount, uint256 decimals) internal pure returns (uint256){ return amount.mul(PRECISION).div(10 ** decimals); } // *********** GOVERNANCE ACTIONS ***************** function setPriceCalculator(address newValue) external onlyControllerOrGovernance { tools[keccak256(abi.encodePacked("calculator"))] = newValue; emit ToolAddressUpdated(newValue); } }
// SPDX-License-Identifier: MIT 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"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a / b + (a % b == 0 ? 0 : 1); } }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "../interface/IController.sol"; import "../interface/IControllable.sol"; /// @title Implement basic functionality for any contract that require strict control /// @dev Can be used with upgradeable pattern. /// Require call initializeControllable() in any case. /// @author belbix abstract contract Controllable is Initializable, IControllable { bytes32 internal constant _CONTROLLER_SLOT = 0x5165972ef41194f06c5007493031d0b927c20741adcb74403b954009fd2c3617; bytes32 internal constant _CREATED_SLOT = 0x6f55f470bdc9cb5f04223fd822021061668e4dccb43e8727b295106dc9769c8a; /// @notice Controller address changed event UpdateController(address oldValue, address newValue); constructor() { assert(_CONTROLLER_SLOT == bytes32(uint256(keccak256("eip1967.controllable.controller")) - 1)); assert(_CREATED_SLOT == bytes32(uint256(keccak256("eip1967.controllable.created")) - 1)); } /// @notice Initialize contract after setup it as proxy implementation /// Save block.timestamp in the "created" variable /// @dev Use it only once after first logic setup /// @param _controller Controller address function initializeControllable(address _controller) public initializer { setController(_controller); setCreated(block.timestamp); } function isController(address _adr) public override view returns (bool) { return _adr == controller(); } /// @notice Return true is given address is setup as governance in Controller /// @param _adr Address for check /// @return true if given address is governance function isGovernance(address _adr) public override view returns (bool) { return IController(controller()).governance() == _adr; } // ************ MODIFIERS ********************** /// @dev Allow operation only for Controller modifier onlyController() { require(controller() == msg.sender, "not controller"); _; } /// @dev Allow operation only for Controller or Governance modifier onlyControllerOrGovernance() { require(isController(msg.sender) || isGovernance(msg.sender), "not controller or gov"); _; } /// @dev Only smart contracts will be affected by this modifier /// If it is a contract it should be whitelisted modifier onlyAllowedUsers() { require(IController(controller()).isAllowedUser(msg.sender), "not allowed"); _; } /// @dev Only Reward Distributor allowed. Governance is Reward Distributor by default. modifier onlyRewardDistribution() { require(IController(controller()).isRewardDistributor(msg.sender), "only distr"); _; } // ************* SETTERS/GETTERS ******************* /// @notice Return controller address saved in the contract slot /// @return adr Controller address function controller() public view returns (address adr) { bytes32 slot = _CONTROLLER_SLOT; assembly { adr := sload(slot) } } /// @dev Set a controller address to contract slot /// @param _newController Controller address function setController(address _newController) internal { require(_newController != address(0), "zero address"); emit UpdateController(controller(), _newController); bytes32 slot = _CONTROLLER_SLOT; assembly { sstore(slot, _newController) } } /// @notice Return creation timestamp /// @return ts Creation timestamp function created() external view returns (uint256 ts) { bytes32 slot = _CREATED_SLOT; assembly { ts := sload(slot) } } /// @dev Filled only once when contract initialized /// @param _created block.timestamp function setCreated(uint256 _created) private { bytes32 slot = _CREATED_SLOT; assembly { sstore(slot, _created) } } }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; interface IBookkeeper { struct PpfsChange { address vault; uint256 block; uint256 time; uint256 value; uint256 oldBlock; uint256 oldTime; uint256 oldValue; } struct HardWork { address strategy; uint256 block; uint256 time; uint256 targetTokenAmount; } function addVault(address _vault) external; function addStrategy(address _strategy) external; function registerStrategyEarned(uint256 _targetTokenAmount) external; function registerFundKeeperEarned(address _token, uint256 _fundTokenAmount) external; function registerUserAction(address _user, uint256 _amount, bool _deposit) external; function registerVaultTransfer(address from, address to, uint256 amount) external; function registerUserEarned(address _user, address _vault, address _rt, uint256 _amount) external; function registerPpfsChange(address vault, uint256 value) external; function registerRewardDistribution(address vault, address token, uint256 amount) external; function vaults() external view returns (address[] memory); function vaultsLength() external view returns (uint256); function strategies() external view returns (address[] memory); function strategiesLength() external view returns (uint256); function lastPpfsChange(address vault) external view returns (PpfsChange memory); /// @notice Return total earned TETU tokens for strategy /// @dev Should be incremented after strategy rewards distribution /// @param strategy Strategy address /// @return Earned TETU tokens function targetTokenEarned(address strategy) external view returns (uint256); /// @notice Return share(xToken) balance of given user /// @dev Should be calculated for each xToken transfer /// @param vault Vault address /// @param user User address /// @return User share (xToken) balance function vaultUsersBalances(address vault, address user) external view returns (uint256); /// @notice Return earned token amount for given token and user /// @dev Fills when user claim rewards /// @param user User address /// @param vault Vault address /// @param token Token address /// @return User's earned tokens amount function userEarned(address user, address vault, address token) external view returns (uint256); function lastHardWork(address vault) external view returns (HardWork memory); /// @notice Return users quantity for given Vault /// @dev Calculation based in Bookkeeper user balances /// @param vault Vault address /// @return Users quantity function vaultUsersQuantity(address vault) external view returns (uint256); function fundKeeperEarned(address vault) external view returns (uint256); function vaultRewards(address vault, address token, uint256 idx) external view returns (uint256); function vaultRewardsLength(address vault, address token) external view returns (uint256); function strategyEarnedSnapshots(address strategy, uint256 idx) external view returns (uint256); function strategyEarnedSnapshotsTime(address strategy, uint256 idx) external view returns (uint256); function strategyEarnedSnapshotsLength(address strategy) external view returns (uint256); }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; interface ISmartVault { function setStrategy(address _strategy) external; function changeActivityStatus(bool _active) external; function changeProtectionMode(bool _active) external; function changePpfsDecreaseAllowed(bool _value) external; function setLockPeriod(uint256 _value) external; function setLockPenalty(uint256 _value) external; function setToInvest(uint256 _value) external; function doHardWork() external; function rebalance() external; function disableLock() external; function notifyTargetRewardAmount(address _rewardToken, uint256 reward) external; function notifyRewardWithoutPeriodChange(address _rewardToken, uint256 reward) external; function deposit(uint256 amount) external; function depositAndInvest(uint256 amount) external; function depositFor(uint256 amount, address holder) external; function withdraw(uint256 numberOfShares) external; function exit() external; function getAllRewards() external; function getReward(address rt) external; function underlying() external view returns (address); function strategy() external view returns (address); function getRewardTokenIndex(address rt) external view returns (uint256); function getPricePerFullShare() external view returns (uint256); function underlyingUnit() external view returns (uint256); function duration() external view returns (uint256); function underlyingBalanceInVault() external view returns (uint256); function underlyingBalanceWithInvestment() external view returns (uint256); function underlyingBalanceWithInvestmentForHolder(address holder) external view returns (uint256); function availableToInvestOut() external view returns (uint256); function earned(address rt, address account) external view returns (uint256); function earnedWithBoost(address rt, address account) external view returns (uint256); function rewardPerToken(address rt) external view returns (uint256); function lastTimeRewardApplicable(address rt) external view returns (uint256); function rewardTokensLength() external view returns (uint256); function active() external view returns (bool); function rewardTokens() external view returns (address[] memory); function periodFinishForToken(address _rt) external view returns (uint256); function rewardRateForToken(address _rt) external view returns (uint256); function lastUpdateTimeForToken(address _rt) external view returns (uint256); function rewardPerTokenStoredForToken(address _rt) external view returns (uint256); function userRewardPerTokenPaidForToken(address _rt, address account) external view returns (uint256); function rewardsForToken(address _rt, address account) external view returns (uint256); function userLastWithdrawTs(address _user) external returns (uint256); function userLastDepositTs(address _user) external returns (uint256); function userBoostTs(address _user) external returns (uint256); function userLockTs(address _user) external returns (uint256); function addRewardToken(address rt) external; function removeRewardToken(address rt) external; function stop() external; function ppfsDecreaseAllowed() external view returns (bool); function lockPeriod() external view returns (uint256); function lockPenalty() external view returns (uint256); function toInvest() external view returns (uint256); function depositFeeNumerator() external view returns (uint256); function lockAllowed() external view returns (bool); function protectionMode() external view returns (bool); }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; interface IStrategy { enum Platform { UNKNOWN, // 0 TETU, // 1 QUICK, // 2 SUSHI, // 3 WAULT, // 4 IRON, // 5 COSMIC, // 6 CURVE, // 7 DINO, // 8 IRON_LEND, // 9 HERMES, // 10 CAFE, // 11 TETU_SWAP, // 12 SPOOKY, // 13 AAVE_LEND, //14 AAVE_MAI_BAL, // 15 GEIST, //16 HARVEST, //17 SCREAM_LEND, //18 KLIMA //19 } // *************** GOVERNANCE ACTIONS ************** function STRATEGY_NAME() external view returns (string memory); function withdrawAllToVault() external; function withdrawToVault(uint256 amount) external; function salvage(address recipient, address token, uint256 amount) external; function doHardWork() external; function investAllUnderlying() external; function emergencyExit() external; function pauseInvesting() external; function continueInvesting() external; // **************** VIEWS *************** function rewardTokens() external view returns (address[] memory); function underlying() external view returns (address); function underlyingBalance() external view returns (uint256); function rewardPoolBalance() external view returns (uint256); function buyBackRatio() external view returns (uint256); function unsalvageableTokens(address token) external view returns (bool); function vault() external view returns (address); function investedUnderlyingBalance() external view returns (uint256); function platform() external view returns (Platform); function assets() external view returns (address[] memory); function pausedInvesting() external view returns (bool); function readyToClaim() external view returns (uint256[] memory); function poolTotalAmount() external view returns (uint256); }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; interface IPriceCalculator { function getPrice(address token, address outputToken) external view returns (uint256); function getPriceWithDefaultOutput(address token) external view returns (uint256); function getLargestPool(address token, address[] memory usedLps) external view returns (address, uint256, address); function getPriceFromLp(address lpAddress, address token) external view returns (uint256); }
// 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"; /** * @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 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) { return msg.data; } }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; interface IController { function addVaultsAndStrategies(address[] memory _vaults, address[] memory _strategies) external; function addStrategy(address _strategy) external; function governance() external view returns (address); function dao() external view returns (address); function bookkeeper() external view returns (address); function feeRewardForwarder() external view returns (address); function mintHelper() external view returns (address); function rewardToken() external view returns (address); function fundToken() external view returns (address); function psVault() external view returns (address); function fund() external view returns (address); function distributor() external view returns (address); function announcer() external view returns (address); function vaultController() external view returns (address); function whiteList(address _target) external view returns (bool); function vaults(address _target) external view returns (bool); function strategies(address _target) external view returns (bool); function psNumerator() external view returns (uint256); function psDenominator() external view returns (uint256); function fundNumerator() external view returns (uint256); function fundDenominator() external view returns (uint256); function isAllowedUser(address _adr) external view returns (bool); function isDao(address _adr) external view returns (bool); function isHardWorker(address _adr) external view returns (bool); function isRewardDistributor(address _adr) external view returns (bool); function isPoorRewardConsumer(address _adr) external view returns (bool); function isValidVault(address _vault) external view returns (bool); function isValidStrategy(address _strategy) external view returns (bool); // ************ DAO ACTIONS ************* function setPSNumeratorDenominator(uint256 numerator, uint256 denominator) external; function setFundNumeratorDenominator(uint256 numerator, uint256 denominator) external; function changeWhiteListStatus(address[] calldata _targets, bool status) external; }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; interface IControllable { function isController(address _contract) external view returns (bool); function isGovernance(address _contract) external view returns (bool); }
{ "optimizer": { "enabled": true, "runs": 150 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"ToolAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"UpdateController","type":"event"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bookkeeper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tvl","type":"uint256"},{"internalType":"uint256","name":"rewards","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"computeApr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"rt","type":"address"}],"name":"computeRewardApr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"adr","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"created","outputs":[{"internalType":"uint256","name":"ts","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"},{"internalType":"address","name":"_calculator","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"initializeControllable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_adr","type":"address"}],"name":"isController","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_adr","type":"address"}],"name":"isGovernance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceCalculator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"setPriceCalculator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategies","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"strategiesLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"strategyAssets","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"strategyCreated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"strategyEarned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"strategyPausedInvesting","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"strategyPlatform","outputs":[{"internalType":"enum IStrategy.Platform","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"strategyRewardTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tetuTokenValues","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_vaults","type":"address[]"}],"name":"totalTetuBoughBack","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_strategies","type":"address[]"}],"name":"totalTetuBoughBack2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_vaults","type":"address[]"}],"name":"totalTvlUsdc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_vaults","type":"address[]"}],"name":"totalUsers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalUsersForAllVaults","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_vault","type":"address"}],"name":"userDepositedShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_vault","type":"address"}],"name":"userDepositedUnderlying","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_vault","type":"address"}],"name":"userDepositedUnderlyingUsdc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_vault","type":"address"}],"name":"userInfo","outputs":[{"components":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"address","name":"vault","type":"address"},{"internalType":"uint256","name":"underlyingBalance","type":"uint256"},{"internalType":"uint256","name":"underlyingBalanceUsdc","type":"uint256"},{"internalType":"uint256","name":"depositedUnderlying","type":"uint256"},{"internalType":"uint256","name":"depositedUnderlyingUsdc","type":"uint256"},{"internalType":"uint256","name":"depositedShare","type":"uint256"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"rewards","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardsUsdc","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardsBoost","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardsBoostUsdc","type":"uint256[]"}],"internalType":"struct ContractReader.UserInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_vault","type":"address"}],"name":"userInfoLight","outputs":[{"components":[{"internalType":"uint256","name":"depositedUnderlying","type":"uint256"},{"internalType":"uint256","name":"depositedUnderlyingUsdc","type":"uint256"},{"internalType":"uint256","name":"depositedShare","type":"uint256"}],"internalType":"struct ContractReader.UserInfoLight","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address[]","name":"_vaults","type":"address[]"}],"name":"userInfosLight","outputs":[{"components":[{"internalType":"uint256","name":"depositedUnderlying","type":"uint256"},{"internalType":"uint256","name":"depositedUnderlyingUsdc","type":"uint256"},{"internalType":"uint256","name":"depositedShare","type":"uint256"}],"internalType":"struct ContractReader.UserInfoLight[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_vault","type":"address"}],"name":"userRewards","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_vault","type":"address"}],"name":"userRewardsBoost","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_vault","type":"address"}],"name":"userRewardsBoostUsdc","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_vault","type":"address"}],"name":"userRewardsUsdc","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_vault","type":"address"}],"name":"userUnderlyingBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_vault","type":"address"}],"name":"userUnderlyingBalanceUsdc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultCreated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"}],"name":"vaultInfo","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"created","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"tvl","type":"uint256"},{"internalType":"uint256","name":"tvlUsdc","type":"uint256"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"rewardTokensBal","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardTokensBalUsdc","type":"uint256[]"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256[]","name":"rewardsApr","type":"uint256[]"},{"internalType":"uint256","name":"ppfsApr","type":"uint256"},{"internalType":"uint256","name":"users","type":"uint256"},{"internalType":"address","name":"strategy","type":"address"},{"internalType":"uint256","name":"strategyCreated","type":"uint256"},{"internalType":"enum IStrategy.Platform","name":"platform","type":"uint8"},{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"address[]","name":"strategyRewards","type":"address[]"},{"internalType":"bool","name":"strategyOnPause","type":"bool"},{"internalType":"uint256","name":"earned","type":"uint256"}],"internalType":"struct ContractReader.VaultInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"}],"name":"vaultInfoLight","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"created","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"tvl","type":"uint256"},{"internalType":"uint256","name":"tvlUsdc","type":"uint256"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"rewardsApr","type":"uint256[]"},{"internalType":"uint256","name":"ppfsApr","type":"uint256"},{"internalType":"enum IStrategy.Platform","name":"platform","type":"uint8"},{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256","name":"earned","type":"uint256"}],"internalType":"struct ContractReader.VaultInfoLight","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_vaults","type":"address[]"}],"name":"vaultInfos","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"created","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"tvl","type":"uint256"},{"internalType":"uint256","name":"tvlUsdc","type":"uint256"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"rewardTokensBal","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardTokensBalUsdc","type":"uint256[]"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256[]","name":"rewardsApr","type":"uint256[]"},{"internalType":"uint256","name":"ppfsApr","type":"uint256"},{"internalType":"uint256","name":"users","type":"uint256"},{"internalType":"address","name":"strategy","type":"address"},{"internalType":"uint256","name":"strategyCreated","type":"uint256"},{"internalType":"enum IStrategy.Platform","name":"platform","type":"uint8"},{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"address[]","name":"strategyRewards","type":"address[]"},{"internalType":"bool","name":"strategyOnPause","type":"bool"},{"internalType":"uint256","name":"earned","type":"uint256"}],"internalType":"struct ContractReader.VaultInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_vaults","type":"address[]"}],"name":"vaultInfosLight","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"created","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"tvl","type":"uint256"},{"internalType":"uint256","name":"tvlUsdc","type":"uint256"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"rewardsApr","type":"uint256[]"},{"internalType":"uint256","name":"ppfsApr","type":"uint256"},{"internalType":"enum IStrategy.Platform","name":"platform","type":"uint8"},{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256","name":"earned","type":"uint256"}],"internalType":"struct ContractReader.VaultInfoLight[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultPlatform","outputs":[{"internalType":"enum IStrategy.Platform","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultPpfs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultPpfsApr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultPpfsLastApr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultRewardTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultRewardTokensBal","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultRewardTokensBalUsdc","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultRewardsApr","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultTvl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultTvlUsdc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultUnderlying","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"vaultUsers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"page","type":"uint256"},{"internalType":"uint256","name":"pageSize","type":"uint256"}],"name":"vaultWithUserInfoPages","outputs":[{"components":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"created","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"tvl","type":"uint256"},{"internalType":"uint256","name":"tvlUsdc","type":"uint256"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"rewardTokensBal","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardTokensBalUsdc","type":"uint256[]"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256[]","name":"rewardsApr","type":"uint256[]"},{"internalType":"uint256","name":"ppfsApr","type":"uint256"},{"internalType":"uint256","name":"users","type":"uint256"},{"internalType":"address","name":"strategy","type":"address"},{"internalType":"uint256","name":"strategyCreated","type":"uint256"},{"internalType":"enum IStrategy.Platform","name":"platform","type":"uint8"},{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"address[]","name":"strategyRewards","type":"address[]"},{"internalType":"bool","name":"strategyOnPause","type":"bool"},{"internalType":"uint256","name":"earned","type":"uint256"}],"internalType":"struct ContractReader.VaultInfo","name":"vault","type":"tuple"},{"components":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"address","name":"vault","type":"address"},{"internalType":"uint256","name":"underlyingBalance","type":"uint256"},{"internalType":"uint256","name":"underlyingBalanceUsdc","type":"uint256"},{"internalType":"uint256","name":"depositedUnderlying","type":"uint256"},{"internalType":"uint256","name":"depositedUnderlyingUsdc","type":"uint256"},{"internalType":"uint256","name":"depositedShare","type":"uint256"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"rewards","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardsUsdc","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardsBoost","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardsBoostUsdc","type":"uint256[]"}],"internalType":"struct ContractReader.UserInfo","name":"user","type":"tuple"}],"internalType":"struct ContractReader.VaultWithUserInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"page","type":"uint256"},{"internalType":"uint256","name":"pageSize","type":"uint256"}],"name":"vaultWithUserInfoPagesLight","outputs":[{"components":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"created","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"tvl","type":"uint256"},{"internalType":"uint256","name":"tvlUsdc","type":"uint256"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"rewardsApr","type":"uint256[]"},{"internalType":"uint256","name":"ppfsApr","type":"uint256"},{"internalType":"enum IStrategy.Platform","name":"platform","type":"uint8"},{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256","name":"earned","type":"uint256"}],"internalType":"struct ContractReader.VaultInfoLight","name":"vault","type":"tuple"},{"components":[{"internalType":"uint256","name":"depositedUnderlying","type":"uint256"},{"internalType":"uint256","name":"depositedUnderlyingUsdc","type":"uint256"},{"internalType":"uint256","name":"depositedShare","type":"uint256"}],"internalType":"struct ContractReader.UserInfoLight","name":"user","type":"tuple"}],"internalType":"struct ContractReader.VaultWithUserInfoLight[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address[]","name":"_vaults","type":"address[]"}],"name":"vaultWithUserInfos","outputs":[{"components":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"created","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"tvl","type":"uint256"},{"internalType":"uint256","name":"tvlUsdc","type":"uint256"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"rewardTokensBal","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardTokensBalUsdc","type":"uint256[]"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256[]","name":"rewardsApr","type":"uint256[]"},{"internalType":"uint256","name":"ppfsApr","type":"uint256"},{"internalType":"uint256","name":"users","type":"uint256"},{"internalType":"address","name":"strategy","type":"address"},{"internalType":"uint256","name":"strategyCreated","type":"uint256"},{"internalType":"enum IStrategy.Platform","name":"platform","type":"uint8"},{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"address[]","name":"strategyRewards","type":"address[]"},{"internalType":"bool","name":"strategyOnPause","type":"bool"},{"internalType":"uint256","name":"earned","type":"uint256"}],"internalType":"struct ContractReader.VaultInfo","name":"vault","type":"tuple"},{"components":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"address","name":"vault","type":"address"},{"internalType":"uint256","name":"underlyingBalance","type":"uint256"},{"internalType":"uint256","name":"underlyingBalanceUsdc","type":"uint256"},{"internalType":"uint256","name":"depositedUnderlying","type":"uint256"},{"internalType":"uint256","name":"depositedUnderlyingUsdc","type":"uint256"},{"internalType":"uint256","name":"depositedShare","type":"uint256"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"rewards","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardsUsdc","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardsBoost","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardsBoostUsdc","type":"uint256[]"}],"internalType":"struct ContractReader.UserInfo","name":"user","type":"tuple"}],"internalType":"struct ContractReader.VaultWithUserInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address[]","name":"_vaults","type":"address[]"}],"name":"vaultWithUserInfosLight","outputs":[{"components":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"created","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"tvl","type":"uint256"},{"internalType":"uint256","name":"tvlUsdc","type":"uint256"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"rewardsApr","type":"uint256[]"},{"internalType":"uint256","name":"ppfsApr","type":"uint256"},{"internalType":"enum IStrategy.Platform","name":"platform","type":"uint8"},{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256","name":"earned","type":"uint256"}],"internalType":"struct ContractReader.VaultInfoLight","name":"vault","type":"tuple"},{"components":[{"internalType":"uint256","name":"depositedUnderlying","type":"uint256"},{"internalType":"uint256","name":"depositedUnderlyingUsdc","type":"uint256"},{"internalType":"uint256","name":"depositedShare","type":"uint256"}],"internalType":"struct ContractReader.UserInfoLight","name":"user","type":"tuple"}],"internalType":"struct ContractReader.VaultWithUserInfoLight[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaults","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506200003f60017f5165972ef41194f06c5007493031d0b927c20741adcb74403b954009fd2c3618620000ec565b7f5165972ef41194f06c5007493031d0b927c20741adcb74403b954009fd2c3617146200007c57634e487b7160e01b600052600160045260246000fd5b620000a960017f6f55f470bdc9cb5f04223fd822021061668e4dccb43e8727b295106dc9769c8b620000ec565b7f6f55f470bdc9cb5f04223fd822021061668e4dccb43e8727b295106dc9769c8a14620000e657634e487b7160e01b600052600160045260246000fd5b62000110565b6000828210156200010b57634e487b7160e01b81526011600452602481fd5b500390565b614cc280620001206000396000f3fe608060405234801561001057600080fd5b50600436106103f15760003560e01c80638b95e33511610215578063d9f9027f11610125578063e527e2c8116100b8578063ee98aa5f11610087578063ee98aa5f14610910578063f2dc7ff514610923578063f4754e0114610669578063f77c479114610936578063ffa1ad741461093e57600080fd5b8063e527e2c8146108cf578063e77fb0d8146108e2578063e945cdcd146108ea578063ebee0406146108fd57600080fd5b8063df0ac912116100f4578063df0ac91214610896578063e2710b89146108a9578063e3d3b66d146108bc578063e410e4a61461087057600080fd5b8063d9f9027f14610848578063db84991d14610850578063dc54c27614610870578063dee1f0e41461088357600080fd5b8063a90f55bf116101a8578063b429afeb11610177578063b429afeb146107dc578063bab6929c146107ef578063be1e27d114610802578063c376dbb314610815578063d0d026331461082857600080fd5b8063a90f55bf14610787578063a980356a146107a7578063aaf5eb68146107ba578063ab1b491c146107c957600080fd5b80639c5d61b4116101e45780639c5d61b41461072e578063a179751b14610741578063a689cbc314610761578063a80a5ce71461077457600080fd5b80638b95e335146106e05780638d852391146106e85780639164359a146106fb57806396ef1b981461071b57600080fd5b80634acd7390116103105780636f8d34f0116102a35780638170bbd5116102725780638170bbd5146106a25780638220ef5b146106aa57806382af54c9146106b2578063849efb71146106ba5780638adab464146106cd57600080fd5b80636f8d34f014610646578063728204e41461066957806372a4aa711461067c5780637e52586c1461068f57600080fd5b8063514b9ec7116102df578063514b9ec7146105e05780636430be8c146106005780636922d7b6146106135780636d5f9b331461062657600080fd5b80634acd7390146105945780634d18e43d146105a75780634e58d37e146105ba5780634f8f0eb0146105cd57600080fd5b8063325a19f1116103885780634624aa44116103575780634624aa441461052a57806347b03bba1461054a578063485cc9551461055f57806349c997ce1461057457600080fd5b8063325a19f1146104d55780633f74bb89146104fc5780634135b6731461050457806341976e091461051757600080fd5b80631184006e116103c45780631184006e1461046f57806319babe8b1461048f57806324d1efcf146104a257806331bd6e2c146104b557600080fd5b806308dc993c146103f65780630bcc41df1461041c5780630f208beb1461042f5780631041cc641461044f575b600080fd5b610409610404366004613f56565b610962565b6040519081526020015b60405180910390f35b61040961042a366004614047565b610ae5565b61044261043d366004613f8e565b610bb3565b6040516104139190614a18565b61046261045d366004613f56565b610e37565b604051610413919061473f565b61048261047d366004613f8e565b610eae565b6040516104139190614975565b61040961049d366004613f56565b6110d8565b6104096104b0366004613f8e565b61110e565b6104c86104c3366004614047565b611141565b6040516104139190614815565b7f6f55f470bdc9cb5f04223fd822021061668e4dccb43e8727b295106dc9769c8a54610409565b610409611222565b610409610512366004613f8e565b6112a6565b610409610525366004613f56565b611335565b61053d610538366004613f56565b6113be565b6040516104139190614a2b565b610552611521565b6040516104139190614711565b61057261056d366004613f8e565b6115a0565b005b610587610582366004613fc6565b61168d565b6040516104139190614752565b6104096105a2366004613f56565b611793565b6104096105b5366004613f56565b611806565b6104096105c8366004614047565b6118a2565b6104826105db366004613f8e565b6118fe565b6105f36105ee366004614013565b611b24565b6040516104139190614869565b61040961060e366004613f8e565b611d22565b610572610621366004613f56565b611d53565b610639610634366004613f56565b611e56565b6040516104139190614996565b610659610654366004613f56565b611ecd565b6040519015158152602001610413565b610409610677366004613f56565b611f40565b61040961068a366004613f8e565b611f7b565b61048261069d366004613f8e565b611fb4565b610482612137565b610462612302565b610409612380565b6104096106c8366004613f56565b6123c2565b6106596106db366004613f56565b61240f565b61055261244a565b6104096106f6366004614047565b6124a4565b61070e610709366004613f56565b612500565b6040516104139190614a3e565b610482610729366004613f56565b6126e8565b61040961073c366004613f56565b61291a565b61075461074f366004613f56565b6129e0565b6040516104139190614988565b61075461076f366004613f56565b612a53565b610409610782366004613f56565b612afe565b61079a610795366004613fc6565b612b3c565b60405161041391906148f1565b6104826107b5366004613f8e565b612c54565b610409670de0b6b3a764000081565b6105526107d7366004613f56565b612d9f565b6106596107ea366004613f56565b612e12565b6104096107fd366004613f8e565b612e37565b610409610810366004613f56565b612e62565b610409610823366004613f56565b612ea0565b61083b610836366004614047565b612f1c565b60405161041391906147b4565b610462612ff0565b61086361085e366004613f8e565b613032565b60405161041391906149f7565b61046261087e366004613f56565b613092565b610659610891366004613f56565b6130cd565b61079a6108a4366004614013565b613161565b6105f36108b7366004613fc6565b61332f565b6104096108ca36600461427c565b61343a565b6104096108dd366004614047565b61349b565b6104096134f7565b6105726108f8366004613f56565b613552565b61048261090b366004613f56565b6135f0565b61040961091e366004613f8e565b613763565b610482610931366004613f56565b6139e2565b610552613af6565b610639604051806040016040528060058152602001640c4b8c0b8d60da1b81525081565b60008061096d613af6565b6001600160a01b031663f7c618c16040518163ffffffff1660e01b815260040160206040518083038186803b1580156109a557600080fd5b505afa1580156109b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109dd9190613f72565b9050610ade6109ea611521565b6001600160a01b031663cb618c9d856040518263ffffffff1660e01b8152600401610a159190614711565b60206040518083038186803b158015610a2d57600080fd5b505afa158015610a41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a659190614264565b826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610a9e57600080fd5b505afa158015610ab2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad691906142a7565b60ff16613b1b565b9392505050565b600080805b8351811015610bac57610b8e848281518110610b1657634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031663a8c62e766040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5657600080fd5b505afa158015610b6a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104049190613f72565b610b989083614aa4565b915080610ba481614c2d565b915050610aea565b5092915050565b610bbb613c91565b6000826001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b158015610bf657600080fd5b505afa158015610c0a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c329190810190614079565b9050600081516001600160401b03811115610c5d57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610c86578160200160208202803683370190505b50905060005b8251811015610d7757846001600160a01b031663211dc32d848381518110610cc457634e487b7160e01b600052603260045260246000fd5b6020026020010151886040518363ffffffff1660e01b8152600401610cea929190614725565b60206040518083038186803b158015610d0257600080fd5b505afa158015610d16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3a9190614264565b828281518110610d5a57634e487b7160e01b600052603260045260246000fd5b602090810291909101015280610d6f81614c2d565b915050610c8c565b50604051806101800160405280866001600160a01b03168152602001856001600160a01b03168152602001610dac8787611f7b565b8152602001610dbb8787612e37565b8152602001610dca87876112a6565b8152602001610dd9878761110e565b8152602001610de88787611d22565b8152602001838152602001610dfd8787612c54565b8152602001610e0c8787611fb4565b8152602001610e1b8787610eae565b8152602001610e2a87876118fe565b9052925050505b92915050565b6060816001600160a01b03166371a973056040518163ffffffff1660e01b815260040160006040518083038186803b158015610e7257600080fd5b505afa158015610e86573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e319190810190614079565b60606000826001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b158015610eeb57600080fd5b505afa158015610eff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f279190810190614079565b9050600081516001600160401b03811115610f5257634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610f7b578160200160208202803683370190505b50905060005b82518110156110cf57611092856001600160a01b031663e81bb2d6858481518110610fbc57634e487b7160e01b600052603260045260246000fd5b6020026020010151896040518363ffffffff1660e01b8152600401610fe2929190614725565b60206040518083038186803b158015610ffa57600080fd5b505afa15801561100e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190614264565b84838151811061105257634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610a9e57600080fd5b8282815181106110b257634e487b7160e01b600052603260045260246000fd5b6020908102919091010152806110c781614c2d565b915050610f81565b50949350505050565b6000806110e761052584612d9f565b9050610ade670de0b6b3a76400006111088361110287612afe565b90613b39565b90613b45565b60008061111d61052584612d9f565b9050611139670de0b6b3a76400006111088361110288886112a6565b949350505050565b6060600082516001600160401b0381111561116c57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156111a557816020015b611192613d04565b81526020019060019003908161118a5790505b50905060005b8351811015610bac576111e48482815181106111d757634e487b7160e01b600052603260045260246000fd5b6020026020010151612500565b82828151811061120457634e487b7160e01b600052603260045260246000fd5b6020026020010181905250808061121a90614c2d565b9150506111ab565b600061122c611521565b6001600160a01b031663d9f9027f6040518163ffffffff1660e01b815260040160006040518083038186803b15801561126457600080fd5b505afa158015611278573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112a09190810190614079565b51905090565b6000610ade826001600160a01b0316638cb1d67f856040518263ffffffff1660e01b81526004016112d79190614711565b60206040518083038186803b1580156112ef57600080fd5b505afa158015611303573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113279190614264565b61133084612ea0565b613b1b565b600061133f61244a565b6001600160a01b0316637539bdb1836040518263ffffffff1660e01b815260040161136a9190614711565b60206040518083038186803b15801561138257600080fd5b505afa9250505080156113b2575060408051601f3d908101601f191682019092526113af91810190614264565b60015b610e3157506000919050565b6113c6613de9565b6000826001600160a01b031663a8c62e766040518163ffffffff1660e01b815260040160206040518083038186803b15801561140157600080fd5b505afa158015611415573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114399190613f72565b90506000604051806101800160405280856001600160a01b0316815260200161146186611f40565b815260200161146f86611ecd565b1515815260200161147f86612afe565b815260200161148d866110d8565b815260200161149b86612d9f565b6001600160a01b031681526020016114b286613092565b81526020016114c0866126e8565b81526020016114ce86611806565b81526020016114dc846129e0565b60138111156114fb57634e487b7160e01b600052602160045260246000fd5b815260200161150984610e37565b815260200161151784610962565b9052949350505050565b600061152b613af6565b6001600160a01b03166347b03bba6040518163ffffffff1660e01b815260040160206040518083038186803b15801561156357600080fd5b505afa158015611577573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159b9190613f72565b905090565b600054610100900460ff16806115b9575060005460ff16155b6115de5760405162461bcd60e51b81526004016115d5906149a9565b60405180910390fd5b600054610100900460ff16158015611600576000805461ffff19166101011790555b61160983613552565b816001600060405160200161162e906931b0b631bab630ba37b960b11b8152600a0190565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508015611688576000805461ff00191690555b505050565b6060600082516001600160401b038111156116b857634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561170d57816020015b6116fa60405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816116d65790505b50905060005b835181101561178b5761174d8585838151811061174057634e487b7160e01b600052603260045260246000fd5b6020026020010151613032565b82828151811061176d57634e487b7160e01b600052603260045260246000fd5b6020026020010181905250808061178390614c2d565b915050611713565b509392505050565b6000816001600160a01b0316630fb5a6b46040518163ffffffff1660e01b815260040160206040518083038186803b1580156117ce57600080fd5b505afa1580156117e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e319190614264565b6000610e31611327836001600160a01b03166377c7b8fc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561184757600080fd5b505afa15801561185b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061187f9190614264565b61188885612ea0565b61189390600a614b1f565b4261189d87611f40565b613b51565b600080805b8351811015610bac576118e08482815181106118d357634e487b7160e01b600052603260045260246000fd5b60200260200101516123c2565b6118ea9083614aa4565b9150806118f681614c2d565b9150506118a7565b60606000826001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b15801561193b57600080fd5b505afa15801561194f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119779190810190614079565b9050600081516001600160401b038111156119a257634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156119cb578160200160208202803683370190505b50905060005b82518110156110cf576000611a0c8483815181106119ff57634e487b7160e01b600052603260045260246000fd5b6020026020010151611335565b9050611ae6611ac6670de0b6b3a7640000611108848a6001600160a01b031663e81bb2d68a8981518110611a5057634e487b7160e01b600052603260045260246000fd5b60200260200101518e6040518363ffffffff1660e01b8152600401611a76929190614725565b60206040518083038186803b158015611a8e57600080fd5b505afa158015611aa2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111029190614264565b85848151811061105257634e487b7160e01b600052603260045260246000fd5b838381518110611b0657634e487b7160e01b600052603260045260246000fd5b60209081029190910101525080611b1c81614c2d565b9150506119d1565b60606000611b30612302565b51905060008111611b725760405162461bcd60e51b815260206004820152600c60248201526b656d707479207661756c747360a01b60448201526064016115d5565b6000611b7e8483614abc565b905081611b8b8583614bc7565b1015611b9f5780611b9b81614c2d565b9150505b80851115611bab578094505b6000611bca611bba8688614bc7565b611bc5600186614be6565b613bb6565b90506000611be1611bdb8784614aa4565b85613bb6565b90506000611bef8383614be6565b6001600160401b03811115611c1457634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611c4d57816020015b611c3a613e7d565b815260200190600190039081611c325790505b509050825b82811015611d15576040518060400160405280611c9c611c70612302565b8481518110611c8f57634e487b7160e01b600052603260045260246000fd5b60200260200101516113be565b8152602001611ccc8c611cad612302565b858151811061174057634e487b7160e01b600052603260045260246000fd5b905282611cd98684614be6565b81518110611cf757634e487b7160e01b600052603260045260246000fd5b60200260200101819052508080611d0d90614c2d565b915050611c52565b5098975050505050505050565b6000610ade826001600160a01b03166370a08231856040518263ffffffff1660e01b81526004016112d79190614711565b611d5c33612e12565b80611d6b5750611d6b336130cd565b611daf5760405162461bcd60e51b81526020600482015260156024820152743737ba1031b7b73a3937b63632b91037b91033b7bb60591b60448201526064016115d5565b8060016000604051602001611dd4906931b0b631bab630ba37b960b11b8152600a0190565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055507f0caadb6ce6adfa207b9ff9c87df2ad8361fe4e2e5c4fb493fba65daa077dc4f481604051611e4b9190614711565b60405180910390a150565b6060816001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015611e9157600080fd5b505afa158015611ea5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e319190810190614153565b6000816001600160a01b03166302fb0c5e6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f0857600080fd5b505afa158015611f1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e319190614114565b6000816001600160a01b031663325a19f16040518163ffffffff1660e01b815260040160206040518083038186803b1580156117ce57600080fd5b6000610ade611f8983612d9f565b6001600160a01b03166370a08231856040518263ffffffff1660e01b81526004016112d79190614711565b60606000826001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b158015611ff157600080fd5b505afa158015612005573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261202d9190810190614079565b9050600081516001600160401b0381111561205857634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612081578160200160208202803683370190505b50905060005b82518110156110cf5760006120b58483815181106119ff57634e487b7160e01b600052603260045260246000fd5b90506120f9611ac6670de0b6b3a7640000611108848a6001600160a01b031663211dc32d8a8981518110611a5057634e487b7160e01b600052603260045260246000fd5b83838151811061211957634e487b7160e01b600052603260045260246000fd5b6020908102919091010152508061212f81614c2d565b915050612087565b606060006121b6612146613af6565b6001600160a01b031663f7c618c16040518163ffffffff1660e01b815260040160206040518083038186803b15801561217e57600080fd5b505afa158015612192573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105259190613f72565b9050600061227a670de0b6b3a7640000611108846121d2613af6565b6001600160a01b031663f7c618c16040518163ffffffff1660e01b815260040160206040518083038186803b15801561220a57600080fd5b505afa15801561221e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122429190613f72565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a8e57600080fd5b604080516002808252606082018352929350600092909160208301908036833701905050905082816000815181106122c257634e487b7160e01b600052603260045260246000fd5b60200260200101818152505081816001815181106122f057634e487b7160e01b600052603260045260246000fd5b60209081029190910101529392505050565b606061230c611521565b6001600160a01b0316638220ef5b6040518163ffffffff1660e01b815260040160006040518083038186803b15801561234457600080fd5b505afa158015612358573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261159b9190810190614079565b600061238a611521565b6001600160a01b0316638220ef5b6040518163ffffffff1660e01b815260040160006040518083038186803b15801561126457600080fd5b60006123cc611521565b6001600160a01b031663c14a38e3836040518263ffffffff1660e01b81526004016123f79190614711565b60206040518083038186803b1580156117ce57600080fd5b6000816001600160a01b031663d3df8aa46040518163ffffffff1660e01b815260040160206040518083038186803b158015611f0857600080fd5b600060016000604051602001612470906931b0b631bab630ba37b960b11b8152600a0190565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b0316919050565b600080805b8351811015610bac576124e28482815181106124d557634e487b7160e01b600052603260045260246000fd5b60200260200101516110d8565b6124ec9083614aa4565b9150806124f881614c2d565b9150506124a9565b612508613d04565b6000826001600160a01b031663a8c62e766040518163ffffffff1660e01b815260040160206040518083038186803b15801561254357600080fd5b505afa158015612557573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257b9190613f72565b90506000604051806102c00160405280856001600160a01b031681526020016125a386611e56565b81526020016125b186611f40565b81526020016125bf86611ecd565b151581526020016125cf86612afe565b81526020016125dd866110d8565b81526020016125eb86612ea0565b81526020016125f986612d9f565b6001600160a01b0316815260200161261086613092565b815260200161261e866139e2565b815260200161262c866135f0565b815260200161263a86611793565b8152602001612648866126e8565b815260200161265686611806565b8152602001612664866123c2565b8152602001836001600160a01b0316815260200161268184611f40565b815260200161268f846129e0565b60138111156126ae57634e487b7160e01b600052602160045260246000fd5b81526020016126bc84610e37565b81526020016126ca84613092565b81526020016126d88461240f565b1515815260200161151784610962565b606060008290506000816001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b15801561272a57600080fd5b505afa15801561273e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526127669190810190614079565b516001600160401b0381111561278c57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156127b5578160200160208202803683370190505b50905060005b826001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b1580156127f457600080fd5b505afa158015612808573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128309190810190614079565b5181101561178b576128dd85846001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b15801561287557600080fd5b505afa158015612889573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128b19190810190614079565b83815181106128d057634e487b7160e01b600052603260045260246000fd5b6020026020010151613763565b8282815181106128fd57634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061291281614c2d565b9150506127bb565b600080612925611521565b6001600160a01b031663400dfebd846040518263ffffffff1660e01b81526004016129509190614711565b60e06040518083038186803b15801561296857600080fd5b505afa15801561297c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129a091906141d9565b90508060400151600014156129b85750600092915050565b610ade6129d782606001518360c0015184604001518560a00151613b51565b61133085612ea0565b6000816001600160a01b0316634bde38c86040518163ffffffff1660e01b815260040160206040518083038186803b158015612a1b57600080fd5b505afa158015612a2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e319190614134565b6000816001600160a01b031663a8c62e766040518163ffffffff1660e01b815260040160206040518083038186803b158015612a8e57600080fd5b505afa158015612aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac69190613f72565b6001600160a01b0316634bde38c86040518163ffffffff1660e01b815260040160206040518083038186803b158015612a1b57600080fd5b6000610e31826001600160a01b0316631bf8e7be6040518163ffffffff1660e01b815260040160206040518083038186803b1580156112ef57600080fd5b6060600082516001600160401b03811115612b6757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612ba057816020015b612b8d613ebe565b815260200190600190039081612b855790505b50905060005b835181101561178b576040518060400160405280612bdd8684815181106111d757634e487b7160e01b600052603260045260246000fd5b8152602001612c1387878581518110612c0657634e487b7160e01b600052603260045260246000fd5b6020026020010151610bb3565b815250828281518110612c3657634e487b7160e01b600052603260045260246000fd5b60200260200101819052508080612c4c90614c2d565b915050612ba6565b60606000826001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b158015612c9157600080fd5b505afa158015612ca5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612ccd9190810190614079565b9050600081516001600160401b03811115612cf857634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612d21578160200160208202803683370190505b50905060005b82518110156110cf57612d62856001600160a01b031663211dc32d858481518110610fbc57634e487b7160e01b600052603260045260246000fd5b828281518110612d8257634e487b7160e01b600052603260045260246000fd5b602090810291909101015280612d9781614c2d565b915050612d27565b6000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b158015612dda57600080fd5b505afa158015612dee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e319190613f72565b6000612e1c613af6565b6001600160a01b0316826001600160a01b0316149050919050565b600080612e4661052584612d9f565b9050611139670de0b6b3a7640000611108836111028888611f7b565b6000610e31826001600160a01b03166377c7b8fc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156112ef57600080fd5b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015612edb57600080fd5b505afa158015612eef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f1391906142a7565b60ff1692915050565b6060600082516001600160401b03811115612f4757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612f8057816020015b612f6d613de9565b815260200190600190039081612f655790505b50905060005b8351811015610bac57612fb2848281518110611c8f57634e487b7160e01b600052603260045260246000fd5b828281518110612fd257634e487b7160e01b600052603260045260246000fd5b60200260200101819052508080612fe890614c2d565b915050612f86565b6060612ffa611521565b6001600160a01b031663d9f9027f6040518163ffffffff1660e01b815260040160006040518083038186803b15801561234457600080fd5b61305660405180606001604052806000815260200160008152602001600081525090565b604051806060016040528061306b85856112a6565b815260200161307a858561110e565b81526020016130898585611d22565b90529392505050565b6060816001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b158015610e7257600080fd5b6000816001600160a01b03166130e1613af6565b6001600160a01b0316635aa6e6756040518163ffffffff1660e01b815260040160206040518083038186803b15801561311957600080fd5b505afa15801561312d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131519190613f72565b6001600160a01b03161492915050565b6060600061316d612302565b519050600081116131af5760405162461bcd60e51b815260206004820152600c60248201526b656d707479207661756c747360a01b60448201526064016115d5565b60006131bb8483614abc565b9050816131c88583614bc7565b10156131dc57806131d881614c2d565b9150505b808511156131e8578094505b60006131f7611bba8688614bc7565b90506000613208611bdb8784614aa4565b905060006132168383614be6565b6001600160401b0381111561323b57634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561327457816020015b613261613ebe565b8152602001906001900390816132595790505b509050825b82811015611d155760405180604001604052806132b6613297612302565b84815181106111d757634e487b7160e01b600052603260045260246000fd5b81526020016132e68c6132c7612302565b8581518110612c0657634e487b7160e01b600052603260045260246000fd5b9052826132f38684614be6565b8151811061331157634e487b7160e01b600052603260045260246000fd5b6020026020010181905250808061332790614c2d565b915050613279565b6060600082516001600160401b0381111561335a57634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561339357816020015b613380613e7d565b8152602001906001900390816133785790505b50905060005b835181101561178b5760405180604001604052806133d0868481518110611c8f57634e487b7160e01b600052603260045260246000fd5b81526020016133f98787858151811061174057634e487b7160e01b600052603260045260246000fd5b81525082828151811061341c57634e487b7160e01b600052603260045260246000fd5b6020026020010181905250808061343290614c2d565b915050613399565b600080613457670de0b6b3a7640000611102876111088884613b39565b9050613492670de0b6b3a7640000611108606461110261016d8161348062015180868c89613b39565b61110889670de0b6b3a7640000613b39565b95945050505050565b600080805b8351811015610bac576134d98482815181106134cc57634e487b7160e01b600052603260045260246000fd5b6020026020010151610962565b6134e39083614aa4565b9150806134ef81614c2d565b9150506134a0565b600080613502612302565b90506000805b8251811015610bac576135348382815181106118d357634e487b7160e01b600052603260045260246000fd5b61353e9083614aa4565b91508061354a81614c2d565b915050613508565b600054610100900460ff168061356b575060005460ff16155b6135875760405162461bcd60e51b81526004016115d5906149a9565b600054610100900460ff161580156135a9576000805461ffff19166101011790555b6135b282613bcc565b6135da427f6f55f470bdc9cb5f04223fd822021061668e4dccb43e8727b295106dc9769c8a55565b80156135ec576000805461ff00191690555b5050565b606060006135fd83613092565b516001600160401b0381111561362357634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561364c578160200160208202803683370190505b50905060005b61365b84613092565b51811015610bac57600061366e85613092565b828151811061368d57634e487b7160e01b600052603260045260246000fd5b6020026020010151905060006136a282611335565b905060006136e2670de0b6b3a764000061110884866001600160a01b03166370a082318c6040518263ffffffff1660e01b8152600401611a769190614711565b905061372181846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610a9e57600080fd5b85858151811061374157634e487b7160e01b600052603260045260246000fd5b602002602001018181525050505050808061375b90614c2d565b915050613652565b600080836001600160a01b0316633fee85e6846040518263ffffffff1660e01b81526004016137929190614711565b60206040518083038186803b1580156137aa57600080fd5b505afa1580156137be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137e29190614264565b905060006137ef856110d8565b905060006137fc85611335565b905060006138a0876001600160a01b0316630fb5a6b46040518163ffffffff1660e01b815260040160206040518083038186803b15801561383c57600080fd5b505afa158015613850573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138749190614264565b604051630b711f0760e11b81526001600160a01b038a16906316e23e0e90611a76908b90600401614711565b905082158015906138b057508015155b80156138bb57504284115b156139d55760006138cc8542613c75565b90506000613956896001600160a01b0316630fb5a6b46040518163ffffffff1660e01b815260040160206040518083038186803b15801561390c57600080fd5b505afa158015613920573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139449190614264565b61110884670de0b6b3a7640000613b39565b9050600061397b6ec097ce7bc90715b34b9f1000000000611108876111028887613b39565b90506139ba818a6001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610a9e57600080fd5b90506139c786828561343a565b975050505050505050610e31565b6000945050505050610e31565b606060006139ef83613092565b516001600160401b03811115613a1557634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015613a3e578160200160208202803683370190505b50905060005b613a4d84613092565b51811015610bac576000613a6085613092565b8281518110613a7f57634e487b7160e01b600052603260045260246000fd5b60200260200101519050613ab8816001600160a01b03166370a08231876040518263ffffffff1660e01b8152600401610a159190614711565b838381518110613ad857634e487b7160e01b600052603260045260246000fd5b60209081029190910101525080613aee81614c2d565b915050613a44565b7f5165972ef41194f06c5007493031d0b927c20741adcb74403b954009fd2c36175490565b6000610ade613b2b83600a614b1f565b61110885670de0b6b3a76400005b6000610ade8284614bc7565b6000610ade8284614abc565b6000838511613b6257506000611139565b6000613b6e8686613c75565b90506000613b86613b7f8686613c75565b6001613c81565b9050613bab670de0b6b3a764000061110860646111026301e133808187858a88613b39565b979650505050505050565b6000818310613bc55781610ade565b5090919050565b6001600160a01b038116613c115760405162461bcd60e51b815260206004820152600c60248201526b7a65726f206164647265737360a01b60448201526064016115d5565b7f19b7d592cea0dfda222f6a4ea5c5a8d018ee9c6b1d0a917483a405de94eb26cd613c3a613af6565b82604051613c49929190614725565b60405180910390a17f5165972ef41194f06c5007493031d0b927c20741adcb74403b954009fd2c361755565b6000610ade8284614be6565b600081831015613bc55781610ade565b60405180610180016040528060006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b604051806102c0016040528060006001600160a01b03168152602001606081526020016000815260200160001515815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016060815260200160608152602001606081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b031681526020016000815260200160006013811115613dc557634e487b7160e01b600052602160045260246000fd5b81526020016060815260200160608152602001600015158152602001600081525090565b60405180610180016040528060006001600160a01b0316815260200160008152602001600015158152602001600081526020016000815260200160006001600160a01b0316815260200160608152602001606081526020016000815260200160006013811115613e6957634e487b7160e01b600052602160045260246000fd5b815260200160608152602001600081525090565b6040518060400160405280613e90613de9565b8152602001613eb960405180606001604052806000815260200160008152602001600081525090565b905290565b6040518060400160405280613ed1613d04565b8152602001613eb9613c91565b600082601f830112613eee578081fd5b81356020613f03613efe83614a81565b614a51565b80838252828201915082860187848660051b8901011115613f22578586fd5b855b85811015613f49578135613f3781614c74565b84529284019290840190600101613f24565b5090979650505050505050565b600060208284031215613f67578081fd5b8135610ade81614c74565b600060208284031215613f83578081fd5b8151610ade81614c74565b60008060408385031215613fa0578081fd5b8235613fab81614c74565b91506020830135613fbb81614c74565b809150509250929050565b60008060408385031215613fd8578182fd5b8235613fe381614c74565b915060208301356001600160401b03811115613ffd578182fd5b61400985828601613ede565b9150509250929050565b600080600060608486031215614027578081fd5b833561403281614c74565b95602085013595506040909401359392505050565b600060208284031215614058578081fd5b81356001600160401b0381111561406d578182fd5b61113984828501613ede565b6000602080838503121561408b578182fd5b82516001600160401b038111156140a0578283fd5b8301601f810185136140b0578283fd5b80516140be613efe82614a81565b80828252848201915084840188868560051b87010111156140dd578687fd5b8694505b838510156141085780516140f481614c74565b8352600194909401939185019185016140e1565b50979650505050505050565b600060208284031215614125578081fd5b81518015158114610ade578182fd5b600060208284031215614145578081fd5b815160148110610ade578182fd5b600060208284031215614164578081fd5b81516001600160401b038082111561417a578283fd5b818401915084601f83011261418d578283fd5b81518181111561419f5761419f614c5e565b6141b2601f8201601f1916602001614a51565b91508082528560208285010111156141c8578384fd5b6110cf816020840160208601614bfd565b600060e082840312156141ea578081fd5b60405160e081018181106001600160401b038211171561420c5761420c614c5e565b604052825161421a81614c74565b808252506020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c08201528091505092915050565b600060208284031215614275578081fd5b5051919050565b600080600060608486031215614290578081fd5b505081359360208301359350604090920135919050565b6000602082840312156142b8578081fd5b815160ff81168114610ade578182fd5b6000815180845260208085019450808401835b838110156143005781516001600160a01b0316875295820195908201906001016142db565b509495945050505050565b6000815180845260208085019450808401835b838110156143005781518752958201959082019060010161431e565b6014811061435857634e487b7160e01b600052602160045260246000fd5b9052565b60008151808452614374816020860160208601614bfd565b601f01601f19169290920160200192915050565b80516001600160a01b03168252600061018060208301516143b460208601826001600160a01b03169052565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e08301518160e08601526143fe828601826142c8565b9150506101008084015185830382870152614419838261430b565b925050506101208084015185830382870152614435838261430b565b925050506101408084015185830382870152614451838261430b565b92505050610160808401518583038287015261446d838261430b565b9695505050505050565b80516001600160a01b0316825260006101806020830151602085015260408301516144a6604086018215159052565b50606083015160608501526080830151608085015260a08301516144d560a08601826001600160a01b03169052565b5060c08301518160c08601526144ed828601826142c8565b91505060e083015184820360e0860152614507828261430b565b915050610100808401518186015250610120808401516145298287018261433a565b5050610140808401518583038287015261454383826142c8565b61016095860151969095019590955250919392505050565b80516001600160a01b0316825260006102c060208301518160208601526145848286018261435c565b9150506040830151604085015260608301516145a4606086018215159052565b506080830151608085015260a083015160a085015260c083015160c085015260e08301516145dd60e08601826001600160a01b03169052565b5061010080840151858303828701526145f683826142c8565b925050506101208084015185830382870152614612838261430b565b92505050610140808401518583038287015261462e838261430b565b925050506101608084015181860152506101808084015185830382870152614656838261430b565b925050506101a08084015181860152506101c08084015181860152506101e08084015161468d828701826001600160a01b03169052565b50506102008381015190850152610220808401516146ad8287018261433a565b505061024080840151858303828701526146c783826142c8565b9250505061026080840151858303828701526146e383826142c8565b92505050610280808401516146fb8287018215159052565b50506102a0928301519390920192909252919050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b602081526000610ade60208301846142c8565b6020808252825182820181905260009190848201906040850190845b818110156147a8576147958385518051825260208082015190830152604090810151910152565b928401926060929092019160010161476e565b50909695505050505050565b6000602080830181845280855180835260408601915060408160051b8701019250838701855b8281101561480857603f198886030184526147f6858351614477565b945092850192908501906001016147da565b5092979650505050505050565b6000602080830181845280855180835260408601915060408160051b8701019250838701855b8281101561480857603f1988860301845261485785835161455b565b9450928501929085019060010161483b565b6000602080830181845280855180835260408601915060408160051b8701019250838701855b8281101561480857603f198886030184528151608081518188526148b582890182614477565b9150508782015191506148de888801838051825260208082015190830152604090810151910152565b955050928501929085019060010161488f565b60006020808301818452808551808352604092508286019150828160051b870101848801865b8381101561496757888303603f190185528151805187855261493b8886018261455b565b91890151858303868b01529190506149538183614388565b968901969450505090860190600101614917565b509098975050505050505050565b602081526000610ade602083018461430b565b60208101610e31828461433a565b602081526000610ade602083018461435c565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b81518152602080830151908201526040808301519082015260608101610e31565b602081526000610ade6020830184614388565b602081526000610ade6020830184614477565b602081526000610ade602083018461455b565b604051601f8201601f191681016001600160401b0381118282101715614a7957614a79614c5e565b604052919050565b60006001600160401b03821115614a9a57614a9a614c5e565b5060051b60200190565b60008219821115614ab757614ab7614c48565b500190565b600082614ad757634e487b7160e01b81526012600452602481fd5b500490565b600181815b80851115614b17578160001904821115614afd57614afd614c48565b80851615614b0a57918102915b93841c9390800290614ae1565b509250929050565b6000610ade8383600082614b3557506001610e31565b81614b4257506000610e31565b8160018114614b585760028114614b6257614b7e565b6001915050610e31565b60ff841115614b7357614b73614c48565b50506001821b610e31565b5060208310610133831016604e8410600b8410161715614ba1575081810a610e31565b614bab8383614adc565b8060001904821115614bbf57614bbf614c48565b029392505050565b6000816000190483118215151615614be157614be1614c48565b500290565b600082821015614bf857614bf8614c48565b500390565b60005b83811015614c18578181015183820152602001614c00565b83811115614c27576000848401525b50505050565b6000600019821415614c4157614c41614c48565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114614c8957600080fd5b5056fea2646970667358221220bc25778b0b2b8da310654fbcc9ecfd812edae3f0312069e9b19db3755989180764736f6c63430008040033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103f15760003560e01c80638b95e33511610215578063d9f9027f11610125578063e527e2c8116100b8578063ee98aa5f11610087578063ee98aa5f14610910578063f2dc7ff514610923578063f4754e0114610669578063f77c479114610936578063ffa1ad741461093e57600080fd5b8063e527e2c8146108cf578063e77fb0d8146108e2578063e945cdcd146108ea578063ebee0406146108fd57600080fd5b8063df0ac912116100f4578063df0ac91214610896578063e2710b89146108a9578063e3d3b66d146108bc578063e410e4a61461087057600080fd5b8063d9f9027f14610848578063db84991d14610850578063dc54c27614610870578063dee1f0e41461088357600080fd5b8063a90f55bf116101a8578063b429afeb11610177578063b429afeb146107dc578063bab6929c146107ef578063be1e27d114610802578063c376dbb314610815578063d0d026331461082857600080fd5b8063a90f55bf14610787578063a980356a146107a7578063aaf5eb68146107ba578063ab1b491c146107c957600080fd5b80639c5d61b4116101e45780639c5d61b41461072e578063a179751b14610741578063a689cbc314610761578063a80a5ce71461077457600080fd5b80638b95e335146106e05780638d852391146106e85780639164359a146106fb57806396ef1b981461071b57600080fd5b80634acd7390116103105780636f8d34f0116102a35780638170bbd5116102725780638170bbd5146106a25780638220ef5b146106aa57806382af54c9146106b2578063849efb71146106ba5780638adab464146106cd57600080fd5b80636f8d34f014610646578063728204e41461066957806372a4aa711461067c5780637e52586c1461068f57600080fd5b8063514b9ec7116102df578063514b9ec7146105e05780636430be8c146106005780636922d7b6146106135780636d5f9b331461062657600080fd5b80634acd7390146105945780634d18e43d146105a75780634e58d37e146105ba5780634f8f0eb0146105cd57600080fd5b8063325a19f1116103885780634624aa44116103575780634624aa441461052a57806347b03bba1461054a578063485cc9551461055f57806349c997ce1461057457600080fd5b8063325a19f1146104d55780633f74bb89146104fc5780634135b6731461050457806341976e091461051757600080fd5b80631184006e116103c45780631184006e1461046f57806319babe8b1461048f57806324d1efcf146104a257806331bd6e2c146104b557600080fd5b806308dc993c146103f65780630bcc41df1461041c5780630f208beb1461042f5780631041cc641461044f575b600080fd5b610409610404366004613f56565b610962565b6040519081526020015b60405180910390f35b61040961042a366004614047565b610ae5565b61044261043d366004613f8e565b610bb3565b6040516104139190614a18565b61046261045d366004613f56565b610e37565b604051610413919061473f565b61048261047d366004613f8e565b610eae565b6040516104139190614975565b61040961049d366004613f56565b6110d8565b6104096104b0366004613f8e565b61110e565b6104c86104c3366004614047565b611141565b6040516104139190614815565b7f6f55f470bdc9cb5f04223fd822021061668e4dccb43e8727b295106dc9769c8a54610409565b610409611222565b610409610512366004613f8e565b6112a6565b610409610525366004613f56565b611335565b61053d610538366004613f56565b6113be565b6040516104139190614a2b565b610552611521565b6040516104139190614711565b61057261056d366004613f8e565b6115a0565b005b610587610582366004613fc6565b61168d565b6040516104139190614752565b6104096105a2366004613f56565b611793565b6104096105b5366004613f56565b611806565b6104096105c8366004614047565b6118a2565b6104826105db366004613f8e565b6118fe565b6105f36105ee366004614013565b611b24565b6040516104139190614869565b61040961060e366004613f8e565b611d22565b610572610621366004613f56565b611d53565b610639610634366004613f56565b611e56565b6040516104139190614996565b610659610654366004613f56565b611ecd565b6040519015158152602001610413565b610409610677366004613f56565b611f40565b61040961068a366004613f8e565b611f7b565b61048261069d366004613f8e565b611fb4565b610482612137565b610462612302565b610409612380565b6104096106c8366004613f56565b6123c2565b6106596106db366004613f56565b61240f565b61055261244a565b6104096106f6366004614047565b6124a4565b61070e610709366004613f56565b612500565b6040516104139190614a3e565b610482610729366004613f56565b6126e8565b61040961073c366004613f56565b61291a565b61075461074f366004613f56565b6129e0565b6040516104139190614988565b61075461076f366004613f56565b612a53565b610409610782366004613f56565b612afe565b61079a610795366004613fc6565b612b3c565b60405161041391906148f1565b6104826107b5366004613f8e565b612c54565b610409670de0b6b3a764000081565b6105526107d7366004613f56565b612d9f565b6106596107ea366004613f56565b612e12565b6104096107fd366004613f8e565b612e37565b610409610810366004613f56565b612e62565b610409610823366004613f56565b612ea0565b61083b610836366004614047565b612f1c565b60405161041391906147b4565b610462612ff0565b61086361085e366004613f8e565b613032565b60405161041391906149f7565b61046261087e366004613f56565b613092565b610659610891366004613f56565b6130cd565b61079a6108a4366004614013565b613161565b6105f36108b7366004613fc6565b61332f565b6104096108ca36600461427c565b61343a565b6104096108dd366004614047565b61349b565b6104096134f7565b6105726108f8366004613f56565b613552565b61048261090b366004613f56565b6135f0565b61040961091e366004613f8e565b613763565b610482610931366004613f56565b6139e2565b610552613af6565b610639604051806040016040528060058152602001640c4b8c0b8d60da1b81525081565b60008061096d613af6565b6001600160a01b031663f7c618c16040518163ffffffff1660e01b815260040160206040518083038186803b1580156109a557600080fd5b505afa1580156109b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109dd9190613f72565b9050610ade6109ea611521565b6001600160a01b031663cb618c9d856040518263ffffffff1660e01b8152600401610a159190614711565b60206040518083038186803b158015610a2d57600080fd5b505afa158015610a41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a659190614264565b826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610a9e57600080fd5b505afa158015610ab2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad691906142a7565b60ff16613b1b565b9392505050565b600080805b8351811015610bac57610b8e848281518110610b1657634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031663a8c62e766040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5657600080fd5b505afa158015610b6a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104049190613f72565b610b989083614aa4565b915080610ba481614c2d565b915050610aea565b5092915050565b610bbb613c91565b6000826001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b158015610bf657600080fd5b505afa158015610c0a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c329190810190614079565b9050600081516001600160401b03811115610c5d57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610c86578160200160208202803683370190505b50905060005b8251811015610d7757846001600160a01b031663211dc32d848381518110610cc457634e487b7160e01b600052603260045260246000fd5b6020026020010151886040518363ffffffff1660e01b8152600401610cea929190614725565b60206040518083038186803b158015610d0257600080fd5b505afa158015610d16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3a9190614264565b828281518110610d5a57634e487b7160e01b600052603260045260246000fd5b602090810291909101015280610d6f81614c2d565b915050610c8c565b50604051806101800160405280866001600160a01b03168152602001856001600160a01b03168152602001610dac8787611f7b565b8152602001610dbb8787612e37565b8152602001610dca87876112a6565b8152602001610dd9878761110e565b8152602001610de88787611d22565b8152602001838152602001610dfd8787612c54565b8152602001610e0c8787611fb4565b8152602001610e1b8787610eae565b8152602001610e2a87876118fe565b9052925050505b92915050565b6060816001600160a01b03166371a973056040518163ffffffff1660e01b815260040160006040518083038186803b158015610e7257600080fd5b505afa158015610e86573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e319190810190614079565b60606000826001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b158015610eeb57600080fd5b505afa158015610eff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f279190810190614079565b9050600081516001600160401b03811115610f5257634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610f7b578160200160208202803683370190505b50905060005b82518110156110cf57611092856001600160a01b031663e81bb2d6858481518110610fbc57634e487b7160e01b600052603260045260246000fd5b6020026020010151896040518363ffffffff1660e01b8152600401610fe2929190614725565b60206040518083038186803b158015610ffa57600080fd5b505afa15801561100e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190614264565b84838151811061105257634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610a9e57600080fd5b8282815181106110b257634e487b7160e01b600052603260045260246000fd5b6020908102919091010152806110c781614c2d565b915050610f81565b50949350505050565b6000806110e761052584612d9f565b9050610ade670de0b6b3a76400006111088361110287612afe565b90613b39565b90613b45565b60008061111d61052584612d9f565b9050611139670de0b6b3a76400006111088361110288886112a6565b949350505050565b6060600082516001600160401b0381111561116c57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156111a557816020015b611192613d04565b81526020019060019003908161118a5790505b50905060005b8351811015610bac576111e48482815181106111d757634e487b7160e01b600052603260045260246000fd5b6020026020010151612500565b82828151811061120457634e487b7160e01b600052603260045260246000fd5b6020026020010181905250808061121a90614c2d565b9150506111ab565b600061122c611521565b6001600160a01b031663d9f9027f6040518163ffffffff1660e01b815260040160006040518083038186803b15801561126457600080fd5b505afa158015611278573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112a09190810190614079565b51905090565b6000610ade826001600160a01b0316638cb1d67f856040518263ffffffff1660e01b81526004016112d79190614711565b60206040518083038186803b1580156112ef57600080fd5b505afa158015611303573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113279190614264565b61133084612ea0565b613b1b565b600061133f61244a565b6001600160a01b0316637539bdb1836040518263ffffffff1660e01b815260040161136a9190614711565b60206040518083038186803b15801561138257600080fd5b505afa9250505080156113b2575060408051601f3d908101601f191682019092526113af91810190614264565b60015b610e3157506000919050565b6113c6613de9565b6000826001600160a01b031663a8c62e766040518163ffffffff1660e01b815260040160206040518083038186803b15801561140157600080fd5b505afa158015611415573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114399190613f72565b90506000604051806101800160405280856001600160a01b0316815260200161146186611f40565b815260200161146f86611ecd565b1515815260200161147f86612afe565b815260200161148d866110d8565b815260200161149b86612d9f565b6001600160a01b031681526020016114b286613092565b81526020016114c0866126e8565b81526020016114ce86611806565b81526020016114dc846129e0565b60138111156114fb57634e487b7160e01b600052602160045260246000fd5b815260200161150984610e37565b815260200161151784610962565b9052949350505050565b600061152b613af6565b6001600160a01b03166347b03bba6040518163ffffffff1660e01b815260040160206040518083038186803b15801561156357600080fd5b505afa158015611577573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159b9190613f72565b905090565b600054610100900460ff16806115b9575060005460ff16155b6115de5760405162461bcd60e51b81526004016115d5906149a9565b60405180910390fd5b600054610100900460ff16158015611600576000805461ffff19166101011790555b61160983613552565b816001600060405160200161162e906931b0b631bab630ba37b960b11b8152600a0190565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508015611688576000805461ff00191690555b505050565b6060600082516001600160401b038111156116b857634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561170d57816020015b6116fa60405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816116d65790505b50905060005b835181101561178b5761174d8585838151811061174057634e487b7160e01b600052603260045260246000fd5b6020026020010151613032565b82828151811061176d57634e487b7160e01b600052603260045260246000fd5b6020026020010181905250808061178390614c2d565b915050611713565b509392505050565b6000816001600160a01b0316630fb5a6b46040518163ffffffff1660e01b815260040160206040518083038186803b1580156117ce57600080fd5b505afa1580156117e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e319190614264565b6000610e31611327836001600160a01b03166377c7b8fc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561184757600080fd5b505afa15801561185b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061187f9190614264565b61188885612ea0565b61189390600a614b1f565b4261189d87611f40565b613b51565b600080805b8351811015610bac576118e08482815181106118d357634e487b7160e01b600052603260045260246000fd5b60200260200101516123c2565b6118ea9083614aa4565b9150806118f681614c2d565b9150506118a7565b60606000826001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b15801561193b57600080fd5b505afa15801561194f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119779190810190614079565b9050600081516001600160401b038111156119a257634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156119cb578160200160208202803683370190505b50905060005b82518110156110cf576000611a0c8483815181106119ff57634e487b7160e01b600052603260045260246000fd5b6020026020010151611335565b9050611ae6611ac6670de0b6b3a7640000611108848a6001600160a01b031663e81bb2d68a8981518110611a5057634e487b7160e01b600052603260045260246000fd5b60200260200101518e6040518363ffffffff1660e01b8152600401611a76929190614725565b60206040518083038186803b158015611a8e57600080fd5b505afa158015611aa2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111029190614264565b85848151811061105257634e487b7160e01b600052603260045260246000fd5b838381518110611b0657634e487b7160e01b600052603260045260246000fd5b60209081029190910101525080611b1c81614c2d565b9150506119d1565b60606000611b30612302565b51905060008111611b725760405162461bcd60e51b815260206004820152600c60248201526b656d707479207661756c747360a01b60448201526064016115d5565b6000611b7e8483614abc565b905081611b8b8583614bc7565b1015611b9f5780611b9b81614c2d565b9150505b80851115611bab578094505b6000611bca611bba8688614bc7565b611bc5600186614be6565b613bb6565b90506000611be1611bdb8784614aa4565b85613bb6565b90506000611bef8383614be6565b6001600160401b03811115611c1457634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611c4d57816020015b611c3a613e7d565b815260200190600190039081611c325790505b509050825b82811015611d15576040518060400160405280611c9c611c70612302565b8481518110611c8f57634e487b7160e01b600052603260045260246000fd5b60200260200101516113be565b8152602001611ccc8c611cad612302565b858151811061174057634e487b7160e01b600052603260045260246000fd5b905282611cd98684614be6565b81518110611cf757634e487b7160e01b600052603260045260246000fd5b60200260200101819052508080611d0d90614c2d565b915050611c52565b5098975050505050505050565b6000610ade826001600160a01b03166370a08231856040518263ffffffff1660e01b81526004016112d79190614711565b611d5c33612e12565b80611d6b5750611d6b336130cd565b611daf5760405162461bcd60e51b81526020600482015260156024820152743737ba1031b7b73a3937b63632b91037b91033b7bb60591b60448201526064016115d5565b8060016000604051602001611dd4906931b0b631bab630ba37b960b11b8152600a0190565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055507f0caadb6ce6adfa207b9ff9c87df2ad8361fe4e2e5c4fb493fba65daa077dc4f481604051611e4b9190614711565b60405180910390a150565b6060816001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015611e9157600080fd5b505afa158015611ea5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e319190810190614153565b6000816001600160a01b03166302fb0c5e6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f0857600080fd5b505afa158015611f1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e319190614114565b6000816001600160a01b031663325a19f16040518163ffffffff1660e01b815260040160206040518083038186803b1580156117ce57600080fd5b6000610ade611f8983612d9f565b6001600160a01b03166370a08231856040518263ffffffff1660e01b81526004016112d79190614711565b60606000826001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b158015611ff157600080fd5b505afa158015612005573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261202d9190810190614079565b9050600081516001600160401b0381111561205857634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612081578160200160208202803683370190505b50905060005b82518110156110cf5760006120b58483815181106119ff57634e487b7160e01b600052603260045260246000fd5b90506120f9611ac6670de0b6b3a7640000611108848a6001600160a01b031663211dc32d8a8981518110611a5057634e487b7160e01b600052603260045260246000fd5b83838151811061211957634e487b7160e01b600052603260045260246000fd5b6020908102919091010152508061212f81614c2d565b915050612087565b606060006121b6612146613af6565b6001600160a01b031663f7c618c16040518163ffffffff1660e01b815260040160206040518083038186803b15801561217e57600080fd5b505afa158015612192573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105259190613f72565b9050600061227a670de0b6b3a7640000611108846121d2613af6565b6001600160a01b031663f7c618c16040518163ffffffff1660e01b815260040160206040518083038186803b15801561220a57600080fd5b505afa15801561221e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122429190613f72565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a8e57600080fd5b604080516002808252606082018352929350600092909160208301908036833701905050905082816000815181106122c257634e487b7160e01b600052603260045260246000fd5b60200260200101818152505081816001815181106122f057634e487b7160e01b600052603260045260246000fd5b60209081029190910101529392505050565b606061230c611521565b6001600160a01b0316638220ef5b6040518163ffffffff1660e01b815260040160006040518083038186803b15801561234457600080fd5b505afa158015612358573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261159b9190810190614079565b600061238a611521565b6001600160a01b0316638220ef5b6040518163ffffffff1660e01b815260040160006040518083038186803b15801561126457600080fd5b60006123cc611521565b6001600160a01b031663c14a38e3836040518263ffffffff1660e01b81526004016123f79190614711565b60206040518083038186803b1580156117ce57600080fd5b6000816001600160a01b031663d3df8aa46040518163ffffffff1660e01b815260040160206040518083038186803b158015611f0857600080fd5b600060016000604051602001612470906931b0b631bab630ba37b960b11b8152600a0190565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b0316919050565b600080805b8351811015610bac576124e28482815181106124d557634e487b7160e01b600052603260045260246000fd5b60200260200101516110d8565b6124ec9083614aa4565b9150806124f881614c2d565b9150506124a9565b612508613d04565b6000826001600160a01b031663a8c62e766040518163ffffffff1660e01b815260040160206040518083038186803b15801561254357600080fd5b505afa158015612557573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257b9190613f72565b90506000604051806102c00160405280856001600160a01b031681526020016125a386611e56565b81526020016125b186611f40565b81526020016125bf86611ecd565b151581526020016125cf86612afe565b81526020016125dd866110d8565b81526020016125eb86612ea0565b81526020016125f986612d9f565b6001600160a01b0316815260200161261086613092565b815260200161261e866139e2565b815260200161262c866135f0565b815260200161263a86611793565b8152602001612648866126e8565b815260200161265686611806565b8152602001612664866123c2565b8152602001836001600160a01b0316815260200161268184611f40565b815260200161268f846129e0565b60138111156126ae57634e487b7160e01b600052602160045260246000fd5b81526020016126bc84610e37565b81526020016126ca84613092565b81526020016126d88461240f565b1515815260200161151784610962565b606060008290506000816001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b15801561272a57600080fd5b505afa15801561273e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526127669190810190614079565b516001600160401b0381111561278c57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156127b5578160200160208202803683370190505b50905060005b826001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b1580156127f457600080fd5b505afa158015612808573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128309190810190614079565b5181101561178b576128dd85846001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b15801561287557600080fd5b505afa158015612889573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128b19190810190614079565b83815181106128d057634e487b7160e01b600052603260045260246000fd5b6020026020010151613763565b8282815181106128fd57634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061291281614c2d565b9150506127bb565b600080612925611521565b6001600160a01b031663400dfebd846040518263ffffffff1660e01b81526004016129509190614711565b60e06040518083038186803b15801561296857600080fd5b505afa15801561297c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129a091906141d9565b90508060400151600014156129b85750600092915050565b610ade6129d782606001518360c0015184604001518560a00151613b51565b61133085612ea0565b6000816001600160a01b0316634bde38c86040518163ffffffff1660e01b815260040160206040518083038186803b158015612a1b57600080fd5b505afa158015612a2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e319190614134565b6000816001600160a01b031663a8c62e766040518163ffffffff1660e01b815260040160206040518083038186803b158015612a8e57600080fd5b505afa158015612aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac69190613f72565b6001600160a01b0316634bde38c86040518163ffffffff1660e01b815260040160206040518083038186803b158015612a1b57600080fd5b6000610e31826001600160a01b0316631bf8e7be6040518163ffffffff1660e01b815260040160206040518083038186803b1580156112ef57600080fd5b6060600082516001600160401b03811115612b6757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612ba057816020015b612b8d613ebe565b815260200190600190039081612b855790505b50905060005b835181101561178b576040518060400160405280612bdd8684815181106111d757634e487b7160e01b600052603260045260246000fd5b8152602001612c1387878581518110612c0657634e487b7160e01b600052603260045260246000fd5b6020026020010151610bb3565b815250828281518110612c3657634e487b7160e01b600052603260045260246000fd5b60200260200101819052508080612c4c90614c2d565b915050612ba6565b60606000826001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b158015612c9157600080fd5b505afa158015612ca5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612ccd9190810190614079565b9050600081516001600160401b03811115612cf857634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612d21578160200160208202803683370190505b50905060005b82518110156110cf57612d62856001600160a01b031663211dc32d858481518110610fbc57634e487b7160e01b600052603260045260246000fd5b828281518110612d8257634e487b7160e01b600052603260045260246000fd5b602090810291909101015280612d9781614c2d565b915050612d27565b6000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b158015612dda57600080fd5b505afa158015612dee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e319190613f72565b6000612e1c613af6565b6001600160a01b0316826001600160a01b0316149050919050565b600080612e4661052584612d9f565b9050611139670de0b6b3a7640000611108836111028888611f7b565b6000610e31826001600160a01b03166377c7b8fc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156112ef57600080fd5b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015612edb57600080fd5b505afa158015612eef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f1391906142a7565b60ff1692915050565b6060600082516001600160401b03811115612f4757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612f8057816020015b612f6d613de9565b815260200190600190039081612f655790505b50905060005b8351811015610bac57612fb2848281518110611c8f57634e487b7160e01b600052603260045260246000fd5b828281518110612fd257634e487b7160e01b600052603260045260246000fd5b60200260200101819052508080612fe890614c2d565b915050612f86565b6060612ffa611521565b6001600160a01b031663d9f9027f6040518163ffffffff1660e01b815260040160006040518083038186803b15801561234457600080fd5b61305660405180606001604052806000815260200160008152602001600081525090565b604051806060016040528061306b85856112a6565b815260200161307a858561110e565b81526020016130898585611d22565b90529392505050565b6060816001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b158015610e7257600080fd5b6000816001600160a01b03166130e1613af6565b6001600160a01b0316635aa6e6756040518163ffffffff1660e01b815260040160206040518083038186803b15801561311957600080fd5b505afa15801561312d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131519190613f72565b6001600160a01b03161492915050565b6060600061316d612302565b519050600081116131af5760405162461bcd60e51b815260206004820152600c60248201526b656d707479207661756c747360a01b60448201526064016115d5565b60006131bb8483614abc565b9050816131c88583614bc7565b10156131dc57806131d881614c2d565b9150505b808511156131e8578094505b60006131f7611bba8688614bc7565b90506000613208611bdb8784614aa4565b905060006132168383614be6565b6001600160401b0381111561323b57634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561327457816020015b613261613ebe565b8152602001906001900390816132595790505b509050825b82811015611d155760405180604001604052806132b6613297612302565b84815181106111d757634e487b7160e01b600052603260045260246000fd5b81526020016132e68c6132c7612302565b8581518110612c0657634e487b7160e01b600052603260045260246000fd5b9052826132f38684614be6565b8151811061331157634e487b7160e01b600052603260045260246000fd5b6020026020010181905250808061332790614c2d565b915050613279565b6060600082516001600160401b0381111561335a57634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561339357816020015b613380613e7d565b8152602001906001900390816133785790505b50905060005b835181101561178b5760405180604001604052806133d0868481518110611c8f57634e487b7160e01b600052603260045260246000fd5b81526020016133f98787858151811061174057634e487b7160e01b600052603260045260246000fd5b81525082828151811061341c57634e487b7160e01b600052603260045260246000fd5b6020026020010181905250808061343290614c2d565b915050613399565b600080613457670de0b6b3a7640000611102876111088884613b39565b9050613492670de0b6b3a7640000611108606461110261016d8161348062015180868c89613b39565b61110889670de0b6b3a7640000613b39565b95945050505050565b600080805b8351811015610bac576134d98482815181106134cc57634e487b7160e01b600052603260045260246000fd5b6020026020010151610962565b6134e39083614aa4565b9150806134ef81614c2d565b9150506134a0565b600080613502612302565b90506000805b8251811015610bac576135348382815181106118d357634e487b7160e01b600052603260045260246000fd5b61353e9083614aa4565b91508061354a81614c2d565b915050613508565b600054610100900460ff168061356b575060005460ff16155b6135875760405162461bcd60e51b81526004016115d5906149a9565b600054610100900460ff161580156135a9576000805461ffff19166101011790555b6135b282613bcc565b6135da427f6f55f470bdc9cb5f04223fd822021061668e4dccb43e8727b295106dc9769c8a55565b80156135ec576000805461ff00191690555b5050565b606060006135fd83613092565b516001600160401b0381111561362357634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561364c578160200160208202803683370190505b50905060005b61365b84613092565b51811015610bac57600061366e85613092565b828151811061368d57634e487b7160e01b600052603260045260246000fd5b6020026020010151905060006136a282611335565b905060006136e2670de0b6b3a764000061110884866001600160a01b03166370a082318c6040518263ffffffff1660e01b8152600401611a769190614711565b905061372181846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610a9e57600080fd5b85858151811061374157634e487b7160e01b600052603260045260246000fd5b602002602001018181525050505050808061375b90614c2d565b915050613652565b600080836001600160a01b0316633fee85e6846040518263ffffffff1660e01b81526004016137929190614711565b60206040518083038186803b1580156137aa57600080fd5b505afa1580156137be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137e29190614264565b905060006137ef856110d8565b905060006137fc85611335565b905060006138a0876001600160a01b0316630fb5a6b46040518163ffffffff1660e01b815260040160206040518083038186803b15801561383c57600080fd5b505afa158015613850573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138749190614264565b604051630b711f0760e11b81526001600160a01b038a16906316e23e0e90611a76908b90600401614711565b905082158015906138b057508015155b80156138bb57504284115b156139d55760006138cc8542613c75565b90506000613956896001600160a01b0316630fb5a6b46040518163ffffffff1660e01b815260040160206040518083038186803b15801561390c57600080fd5b505afa158015613920573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139449190614264565b61110884670de0b6b3a7640000613b39565b9050600061397b6ec097ce7bc90715b34b9f1000000000611108876111028887613b39565b90506139ba818a6001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610a9e57600080fd5b90506139c786828561343a565b975050505050505050610e31565b6000945050505050610e31565b606060006139ef83613092565b516001600160401b03811115613a1557634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015613a3e578160200160208202803683370190505b50905060005b613a4d84613092565b51811015610bac576000613a6085613092565b8281518110613a7f57634e487b7160e01b600052603260045260246000fd5b60200260200101519050613ab8816001600160a01b03166370a08231876040518263ffffffff1660e01b8152600401610a159190614711565b838381518110613ad857634e487b7160e01b600052603260045260246000fd5b60209081029190910101525080613aee81614c2d565b915050613a44565b7f5165972ef41194f06c5007493031d0b927c20741adcb74403b954009fd2c36175490565b6000610ade613b2b83600a614b1f565b61110885670de0b6b3a76400005b6000610ade8284614bc7565b6000610ade8284614abc565b6000838511613b6257506000611139565b6000613b6e8686613c75565b90506000613b86613b7f8686613c75565b6001613c81565b9050613bab670de0b6b3a764000061110860646111026301e133808187858a88613b39565b979650505050505050565b6000818310613bc55781610ade565b5090919050565b6001600160a01b038116613c115760405162461bcd60e51b815260206004820152600c60248201526b7a65726f206164647265737360a01b60448201526064016115d5565b7f19b7d592cea0dfda222f6a4ea5c5a8d018ee9c6b1d0a917483a405de94eb26cd613c3a613af6565b82604051613c49929190614725565b60405180910390a17f5165972ef41194f06c5007493031d0b927c20741adcb74403b954009fd2c361755565b6000610ade8284614be6565b600081831015613bc55781610ade565b60405180610180016040528060006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b604051806102c0016040528060006001600160a01b03168152602001606081526020016000815260200160001515815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016060815260200160608152602001606081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b031681526020016000815260200160006013811115613dc557634e487b7160e01b600052602160045260246000fd5b81526020016060815260200160608152602001600015158152602001600081525090565b60405180610180016040528060006001600160a01b0316815260200160008152602001600015158152602001600081526020016000815260200160006001600160a01b0316815260200160608152602001606081526020016000815260200160006013811115613e6957634e487b7160e01b600052602160045260246000fd5b815260200160608152602001600081525090565b6040518060400160405280613e90613de9565b8152602001613eb960405180606001604052806000815260200160008152602001600081525090565b905290565b6040518060400160405280613ed1613d04565b8152602001613eb9613c91565b600082601f830112613eee578081fd5b81356020613f03613efe83614a81565b614a51565b80838252828201915082860187848660051b8901011115613f22578586fd5b855b85811015613f49578135613f3781614c74565b84529284019290840190600101613f24565b5090979650505050505050565b600060208284031215613f67578081fd5b8135610ade81614c74565b600060208284031215613f83578081fd5b8151610ade81614c74565b60008060408385031215613fa0578081fd5b8235613fab81614c74565b91506020830135613fbb81614c74565b809150509250929050565b60008060408385031215613fd8578182fd5b8235613fe381614c74565b915060208301356001600160401b03811115613ffd578182fd5b61400985828601613ede565b9150509250929050565b600080600060608486031215614027578081fd5b833561403281614c74565b95602085013595506040909401359392505050565b600060208284031215614058578081fd5b81356001600160401b0381111561406d578182fd5b61113984828501613ede565b6000602080838503121561408b578182fd5b82516001600160401b038111156140a0578283fd5b8301601f810185136140b0578283fd5b80516140be613efe82614a81565b80828252848201915084840188868560051b87010111156140dd578687fd5b8694505b838510156141085780516140f481614c74565b8352600194909401939185019185016140e1565b50979650505050505050565b600060208284031215614125578081fd5b81518015158114610ade578182fd5b600060208284031215614145578081fd5b815160148110610ade578182fd5b600060208284031215614164578081fd5b81516001600160401b038082111561417a578283fd5b818401915084601f83011261418d578283fd5b81518181111561419f5761419f614c5e565b6141b2601f8201601f1916602001614a51565b91508082528560208285010111156141c8578384fd5b6110cf816020840160208601614bfd565b600060e082840312156141ea578081fd5b60405160e081018181106001600160401b038211171561420c5761420c614c5e565b604052825161421a81614c74565b808252506020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c08201528091505092915050565b600060208284031215614275578081fd5b5051919050565b600080600060608486031215614290578081fd5b505081359360208301359350604090920135919050565b6000602082840312156142b8578081fd5b815160ff81168114610ade578182fd5b6000815180845260208085019450808401835b838110156143005781516001600160a01b0316875295820195908201906001016142db565b509495945050505050565b6000815180845260208085019450808401835b838110156143005781518752958201959082019060010161431e565b6014811061435857634e487b7160e01b600052602160045260246000fd5b9052565b60008151808452614374816020860160208601614bfd565b601f01601f19169290920160200192915050565b80516001600160a01b03168252600061018060208301516143b460208601826001600160a01b03169052565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e08301518160e08601526143fe828601826142c8565b9150506101008084015185830382870152614419838261430b565b925050506101208084015185830382870152614435838261430b565b925050506101408084015185830382870152614451838261430b565b92505050610160808401518583038287015261446d838261430b565b9695505050505050565b80516001600160a01b0316825260006101806020830151602085015260408301516144a6604086018215159052565b50606083015160608501526080830151608085015260a08301516144d560a08601826001600160a01b03169052565b5060c08301518160c08601526144ed828601826142c8565b91505060e083015184820360e0860152614507828261430b565b915050610100808401518186015250610120808401516145298287018261433a565b5050610140808401518583038287015261454383826142c8565b61016095860151969095019590955250919392505050565b80516001600160a01b0316825260006102c060208301518160208601526145848286018261435c565b9150506040830151604085015260608301516145a4606086018215159052565b506080830151608085015260a083015160a085015260c083015160c085015260e08301516145dd60e08601826001600160a01b03169052565b5061010080840151858303828701526145f683826142c8565b925050506101208084015185830382870152614612838261430b565b92505050610140808401518583038287015261462e838261430b565b925050506101608084015181860152506101808084015185830382870152614656838261430b565b925050506101a08084015181860152506101c08084015181860152506101e08084015161468d828701826001600160a01b03169052565b50506102008381015190850152610220808401516146ad8287018261433a565b505061024080840151858303828701526146c783826142c8565b9250505061026080840151858303828701526146e383826142c8565b92505050610280808401516146fb8287018215159052565b50506102a0928301519390920192909252919050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b602081526000610ade60208301846142c8565b6020808252825182820181905260009190848201906040850190845b818110156147a8576147958385518051825260208082015190830152604090810151910152565b928401926060929092019160010161476e565b50909695505050505050565b6000602080830181845280855180835260408601915060408160051b8701019250838701855b8281101561480857603f198886030184526147f6858351614477565b945092850192908501906001016147da565b5092979650505050505050565b6000602080830181845280855180835260408601915060408160051b8701019250838701855b8281101561480857603f1988860301845261485785835161455b565b9450928501929085019060010161483b565b6000602080830181845280855180835260408601915060408160051b8701019250838701855b8281101561480857603f198886030184528151608081518188526148b582890182614477565b9150508782015191506148de888801838051825260208082015190830152604090810151910152565b955050928501929085019060010161488f565b60006020808301818452808551808352604092508286019150828160051b870101848801865b8381101561496757888303603f190185528151805187855261493b8886018261455b565b91890151858303868b01529190506149538183614388565b968901969450505090860190600101614917565b509098975050505050505050565b602081526000610ade602083018461430b565b60208101610e31828461433a565b602081526000610ade602083018461435c565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b81518152602080830151908201526040808301519082015260608101610e31565b602081526000610ade6020830184614388565b602081526000610ade6020830184614477565b602081526000610ade602083018461455b565b604051601f8201601f191681016001600160401b0381118282101715614a7957614a79614c5e565b604052919050565b60006001600160401b03821115614a9a57614a9a614c5e565b5060051b60200190565b60008219821115614ab757614ab7614c48565b500190565b600082614ad757634e487b7160e01b81526012600452602481fd5b500490565b600181815b80851115614b17578160001904821115614afd57614afd614c48565b80851615614b0a57918102915b93841c9390800290614ae1565b509250929050565b6000610ade8383600082614b3557506001610e31565b81614b4257506000610e31565b8160018114614b585760028114614b6257614b7e565b6001915050610e31565b60ff841115614b7357614b73614c48565b50506001821b610e31565b5060208310610133831016604e8410600b8410161715614ba1575081810a610e31565b614bab8383614adc565b8060001904821115614bbf57614bbf614c48565b029392505050565b6000816000190483118215151615614be157614be1614c48565b500290565b600082821015614bf857614bf8614c48565b500390565b60005b83811015614c18578181015183820152602001614c00565b83811115614c27576000848401525b50505050565b6000600019821415614c4157614c41614c48565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114614c8957600080fd5b5056fea2646970667358221220bc25778b0b2b8da310654fbcc9ecfd812edae3f0312069e9b19db3755989180764736f6c63430008040033
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.