Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x61010060 | 14391460 | 867 days ago | IN | 0 ETH | 0.18486384 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
EthVault
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-03-15 */ // SPDX-License-Identifier: GPL-3.0-or-later // Sources flattened with hardhat v2.6.1 https://hardhat.org // File @openzeppelin/contracts/token/ERC20/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) 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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, 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); } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts/token/ERC20/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File @openzeppelin/contracts-upgradeable/utils/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts-upgradeable/proxy/utils/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol) 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 proxied contracts do not make use of 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. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ 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() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } } // File interfaces/IStrategy.sol pragma solidity 0.8.9; interface IStrategy { function name() external view returns (string memory); function deposit() external payable returns (bool); function balance() external view returns (uint256); function withdraw(uint256 amount) external returns (bool); function withdrawAll() external returns (uint256); function harvestable() external view returns (uint256); function harvest() external returns (uint256); function strategist() external view returns (address); function shutdown() external returns (bool); function hasPendingFunds() external view returns (bool); } // File interfaces/IPreparable.sol pragma solidity 0.8.9; interface IPreparable { event ConfigPreparedAddress(bytes32 indexed key, address value, uint256 delay); event ConfigPreparedNumber(bytes32 indexed key, uint256 value, uint256 delay); event ConfigUpdatedAddress(bytes32 indexed key, address oldValue, address newValue); event ConfigUpdatedNumber(bytes32 indexed key, uint256 oldValue, uint256 newValue); event ConfigReset(bytes32 indexed key); } // File interfaces/IVault.sol pragma solidity 0.8.9; /** * @title Interface for a Vault */ interface IVault is IPreparable { event StrategyActivated(address indexed strategy); event StrategyDeactivated(address indexed strategy); /** * @dev 'netProfit' is the profit after all fees have been deducted */ event Harvest(uint256 indexed netProfit, uint256 indexed loss); function initialize( address _pool, uint256 _debtLimit, uint256 _targetAllocation, uint256 _bound ) external; function withdrawFromStrategyWaitingForRemoval(address strategy) external returns (uint256); function deposit() external payable; function withdraw(uint256 amount) external returns (bool); function initializeStrategy(address strategy_) external returns (bool); function withdrawAll() external; function withdrawFromReserve(uint256 amount) external; function getStrategy() external view returns (IStrategy); function getStrategiesWaitingForRemoval() external view returns (address[] memory); function getAllocatedToStrategyWaitingForRemoval(address strategy) external view returns (uint256); function getTotalUnderlying() external view returns (uint256); function getUnderlying() external view returns (address); } // File interfaces/IVaultReserve.sol pragma solidity 0.8.9; interface IVaultReserve { event Deposit(address indexed vault, address indexed token, uint256 amount); event Withdraw(address indexed vault, address indexed token, uint256 amount); event VaultListed(address indexed vault); function deposit(address token, uint256 amount) external payable returns (bool); function withdraw(address token, uint256 amount) external returns (bool); function getBalance(address vault, address token) external view returns (uint256); function canWithdraw(address vault) external view returns (bool); } // File interfaces/pool/ILiquidityPool.sol pragma solidity 0.8.9; interface ILiquidityPool is IPreparable { event Deposit(address indexed minter, uint256 depositAmount, uint256 mintedLpTokens); event DepositFor( address indexed minter, address indexed mintee, uint256 depositAmount, uint256 mintedLpTokens ); event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens); event LpTokenSet(address indexed lpToken); event StakerVaultSet(address indexed stakerVault); function redeem(uint256 redeemTokens) external returns (uint256); function redeem(uint256 redeemTokens, uint256 minRedeemAmount) external returns (uint256); function calcRedeem(address account, uint256 underlyingAmount) external returns (uint256); function deposit(uint256 mintAmount) external payable returns (uint256); function deposit(uint256 mintAmount, uint256 minTokenAmount) external payable returns (uint256); function depositAndStake(uint256 depositAmount, uint256 minTokenAmount) external payable returns (uint256); function depositFor(address account, uint256 depositAmount) external payable returns (uint256); function depositFor( address account, uint256 depositAmount, uint256 minTokenAmount ) external payable returns (uint256); function unstakeAndRedeem(uint256 redeemLpTokens, uint256 minRedeemAmount) external returns (uint256); function handleLpTokenTransfer( address from, address to, uint256 amount ) external; function executeNewVault() external returns (address); function executeNewMaxWithdrawalFee() external returns (uint256); function executeNewRequiredReserves() external returns (uint256); function executeNewReserveDeviation() external returns (uint256); function setLpToken(address _lpToken) external returns (bool); function setStaker() external returns (bool); function isCapped() external returns (bool); function uncap() external returns (bool); function updateDepositCap(uint256 _depositCap) external returns (bool); function getUnderlying() external view returns (address); function getLpToken() external view returns (address); function getWithdrawalFee(address account, uint256 amount) external view returns (uint256); function getVault() external view returns (IVault); function exchangeRate() external view returns (uint256); } // File interfaces/IGasBank.sol pragma solidity 0.8.9; interface IGasBank { event Deposit(address indexed account, uint256 value); event Withdraw(address indexed account, address indexed receiver, uint256 value); function depositFor(address account) external payable; function withdrawUnused(address account) external; function withdrawFrom(address account, uint256 amount) external; function withdrawFrom( address account, address payable to, uint256 amount ) external; function balanceOf(address account) external view returns (uint256); } // File interfaces/oracles/IOracleProvider.sol pragma solidity 0.8.9; interface IOracleProvider { /// @notice Quotes the USD price of `baseAsset` /// @param baseAsset the asset of which the price is to be quoted /// @return the USD price of the asset function getPriceUSD(address baseAsset) external view returns (uint256); /// @notice Quotes the ETH price of `baseAsset` /// @param baseAsset the asset of which the price is to be quoted /// @return the ETH price of the asset function getPriceETH(address baseAsset) external view returns (uint256); } // File libraries/AddressProviderMeta.sol pragma solidity 0.8.9; library AddressProviderMeta { struct Meta { bool freezable; bool frozen; } function fromUInt(uint256 value) internal pure returns (Meta memory) { Meta memory meta; meta.freezable = (value & 1) == 1; meta.frozen = ((value >> 1) & 1) == 1; return meta; } function toUInt(Meta memory meta) internal pure returns (uint256) { uint256 value; value |= meta.freezable ? 1 : 0; value |= meta.frozen ? 1 << 1 : 0; return value; } } // File interfaces/IAddressProvider.sol pragma solidity 0.8.9; // solhint-disable ordering interface IAddressProvider is IPreparable { event KnownAddressKeyAdded(bytes32 indexed key); event StakerVaultListed(address indexed stakerVault); event StakerVaultDelisted(address indexed stakerVault); event ActionListed(address indexed action); event PoolListed(address indexed pool); event PoolDelisted(address indexed pool); event VaultUpdated(address indexed previousVault, address indexed newVault); /** Key functions */ function getKnownAddressKeys() external view returns (bytes32[] memory); function freezeAddress(bytes32 key) external; /** Pool functions */ function allPools() external view returns (address[] memory); function addPool(address pool) external; function poolsCount() external view returns (uint256); function getPoolAtIndex(uint256 index) external view returns (address); function isPool(address pool) external view returns (bool); function removePool(address pool) external returns (bool); function getPoolForToken(address token) external view returns (ILiquidityPool); function safeGetPoolForToken(address token) external view returns (address); /** Vault functions */ function updateVault(address previousVault, address newVault) external; function allVaults() external view returns (address[] memory); function vaultsCount() external view returns (uint256); function getVaultAtIndex(uint256 index) external view returns (address); function isVault(address vault) external view returns (bool); /** Action functions */ function allActions() external view returns (address[] memory); function addAction(address action) external returns (bool); function isAction(address action) external view returns (bool); /** Address functions */ function initializeAddress( bytes32 key, address initialAddress, bool frezable ) external; function initializeAndFreezeAddress(bytes32 key, address initialAddress) external; function getAddress(bytes32 key) external view returns (address); function getAddress(bytes32 key, bool checkExists) external view returns (address); function getAddressMeta(bytes32 key) external view returns (AddressProviderMeta.Meta memory); function prepareAddress(bytes32 key, address newAddress) external returns (bool); function executeAddress(bytes32 key) external returns (address); function resetAddress(bytes32 key) external returns (bool); /** Staker vault functions */ function allStakerVaults() external view returns (address[] memory); function tryGetStakerVault(address token) external view returns (bool, address); function getStakerVault(address token) external view returns (address); function addStakerVault(address stakerVault) external returns (bool); function isStakerVault(address stakerVault, address token) external view returns (bool); function isStakerVaultRegistered(address stakerVault) external view returns (bool); function isWhiteListedFeeHandler(address feeHandler) external view returns (bool); } // File interfaces/tokenomics/IInflationManager.sol pragma solidity 0.8.9; interface IInflationManager { event KeeperGaugeListed(address indexed pool, address indexed keeperGauge); event AmmGaugeListed(address indexed token, address indexed ammGauge); event KeeperGaugeDelisted(address indexed pool, address indexed keeperGauge); event AmmGaugeDelisted(address indexed token, address indexed ammGauge); /** Pool functions */ function setKeeperGauge(address pool, address _keeperGauge) external returns (bool); function setAmmGauge(address token, address _ammGauge) external returns (bool); function getAllAmmGauges() external view returns (address[] memory); function getLpRateForStakerVault(address stakerVault) external view returns (uint256); function getKeeperRateForPool(address pool) external view returns (uint256); function getAmmRateForToken(address token) external view returns (uint256); function getKeeperWeightForPool(address pool) external view returns (uint256); function getAmmWeightForToken(address pool) external view returns (uint256); function getLpPoolWeight(address pool) external view returns (uint256); function getKeeperGaugeForPool(address pool) external view returns (address); function getAmmGaugeForToken(address token) external view returns (address); function isInflationWeightManager(address account) external view returns (bool); function removeStakerVaultFromInflation(address stakerVault, address lpToken) external; function addGaugeForVault(address lpToken) external returns (bool); function whitelistGauge(address gauge) external; function checkpointAllGauges() external returns (bool); function mintRewards(address beneficiary, uint256 amount) external; function addStrategyToDepositStakerVault(address depositStakerVault, address strategyPool) external returns (bool); /** Weight setter functions **/ function prepareLpPoolWeight(address lpToken, uint256 newPoolWeight) external returns (bool); function prepareAmmTokenWeight(address token, uint256 newTokenWeight) external returns (bool); function prepareKeeperPoolWeight(address pool, uint256 newPoolWeight) external returns (bool); function executeLpPoolWeight(address lpToken) external returns (uint256); function executeAmmTokenWeight(address token) external returns (uint256); function executeKeeperPoolWeight(address pool) external returns (uint256); function batchPrepareLpPoolWeights(address[] calldata lpTokens, uint256[] calldata weights) external returns (bool); function batchPrepareAmmTokenWeights(address[] calldata tokens, uint256[] calldata weights) external returns (bool); function batchPrepareKeeperPoolWeights(address[] calldata pools, uint256[] calldata weights) external returns (bool); function batchExecuteLpPoolWeights(address[] calldata lpTokens) external returns (bool); function batchExecuteAmmTokenWeights(address[] calldata tokens) external returns (bool); function batchExecuteKeeperPoolWeights(address[] calldata pools) external returns (bool); } // File interfaces/IController.sol pragma solidity 0.8.9; // solhint-disable ordering interface IController is IPreparable { function addressProvider() external view returns (IAddressProvider); function inflationManager() external view returns (IInflationManager); function addStakerVault(address stakerVault) external returns (bool); function removePool(address pool) external returns (bool); /** Keeper functions */ function prepareKeeperRequiredStakedBKD(uint256 amount) external; function executeKeeperRequiredStakedBKD() external; function getKeeperRequiredStakedBKD() external view returns (uint256); function canKeeperExecuteAction(address keeper) external view returns (bool); /** Miscellaneous functions */ function getTotalEthRequiredForGas(address payer) external view returns (uint256); } // File libraries/ScaledMath.sol pragma solidity 0.8.9; /* * @dev To use functions of this contract, at least one of the numbers must * be scaled to `DECIMAL_SCALE`. The result will scaled to `DECIMAL_SCALE` * if both numbers are scaled to `DECIMAL_SCALE`, otherwise to the scale * of the number not scaled by `DECIMAL_SCALE` */ library ScaledMath { // solhint-disable-next-line private-vars-leading-underscore uint256 internal constant DECIMAL_SCALE = 1e18; // solhint-disable-next-line private-vars-leading-underscore uint256 internal constant ONE = 1e18; /** * @notice Performs a multiplication between two scaled numbers */ function scaledMul(uint256 a, uint256 b) internal pure returns (uint256) { return (a * b) / DECIMAL_SCALE; } /** * @notice Performs a division between two scaled numbers */ function scaledDiv(uint256 a, uint256 b) internal pure returns (uint256) { return (a * DECIMAL_SCALE) / b; } /** * @notice Performs a division between two numbers, rounding up the result */ function scaledDivRoundUp(uint256 a, uint256 b) internal pure returns (uint256) { return (a * DECIMAL_SCALE + b - 1) / b; } /** * @notice Performs a division between two numbers, ignoring any scaling and rounding up the result */ function divRoundUp(uint256 a, uint256 b) internal pure returns (uint256) { return (a + b - 1) / b; } } // File libraries/Errors.sol pragma solidity 0.8.9; // solhint-disable private-vars-leading-underscore library Error { string internal constant ADDRESS_WHITELISTED = "address already whitelisted"; string internal constant ADMIN_ALREADY_SET = "admin has already been set once"; string internal constant ADDRESS_NOT_WHITELISTED = "address not whitelisted"; string internal constant ADDRESS_NOT_FOUND = "address not found"; string internal constant CONTRACT_INITIALIZED = "contract can only be initialized once"; string internal constant CONTRACT_PAUSED = "contract is paused"; string internal constant INVALID_AMOUNT = "invalid amount"; string internal constant INVALID_INDEX = "invalid index"; string internal constant INVALID_VALUE = "invalid msg.value"; string internal constant INVALID_SENDER = "invalid msg.sender"; string internal constant INVALID_TOKEN = "token address does not match pool's LP token address"; string internal constant INVALID_DECIMALS = "incorrect number of decimals"; string internal constant INVALID_ARGUMENT = "invalid argument"; string internal constant INVALID_PARAMETER_VALUE = "invalid parameter value attempted"; string internal constant INVALID_IMPLEMENTATION = "invalid pool implementation for given coin"; string internal constant INVALID_POOL_IMPLEMENTATION = "invalid pool implementation for given coin"; string internal constant INVALID_LP_TOKEN_IMPLEMENTATION = "invalid LP Token implementation for given coin"; string internal constant INVALID_VAULT_IMPLEMENTATION = "invalid vault implementation for given coin"; string internal constant INVALID_STAKER_VAULT_IMPLEMENTATION = "invalid stakerVault implementation for given coin"; string internal constant INSUFFICIENT_BALANCE = "insufficient balance"; string internal constant ADDRESS_ALREADY_SET = "Address is already set"; string internal constant INSUFFICIENT_STRATEGY_BALANCE = "insufficient strategy balance"; string internal constant INSUFFICIENT_FUNDS_RECEIVED = "insufficient funds received"; string internal constant ADDRESS_DOES_NOT_EXIST = "address does not exist"; string internal constant ADDRESS_FROZEN = "address is frozen"; string internal constant ROLE_EXISTS = "role already exists"; string internal constant CANNOT_REVOKE_ROLE = "cannot revoke role"; string internal constant UNAUTHORIZED_ACCESS = "unauthorized access"; string internal constant SAME_ADDRESS_NOT_ALLOWED = "same address not allowed"; string internal constant SELF_TRANSFER_NOT_ALLOWED = "self-transfer not allowed"; string internal constant ZERO_ADDRESS_NOT_ALLOWED = "zero address not allowed"; string internal constant ZERO_TRANSFER_NOT_ALLOWED = "zero transfer not allowed"; string internal constant THRESHOLD_TOO_HIGH = "threshold is too high, must be under 10"; string internal constant INSUFFICIENT_THRESHOLD = "insufficient threshold"; string internal constant NO_POSITION_EXISTS = "no position exists"; string internal constant POSITION_ALREADY_EXISTS = "position already exists"; string internal constant PROTOCOL_NOT_FOUND = "protocol not found"; string internal constant TOP_UP_FAILED = "top up failed"; string internal constant SWAP_PATH_NOT_FOUND = "swap path not found"; string internal constant UNDERLYING_NOT_SUPPORTED = "underlying token not supported"; string internal constant NOT_ENOUGH_FUNDS_WITHDRAWN = "not enough funds were withdrawn from the pool"; string internal constant FAILED_TRANSFER = "transfer failed"; string internal constant FAILED_MINT = "mint failed"; string internal constant FAILED_REPAY_BORROW = "repay borrow failed"; string internal constant FAILED_METHOD_CALL = "method call failed"; string internal constant NOTHING_TO_CLAIM = "there is no claimable balance"; string internal constant ERC20_BALANCE_EXCEEDED = "ERC20: transfer amount exceeds balance"; string internal constant INVALID_MINTER = "the minter address of the LP token and the pool address do not match"; string internal constant STAKER_VAULT_EXISTS = "a staker vault already exists for the token"; string internal constant DEADLINE_NOT_ZERO = "deadline must be 0"; string internal constant DEADLINE_NOT_SET = "deadline is 0"; string internal constant DEADLINE_NOT_REACHED = "deadline has not been reached yet"; string internal constant DELAY_TOO_SHORT = "delay be at least 3 days"; string internal constant INSUFFICIENT_UPDATE_BALANCE = "insufficient funds for updating the position"; string internal constant SAME_AS_CURRENT = "value must be different to existing value"; string internal constant NOT_CAPPED = "the pool is not currently capped"; string internal constant ALREADY_CAPPED = "the pool is already capped"; string internal constant EXCEEDS_DEPOSIT_CAP = "deposit exceeds deposit cap"; string internal constant VALUE_TOO_LOW_FOR_GAS = "value too low to cover gas"; string internal constant NOT_ENOUGH_FUNDS = "not enough funds to withdraw"; string internal constant ESTIMATED_GAS_TOO_HIGH = "too much ETH will be used for gas"; string internal constant DEPOSIT_FAILED = "deposit failed"; string internal constant GAS_TOO_HIGH = "too much ETH used for gas"; string internal constant GAS_BANK_BALANCE_TOO_LOW = "not enough ETH in gas bank to cover gas"; string internal constant INVALID_TOKEN_TO_ADD = "Invalid token to add"; string internal constant INVALID_TOKEN_TO_REMOVE = "token can not be removed"; string internal constant TIME_DELAY_NOT_EXPIRED = "time delay not expired yet"; string internal constant UNDERLYING_NOT_WITHDRAWABLE = "pool does not support additional underlying coins to be withdrawn"; string internal constant STRATEGY_SHUT_DOWN = "Strategy is shut down"; string internal constant STRATEGY_DOES_NOT_EXIST = "Strategy does not exist"; string internal constant UNSUPPORTED_UNDERLYING = "Underlying not supported"; string internal constant NO_DEX_SET = "no dex has been set for token"; string internal constant INVALID_TOKEN_PAIR = "invalid token pair"; string internal constant TOKEN_NOT_USABLE = "token not usable for the specific action"; string internal constant ADDRESS_NOT_ACTION = "address is not registered action"; string internal constant INVALID_SLIPPAGE_TOLERANCE = "Invalid slippage tolerance"; string internal constant POOL_NOT_PAUSED = "Pool must be paused to withdraw from reserve"; string internal constant INTERACTION_LIMIT = "Max of one deposit and withdraw per block"; string internal constant GAUGE_EXISTS = "Gauge already exists"; string internal constant GAUGE_DOES_NOT_EXIST = "Gauge does not exist"; string internal constant EXCEEDS_MAX_BOOST = "Not allowed to exceed maximum boost on Convex"; string internal constant PREPARED_WITHDRAWAL = "Cannot relock funds when withdrawal is being prepared"; string internal constant ASSET_NOT_SUPPORTED = "Asset not supported"; string internal constant STALE_PRICE = "Price is stale"; string internal constant NEGATIVE_PRICE = "Price is negative"; string internal constant NOT_ENOUGH_BKD_STAKED = "Not enough BKD tokens staked"; string internal constant RESERVE_ACCESS_EXCEEDED = "Reserve access exceeded"; } // File @openzeppelin/contracts/utils/structs/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } } // File libraries/EnumerableMapping.sol pragma solidity 0.8.9; library EnumerableMapping { using EnumerableSet for EnumerableSet.Bytes32Set; // Code take from contracts/utils/structs/EnumerableMap.sol // because the helper functions are private // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct Map { // Storage of keys EnumerableSet.Bytes32Set _keys; mapping(bytes32 => bytes32) _values; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function _set( Map storage map, bytes32 key, bytes32 value ) private returns (bool) { map._values[key] = value; return map._keys.add(key); } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function _remove(Map storage map, bytes32 key) private returns (bool) { delete map._values[key]; return map._keys.remove(key); } /** * @dev Returns true if the key is in the map. O(1). */ function _contains(Map storage map, bytes32 key) private view returns (bool) { return map._keys.contains(key); } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function _length(Map storage map) private view returns (uint256) { return map._keys.length(); } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) { bytes32 key = map._keys.at(index); return (key, map._values[key]); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) { bytes32 value = map._values[key]; if (value == bytes32(0)) { return (_contains(map, key), bytes32(0)); } else { return (true, value); } } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function _get(Map storage map, bytes32 key) private view returns (bytes32) { bytes32 value = map._values[key]; require(value != 0 || _contains(map, key), "EnumerableMap: nonexistent key"); return value; } // AddressToAddressMap struct AddressToAddressMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( AddressToAddressMap storage map, address key, address value ) internal returns (bool) { return _set(map._inner, bytes32(uint256(uint160(key))), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(AddressToAddressMap storage map, address key) internal returns (bool) { return _remove(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(AddressToAddressMap storage map, address key) internal view returns (bool) { return _contains(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns the number of elements in the map. O(1). */ function length(AddressToAddressMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressToAddressMap storage map, uint256 index) internal view returns (address, address) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (address(uint160(uint256(key))), address(uint160(uint256(value)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(AddressToAddressMap storage map, address key) internal view returns (bool, address) { (bool success, bytes32 value) = _tryGet(map._inner, bytes32(uint256(uint160(key)))); return (success, address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(AddressToAddressMap storage map, address key) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(uint256(uint160(key))))))); } // AddressToUintMap struct AddressToUintMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( AddressToUintMap storage map, address key, uint256 value ) internal returns (bool) { return _set(map._inner, bytes32(uint256(uint160(key))), bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(AddressToUintMap storage map, address key) internal returns (bool) { return _remove(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(AddressToUintMap storage map, address key) internal view returns (bool) { return _contains(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns the number of elements in the map. O(1). */ function length(AddressToUintMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (address(uint160(uint256(key))), uint256(value)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) { (bool success, bytes32 value) = _tryGet(map._inner, bytes32(uint256(uint160(key)))); return (success, uint256(value)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(AddressToUintMap storage map, address key) internal view returns (uint256) { return uint256(_get(map._inner, bytes32(uint256(uint160(key))))); } // Bytes32ToUIntMap struct Bytes32ToUIntMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( Bytes32ToUIntMap storage map, bytes32 key, uint256 value ) internal returns (bool) { return _set(map._inner, key, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(Bytes32ToUIntMap storage map, bytes32 key) internal returns (bool) { return _remove(map._inner, key); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(Bytes32ToUIntMap storage map, bytes32 key) internal view returns (bool) { return _contains(map._inner, key); } /** * @dev Returns the number of elements in the map. O(1). */ function length(Bytes32ToUIntMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32ToUIntMap storage map, uint256 index) internal view returns (bytes32, uint256) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (key, uint256(value)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(Bytes32ToUIntMap storage map, bytes32 key) internal view returns (bool, uint256) { (bool success, bytes32 value) = _tryGet(map._inner, key); return (success, uint256(value)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(Bytes32ToUIntMap storage map, bytes32 key) internal view returns (uint256) { return uint256(_get(map._inner, key)); } } // File libraries/EnumerableExtensions.sol pragma solidity 0.8.9; library EnumerableExtensions { using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.Bytes32Set; using EnumerableMapping for EnumerableMapping.AddressToAddressMap; using EnumerableMapping for EnumerableMapping.AddressToUintMap; using EnumerableMapping for EnumerableMapping.Bytes32ToUIntMap; function toArray(EnumerableSet.AddressSet storage addresses) internal view returns (address[] memory) { uint256 len = addresses.length(); address[] memory result = new address[](len); for (uint256 i = 0; i < len; i++) { result[i] = addresses.at(i); } return result; } function toArray(EnumerableSet.Bytes32Set storage values) internal view returns (bytes32[] memory) { uint256 len = values.length(); bytes32[] memory result = new bytes32[](len); for (uint256 i = 0; i < len; i++) { result[i] = values.at(i); } return result; } function keyAt(EnumerableMapping.AddressToAddressMap storage map, uint256 index) internal view returns (address) { (address key, ) = map.at(index); return key; } function valueAt(EnumerableMapping.AddressToAddressMap storage map, uint256 index) internal view returns (address) { (, address value) = map.at(index); return value; } function keyAt(EnumerableMapping.AddressToUintMap storage map, uint256 index) internal view returns (address) { (address key, ) = map.at(index); return key; } function keyAt(EnumerableMapping.Bytes32ToUIntMap storage map, uint256 index) internal view returns (bytes32) { (bytes32 key, ) = map.at(index); return key; } function valueAt(EnumerableMapping.AddressToUintMap storage map, uint256 index) internal view returns (uint256) { (, uint256 value) = map.at(index); return value; } function keysArray(EnumerableMapping.AddressToAddressMap storage map) internal view returns (address[] memory) { uint256 len = map.length(); address[] memory result = new address[](len); for (uint256 i = 0; i < len; i++) { result[i] = keyAt(map, i); } return result; } function valuesArray(EnumerableMapping.AddressToAddressMap storage map) internal view returns (address[] memory) { uint256 len = map.length(); address[] memory result = new address[](len); for (uint256 i = 0; i < len; i++) { result[i] = valueAt(map, i); } return result; } function keysArray(EnumerableMapping.AddressToUintMap storage map) internal view returns (address[] memory) { uint256 len = map.length(); address[] memory result = new address[](len); for (uint256 i = 0; i < len; i++) { result[i] = keyAt(map, i); } return result; } function keysArray(EnumerableMapping.Bytes32ToUIntMap storage map) internal view returns (bytes32[] memory) { uint256 len = map.length(); bytes32[] memory result = new bytes32[](len); for (uint256 i = 0; i < len; i++) { result[i] = keyAt(map, i); } return result; } } // File interfaces/IRoleManager.sol pragma solidity 0.8.9; interface IRoleManager { event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); function grantRole(bytes32 role, address account) external; function revokeRole(bytes32 role, address account) external; function hasRole(bytes32 role, address account) external view returns (bool); function hasAnyRole(bytes32[] memory roles, address account) external view returns (bool); function hasAnyRole( bytes32 role1, bytes32 role2, address account ) external view returns (bool); function hasAnyRole( bytes32 role1, bytes32 role2, bytes32 role3, address account ) external view returns (bool); function getRoleMemberCount(bytes32 role) external view returns (uint256); function getRoleMember(bytes32 role, uint256 index) external view returns (address); } // File interfaces/tokenomics/IBkdToken.sol pragma solidity 0.8.9; interface IBkdToken is IERC20 { function mint(address account, uint256 amount) external; } // File libraries/AddressProviderKeys.sol pragma solidity 0.8.9; library AddressProviderKeys { bytes32 internal constant _TREASURY_KEY = "treasury"; bytes32 internal constant _GAS_BANK_KEY = "gasBank"; bytes32 internal constant _VAULT_RESERVE_KEY = "vaultReserve"; bytes32 internal constant _SWAPPER_REGISTRY_KEY = "swapperRegistry"; bytes32 internal constant _ORACLE_PROVIDER_KEY = "oracleProvider"; bytes32 internal constant _POOL_FACTORY_KEY = "poolFactory"; bytes32 internal constant _CONTROLLER_KEY = "controller"; bytes32 internal constant _BKD_LOCKER_KEY = "bkdLocker"; bytes32 internal constant _ROLE_MANAGER_KEY = "roleManager"; } // File libraries/AddressProviderHelpers.sol pragma solidity 0.8.9; library AddressProviderHelpers { /** * @return The address of the treasury. */ function getTreasury(IAddressProvider provider) internal view returns (address) { return provider.getAddress(AddressProviderKeys._TREASURY_KEY); } /** * @return The gas bank. */ function getGasBank(IAddressProvider provider) internal view returns (IGasBank) { return IGasBank(provider.getAddress(AddressProviderKeys._GAS_BANK_KEY)); } /** * @return The address of the vault reserve. */ function getVaultReserve(IAddressProvider provider) internal view returns (IVaultReserve) { return IVaultReserve(provider.getAddress(AddressProviderKeys._VAULT_RESERVE_KEY)); } /** * @return The address of the swapperRegistry. */ function getSwapperRegistry(IAddressProvider provider) internal view returns (address) { return provider.getAddress(AddressProviderKeys._SWAPPER_REGISTRY_KEY); } /** * @return The oracleProvider. */ function getOracleProvider(IAddressProvider provider) internal view returns (IOracleProvider) { return IOracleProvider(provider.getAddress(AddressProviderKeys._ORACLE_PROVIDER_KEY)); } /** * @return the address of the BKD locker */ function getBKDLocker(IAddressProvider provider) internal view returns (address) { return provider.getAddress(AddressProviderKeys._BKD_LOCKER_KEY); } /** * @return the address of the BKD locker */ function getRoleManager(IAddressProvider provider) internal view returns (IRoleManager) { return IRoleManager(provider.getAddress(AddressProviderKeys._ROLE_MANAGER_KEY)); } /** * @return the controller */ function getController(IAddressProvider provider) internal view returns (IController) { return IController(provider.getAddress(AddressProviderKeys._CONTROLLER_KEY)); } } // File contracts/vault/VaultStorage.sol pragma solidity 0.8.9; contract VaultStorage { uint256 public currentAllocated; uint256 public waitingForRemovalAllocated; address public pool; uint256 public totalDebt; bool public strategyActive; EnumerableMapping.AddressToUintMap internal _strategiesWaitingForRemoval; } contract VaultStorageV1 is VaultStorage { /** * @dev This is to avoid breaking contracts inheriting from `VaultStorage` * such as `Erc20Vault`, especially if they have storage variables * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps * for more details * * A new field can be added using a new contract such as * * ```solidity * contract VaultStorageV2 is VaultStorage { * uint256 someNewField; * uint256[49] private __gap; * } */ uint256[50] private __gap; } // File contracts/utils/Preparable.sol pragma solidity 0.8.9; /** * @notice Implements the base logic for a two-phase commit * @dev This does not implements any access-control so publicly exposed * callers should make sure to have the proper checks in palce */ contract Preparable is IPreparable { uint256 private constant _MIN_DELAY = 3 days; mapping(bytes32 => address) public pendingAddresses; mapping(bytes32 => uint256) public pendingUInts256; mapping(bytes32 => address) public currentAddresses; mapping(bytes32 => uint256) public currentUInts256; /** * @dev Deadlines shares the same namespace regardless of the type * of the pending variable so this needs to be enforced in the caller */ mapping(bytes32 => uint256) public deadlines; function _prepareDeadline(bytes32 key, uint256 delay) internal { require(deadlines[key] == 0, Error.DEADLINE_NOT_ZERO); require(delay >= _MIN_DELAY, Error.DELAY_TOO_SHORT); deadlines[key] = block.timestamp + delay; } /** * @notice Prepares an uint256 that should be commited to the contract * after `_MIN_DELAY` elapsed * @param value The value to prepare * @return `true` if success. */ function _prepare( bytes32 key, uint256 value, uint256 delay ) internal returns (bool) { _prepareDeadline(key, delay); pendingUInts256[key] = value; emit ConfigPreparedNumber(key, value, delay); return true; } /** * @notice Same as `_prepare(bytes32,uint256,uint256)` but uses a default delay */ function _prepare(bytes32 key, uint256 value) internal returns (bool) { return _prepare(key, value, _MIN_DELAY); } /** * @notice Prepares an address that should be commited to the contract * after `_MIN_DELAY` elapsed * @param value The value to prepare * @return `true` if success. */ function _prepare( bytes32 key, address value, uint256 delay ) internal returns (bool) { _prepareDeadline(key, delay); pendingAddresses[key] = value; emit ConfigPreparedAddress(key, value, delay); return true; } /** * @notice Same as `_prepare(bytes32,address,uint256)` but uses a default delay */ function _prepare(bytes32 key, address value) internal returns (bool) { return _prepare(key, value, _MIN_DELAY); } /** * @notice Reset a uint256 key * @return `true` if success. */ function _resetUInt256Config(bytes32 key) internal returns (bool) { require(deadlines[key] != 0, Error.DEADLINE_NOT_ZERO); deadlines[key] = 0; pendingUInts256[key] = 0; emit ConfigReset(key); return true; } /** * @notice Reset an address key * @return `true` if success. */ function _resetAddressConfig(bytes32 key) internal returns (bool) { require(deadlines[key] != 0, Error.DEADLINE_NOT_ZERO); deadlines[key] = 0; pendingAddresses[key] = address(0); emit ConfigReset(key); return true; } /** * @dev Checks the deadline of the key and reset it */ function _executeDeadline(bytes32 key) internal { uint256 deadline = deadlines[key]; require(block.timestamp >= deadline, Error.DEADLINE_NOT_REACHED); require(deadline != 0, Error.DEADLINE_NOT_SET); deadlines[key] = 0; } /** * @notice Execute uint256 config update (with time delay enforced). * @dev Needs to be called after the update was prepared. Fails if called before time delay is met. * @return New value. */ function _executeUInt256(bytes32 key) internal returns (uint256) { _executeDeadline(key); uint256 newValue = pendingUInts256[key]; _setConfig(key, newValue); return newValue; } /** * @notice Execute address config update (with time delay enforced). * @dev Needs to be called after the update was prepared. Fails if called before time delay is met. * @return New value. */ function _executeAddress(bytes32 key) internal returns (address) { _executeDeadline(key); address newValue = pendingAddresses[key]; _setConfig(key, newValue); return newValue; } function _setConfig(bytes32 key, address value) internal returns (address) { address oldValue = currentAddresses[key]; currentAddresses[key] = value; pendingAddresses[key] = address(0); deadlines[key] = 0; emit ConfigUpdatedAddress(key, oldValue, value); return value; } function _setConfig(bytes32 key, uint256 value) internal returns (uint256) { uint256 oldValue = currentUInts256[key]; currentUInts256[key] = value; pendingUInts256[key] = 0; deadlines[key] = 0; emit ConfigUpdatedNumber(key, oldValue, value); return value; } } // File contracts/utils/IPausable.sol pragma solidity 0.8.9; interface IPausable { function pause() external returns (bool); function unpause() external returns (bool); function isPaused() external view returns (bool); function isAuthorizedToPause(address account) external view returns (bool); } // File libraries/Roles.sol pragma solidity 0.8.9; // solhint-disable private-vars-leading-underscore library Roles { bytes32 internal constant GOVERNANCE = "governance"; bytes32 internal constant ADDRESS_PROVIDER = "address_provider"; bytes32 internal constant POOL_FACTORY = "pool_factory"; bytes32 internal constant CONTROLLER = "controller"; bytes32 internal constant GAUGE_ZAP = "gauge_zap"; bytes32 internal constant MAINTENANCE = "maintenance"; bytes32 internal constant INFLATION_MANAGER = "inflation_manager"; bytes32 internal constant POOL = "pool"; bytes32 internal constant VAULT = "vault"; } // File contracts/access/AuthorizationBase.sol pragma solidity 0.8.9; /** * @notice Provides modifiers for authorization */ abstract contract AuthorizationBase { /** * @notice Only allows a sender with `role` to perform the given action */ modifier onlyRole(bytes32 role) { require(_roleManager().hasRole(role, msg.sender), Error.UNAUTHORIZED_ACCESS); _; } /** * @notice Only allows a sender with GOVERNANCE role to perform the given action */ modifier onlyGovernance() { require(_roleManager().hasRole(Roles.GOVERNANCE, msg.sender), Error.UNAUTHORIZED_ACCESS); _; } /** * @notice Only allows a sender with any of `roles` to perform the given action */ modifier onlyRoles2(bytes32 role1, bytes32 role2) { require(_roleManager().hasAnyRole(role1, role2, msg.sender), Error.UNAUTHORIZED_ACCESS); _; } /** * @notice Only allows a sender with any of `roles` to perform the given action */ modifier onlyRoles3( bytes32 role1, bytes32 role2, bytes32 role3 ) { require( _roleManager().hasAnyRole(role1, role2, role3, msg.sender), Error.UNAUTHORIZED_ACCESS ); _; } function roleManager() external view virtual returns (IRoleManager) { return _roleManager(); } function _roleManager() internal view virtual returns (IRoleManager); } // File contracts/access/Authorization.sol pragma solidity 0.8.9; contract Authorization is AuthorizationBase { IRoleManager internal immutable __roleManager; constructor(IRoleManager roleManager) { __roleManager = roleManager; } function _roleManager() internal view override returns (IRoleManager) { return __roleManager; } } // File contracts/vault/Vault.sol pragma solidity 0.8.9; abstract contract Vault is IVault, Authorization, VaultStorageV1, Preparable, Initializable { using ScaledMath for uint256; using SafeERC20 for IERC20; using EnumerableSet for EnumerableSet.AddressSet; using EnumerableExtensions for EnumerableSet.AddressSet; using EnumerableMapping for EnumerableMapping.AddressToUintMap; using EnumerableExtensions for EnumerableMapping.AddressToUintMap; using AddressProviderHelpers for IAddressProvider; bytes32 internal constant _STRATEGY_KEY = "Strategy"; bytes32 internal constant _PERFORMANCE_FEE_KEY = "PerformanceFee"; bytes32 internal constant _STRATEGIST_FEE_KEY = "StrategistFee"; bytes32 internal constant _DEBT_LIMIT_KEY = "DebtLimit"; bytes32 internal constant _TARGET_ALLOCATION_KEY = "TargetAllocation"; bytes32 internal constant _RESERVE_FEE_KEY = "ReserveFee"; bytes32 internal constant _BOUND_KEY = "Bound"; uint256 internal constant _INITIAL_RESERVE_FEE = 0.01e18; uint256 internal constant _INITIAL_STRATEGIST_FEE = 0.1e18; uint256 internal constant _INITIAL_PERFORMANCE_FEE = 0; uint256 public constant MAX_PERFORMANCE_FEE = 0.5e18; uint256 public constant MAX_DEVIATION_BOUND = 0.5e18; uint256 public constant STRATEGY_DELAY = 5 days; IController public immutable controller; IAddressProvider public immutable addressProvider; IVaultReserve public immutable reserve; modifier onlyPool() { require(msg.sender == pool, Error.UNAUTHORIZED_ACCESS); _; } modifier onlyPoolOrGovernance() { require( msg.sender == pool || _roleManager().hasRole(Roles.GOVERNANCE, msg.sender), Error.UNAUTHORIZED_ACCESS ); _; } modifier onlyPoolOrMaintenance() { require( msg.sender == pool || _roleManager().hasRole(Roles.MAINTENANCE, msg.sender), Error.UNAUTHORIZED_ACCESS ); _; } constructor(IController _controller) Authorization(_controller.addressProvider().getRoleManager()) { controller = _controller; IAddressProvider addressProvider_ = _controller.addressProvider(); addressProvider = addressProvider_; reserve = IVaultReserve(addressProvider_.getVaultReserve()); } function _initialize( address _pool, uint256 _debtLimit, uint256 _targetAllocation, uint256 _bound ) internal { require(_debtLimit <= ScaledMath.ONE, Error.INVALID_AMOUNT); require(_targetAllocation <= ScaledMath.ONE, Error.INVALID_AMOUNT); require(_bound <= MAX_DEVIATION_BOUND, Error.INVALID_AMOUNT); pool = _pool; _setConfig(_DEBT_LIMIT_KEY, _debtLimit); _setConfig(_TARGET_ALLOCATION_KEY, _targetAllocation); _setConfig(_BOUND_KEY, _bound); _setConfig(_RESERVE_FEE_KEY, _INITIAL_RESERVE_FEE); _setConfig(_STRATEGIST_FEE_KEY, _INITIAL_STRATEGIST_FEE); _setConfig(_PERFORMANCE_FEE_KEY, _INITIAL_PERFORMANCE_FEE); } /** * @notice Handles deposits from the liquidity pool */ function deposit() external payable override onlyPoolOrMaintenance { // solhint-disable-previous-line ordering _deposit(); } /** * @notice Withdraws specified amount of underlying from vault. * @dev If the specified amount exceeds idle funds, an amount of funds is withdrawn * from the strategy such that it will achieve a target allocation for after the * amount has been withdrawn. * @param amount Amount to withdraw. * @return `true` if successful. */ function withdraw(uint256 amount) external override onlyPoolOrGovernance returns (bool) { IStrategy strategy = getStrategy(); uint256 availableUnderlying_ = _availableUnderlying(); if (availableUnderlying_ < amount) { if (address(strategy) == address(0)) return false; uint256 allocated = strategy.balance(); uint256 requiredWithdrawal = amount - availableUnderlying_; if (requiredWithdrawal > allocated) return false; // compute withdrawal amount to sustain target allocation uint256 newTarget = (allocated - requiredWithdrawal).scaledMul(getTargetAllocation()); uint256 excessAmount = allocated - newTarget; strategy.withdraw(excessAmount); currentAllocated = _computeNewAllocated(currentAllocated, excessAmount); } else { uint256 allocatedUnderlying = 0; if (address(strategy) != address(0)) allocatedUnderlying = IStrategy(strategy).balance(); uint256 totalUnderlying = availableUnderlying_ + allocatedUnderlying + waitingForRemovalAllocated; uint256 totalUnderlyingAfterWithdraw = totalUnderlying - amount; _rebalance(totalUnderlyingAfterWithdraw, allocatedUnderlying); } _transfer(pool, amount); return true; } /** * @notice Withdraws all funds from vault and strategy and transfer them to the pool. */ function withdrawAll() external override onlyPoolOrGovernance { _withdrawAllFromStrategy(); _transfer(pool, _availableUnderlying()); } /** * @notice Withdraws specified amount of underlying from reserve to vault. * @dev Withdraws from reserve will cause a spike in pool exchange rate. * Pool deposits should be paused during this to prevent front running * @param amount Amount to withdraw. */ function withdrawFromReserve(uint256 amount) external override onlyGovernance { require(amount > 0, Error.INVALID_AMOUNT); require(IPausable(pool).isPaused(), Error.POOL_NOT_PAUSED); uint256 reserveBalance_ = reserve.getBalance(address(this), getUnderlying()); require(amount <= reserveBalance_, Error.INSUFFICIENT_BALANCE); reserve.withdraw(getUnderlying(), amount); } /** * @notice Activate the current strategy set for the vault. * @return `true` if strategy has been activated */ function activateStrategy() external onlyGovernance returns (bool) { return _activateStrategy(); } /** * @notice Deactivates a strategy. * @return `true` if strategy has been deactivated */ function deactivateStrategy() external onlyGovernance returns (bool) { return _deactivateStrategy(); } /** * @notice Initializes the vault's strategy. * @dev Bypasses the time delay, but can only be called if strategy is not set already. * @param strategy_ Address of the strategy. * @return `true` if successful. */ function initializeStrategy(address strategy_) external override onlyGovernance returns (bool) { require(currentAddresses[_STRATEGY_KEY] == address(0), Error.ADDRESS_ALREADY_SET); require(strategy_ != address(0), Error.ZERO_ADDRESS_NOT_ALLOWED); _setConfig(_STRATEGY_KEY, strategy_); _activateStrategy(); require(IStrategy(strategy_).strategist() != address(0), Error.ZERO_ADDRESS_NOT_ALLOWED); return true; } /** * @notice Prepare update of the vault's strategy (with time delay enforced). * @param newStrategy Address of the new strategy. * @return `true` if successful. */ function prepareNewStrategy(address newStrategy) external onlyGovernance returns (bool) { return _prepare(_STRATEGY_KEY, newStrategy, STRATEGY_DELAY); } /** * @notice Execute strategy update (with time delay enforced). * @dev Needs to be called after the update was prepraed. Fails if called before time delay is met. * @return New strategy address. */ function executeNewStrategy() external returns (address) { _executeDeadline(_STRATEGY_KEY); IStrategy strategy = getStrategy(); if (address(strategy) != address(0)) { _harvest(); strategy.shutdown(); strategy.withdrawAll(); // there might still be some balance left if the strategy did not // manage to withdraw all funds (e.g. due to locking) uint256 remainingStrategyBalance = strategy.balance(); if (remainingStrategyBalance > 0) { _strategiesWaitingForRemoval.set(address(strategy), remainingStrategyBalance); waitingForRemovalAllocated += remainingStrategyBalance; } } _deactivateStrategy(); currentAllocated = 0; totalDebt = 0; address newStrategy = pendingAddresses[_STRATEGY_KEY]; _setConfig(_STRATEGY_KEY, newStrategy); if (newStrategy != address(0)) { _activateStrategy(); } return newStrategy; } function resetNewStrategy() external onlyGovernance returns (bool) { return _resetAddressConfig(_STRATEGY_KEY); } /** * @notice Prepare update of performance fee (with time delay enforced). * @param newPerformanceFee New performance fee value. * @return `true` if successful. */ function preparePerformanceFee(uint256 newPerformanceFee) external onlyGovernance returns (bool) { require(newPerformanceFee <= MAX_PERFORMANCE_FEE, Error.INVALID_AMOUNT); return _prepare(_PERFORMANCE_FEE_KEY, newPerformanceFee); } /** * @notice Execute update of performance fee (with time delay enforced). * @dev Needs to be called after the update was prepraed. Fails if called before time delay is met. * @return New performance fee. */ function executePerformanceFee() external returns (uint256) { return _executeUInt256(_PERFORMANCE_FEE_KEY); } function resetPerformanceFee() external onlyGovernance returns (bool) { return _resetUInt256Config(_PERFORMANCE_FEE_KEY); } /** * @notice Prepare update of strategist fee (with time delay enforced). * @param newStrategistFee New strategist fee value. * @return `true` if successful. */ function prepareStrategistFee(uint256 newStrategistFee) external onlyGovernance returns (bool) { _checkFeesInvariant(getReserveFee(), newStrategistFee); return _prepare(_STRATEGIST_FEE_KEY, newStrategistFee); } /** * @notice Execute update of strategist fee (with time delay enforced). * @dev Needs to be called after the update was prepraed. Fails if called before time delay is met. * @return New strategist fee. */ function executeStrategistFee() external returns (uint256) { uint256 newStrategistFee = _executeUInt256(_STRATEGIST_FEE_KEY); _checkFeesInvariant(getReserveFee(), newStrategistFee); return newStrategistFee; } function resetStrategistFee() external onlyGovernance returns (bool) { return _resetUInt256Config(_STRATEGIST_FEE_KEY); } /** * @notice Prepare update of debt limit (with time delay enforced). * @param newDebtLimit New debt limit. * @return `true` if successful. */ function prepareDebtLimit(uint256 newDebtLimit) external onlyGovernance returns (bool) { return _prepare(_DEBT_LIMIT_KEY, newDebtLimit); } /** * @notice Execute update of debt limit (with time delay enforced). * @dev Needs to be called after the update was prepraed. Fails if called before time delay is met. * @return New debt limit. */ function executeDebtLimit() external returns (uint256) { uint256 debtLimit = _executeUInt256(_DEBT_LIMIT_KEY); uint256 debtLimitAllocated = currentAllocated.scaledMul(debtLimit); if (totalDebt >= debtLimitAllocated) { _handleExcessDebt(); } return debtLimit; } function resetDebtLimit() external onlyGovernance returns (bool) { return _resetUInt256Config(_DEBT_LIMIT_KEY); } /** * @notice Prepare update of target allocation (with time delay enforced). * @param newTargetAllocation New target allocation. * @return `true` if successful. */ function prepareTargetAllocation(uint256 newTargetAllocation) external onlyGovernance returns (bool) { return _prepare(_TARGET_ALLOCATION_KEY, newTargetAllocation); } /** * @notice Execute update of target allocation (with time delay enforced). * @dev Needs to be called after the update was prepraed. Fails if called before time delay is met. * @return New target allocation. */ function executeTargetAllocation() external returns (uint256) { uint256 targetAllocation = _executeUInt256(_TARGET_ALLOCATION_KEY); _deposit(); return targetAllocation; } function resetTargetAllocation() external onlyGovernance returns (bool) { return _resetUInt256Config(_TARGET_ALLOCATION_KEY); } /** * @notice Prepare update of reserve fee (with time delay enforced). * @param newReserveFee New reserve fee. * @return `true` if successful. */ function prepareReserveFee(uint256 newReserveFee) external onlyGovernance returns (bool) { _checkFeesInvariant(newReserveFee, getStrategistFee()); return _prepare(_RESERVE_FEE_KEY, newReserveFee); } /** * @notice Execute update of reserve fee (with time delay enforced). * @dev Needs to be called after the update was prepraed. Fails if called before time delay is met. * @return New reserve fee. */ function executeReserveFee() external returns (uint256) { uint256 newReserveFee = _executeUInt256(_RESERVE_FEE_KEY); _checkFeesInvariant(newReserveFee, getStrategistFee()); return newReserveFee; } function resetReserveFee() external onlyGovernance returns (bool) { return _resetUInt256Config(_RESERVE_FEE_KEY); } /** * @notice Prepare update of deviation bound for strategy allocation (with time delay enforced). * @param newBound New deviation bound for target allocation. * @return `true` if successful. */ function prepareBound(uint256 newBound) external onlyGovernance returns (bool) { require(newBound <= MAX_DEVIATION_BOUND, Error.INVALID_AMOUNT); return _prepare(_BOUND_KEY, newBound); } /** * @notice Execute update of deviation bound for strategy allocation (with time delay enforced). * @dev Needs to be called after the update was prepraed. Fails if called before time delay is met. * @return New deviation bound. */ function executeBound() external returns (uint256) { uint256 bound = _executeUInt256(_BOUND_KEY); _deposit(); return bound; } function resetBound() external onlyGovernance returns (bool) { return _resetUInt256Config(_BOUND_KEY); } /** * @notice Withdraws an amount of underlying from the strategy to the vault. * @param amount Amount of underlying to withdraw. * @return True if successful withdrawal. */ function withdrawFromStrategy(uint256 amount) external onlyGovernance returns (bool) { IStrategy strategy = getStrategy(); if (address(strategy) == address(0)) return false; if (strategy.balance() < amount) return false; uint256 oldBalance = _availableUnderlying(); strategy.withdraw(amount); uint256 newBalance = _availableUnderlying(); currentAllocated -= newBalance - oldBalance; return true; } function withdrawFromStrategyWaitingForRemoval(address strategy) external returns (uint256) { (bool exists, uint256 allocated) = _strategiesWaitingForRemoval.tryGet(strategy); require(exists, Error.STRATEGY_DOES_NOT_EXIST); IStrategy strategy_ = IStrategy(strategy); strategy_.harvest(); uint256 withdrawn = strategy_.withdrawAll(); uint256 _waitingForRemovalAllocated = waitingForRemovalAllocated; if (withdrawn >= _waitingForRemovalAllocated) { waitingForRemovalAllocated = 0; } else { waitingForRemovalAllocated = _waitingForRemovalAllocated - withdrawn; } if (withdrawn > allocated) { uint256 profit = withdrawn - allocated; uint256 strategistShare = _shareFees(profit.scaledMul(getPerformanceFee())); if (strategistShare > 0) { _payStrategist(strategistShare, strategy_.strategist()); } allocated = 0; emit Harvest(profit, 0); } else { allocated -= withdrawn; } if (strategy_.balance() == 0) { _strategiesWaitingForRemoval.remove(address(strategy_)); } else { _strategiesWaitingForRemoval.set(address(strategy_), allocated); } return withdrawn; } function getStrategiesWaitingForRemoval() external view returns (address[] memory) { return _strategiesWaitingForRemoval.keysArray(); } /** * @notice Computes the total underlying of the vault: idle funds + allocated funds - debt * @return Total amount of underlying. */ function getTotalUnderlying() external view override returns (uint256) { uint256 availableUnderlying_ = _availableUnderlying(); if (address(getStrategy()) == address(0)) { return availableUnderlying_; } uint256 netUnderlying = availableUnderlying_ + currentAllocated + waitingForRemovalAllocated; if (totalDebt <= netUnderlying) return netUnderlying - totalDebt; return 0; } function getAllocatedToStrategyWaitingForRemoval(address strategy) external view returns (uint256) { return _strategiesWaitingForRemoval.get(strategy); } /** * @notice Withdraws all funds from strategy to vault. * @dev Harvests profits before withdrawing. Deactivates strategy after withdrawing. * @return `true` if successful. */ function withdrawAllFromStrategy() public onlyPoolOrGovernance returns (bool) { return _withdrawAllFromStrategy(); } /** * @notice Harvest profits from the vault's strategy. * @dev Harvesting adds profits to the vault's balance and deducts fees. * No performance fees are charged on profit used to repay debt. * @return `true` if successful. */ function harvest() public onlyPoolOrMaintenance returns (bool) { return _harvest(); } /** * @notice Returns the percentage of the performance fee that goes to the strategist. */ function getStrategistFee() public view returns (uint256) { return currentUInts256[_STRATEGIST_FEE_KEY]; } function getStrategy() public view override returns (IStrategy) { return IStrategy(currentAddresses[_STRATEGY_KEY]); } /** * @notice Returns the percentage of the performance fee which is allocated to the vault reserve */ function getReserveFee() public view returns (uint256) { return currentUInts256[_RESERVE_FEE_KEY]; } /** * @notice Returns the fee charged on a strategy's generated profits. * @dev The strategist is paid in LP tokens, while the remainder of the profit stays in the vault. * Default performance fee is set to 5% of harvested profits. */ function getPerformanceFee() public view returns (uint256) { return currentUInts256[_PERFORMANCE_FEE_KEY]; } /** * @notice Returns the allowed symmetric bound for target allocation (e.g. +- 5%) */ function getBound() public view returns (uint256) { return currentUInts256[_BOUND_KEY]; } /** * @notice The target percentage of total underlying funds to be allocated towards a strategy. * @dev this is to reduce gas costs. Withdrawals first come from idle funds and can therefore * avoid unnecessary gas costs. */ function getTargetAllocation() public view returns (uint256) { return currentUInts256[_TARGET_ALLOCATION_KEY]; } /** * @notice The debt limit that the total debt of a strategy may not exceed. */ function getDebtLimit() public view returns (uint256) { return currentUInts256[_DEBT_LIMIT_KEY]; } function getUnderlying() public view virtual override returns (address); function _activateStrategy() internal returns (bool) { IStrategy strategy = getStrategy(); if (address(strategy) == address(0)) return false; strategyActive = true; emit StrategyActivated(address(strategy)); _deposit(); return true; } function _harvest() internal returns (bool) { IStrategy strategy = getStrategy(); if (address(strategy) == address(0)) { return false; } strategy.harvest(); uint256 strategistShare = 0; uint256 allocatedUnderlying = strategy.balance(); uint256 amountAllocated = currentAllocated; uint256 currentDebt = totalDebt; if (allocatedUnderlying > amountAllocated) { // we made profits uint256 profit = allocatedUnderlying - amountAllocated; if (profit > currentDebt) { if (currentDebt > 0) { profit -= currentDebt; currentDebt = 0; } (profit, strategistShare) = _shareProfit(profit); } else { currentDebt -= profit; } emit Harvest(profit, 0); } else if (allocatedUnderlying < amountAllocated) { // we made a loss uint256 loss = amountAllocated - allocatedUnderlying; currentDebt += loss; // check debt limit and withdraw funds if exceeded uint256 debtLimit = getDebtLimit(); uint256 debtLimitAllocated = amountAllocated.scaledMul(debtLimit); if (currentDebt > debtLimitAllocated) { currentDebt = _handleExcessDebt(currentDebt); } emit Harvest(0, loss); } else { // nothing to declare return true; } totalDebt = currentDebt; currentAllocated = strategy.balance(); if (strategistShare > 0) { _payStrategist(strategistShare); } return true; } function _withdrawAllFromStrategy() internal returns (bool) { IStrategy strategy = getStrategy(); if (address(strategy) == address(0)) return false; _harvest(); uint256 oldBalance = _availableUnderlying(); strategy.withdrawAll(); uint256 newBalance = _availableUnderlying(); uint256 withdrawnAmount = newBalance - oldBalance; currentAllocated = _computeNewAllocated(currentAllocated, withdrawnAmount); _deactivateStrategy(); return true; } function _handleExcessDebt(uint256 currentDebt) internal returns (uint256) { uint256 underlyingReserves = reserve.getBalance(address(this), getUnderlying()); if (currentDebt > underlyingReserves) { _emergencyStop(underlyingReserves); } else if (reserve.canWithdraw(address(this))) { reserve.withdraw(getUnderlying(), currentDebt); currentDebt = 0; _deposit(); } return currentDebt; } function _handleExcessDebt() internal { uint256 currentDebt = totalDebt; uint256 newDebt = _handleExcessDebt(totalDebt); if (currentDebt != newDebt) { totalDebt = newDebt; } } /** * @notice Invest the underlying money in the vault after a deposit from the pool is made. * @dev After each deposit, the vault checks whether it needs to rebalance underlying funds allocated to strategy. * If no strategy is set then all deposited funds will be idle. */ function _deposit() internal { if (!strategyActive) return; uint256 allocatedUnderlying = getStrategy().balance(); uint256 totalUnderlying = _availableUnderlying() + allocatedUnderlying + waitingForRemovalAllocated; if (totalUnderlying == 0) return; _rebalance(totalUnderlying, allocatedUnderlying); } function _shareProfit(uint256 profit) internal returns (uint256, uint256) { uint256 totalFeeAmount = profit.scaledMul(getPerformanceFee()); if (_availableUnderlying() < totalFeeAmount) { getStrategy().withdraw(totalFeeAmount); } uint256 strategistShare = _shareFees(totalFeeAmount); return ((profit - totalFeeAmount), strategistShare); } function _shareFees(uint256 totalFeeAmount) internal returns (uint256) { uint256 strategistShare = totalFeeAmount.scaledMul(getStrategistFee()); uint256 reserveShare = totalFeeAmount.scaledMul(getReserveFee()); uint256 treasuryShare = totalFeeAmount - strategistShare - reserveShare; _depositToReserve(reserveShare); if (treasuryShare > 0) { _depositToTreasury(treasuryShare); } return strategistShare; } function _emergencyStop(uint256 underlyingReserves) internal { // debt limit exceeded: withdraw funds from strategy uint256 withdrawn = getStrategy().withdrawAll(); uint256 actualDebt = _computeNewAllocated(currentAllocated, withdrawn); if (reserve.canWithdraw(address(this))) { // check if debt can be covered with reserve funds if (underlyingReserves >= actualDebt) { reserve.withdraw(getUnderlying(), actualDebt); } else if (underlyingReserves > 0) { // debt can not be covered with reserves reserve.withdraw(getUnderlying(), underlyingReserves); } } // too much money lost, stop the strategy _deactivateStrategy(); } /** * @notice Deactivates a strategy. All positions of the strategy are exited. * @return `true` if strategy has been deactivated */ function _deactivateStrategy() internal returns (bool) { if (!strategyActive) return false; strategyActive = false; emit StrategyDeactivated(address(getStrategy())); return true; } function _payStrategist(uint256 amount) internal { _payStrategist(amount, getStrategy().strategist()); } function _payStrategist(uint256 amount, address strategist) internal virtual; function _transfer(address to, uint256 amount) internal virtual; function _depositToReserve(uint256 amount) internal virtual; function _depositToTreasury(uint256 amount) internal virtual; function _availableUnderlying() internal view virtual returns (uint256); function _computeNewAllocated(uint256 allocated, uint256 withdrawn) internal pure returns (uint256) { if (allocated > withdrawn) { return allocated - withdrawn; } return 0; } function _checkFeesInvariant(uint256 reserveFee, uint256 strategistFee) internal pure { require( reserveFee + strategistFee <= ScaledMath.ONE, "sum of strategist fee and reserve fee should be below 1" ); } function _rebalance(uint256 totalUnderlying, uint256 allocatedUnderlying) private returns (bool) { if (!strategyActive) return false; uint256 targetAllocation = getTargetAllocation(); IStrategy strategy = getStrategy(); uint256 bound = getBound(); uint256 target = totalUnderlying.scaledMul(targetAllocation); uint256 upperBound = targetAllocation == 0 ? 0 : targetAllocation + bound; upperBound = upperBound > ScaledMath.ONE ? ScaledMath.ONE : upperBound; uint256 lowerBound = bound > targetAllocation ? 0 : targetAllocation - bound; if (allocatedUnderlying > totalUnderlying.scaledMul(upperBound)) { // withdraw funds from strategy uint256 withdrawAmount = allocatedUnderlying - target; strategy.withdraw(withdrawAmount); currentAllocated = _computeNewAllocated(currentAllocated, withdrawAmount); } else if (allocatedUnderlying < totalUnderlying.scaledMul(lowerBound)) { // allocate more funds to strategy uint256 depositAmount = target - allocatedUnderlying; _transfer(address(strategy), depositAmount); currentAllocated += depositAmount; strategy.deposit(); } return true; } } // File contracts/vault/EthVault.sol pragma solidity 0.8.9; contract EthVault is Vault { using AddressProviderHelpers for IAddressProvider; address private constant _UNDERLYING = address(0); constructor(IController controller) Vault(controller) {} receive() external payable {} function initialize( address _pool, uint256 _debtLimit, uint256 _targetAllocation, uint256 _bound ) external virtual override initializer { _initialize(_pool, _debtLimit, _targetAllocation, _bound); } function getUnderlying() public pure override returns (address) { return _UNDERLYING; } function _transfer(address to, uint256 amount) internal override { payable(to).transfer(amount); } function _depositToReserve(uint256 amount) internal override { reserve.deposit{value: amount}(_UNDERLYING, amount); } function _depositToTreasury(uint256 amount) internal override { payable(addressProvider.getTreasury()).transfer(amount); } function _payStrategist(uint256 amount, address strategist) internal override { if (strategist == address(0)) return; ILiquidityPool(pool).depositFor{value: amount}(strategist, amount); } function _availableUnderlying() internal view override returns (uint256) { return address(this).balance; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IController","name":"controller","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"address","name":"value","type":"address"},{"indexed":false,"internalType":"uint256","name":"delay","type":"uint256"}],"name":"ConfigPreparedAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"delay","type":"uint256"}],"name":"ConfigPreparedNumber","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"ConfigReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"address","name":"oldValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"ConfigUpdatedAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"ConfigUpdatedNumber","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"netProfit","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"loss","type":"uint256"}],"name":"Harvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"}],"name":"StrategyActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"}],"name":"StrategyDeactivated","type":"event"},{"inputs":[],"name":"MAX_DEVIATION_BOUND","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PERFORMANCE_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STRATEGY_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activateStrategy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"addressProvider","outputs":[{"internalType":"contract IAddressProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"contract IController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"currentAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentAllocated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"currentUInts256","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deactivateStrategy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"deadlines","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"executeBound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"executeDebtLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"executeNewStrategy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"executePerformanceFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"executeReserveFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"executeStrategistFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"executeTargetAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategy","type":"address"}],"name":"getAllocatedToStrategyWaitingForRemoval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDebtLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerformanceFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReserveFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStrategiesWaitingForRemoval","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStrategistFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStrategy","outputs":[{"internalType":"contract IStrategy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTargetAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalUnderlying","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnderlying","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"harvest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"},{"internalType":"uint256","name":"_debtLimit","type":"uint256"},{"internalType":"uint256","name":"_targetAllocation","type":"uint256"},{"internalType":"uint256","name":"_bound","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategy_","type":"address"}],"name":"initializeStrategy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"pendingAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"pendingUInts256","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newBound","type":"uint256"}],"name":"prepareBound","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newDebtLimit","type":"uint256"}],"name":"prepareDebtLimit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newStrategy","type":"address"}],"name":"prepareNewStrategy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPerformanceFee","type":"uint256"}],"name":"preparePerformanceFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newReserveFee","type":"uint256"}],"name":"prepareReserveFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newStrategistFee","type":"uint256"}],"name":"prepareStrategistFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newTargetAllocation","type":"uint256"}],"name":"prepareTargetAllocation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserve","outputs":[{"internalType":"contract IVaultReserve","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"resetBound","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetDebtLimit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetNewStrategy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetPerformanceFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetReserveFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetStrategistFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetTargetAllocation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"roleManager","outputs":[{"internalType":"contract IRoleManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"strategyActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"waitingForRemovalAllocated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAllFromStrategy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawFromReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawFromStrategy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategy","type":"address"}],"name":"withdrawFromStrategyWaitingForRemoval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101006040523480156200001257600080fd5b506040516200556a3803806200556a83398101604081905262000035916200028f565b80620000c9816001600160a01b0316632954018c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200007457600080fd5b505afa15801562000089573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000af91906200028f565b6001600160a01b0316620001a460201b620033071760201c565b6001600160a01b03908116608052811660a081905260408051630a55006360e21b8152905160009291632954018c916004808301926020929190829003018186803b1580156200011857600080fd5b505afa1580156200012d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200015391906200028f565b9050806001600160a01b031660c0816001600160a01b0316815250506200018e816001600160a01b03166200023760201b620033901760201c565b6001600160a01b031660e05250620002b6915050565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a721906024015b60206040518083038186803b158015620001f657600080fd5b505afa1580156200020b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200023191906200028f565b92915050565b6040516321f8a72160e01b81526b7661756c745265736572766560a01b60048201526000906001600160a01b038316906321f8a72190602401620001dd565b6001600160a01b03811681146200028c57600080fd5b50565b600060208284031215620002a257600080fd5b8151620002af8162000276565b9392505050565b60805160a05160c05160e05161523462000336600039600081816108e201528181610cb301528181610db4015281816144de015281816145b0015281816146410152818161492201528181614ad301528181614b6b0152614c2801526000818161053601526149ad01526000610a28015260006133d001526152346000f3fe6080604052600436106103a55760003560e01c80638e6ac89b116101e7578063c4baed931161010d578063e3976edf116100a0578063f76c33991161006f578063f76c3399146109e0578063f77c479114610a16578063f95d943814610a4a578063fc7b9c1814610a6057600080fd5b8063e3976edf14610960578063f09b8fb114610996578063f1eeb9e6146109ab578063f3e7fc80146109cb57600080fd5b8063d46a8478116100dc578063d46a84781461090c578063d583e65914610921578063d698e2bb14610936578063d8ae7bf81461094b57600080fd5b8063c4baed931461089b578063c9fd9227146108bb578063cd3293de146108d0578063d0e30db01461090457600080fd5b8063a852d3e011610185578063aff1b7e411610154578063aff1b7e41461083f578063b40494e51461086c578063bd2a8b0714610881578063bdca91651461075957600080fd5b8063a852d3e0146107d5578063a966bc09146107f5578063ade109601461080a578063af2a8fff1461081f57600080fd5b80639816f473116101c15780639816f473146107755780639cf7fcc9146107895780639d711f3b146107ab578063a50ec876146107c057600080fd5b80638e6ac89b1461072f57806390f38918146107445780639407d08f1461075957600080fd5b80634278a673116102cc5780636f21cac31161026a5780637fef50da116102395780637fef50da146106da578063853828b6146106ef578063890f5f831461070457806389efcaac1461071957600080fd5b80636f21cac31461067b578063779ce5a41461069b578063798cf01d146106b05780637cd32a12146106c557600080fd5b80634ec81af1116102a65780634ec81af11461060f5780636741c1b91461062f578063678cbcb5146106445780636d785cf31461066457600080fd5b80634278a673146105ba5780634641257d146105da57806348b19335146105ef57600080fd5b806316f0115b116103445780632954018c116103135780632954018c146105245780632e1a7d4d1461055857806332a894c114610578578063346a4a511461058d57600080fd5b806316f0115b146104ba57806321401dd1146104da5780632182a5c4146104ef578063235c36031461050f57600080fd5b80630ee43c20116103805780630ee43c201461041a5780630fe6cbcf1461043f578063102a91261461045f57806315dbfe621461047f57600080fd5b8062435da5146103b157806307da0603146103e35780630a8bcdb9146103f857600080fd5b366103ac57005b600080fd5b3480156103bd57600080fd5b506103c6610a76565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156103ef57600080fd5b506103c6610a85565b34801561040457600080fd5b50610418610413366004614f17565b610ac7565b005b34801561042657600080fd5b5061042f610e60565b60405190151581526020016103da565b34801561044b57600080fd5b5061042f61045a366004614f17565b610f53565b34801561046b57600080fd5b5061042f61047a366004614f17565b61105b565b34801561048b57600080fd5b506104ac61049a366004614f17565b603b6020526000908152604090205481565b6040519081526020016103da565b3480156104c657600080fd5b506002546103c6906001600160a01b031681565b3480156104e657600080fd5b5061042f61115a565b3480156104fb57600080fd5b5061042f61050a366004614f17565b611239565b34801561051b57600080fd5b506104ac611326565b34801561053057600080fd5b506103c67f000000000000000000000000000000000000000000000000000000000000000081565b34801561056457600080fd5b5061042f610573366004614f17565b611365565b34801561058457600080fd5b506104ac6116b5565b34801561059957600080fd5b506104ac6105a8366004614f17565b603e6020526000908152604090205481565b3480156105c657600080fd5b5061042f6105d5366004614f17565b6116d8565b3480156105e657600080fd5b5061042f611810565b3480156105fb57600080fd5b5061042f61060a366004614f17565b611905565b34801561061b57600080fd5b5061041861062a366004614f45565b611b2c565b34801561063b57600080fd5b5061042f611bf5565b34801561065057600080fd5b5061042f61065f366004614f80565b611cd4565b34801561067057600080fd5b506104ac6206978081565b34801561068757600080fd5b506104ac610696366004614f80565b611f8f565b3480156106a757600080fd5b506104ac611f9c565b3480156106bc57600080fd5b506104ac611fdd565b3480156106d157600080fd5b506104ac61201b565b3480156106e657600080fd5b506104ac612055565b3480156106fb57600080fd5b5061041861208b565b34801561071057600080fd5b5061042f612195565b34801561072557600080fd5b506104ac60015481565b34801561073b57600080fd5b5061042f612282565b34801561075057600080fd5b506104ac612372565b34801561076557600080fd5b506104ac6706f05b59d3b2000081565b34801561078157600080fd5b5060006103c6565b34801561079557600080fd5b5061079e6123a1565b6040516103da9190614f9d565b3480156107b757600080fd5b5061042f6123ad565b3480156107cc57600080fd5b506103c6612498565b3480156107e157600080fd5b5061042f6107f0366004614f17565b6126d9565b34801561080157600080fd5b5061042f6127cd565b34801561081657600080fd5b5061042f6128b5565b34801561082b57600080fd5b5061042f61083a366004614f80565b6129a9565b34801561084b57600080fd5b506104ac61085a366004614f17565b603d6020526000908152604090205481565b34801561087857600080fd5b506104ac612a99565b34801561088d57600080fd5b5060045461042f9060ff1681565b3480156108a757600080fd5b5061042f6108b6366004614f17565b612afe565b3480156108c757600080fd5b506104ac612c3f565b3480156108dc57600080fd5b506103c67f000000000000000000000000000000000000000000000000000000000000000081565b610418612c5e565b34801561091857600080fd5b506104ac612d50565b34801561092d57600080fd5b506104ac612d77565b34801561094257600080fd5b5061042f612dc1565b34801561095757600080fd5b5061042f612eb2565b34801561096c57600080fd5b506103c661097b366004614f17565b603a602052600090815260409020546001600160a01b031681565b3480156109a257600080fd5b506104ac612f9e565b3480156109b757600080fd5b506104ac6109c6366004614f80565b612fba565b3480156109d757600080fd5b506104ac6132cc565b3480156109ec57600080fd5b506103c66109fb366004614f17565b603c602052600090815260409020546001600160a01b031681565b348015610a2257600080fd5b506103c67f000000000000000000000000000000000000000000000000000000000000000081565b348015610a5657600080fd5b506104ac60005481565b348015610a6c57600080fd5b506104ac60035481565b6000610a806133ce565b905090565b67537472617465677960c01b600052603c6020527f15bdd40257915f753934b43755984618aeb2ae4fff096845769c2bb729e989be546001600160a01b031690565b610acf6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401610b09929190614fea565b60206040518083038186803b158015610b2157600080fd5b505afa158015610b35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b599190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090610ba45760405162461bcd60e51b8152600401610b9b9190615023565b60405180910390fd5b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b602082015281610be85760405162461bcd60e51b8152600401610b9b9190615023565b50600260009054906101000a90046001600160a01b03166001600160a01b031663b187bd266040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3757600080fd5b505afa158015610c4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6f9190615001565b6040518060600160405280602c8152602001615192602c913990610ca65760405162461bcd60e51b8152600401610b9b9190615023565b5060006001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663d4fac45d30836040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260440160206040518083038186803b158015610d2057600080fd5b505afa158015610d34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d589190615078565b90508082111560405180604001604052806014815260200173696e73756666696369656e742062616c616e636560601b81525090610da95760405162461bcd60e51b8152600401610b9b9190615023565b506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663f3fef3a360006040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101859052604401602060405180830381600087803b158015610e2357600080fd5b505af1158015610e37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5b9190615001565b505050565b6000610e6a6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401610ea4929190614fea565b60206040518083038186803b158015610ebc57600080fd5b505afa158015610ed0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef49190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090610f365760405162461bcd60e51b8152600401610b9b9190615023565b50610a806f2a30b933b2ba20b63637b1b0ba34b7b760811b6133f2565b6000610f5d6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401610f97929190614fea565b60206040518083038186803b158015610faf57600080fd5b505afa158015610fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe79190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906110295760405162461bcd60e51b8152600401610b9b9190615023565b5061103b6110356132cc565b83613499565b6110556c5374726174656769737446656560981b83613524565b92915050565b60006110656133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b815260040161109f929190614fea565b60206040518083038186803b1580156110b757600080fd5b505afa1580156110cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ef9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906111315760405162461bcd60e51b8152600401610b9b9190615023565b506111438261113e611fdd565b613499565b611055695265736572766546656560b01b83613524565b60006111646133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b815260040161119e929190614fea565b60206040518083038186803b1580156111b657600080fd5b505afa1580156111ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ee9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906112305760405162461bcd60e51b8152600401610b9b9190615023565b50610a8061353b565b60006112436133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b815260040161127d929190614fea565b60206040518083038186803b15801561129557600080fd5b505afa1580156112a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cd9190615001565b6040518060400160405280601381526020016000805160206151be8339815191528152509061130f5760405162461bcd60e51b8152600401610b9b9190615023565b50611055681119589d131a5b5a5d60ba1b83613524565b6d506572666f726d616e636546656560901b600052603d6020527fbadb955f4a57baa7811abc9bcd6809eb9d3b80456cae1a7ea27f30fddfd0c0a65490565b6002546000906001600160a01b031633148061140e57506113846133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b81526004016113be929190614fea565b60206040518083038186803b1580156113d657600080fd5b505afa1580156113ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061140e9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906114505760405162461bcd60e51b8152600401610b9b9190615023565b50600061145b610a85565b905047838110156115d7576001600160a01b03821661147e575060009392505050565b6000826001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b1580156114b957600080fd5b505afa1580156114cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f19190615078565b905060006114ff83876150a7565b9050818111156115155750600095945050505050565b6000611532611522611f9c565b61152c84866150a7565b9061359b565b9050600061154082856150a7565b604051632e1a7d4d60e01b8152600481018290529091506001600160a01b03871690632e1a7d4d90602401602060405180830381600087803b15801561158557600080fd5b505af1158015611599573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115bd9190615001565b506115ca600054826135ba565b6000555061169592505050565b60006001600160a01b0383161561165c57826001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b15801561162157600080fd5b505afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190615078565b90505b60015460009061166c83856150be565b61167691906150be565b9050600061168487836150a7565b905061169081846135de565b505050505b6002546116ab906001600160a01b0316856137f5565b5060019392505050565b6000806116c964109bdd5b9960da1b61382b565b90506116d361384f565b919050565b60006116e26133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b815260040161171c929190614fea565b60206040518083038186803b15801561173457600080fd5b505afa158015611748573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176c9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906117ae5760405162461bcd60e51b8152600401610b9b9190615023565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b60208201526706f05b59d3b200008311156117fd5760405162461bcd60e51b8152600401610b9b9190615023565b5061105564109bdd5b9960da1b83613524565b6002546000906001600160a01b03163314806118ba575061182f6133ce565b6001600160a01b03166391d148546a6d61696e74656e616e636560a81b336040518363ffffffff1660e01b815260040161186a929190614fea565b60206040518083038186803b15801561188257600080fd5b505afa158015611896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ba9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906118fc5760405162461bcd60e51b8152600401610b9b9190615023565b50610a8061390d565b600061190f6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401611949929190614fea565b60206040518083038186803b15801561196157600080fd5b505afa158015611975573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119999190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906119db5760405162461bcd60e51b8152600401610b9b9190615023565b5060006119e6610a85565b90506001600160a01b0381166119ff5750600092915050565b82816001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3957600080fd5b505afa158015611a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a719190615078565b1015611a805750600092915050565b600047604051632e1a7d4d60e01b8152600481018690529091506001600160a01b03831690632e1a7d4d90602401602060405180830381600087803b158015611ac857600080fd5b505af1158015611adc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b009190615001565b5047611b0c82826150a7565b600080828254611b1c91906150a7565b9091555060019695505050505050565b603f54610100900460ff16611b4757603f5460ff1615611b4b565b303b155b611bae5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610b9b565b603f54610100900460ff16158015611bd057603f805461ffff19166101011790555b611bdc85858585613bc4565b8015611bee57603f805461ff00191690555b5050505050565b6000611bff6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401611c39929190614fea565b60206040518083038186803b158015611c5157600080fd5b505afa158015611c65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c899190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090611ccb5760405162461bcd60e51b8152600401610b9b9190615023565b50610a80613d72565b6000611cde6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401611d18929190614fea565b60206040518083038186803b158015611d3057600080fd5b505afa158015611d44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d689190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090611daa5760405162461bcd60e51b8152600401610b9b9190615023565b5067537472617465677960c01b600052603c60209081527f15bdd40257915f753934b43755984618aeb2ae4fff096845769c2bb729e989be546040805180820190915260168152751059191c995cdcc81a5cc8185b1c9958591e481cd95d60521b928101929092526001600160a01b031615611e395760405162461bcd60e51b8152600401610b9b9190615023565b506040805180820190915260188152771e995c9bc81859191c995cdcc81b9bdd08185b1b1bddd95960421b60208201526001600160a01b038316611e905760405162461bcd60e51b8152600401610b9b9190615023565b50611ea667537472617465677960c01b83613de6565b50611eaf613d72565b5060006001600160a01b0316826001600160a01b0316631fe4a6866040518163ffffffff1660e01b815260040160206040518083038186803b158015611ef457600080fd5b505afa158015611f08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2c91906150d6565b6001600160a01b03161415604051806040016040528060188152602001771e995c9bc81859191c995cdcc81b9bdd08185b1b1bddd95960421b81525090611f865760405162461bcd60e51b8152600401610b9b9190615023565b50600192915050565b6000611055600583613e72565b6f2a30b933b2ba20b63637b1b0ba34b7b760811b600052603d6020527f0a3006de449e2f6da78c92d58370b3dd2ef3b1e1963fc373ed67d46ced02eb8f5490565b6c5374726174656769737446656560981b600052603d6020527f9991a201724620367b875943d3f1e2d8a65d067f05ccd6a37af85ae33cf679e95490565b681119589d131a5b5a5d60ba1b600052603d6020527fed35bbff007ae1d09677de3676c3cb1b0411569c4ab270913b3fb2a177a703195490565b64109bdd5b9960da1b600052603d6020527fcba6df5081839cab6ded1888d57f2772386c9d156438bb2faa7b07ec10c244705490565b6002546001600160a01b031633148061213157506120a76133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b81526004016120e1929190614fea565b60206040518083038186803b1580156120f957600080fd5b505afa15801561210d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121319190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906121735760405162461bcd60e51b8152600401610b9b9190615023565b5061217c613e87565b50600254612193906001600160a01b0316476137f5565b565b600061219f6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b81526004016121d9929190614fea565b60206040518083038186803b1580156121f157600080fd5b505afa158015612205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122299190615001565b6040518060400160405280601381526020016000805160206151be8339815191528152509061226b5760405162461bcd60e51b8152600401610b9b9190615023565b50610a80695265736572766546656560b01b6133f2565b600061228c6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b81526004016122c6929190614fea565b60206040518083038186803b1580156122de57600080fd5b505afa1580156122f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123169190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906123585760405162461bcd60e51b8152600401610b9b9190615023565b50610a806c5374726174656769737446656560981b6133f2565b60008061238e6c5374726174656769737446656560981b61382b565b90506116d361239b6132cc565b82613499565b6060610a806005613f5e565b60006123b76133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b81526004016123f1929190614fea565b60206040518083038186803b15801561240957600080fd5b505afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906124835760405162461bcd60e51b8152600401610b9b9190615023565b50610a8067537472617465677960c01b61400d565b60006124ae67537472617465677960c01b6140bf565b60006124b8610a85565b90506001600160a01b0381161561265c576124d161390d565b50806001600160a01b031663fc0e74d16040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561250d57600080fd5b505af1158015612521573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125459190615001565b50806001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561258157600080fd5b505af1158015612595573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b99190615078565b506000816001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b1580156125f557600080fd5b505afa158015612609573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262d9190615078565b9050801561265a5761264160058383614168565b50806001600082825461265491906150be565b90915550505b505b61266461353b565b506000808055600381905567537472617465677960c01b90819052603a6020527fa4caf68bc3013a9a5274c5d8968485ae05b8c28e9f50493f41acc96b22818c23546001600160a01b0316906126ba9082613de6565b506001600160a01b03811615611055576126d2613d72565b5092915050565b60006126e36133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b815260040161271d929190614fea565b60206040518083038186803b15801561273557600080fd5b505afa158015612749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276d9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906127af5760405162461bcd60e51b8152600401610b9b9190615023565b506110556f2a30b933b2ba20b63637b1b0ba34b7b760811b83613524565b60006127d76133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401612811929190614fea565b60206040518083038186803b15801561282957600080fd5b505afa15801561283d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128619190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906128a35760405162461bcd60e51b8152600401610b9b9190615023565b50610a8064109bdd5b9960da1b6133f2565b6002546000906001600160a01b031633148061295e57506128d46133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b815260040161290e929190614fea565b60206040518083038186803b15801561292657600080fd5b505afa15801561293a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295e9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906129a05760405162461bcd60e51b8152600401610b9b9190615023565b50610a80613e87565b60006129b36133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b81526004016129ed929190614fea565b60206040518083038186803b158015612a0557600080fd5b505afa158015612a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a3d9190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090612a7f5760405162461bcd60e51b8152600401610b9b9190615023565b5061105567537472617465677960c01b8362069780614186565b60004781612aa5610a85565b6001600160a01b03161415612ab957919050565b600060015460005483612acc91906150be565b612ad691906150be565b90508060035411612af557600354612aee90826150a7565b9250505090565b60009250505090565b6000612b086133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401612b42929190614fea565b60206040518083038186803b158015612b5a57600080fd5b505afa158015612b6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b929190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090612bd45760405162461bcd60e51b8152600401610b9b9190615023565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b60208201526706f05b59d3b20000831115612c235760405162461bcd60e51b8152600401610b9b9190615023565b506110556d506572666f726d616e636546656560901b83613524565b6000806116c96f2a30b933b2ba20b63637b1b0ba34b7b760811b61382b565b6002546001600160a01b0316331480612d055750612c7a6133ce565b6001600160a01b03166391d148546a6d61696e74656e616e636560a81b336040518363ffffffff1660e01b8152600401612cb5929190614fea565b60206040518083038186803b158015612ccd57600080fd5b505afa158015612ce1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d059190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090612d475760405162461bcd60e51b8152600401610b9b9190615023565b5061219361384f565b600080612d69695265736572766546656560b01b61382b565b90506116d38161113e611fdd565b600080612d8f681119589d131a5b5a5d60ba1b61382b565b90506000612da88260005461359b90919063ffffffff16565b90508060035410612dbb57612dbb614203565b50919050565b6000612dcb6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401612e05929190614fea565b60206040518083038186803b158015612e1d57600080fd5b505afa158015612e31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e559190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090612e975760405162461bcd60e51b8152600401610b9b9190615023565b50610a806d506572666f726d616e636546656560901b6133f2565b6000612ebc6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401612ef6929190614fea565b60206040518083038186803b158015612f0e57600080fd5b505afa158015612f22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f469190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090612f885760405162461bcd60e51b8152600401610b9b9190615023565b50610a80681119589d131a5b5a5d60ba1b6133f2565b6000610a806d506572666f726d616e636546656560901b61382b565b60008080612fc9600585614220565b91509150816040518060400160405280601781526020017f537472617465677920646f6573206e6f74206578697374000000000000000000815250906130225760405162461bcd60e51b8152600401610b9b9190615023565b506000849050806001600160a01b0316634641257d6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561306357600080fd5b505af1158015613077573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309b9190615078565b506000816001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156130d957600080fd5b505af11580156130ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131119190615078565b600154909150808210613128576000600155613136565b61313282826150a7565b6001555b8382111561322157600061314a85846150a7565b9050600061316861316361315c611326565b849061359b565b614247565b905080156131ea576131ea81866001600160a01b0316631fe4a6866040518163ffffffff1660e01b815260040160206040518083038186803b1580156131ad57600080fd5b505afa1580156131c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131e591906150d6565b6142a7565b60405160009650869083907f6c8433a8e155f0af04dba058d4e4695f7da554578963d876bdf4a6d8d6399d9c908390a3505061322e565b61322b82856150a7565b93505b826001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b15801561326757600080fd5b505afa15801561327b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061329f9190615078565b6132b4576132ae600584614341565b506132c2565b6132c060058486614168565b505b5095945050505050565b695265736572766546656560b01b600052603d6020527fa61f8e25cb35ba15fc70bbd3ba789d53bf34a4deddb38a43a213af3182d35aae5490565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a721906024015b60206040518083038186803b15801561335857600080fd5b505afa15801561336c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105591906150d6565b6040516321f8a72160e01b81526b7661756c745265736572766560a01b60048201526000906001600160a01b038316906321f8a72190602401613340565b7f000000000000000000000000000000000000000000000000000000000000000090565b6000818152603e6020908152604080832054815180830190925260128252710646561646c696e65206d75737420626520360741b928201929092529061344b5760405162461bcd60e51b8152600401610b9b9190615023565b506000828152603e60209081526040808320839055603b9091528082208290555183917f90fb84ad67dd037c388289337bb80b61b8605d38ba9a875dc38b5600909d172f91a2506001919050565b670de0b6b3a76400006134ac82846150be565b11156135205760405162461bcd60e51b815260206004820152603760248201527f73756d206f6620737472617465676973742066656520616e642072657365727660448201527f65206665652073686f756c642062652062656c6f7720310000000000000000006064820152608401610b9b565b5050565b600061353483836203f480614356565b9392505050565b60045460009060ff1661354e5750600090565b6004805460ff19169055613560610a85565b6001600160a01b03167f274ec28d31430170ad5dd350f8e7505ffab078c309300878c710383ae4cbed4960405160405180910390a250600190565b6000670de0b6b3a76400006135b083856150f3565b6135349190615112565b6000818311156135d5576135ce82846150a7565b9050611055565b50600092915050565b60045460009060ff166135f357506000611055565b60006135fd611f9c565b90506000613609610a85565b90506000613615612055565b90506000613623878561359b565b90506000841561363c5761363783866150be565b61363f565b60005b9050670de0b6b3a764000081116136565780613660565b670de0b6b3a76400005b9050600085841161367a5761367584876150a7565b61367d565b60005b9050613689898361359b565b88111561372f57600061369c848a6150a7565b604051632e1a7d4d60e01b8152600481018290529091506001600160a01b03871690632e1a7d4d90602401602060405180830381600087803b1580156136e157600080fd5b505af11580156136f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137199190615001565b50613726600054826135ba565b600055506137e6565b613739898261359b565b8810156137e657600061374c89856150a7565b905061375886826137f5565b8060008082825461376991906150be565b92505081905550856001600160a01b031663d0e30db06040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156137ab57600080fd5b505af11580156137bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137e39190615001565b50505b50600198975050505050505050565b6040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015610e5b573d6000803e3d6000fd5b6000613836826140bf565b6000828152603b60205260409020546126d283826143ac565b60045460ff1661385b57565b6000613865610a85565b6001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b15801561389d57600080fd5b505afa1580156138b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138d59190615078565b90506000600154826138e44790565b6138ee91906150be565b6138f891906150be565b905080613903575050565b610e5b81836135de565b600080613918610a85565b90506001600160a01b03811661393057600091505090565b806001600160a01b0316634641257d6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561396b57600080fd5b505af115801561397f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139a39190615078565b50600080826001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b1580156139e057600080fd5b505afa1580156139f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a189190615078565b6000546003549192509081831115613aa9576000613a3683856150a7565b905081811115613a69578115613a5757613a5082826150a7565b9050600091505b613a608161440d565b95509050613a76565b613a7381836150a7565b91505b60405160009082907f6c8433a8e155f0af04dba058d4e4695f7da554578963d876bdf4a6d8d6399d9c908390a350613b3a565b81831015613b2e576000613abd84846150a7565b9050613ac981836150be565b91506000613ad561201b565b90506000613ae3858361359b565b905080841115613af957613af6846144d1565b93505b60405183906000907f6c8433a8e155f0af04dba058d4e4695f7da554578963d876bdf4a6d8d6399d9c908290a3505050613b3a565b60019550505050505090565b80600381905550846001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b158015613b7a57600080fd5b505afa158015613b8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb29190615078565b6000558315613b2e57613b2e846146fc565b60408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b6020820152670de0b6b3a7640000841115613c125760405162461bcd60e51b8152600401610b9b9190615023565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b6020820152670de0b6b3a7640000831115613c615760405162461bcd60e51b8152600401610b9b9190615023565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b60208201526706f05b59d3b20000821115613cb05760405162461bcd60e51b8152600401610b9b9190615023565b50600280546001600160a01b0319166001600160a01b038616179055613ce2681119589d131a5b5a5d60ba1b846143ac565b50613d006f2a30b933b2ba20b63637b1b0ba34b7b760811b836143ac565b50613d1364109bdd5b9960da1b826143ac565b50613d32695265736572766546656560b01b662386f26fc100006143ac565b50613d556c5374726174656769737446656560981b67016345785d8a00006143ac565b50611bee6d506572666f726d616e636546656560901b60006143ac565b600080613d7d610a85565b90506001600160a01b038116613d9557600091505090565b6004805460ff191660011790556040516001600160a01b038216907f652f053fc39779b70b29678135ade972fcb79966fc68fcb77c996b1aa4fd9afb90600090a2613dde61384f565b600191505090565b6000828152603c6020908152604080832080546001600160a01b03198082166001600160a01b03888116918217909455603a86528487208054909216909155603e85528386208690558351929091168083529382015285917fc4a957706c639829ad54381b04930c464db6c7ffdc09d2b4b1acc9ee34fb926191015b60405180910390a2509092915050565b6000613534836001600160a01b038416614743565b600080613e92610a85565b90506001600160a01b038116613eaa57600091505090565b613eb261390d565b506000479050816001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613ef357600080fd5b505af1158015613f07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f2b9190615078565b50476000613f3983836150a7565b9050613f47600054826135ba565b600055613f5261353b565b50600194505050505090565b60606000613f6b836147b3565b905060008167ffffffffffffffff811115613f8857613f88615134565b604051908082528060200260200182016040528015613fb1578160200160208202803683370190505b50905060005b8281101561400557613fc985826147be565b828281518110613fdb57613fdb61514a565b6001600160a01b039092166020928302919091019091015280613ffd81615160565b915050613fb7565b509392505050565b6000818152603e6020908152604080832054815180830190925260128252710646561646c696e65206d75737420626520360741b92820192909252906140665760405162461bcd60e51b8152600401610b9b9190615023565b506000828152603e60209081526040808320839055603a90915280822080546001600160a01b03191690555183917f90fb84ad67dd037c388289337bb80b61b8605d38ba9a875dc38b5600909d172f91a2506001919050565b6000603e6000838152602001908152602001600020549050804210156040518060600160405280602181526020016151de60219139906141125760405162461bcd60e51b8152600401610b9b9190615023565b5060408051808201909152600d81526c0646561646c696e65206973203609c1b6020820152816141555760405162461bcd60e51b8152600401610b9b9190615023565b50506000908152603e6020526040812055565b600061417e846001600160a01b038516846147d4565b949350505050565b600061419284836147f1565b6000848152603a602090815260409182902080546001600160a01b0319166001600160a01b038716908117909155825190815290810184905285917fd46e58ee9dc1ae703349f8c09c19f23213a531b4d57f00cfd4a5a6cb6519668d91015b60405180910390a25060019392505050565b6003546000614211826144d1565b90508082146135205760035550565b6000808080614238866001600160a01b0387166148cb565b909450925050505b9250929050565b60008061425561315c611fdd565b9050600061426b6142646132cc565b859061359b565b905060008161427a84876150a7565b61428491906150a7565b905061428f82614905565b801561429e5761429e816149a8565b50909392505050565b6001600160a01b0381166142b9575050565b6002546040516317a790f160e11b81526001600160a01b0383811660048301526024820185905290911690632f4f21e29084906044016020604051808303818588803b15801561430857600080fd5b505af115801561431c573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e5b9190615078565b6000613534836001600160a01b038416614a12565b600061436284836147f1565b6000848152603b6020908152604091829020859055815185815290810184905285917f0e6790002e78fb96ff1fdfe3a3bb2a86489d3f3923372c1fe5b6b1fed071eed491016141f1565b6000828152603d60209081526040808320805490859055603b8352818420849055603e835281842084905581518181529283018590529185917fcc0bafe2accb565ea70674bf4b2555e49a47d410fb9932dfab3e5f41855d0a2f9101613e62565b600080600061441d614264611326565b9050804710156144b05761442f610a85565b6001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040161445c91815260200190565b602060405180830381600087803b15801561447657600080fd5b505af115801561448a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144ae9190615001565b505b60006144bb82614247565b90506144c782866150a7565b9590945092505050565b6000806001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663d4fac45d30836040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260440160206040518083038186803b15801561454b57600080fd5b505afa15801561455f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145839190615078565b90508083111561459b5761459681614a2f565b6146f5565b60405163019262d360e41b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906319262d309060240160206040518083038186803b1580156145fa57600080fd5b505afa15801561460e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146329190615001565b156146f5576001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663f3fef3a360006040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101869052604401602060405180830381600087803b1580156146b057600080fd5b505af11580156146c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146e89190615001565b50600092506146f561384f565b5090919050565b61474081614708610a85565b6001600160a01b0316631fe4a6866040518163ffffffff1660e01b815260040160206040518083038186803b1580156131ad57600080fd5b50565b60008181526002830160205260408120548015158061476757506147678484614cdf565b6135345760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b657900006044820152606401610b9b565b600061105582614ceb565b6000806147cb8484614cf6565b50949350505050565b6000828152600284016020526040812082905561417e8484614d05565b603e600083815260200190815260200160002054600014604051806040016040528060128152602001710646561646c696e65206d75737420626520360741b815250906148515760405162461bcd60e51b8152600401610b9b9190615023565b5060408051808201909152601881527f64656c6179206265206174206c6561737420332064617973000000000000000060208201526203f4808210156148aa5760405162461bcd60e51b8152600401610b9b9190615023565b506148b581426150be565b6000928352603e60205260409092209190915550565b60008181526002830160205260408120548190806148fa576148ed8585614cdf565b9250600091506142409050565b600192509050614240565b6040516311f9fbc960e21b815260006004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906347e7ef249083906044016020604051808303818588803b15801561496f57600080fd5b505af1158015614983573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906135209190615001565b6149da7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316614d11565b6001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015613520573d6000803e3d6000fd5b600081815260028301602052604081208190556135348383614d4b565b6000614a39610a85565b6001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b158015614a7357600080fd5b505af1158015614a87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614aab9190615078565b90506000614abb600054836135ba565b60405163019262d360e41b81523060048201529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906319262d309060240160206040518083038186803b158015614b1d57600080fd5b505afa158015614b31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b559190615001565b15614cd157808310614c18576001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663f3fef3a360006040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101849052604401602060405180830381600087803b158015614bda57600080fd5b505af1158015614bee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c129190615001565b50614cd1565b8215614cd1576001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663f3fef3a360006040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101869052604401602060405180830381600087803b158015614c9757600080fd5b505af1158015614cab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614ccf9190615001565b505b614cd961353b565b50505050565b60006135348383614d57565b600061105582614d6f565b60008080806142388686614d79565b60006135348383614da4565b6040516321f8a72160e01b815267747265617375727960c01b60048201526000906001600160a01b038316906321f8a72190602401613340565b60006135348383614df3565b60008181526001830160205260408120541515613534565b6000611055825490565b60008080614d878585614ee6565b600081815260029690960160205260409095205494959350505050565b6000818152600183016020526040812054614deb57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611055565b506000611055565b60008181526001830160205260408120548015614edc576000614e176001836150a7565b8554909150600090614e2b906001906150a7565b9050818114614e90576000866000018281548110614e4b57614e4b61514a565b9060005260206000200154905080876000018481548110614e6e57614e6e61514a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614ea157614ea161517b565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611055565b6000915050611055565b600061353483836000826000018281548110614f0457614f0461514a565b9060005260206000200154905092915050565b600060208284031215614f2957600080fd5b5035919050565b6001600160a01b038116811461474057600080fd5b60008060008060808587031215614f5b57600080fd5b8435614f6681614f30565b966020860135965060408601359560600135945092505050565b600060208284031215614f9257600080fd5b813561353481614f30565b6020808252825182820181905260009190848201906040850190845b81811015614fde5783516001600160a01b031683529284019291840191600101614fb9565b50909695505050505050565b9182526001600160a01b0316602082015260400190565b60006020828403121561501357600080fd5b8151801515811461353457600080fd5b600060208083528351808285015260005b8181101561505057858101830151858201604001528201615034565b81811115615062576000604083870101525b50601f01601f1916929092016040019392505050565b60006020828403121561508a57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000828210156150b9576150b9615091565b500390565b600082198211156150d1576150d1615091565b500190565b6000602082840312156150e857600080fd5b815161353481614f30565b600081600019048311821515161561510d5761510d615091565b500290565b60008261512f57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060001982141561517457615174615091565b5060010190565b634e487b7160e01b600052603160045260246000fdfe506f6f6c206d7573742062652070617573656420746f2077697468647261772066726f6d2072657365727665756e617574686f72697a65642061636365737300000000000000000000000000646561646c696e6520686173206e6f74206265656e207265616368656420796574a2646970667358221220fc706e7436a7324f36c875278d8608814f2e5d3165c906971dbf304d8b43a28e64736f6c63430008090033000000000000000000000000f88864b5d747961eb1caf88d395d13aca8274c9f
Deployed Bytecode
0x6080604052600436106103a55760003560e01c80638e6ac89b116101e7578063c4baed931161010d578063e3976edf116100a0578063f76c33991161006f578063f76c3399146109e0578063f77c479114610a16578063f95d943814610a4a578063fc7b9c1814610a6057600080fd5b8063e3976edf14610960578063f09b8fb114610996578063f1eeb9e6146109ab578063f3e7fc80146109cb57600080fd5b8063d46a8478116100dc578063d46a84781461090c578063d583e65914610921578063d698e2bb14610936578063d8ae7bf81461094b57600080fd5b8063c4baed931461089b578063c9fd9227146108bb578063cd3293de146108d0578063d0e30db01461090457600080fd5b8063a852d3e011610185578063aff1b7e411610154578063aff1b7e41461083f578063b40494e51461086c578063bd2a8b0714610881578063bdca91651461075957600080fd5b8063a852d3e0146107d5578063a966bc09146107f5578063ade109601461080a578063af2a8fff1461081f57600080fd5b80639816f473116101c15780639816f473146107755780639cf7fcc9146107895780639d711f3b146107ab578063a50ec876146107c057600080fd5b80638e6ac89b1461072f57806390f38918146107445780639407d08f1461075957600080fd5b80634278a673116102cc5780636f21cac31161026a5780637fef50da116102395780637fef50da146106da578063853828b6146106ef578063890f5f831461070457806389efcaac1461071957600080fd5b80636f21cac31461067b578063779ce5a41461069b578063798cf01d146106b05780637cd32a12146106c557600080fd5b80634ec81af1116102a65780634ec81af11461060f5780636741c1b91461062f578063678cbcb5146106445780636d785cf31461066457600080fd5b80634278a673146105ba5780634641257d146105da57806348b19335146105ef57600080fd5b806316f0115b116103445780632954018c116103135780632954018c146105245780632e1a7d4d1461055857806332a894c114610578578063346a4a511461058d57600080fd5b806316f0115b146104ba57806321401dd1146104da5780632182a5c4146104ef578063235c36031461050f57600080fd5b80630ee43c20116103805780630ee43c201461041a5780630fe6cbcf1461043f578063102a91261461045f57806315dbfe621461047f57600080fd5b8062435da5146103b157806307da0603146103e35780630a8bcdb9146103f857600080fd5b366103ac57005b600080fd5b3480156103bd57600080fd5b506103c6610a76565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156103ef57600080fd5b506103c6610a85565b34801561040457600080fd5b50610418610413366004614f17565b610ac7565b005b34801561042657600080fd5b5061042f610e60565b60405190151581526020016103da565b34801561044b57600080fd5b5061042f61045a366004614f17565b610f53565b34801561046b57600080fd5b5061042f61047a366004614f17565b61105b565b34801561048b57600080fd5b506104ac61049a366004614f17565b603b6020526000908152604090205481565b6040519081526020016103da565b3480156104c657600080fd5b506002546103c6906001600160a01b031681565b3480156104e657600080fd5b5061042f61115a565b3480156104fb57600080fd5b5061042f61050a366004614f17565b611239565b34801561051b57600080fd5b506104ac611326565b34801561053057600080fd5b506103c67f000000000000000000000000139c15e21b0f6e43fc397face5de5b7d5ae6874a81565b34801561056457600080fd5b5061042f610573366004614f17565b611365565b34801561058457600080fd5b506104ac6116b5565b34801561059957600080fd5b506104ac6105a8366004614f17565b603e6020526000908152604090205481565b3480156105c657600080fd5b5061042f6105d5366004614f17565b6116d8565b3480156105e657600080fd5b5061042f611810565b3480156105fb57600080fd5b5061042f61060a366004614f17565b611905565b34801561061b57600080fd5b5061041861062a366004614f45565b611b2c565b34801561063b57600080fd5b5061042f611bf5565b34801561065057600080fd5b5061042f61065f366004614f80565b611cd4565b34801561067057600080fd5b506104ac6206978081565b34801561068757600080fd5b506104ac610696366004614f80565b611f8f565b3480156106a757600080fd5b506104ac611f9c565b3480156106bc57600080fd5b506104ac611fdd565b3480156106d157600080fd5b506104ac61201b565b3480156106e657600080fd5b506104ac612055565b3480156106fb57600080fd5b5061041861208b565b34801561071057600080fd5b5061042f612195565b34801561072557600080fd5b506104ac60015481565b34801561073b57600080fd5b5061042f612282565b34801561075057600080fd5b506104ac612372565b34801561076557600080fd5b506104ac6706f05b59d3b2000081565b34801561078157600080fd5b5060006103c6565b34801561079557600080fd5b5061079e6123a1565b6040516103da9190614f9d565b3480156107b757600080fd5b5061042f6123ad565b3480156107cc57600080fd5b506103c6612498565b3480156107e157600080fd5b5061042f6107f0366004614f17565b6126d9565b34801561080157600080fd5b5061042f6127cd565b34801561081657600080fd5b5061042f6128b5565b34801561082b57600080fd5b5061042f61083a366004614f80565b6129a9565b34801561084b57600080fd5b506104ac61085a366004614f17565b603d6020526000908152604090205481565b34801561087857600080fd5b506104ac612a99565b34801561088d57600080fd5b5060045461042f9060ff1681565b3480156108a757600080fd5b5061042f6108b6366004614f17565b612afe565b3480156108c757600080fd5b506104ac612c3f565b3480156108dc57600080fd5b506103c67f00000000000000000000000007d142abcce99defa936e8e8c18595e5f30a109f81565b610418612c5e565b34801561091857600080fd5b506104ac612d50565b34801561092d57600080fd5b506104ac612d77565b34801561094257600080fd5b5061042f612dc1565b34801561095757600080fd5b5061042f612eb2565b34801561096c57600080fd5b506103c661097b366004614f17565b603a602052600090815260409020546001600160a01b031681565b3480156109a257600080fd5b506104ac612f9e565b3480156109b757600080fd5b506104ac6109c6366004614f80565b612fba565b3480156109d757600080fd5b506104ac6132cc565b3480156109ec57600080fd5b506103c66109fb366004614f17565b603c602052600090815260409020546001600160a01b031681565b348015610a2257600080fd5b506103c67f000000000000000000000000f88864b5d747961eb1caf88d395d13aca8274c9f81565b348015610a5657600080fd5b506104ac60005481565b348015610a6c57600080fd5b506104ac60035481565b6000610a806133ce565b905090565b67537472617465677960c01b600052603c6020527f15bdd40257915f753934b43755984618aeb2ae4fff096845769c2bb729e989be546001600160a01b031690565b610acf6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401610b09929190614fea565b60206040518083038186803b158015610b2157600080fd5b505afa158015610b35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b599190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090610ba45760405162461bcd60e51b8152600401610b9b9190615023565b60405180910390fd5b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b602082015281610be85760405162461bcd60e51b8152600401610b9b9190615023565b50600260009054906101000a90046001600160a01b03166001600160a01b031663b187bd266040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3757600080fd5b505afa158015610c4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6f9190615001565b6040518060600160405280602c8152602001615192602c913990610ca65760405162461bcd60e51b8152600401610b9b9190615023565b5060006001600160a01b037f00000000000000000000000007d142abcce99defa936e8e8c18595e5f30a109f1663d4fac45d30836040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260440160206040518083038186803b158015610d2057600080fd5b505afa158015610d34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d589190615078565b90508082111560405180604001604052806014815260200173696e73756666696369656e742062616c616e636560601b81525090610da95760405162461bcd60e51b8152600401610b9b9190615023565b506001600160a01b037f00000000000000000000000007d142abcce99defa936e8e8c18595e5f30a109f1663f3fef3a360006040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101859052604401602060405180830381600087803b158015610e2357600080fd5b505af1158015610e37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5b9190615001565b505050565b6000610e6a6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401610ea4929190614fea565b60206040518083038186803b158015610ebc57600080fd5b505afa158015610ed0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef49190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090610f365760405162461bcd60e51b8152600401610b9b9190615023565b50610a806f2a30b933b2ba20b63637b1b0ba34b7b760811b6133f2565b6000610f5d6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401610f97929190614fea565b60206040518083038186803b158015610faf57600080fd5b505afa158015610fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe79190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906110295760405162461bcd60e51b8152600401610b9b9190615023565b5061103b6110356132cc565b83613499565b6110556c5374726174656769737446656560981b83613524565b92915050565b60006110656133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b815260040161109f929190614fea565b60206040518083038186803b1580156110b757600080fd5b505afa1580156110cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ef9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906111315760405162461bcd60e51b8152600401610b9b9190615023565b506111438261113e611fdd565b613499565b611055695265736572766546656560b01b83613524565b60006111646133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b815260040161119e929190614fea565b60206040518083038186803b1580156111b657600080fd5b505afa1580156111ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ee9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906112305760405162461bcd60e51b8152600401610b9b9190615023565b50610a8061353b565b60006112436133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b815260040161127d929190614fea565b60206040518083038186803b15801561129557600080fd5b505afa1580156112a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cd9190615001565b6040518060400160405280601381526020016000805160206151be8339815191528152509061130f5760405162461bcd60e51b8152600401610b9b9190615023565b50611055681119589d131a5b5a5d60ba1b83613524565b6d506572666f726d616e636546656560901b600052603d6020527fbadb955f4a57baa7811abc9bcd6809eb9d3b80456cae1a7ea27f30fddfd0c0a65490565b6002546000906001600160a01b031633148061140e57506113846133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b81526004016113be929190614fea565b60206040518083038186803b1580156113d657600080fd5b505afa1580156113ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061140e9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906114505760405162461bcd60e51b8152600401610b9b9190615023565b50600061145b610a85565b905047838110156115d7576001600160a01b03821661147e575060009392505050565b6000826001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b1580156114b957600080fd5b505afa1580156114cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f19190615078565b905060006114ff83876150a7565b9050818111156115155750600095945050505050565b6000611532611522611f9c565b61152c84866150a7565b9061359b565b9050600061154082856150a7565b604051632e1a7d4d60e01b8152600481018290529091506001600160a01b03871690632e1a7d4d90602401602060405180830381600087803b15801561158557600080fd5b505af1158015611599573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115bd9190615001565b506115ca600054826135ba565b6000555061169592505050565b60006001600160a01b0383161561165c57826001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b15801561162157600080fd5b505afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190615078565b90505b60015460009061166c83856150be565b61167691906150be565b9050600061168487836150a7565b905061169081846135de565b505050505b6002546116ab906001600160a01b0316856137f5565b5060019392505050565b6000806116c964109bdd5b9960da1b61382b565b90506116d361384f565b919050565b60006116e26133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b815260040161171c929190614fea565b60206040518083038186803b15801561173457600080fd5b505afa158015611748573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176c9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906117ae5760405162461bcd60e51b8152600401610b9b9190615023565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b60208201526706f05b59d3b200008311156117fd5760405162461bcd60e51b8152600401610b9b9190615023565b5061105564109bdd5b9960da1b83613524565b6002546000906001600160a01b03163314806118ba575061182f6133ce565b6001600160a01b03166391d148546a6d61696e74656e616e636560a81b336040518363ffffffff1660e01b815260040161186a929190614fea565b60206040518083038186803b15801561188257600080fd5b505afa158015611896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ba9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906118fc5760405162461bcd60e51b8152600401610b9b9190615023565b50610a8061390d565b600061190f6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401611949929190614fea565b60206040518083038186803b15801561196157600080fd5b505afa158015611975573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119999190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906119db5760405162461bcd60e51b8152600401610b9b9190615023565b5060006119e6610a85565b90506001600160a01b0381166119ff5750600092915050565b82816001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3957600080fd5b505afa158015611a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a719190615078565b1015611a805750600092915050565b600047604051632e1a7d4d60e01b8152600481018690529091506001600160a01b03831690632e1a7d4d90602401602060405180830381600087803b158015611ac857600080fd5b505af1158015611adc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b009190615001565b5047611b0c82826150a7565b600080828254611b1c91906150a7565b9091555060019695505050505050565b603f54610100900460ff16611b4757603f5460ff1615611b4b565b303b155b611bae5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610b9b565b603f54610100900460ff16158015611bd057603f805461ffff19166101011790555b611bdc85858585613bc4565b8015611bee57603f805461ff00191690555b5050505050565b6000611bff6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401611c39929190614fea565b60206040518083038186803b158015611c5157600080fd5b505afa158015611c65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c899190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090611ccb5760405162461bcd60e51b8152600401610b9b9190615023565b50610a80613d72565b6000611cde6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401611d18929190614fea565b60206040518083038186803b158015611d3057600080fd5b505afa158015611d44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d689190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090611daa5760405162461bcd60e51b8152600401610b9b9190615023565b5067537472617465677960c01b600052603c60209081527f15bdd40257915f753934b43755984618aeb2ae4fff096845769c2bb729e989be546040805180820190915260168152751059191c995cdcc81a5cc8185b1c9958591e481cd95d60521b928101929092526001600160a01b031615611e395760405162461bcd60e51b8152600401610b9b9190615023565b506040805180820190915260188152771e995c9bc81859191c995cdcc81b9bdd08185b1b1bddd95960421b60208201526001600160a01b038316611e905760405162461bcd60e51b8152600401610b9b9190615023565b50611ea667537472617465677960c01b83613de6565b50611eaf613d72565b5060006001600160a01b0316826001600160a01b0316631fe4a6866040518163ffffffff1660e01b815260040160206040518083038186803b158015611ef457600080fd5b505afa158015611f08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2c91906150d6565b6001600160a01b03161415604051806040016040528060188152602001771e995c9bc81859191c995cdcc81b9bdd08185b1b1bddd95960421b81525090611f865760405162461bcd60e51b8152600401610b9b9190615023565b50600192915050565b6000611055600583613e72565b6f2a30b933b2ba20b63637b1b0ba34b7b760811b600052603d6020527f0a3006de449e2f6da78c92d58370b3dd2ef3b1e1963fc373ed67d46ced02eb8f5490565b6c5374726174656769737446656560981b600052603d6020527f9991a201724620367b875943d3f1e2d8a65d067f05ccd6a37af85ae33cf679e95490565b681119589d131a5b5a5d60ba1b600052603d6020527fed35bbff007ae1d09677de3676c3cb1b0411569c4ab270913b3fb2a177a703195490565b64109bdd5b9960da1b600052603d6020527fcba6df5081839cab6ded1888d57f2772386c9d156438bb2faa7b07ec10c244705490565b6002546001600160a01b031633148061213157506120a76133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b81526004016120e1929190614fea565b60206040518083038186803b1580156120f957600080fd5b505afa15801561210d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121319190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906121735760405162461bcd60e51b8152600401610b9b9190615023565b5061217c613e87565b50600254612193906001600160a01b0316476137f5565b565b600061219f6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b81526004016121d9929190614fea565b60206040518083038186803b1580156121f157600080fd5b505afa158015612205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122299190615001565b6040518060400160405280601381526020016000805160206151be8339815191528152509061226b5760405162461bcd60e51b8152600401610b9b9190615023565b50610a80695265736572766546656560b01b6133f2565b600061228c6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b81526004016122c6929190614fea565b60206040518083038186803b1580156122de57600080fd5b505afa1580156122f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123169190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906123585760405162461bcd60e51b8152600401610b9b9190615023565b50610a806c5374726174656769737446656560981b6133f2565b60008061238e6c5374726174656769737446656560981b61382b565b90506116d361239b6132cc565b82613499565b6060610a806005613f5e565b60006123b76133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b81526004016123f1929190614fea565b60206040518083038186803b15801561240957600080fd5b505afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906124835760405162461bcd60e51b8152600401610b9b9190615023565b50610a8067537472617465677960c01b61400d565b60006124ae67537472617465677960c01b6140bf565b60006124b8610a85565b90506001600160a01b0381161561265c576124d161390d565b50806001600160a01b031663fc0e74d16040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561250d57600080fd5b505af1158015612521573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125459190615001565b50806001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561258157600080fd5b505af1158015612595573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b99190615078565b506000816001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b1580156125f557600080fd5b505afa158015612609573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262d9190615078565b9050801561265a5761264160058383614168565b50806001600082825461265491906150be565b90915550505b505b61266461353b565b506000808055600381905567537472617465677960c01b90819052603a6020527fa4caf68bc3013a9a5274c5d8968485ae05b8c28e9f50493f41acc96b22818c23546001600160a01b0316906126ba9082613de6565b506001600160a01b03811615611055576126d2613d72565b5092915050565b60006126e36133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b815260040161271d929190614fea565b60206040518083038186803b15801561273557600080fd5b505afa158015612749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276d9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906127af5760405162461bcd60e51b8152600401610b9b9190615023565b506110556f2a30b933b2ba20b63637b1b0ba34b7b760811b83613524565b60006127d76133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401612811929190614fea565b60206040518083038186803b15801561282957600080fd5b505afa15801561283d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128619190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906128a35760405162461bcd60e51b8152600401610b9b9190615023565b50610a8064109bdd5b9960da1b6133f2565b6002546000906001600160a01b031633148061295e57506128d46133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b815260040161290e929190614fea565b60206040518083038186803b15801561292657600080fd5b505afa15801561293a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295e9190615001565b6040518060400160405280601381526020016000805160206151be833981519152815250906129a05760405162461bcd60e51b8152600401610b9b9190615023565b50610a80613e87565b60006129b36133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b81526004016129ed929190614fea565b60206040518083038186803b158015612a0557600080fd5b505afa158015612a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a3d9190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090612a7f5760405162461bcd60e51b8152600401610b9b9190615023565b5061105567537472617465677960c01b8362069780614186565b60004781612aa5610a85565b6001600160a01b03161415612ab957919050565b600060015460005483612acc91906150be565b612ad691906150be565b90508060035411612af557600354612aee90826150a7565b9250505090565b60009250505090565b6000612b086133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401612b42929190614fea565b60206040518083038186803b158015612b5a57600080fd5b505afa158015612b6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b929190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090612bd45760405162461bcd60e51b8152600401610b9b9190615023565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b60208201526706f05b59d3b20000831115612c235760405162461bcd60e51b8152600401610b9b9190615023565b506110556d506572666f726d616e636546656560901b83613524565b6000806116c96f2a30b933b2ba20b63637b1b0ba34b7b760811b61382b565b6002546001600160a01b0316331480612d055750612c7a6133ce565b6001600160a01b03166391d148546a6d61696e74656e616e636560a81b336040518363ffffffff1660e01b8152600401612cb5929190614fea565b60206040518083038186803b158015612ccd57600080fd5b505afa158015612ce1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d059190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090612d475760405162461bcd60e51b8152600401610b9b9190615023565b5061219361384f565b600080612d69695265736572766546656560b01b61382b565b90506116d38161113e611fdd565b600080612d8f681119589d131a5b5a5d60ba1b61382b565b90506000612da88260005461359b90919063ffffffff16565b90508060035410612dbb57612dbb614203565b50919050565b6000612dcb6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401612e05929190614fea565b60206040518083038186803b158015612e1d57600080fd5b505afa158015612e31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e559190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090612e975760405162461bcd60e51b8152600401610b9b9190615023565b50610a806d506572666f726d616e636546656560901b6133f2565b6000612ebc6133ce565b6001600160a01b03166391d1485469676f7665726e616e636560b01b336040518363ffffffff1660e01b8152600401612ef6929190614fea565b60206040518083038186803b158015612f0e57600080fd5b505afa158015612f22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f469190615001565b6040518060400160405280601381526020016000805160206151be83398151915281525090612f885760405162461bcd60e51b8152600401610b9b9190615023565b50610a80681119589d131a5b5a5d60ba1b6133f2565b6000610a806d506572666f726d616e636546656560901b61382b565b60008080612fc9600585614220565b91509150816040518060400160405280601781526020017f537472617465677920646f6573206e6f74206578697374000000000000000000815250906130225760405162461bcd60e51b8152600401610b9b9190615023565b506000849050806001600160a01b0316634641257d6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561306357600080fd5b505af1158015613077573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309b9190615078565b506000816001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156130d957600080fd5b505af11580156130ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131119190615078565b600154909150808210613128576000600155613136565b61313282826150a7565b6001555b8382111561322157600061314a85846150a7565b9050600061316861316361315c611326565b849061359b565b614247565b905080156131ea576131ea81866001600160a01b0316631fe4a6866040518163ffffffff1660e01b815260040160206040518083038186803b1580156131ad57600080fd5b505afa1580156131c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131e591906150d6565b6142a7565b60405160009650869083907f6c8433a8e155f0af04dba058d4e4695f7da554578963d876bdf4a6d8d6399d9c908390a3505061322e565b61322b82856150a7565b93505b826001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b15801561326757600080fd5b505afa15801561327b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061329f9190615078565b6132b4576132ae600584614341565b506132c2565b6132c060058486614168565b505b5095945050505050565b695265736572766546656560b01b600052603d6020527fa61f8e25cb35ba15fc70bbd3ba789d53bf34a4deddb38a43a213af3182d35aae5490565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a721906024015b60206040518083038186803b15801561335857600080fd5b505afa15801561336c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105591906150d6565b6040516321f8a72160e01b81526b7661756c745265736572766560a01b60048201526000906001600160a01b038316906321f8a72190602401613340565b7f00000000000000000000000083174c049116271f64a661b8371658792f62e36390565b6000818152603e6020908152604080832054815180830190925260128252710646561646c696e65206d75737420626520360741b928201929092529061344b5760405162461bcd60e51b8152600401610b9b9190615023565b506000828152603e60209081526040808320839055603b9091528082208290555183917f90fb84ad67dd037c388289337bb80b61b8605d38ba9a875dc38b5600909d172f91a2506001919050565b670de0b6b3a76400006134ac82846150be565b11156135205760405162461bcd60e51b815260206004820152603760248201527f73756d206f6620737472617465676973742066656520616e642072657365727660448201527f65206665652073686f756c642062652062656c6f7720310000000000000000006064820152608401610b9b565b5050565b600061353483836203f480614356565b9392505050565b60045460009060ff1661354e5750600090565b6004805460ff19169055613560610a85565b6001600160a01b03167f274ec28d31430170ad5dd350f8e7505ffab078c309300878c710383ae4cbed4960405160405180910390a250600190565b6000670de0b6b3a76400006135b083856150f3565b6135349190615112565b6000818311156135d5576135ce82846150a7565b9050611055565b50600092915050565b60045460009060ff166135f357506000611055565b60006135fd611f9c565b90506000613609610a85565b90506000613615612055565b90506000613623878561359b565b90506000841561363c5761363783866150be565b61363f565b60005b9050670de0b6b3a764000081116136565780613660565b670de0b6b3a76400005b9050600085841161367a5761367584876150a7565b61367d565b60005b9050613689898361359b565b88111561372f57600061369c848a6150a7565b604051632e1a7d4d60e01b8152600481018290529091506001600160a01b03871690632e1a7d4d90602401602060405180830381600087803b1580156136e157600080fd5b505af11580156136f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137199190615001565b50613726600054826135ba565b600055506137e6565b613739898261359b565b8810156137e657600061374c89856150a7565b905061375886826137f5565b8060008082825461376991906150be565b92505081905550856001600160a01b031663d0e30db06040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156137ab57600080fd5b505af11580156137bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137e39190615001565b50505b50600198975050505050505050565b6040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015610e5b573d6000803e3d6000fd5b6000613836826140bf565b6000828152603b60205260409020546126d283826143ac565b60045460ff1661385b57565b6000613865610a85565b6001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b15801561389d57600080fd5b505afa1580156138b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138d59190615078565b90506000600154826138e44790565b6138ee91906150be565b6138f891906150be565b905080613903575050565b610e5b81836135de565b600080613918610a85565b90506001600160a01b03811661393057600091505090565b806001600160a01b0316634641257d6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561396b57600080fd5b505af115801561397f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139a39190615078565b50600080826001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b1580156139e057600080fd5b505afa1580156139f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a189190615078565b6000546003549192509081831115613aa9576000613a3683856150a7565b905081811115613a69578115613a5757613a5082826150a7565b9050600091505b613a608161440d565b95509050613a76565b613a7381836150a7565b91505b60405160009082907f6c8433a8e155f0af04dba058d4e4695f7da554578963d876bdf4a6d8d6399d9c908390a350613b3a565b81831015613b2e576000613abd84846150a7565b9050613ac981836150be565b91506000613ad561201b565b90506000613ae3858361359b565b905080841115613af957613af6846144d1565b93505b60405183906000907f6c8433a8e155f0af04dba058d4e4695f7da554578963d876bdf4a6d8d6399d9c908290a3505050613b3a565b60019550505050505090565b80600381905550846001600160a01b031663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b158015613b7a57600080fd5b505afa158015613b8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb29190615078565b6000558315613b2e57613b2e846146fc565b60408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b6020820152670de0b6b3a7640000841115613c125760405162461bcd60e51b8152600401610b9b9190615023565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b6020820152670de0b6b3a7640000831115613c615760405162461bcd60e51b8152600401610b9b9190615023565b5060408051808201909152600e81526d1a5b9d985b1a5908185b5bdd5b9d60921b60208201526706f05b59d3b20000821115613cb05760405162461bcd60e51b8152600401610b9b9190615023565b50600280546001600160a01b0319166001600160a01b038616179055613ce2681119589d131a5b5a5d60ba1b846143ac565b50613d006f2a30b933b2ba20b63637b1b0ba34b7b760811b836143ac565b50613d1364109bdd5b9960da1b826143ac565b50613d32695265736572766546656560b01b662386f26fc100006143ac565b50613d556c5374726174656769737446656560981b67016345785d8a00006143ac565b50611bee6d506572666f726d616e636546656560901b60006143ac565b600080613d7d610a85565b90506001600160a01b038116613d9557600091505090565b6004805460ff191660011790556040516001600160a01b038216907f652f053fc39779b70b29678135ade972fcb79966fc68fcb77c996b1aa4fd9afb90600090a2613dde61384f565b600191505090565b6000828152603c6020908152604080832080546001600160a01b03198082166001600160a01b03888116918217909455603a86528487208054909216909155603e85528386208690558351929091168083529382015285917fc4a957706c639829ad54381b04930c464db6c7ffdc09d2b4b1acc9ee34fb926191015b60405180910390a2509092915050565b6000613534836001600160a01b038416614743565b600080613e92610a85565b90506001600160a01b038116613eaa57600091505090565b613eb261390d565b506000479050816001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613ef357600080fd5b505af1158015613f07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f2b9190615078565b50476000613f3983836150a7565b9050613f47600054826135ba565b600055613f5261353b565b50600194505050505090565b60606000613f6b836147b3565b905060008167ffffffffffffffff811115613f8857613f88615134565b604051908082528060200260200182016040528015613fb1578160200160208202803683370190505b50905060005b8281101561400557613fc985826147be565b828281518110613fdb57613fdb61514a565b6001600160a01b039092166020928302919091019091015280613ffd81615160565b915050613fb7565b509392505050565b6000818152603e6020908152604080832054815180830190925260128252710646561646c696e65206d75737420626520360741b92820192909252906140665760405162461bcd60e51b8152600401610b9b9190615023565b506000828152603e60209081526040808320839055603a90915280822080546001600160a01b03191690555183917f90fb84ad67dd037c388289337bb80b61b8605d38ba9a875dc38b5600909d172f91a2506001919050565b6000603e6000838152602001908152602001600020549050804210156040518060600160405280602181526020016151de60219139906141125760405162461bcd60e51b8152600401610b9b9190615023565b5060408051808201909152600d81526c0646561646c696e65206973203609c1b6020820152816141555760405162461bcd60e51b8152600401610b9b9190615023565b50506000908152603e6020526040812055565b600061417e846001600160a01b038516846147d4565b949350505050565b600061419284836147f1565b6000848152603a602090815260409182902080546001600160a01b0319166001600160a01b038716908117909155825190815290810184905285917fd46e58ee9dc1ae703349f8c09c19f23213a531b4d57f00cfd4a5a6cb6519668d91015b60405180910390a25060019392505050565b6003546000614211826144d1565b90508082146135205760035550565b6000808080614238866001600160a01b0387166148cb565b909450925050505b9250929050565b60008061425561315c611fdd565b9050600061426b6142646132cc565b859061359b565b905060008161427a84876150a7565b61428491906150a7565b905061428f82614905565b801561429e5761429e816149a8565b50909392505050565b6001600160a01b0381166142b9575050565b6002546040516317a790f160e11b81526001600160a01b0383811660048301526024820185905290911690632f4f21e29084906044016020604051808303818588803b15801561430857600080fd5b505af115801561431c573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e5b9190615078565b6000613534836001600160a01b038416614a12565b600061436284836147f1565b6000848152603b6020908152604091829020859055815185815290810184905285917f0e6790002e78fb96ff1fdfe3a3bb2a86489d3f3923372c1fe5b6b1fed071eed491016141f1565b6000828152603d60209081526040808320805490859055603b8352818420849055603e835281842084905581518181529283018590529185917fcc0bafe2accb565ea70674bf4b2555e49a47d410fb9932dfab3e5f41855d0a2f9101613e62565b600080600061441d614264611326565b9050804710156144b05761442f610a85565b6001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040161445c91815260200190565b602060405180830381600087803b15801561447657600080fd5b505af115801561448a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144ae9190615001565b505b60006144bb82614247565b90506144c782866150a7565b9590945092505050565b6000806001600160a01b037f00000000000000000000000007d142abcce99defa936e8e8c18595e5f30a109f1663d4fac45d30836040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260440160206040518083038186803b15801561454b57600080fd5b505afa15801561455f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145839190615078565b90508083111561459b5761459681614a2f565b6146f5565b60405163019262d360e41b81523060048201527f00000000000000000000000007d142abcce99defa936e8e8c18595e5f30a109f6001600160a01b0316906319262d309060240160206040518083038186803b1580156145fa57600080fd5b505afa15801561460e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146329190615001565b156146f5576001600160a01b037f00000000000000000000000007d142abcce99defa936e8e8c18595e5f30a109f1663f3fef3a360006040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101869052604401602060405180830381600087803b1580156146b057600080fd5b505af11580156146c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146e89190615001565b50600092506146f561384f565b5090919050565b61474081614708610a85565b6001600160a01b0316631fe4a6866040518163ffffffff1660e01b815260040160206040518083038186803b1580156131ad57600080fd5b50565b60008181526002830160205260408120548015158061476757506147678484614cdf565b6135345760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b657900006044820152606401610b9b565b600061105582614ceb565b6000806147cb8484614cf6565b50949350505050565b6000828152600284016020526040812082905561417e8484614d05565b603e600083815260200190815260200160002054600014604051806040016040528060128152602001710646561646c696e65206d75737420626520360741b815250906148515760405162461bcd60e51b8152600401610b9b9190615023565b5060408051808201909152601881527f64656c6179206265206174206c6561737420332064617973000000000000000060208201526203f4808210156148aa5760405162461bcd60e51b8152600401610b9b9190615023565b506148b581426150be565b6000928352603e60205260409092209190915550565b60008181526002830160205260408120548190806148fa576148ed8585614cdf565b9250600091506142409050565b600192509050614240565b6040516311f9fbc960e21b815260006004820152602481018290527f00000000000000000000000007d142abcce99defa936e8e8c18595e5f30a109f6001600160a01b0316906347e7ef249083906044016020604051808303818588803b15801561496f57600080fd5b505af1158015614983573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906135209190615001565b6149da7f000000000000000000000000139c15e21b0f6e43fc397face5de5b7d5ae6874a6001600160a01b0316614d11565b6001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015613520573d6000803e3d6000fd5b600081815260028301602052604081208190556135348383614d4b565b6000614a39610a85565b6001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b158015614a7357600080fd5b505af1158015614a87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614aab9190615078565b90506000614abb600054836135ba565b60405163019262d360e41b81523060048201529091507f00000000000000000000000007d142abcce99defa936e8e8c18595e5f30a109f6001600160a01b0316906319262d309060240160206040518083038186803b158015614b1d57600080fd5b505afa158015614b31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b559190615001565b15614cd157808310614c18576001600160a01b037f00000000000000000000000007d142abcce99defa936e8e8c18595e5f30a109f1663f3fef3a360006040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101849052604401602060405180830381600087803b158015614bda57600080fd5b505af1158015614bee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c129190615001565b50614cd1565b8215614cd1576001600160a01b037f00000000000000000000000007d142abcce99defa936e8e8c18595e5f30a109f1663f3fef3a360006040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101869052604401602060405180830381600087803b158015614c9757600080fd5b505af1158015614cab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614ccf9190615001565b505b614cd961353b565b50505050565b60006135348383614d57565b600061105582614d6f565b60008080806142388686614d79565b60006135348383614da4565b6040516321f8a72160e01b815267747265617375727960c01b60048201526000906001600160a01b038316906321f8a72190602401613340565b60006135348383614df3565b60008181526001830160205260408120541515613534565b6000611055825490565b60008080614d878585614ee6565b600081815260029690960160205260409095205494959350505050565b6000818152600183016020526040812054614deb57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611055565b506000611055565b60008181526001830160205260408120548015614edc576000614e176001836150a7565b8554909150600090614e2b906001906150a7565b9050818114614e90576000866000018281548110614e4b57614e4b61514a565b9060005260206000200154905080876000018481548110614e6e57614e6e61514a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614ea157614ea161517b565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611055565b6000915050611055565b600061353483836000826000018281548110614f0457614f0461514a565b9060005260206000200154905092915050565b600060208284031215614f2957600080fd5b5035919050565b6001600160a01b038116811461474057600080fd5b60008060008060808587031215614f5b57600080fd5b8435614f6681614f30565b966020860135965060408601359560600135945092505050565b600060208284031215614f9257600080fd5b813561353481614f30565b6020808252825182820181905260009190848201906040850190845b81811015614fde5783516001600160a01b031683529284019291840191600101614fb9565b50909695505050505050565b9182526001600160a01b0316602082015260400190565b60006020828403121561501357600080fd5b8151801515811461353457600080fd5b600060208083528351808285015260005b8181101561505057858101830151858201604001528201615034565b81811115615062576000604083870101525b50601f01601f1916929092016040019392505050565b60006020828403121561508a57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000828210156150b9576150b9615091565b500390565b600082198211156150d1576150d1615091565b500190565b6000602082840312156150e857600080fd5b815161353481614f30565b600081600019048311821515161561510d5761510d615091565b500290565b60008261512f57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060001982141561517457615174615091565b5060010190565b634e487b7160e01b600052603160045260246000fdfe506f6f6c206d7573742062652070617573656420746f2077697468647261772066726f6d2072657365727665756e617574686f72697a65642061636365737300000000000000000000000000646561646c696e6520686173206e6f74206265656e207265616368656420796574a2646970667358221220fc706e7436a7324f36c875278d8608814f2e5d3165c906971dbf304d8b43a28e64736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f88864b5d747961eb1caf88d395d13aca8274c9f
-----Decoded View---------------
Arg [0] : controller (address): 0xf88864B5D747961EB1CAf88d395D13aCa8274C9F
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000f88864b5d747961eb1caf88d395d13aca8274c9f
Deployed Bytecode Sourcemap
121301:1367:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91020:108;;;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;199:32:1;;;181:51;;169:2;154:18;91020:108:0;;;;;;;;111022:132;;;;;;;;;;;;;:::i;97430:419::-;;;;;;;;;;-1:-1:-1;97430:419:0;;;;;:::i;:::-;;:::i;:::-;;104848:141;;;;;;;;;;;;;:::i;:::-;;;818:14:1;;811:22;793:41;;781:2;766:18;104848:141:0;653:187:1;102087:233:0;;;;;;;;;;-1:-1:-1;102087:233:0;;;;;:::i;:::-;;:::i;105173:221::-;;;;;;;;;;-1:-1:-1;105173:221:0;;;;;:::i;:::-;;:::i;83946:50::-;;;;;;;;;;-1:-1:-1;83946:50:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;1176:25:1;;;1164:2;1149:18;83946:50:0;1030:177:1;82756:19:0;;;;;;;;;;-1:-1:-1;82756:19:0;;;;-1:-1:-1;;;;;82756:19:0;;;98228:116;;;;;;;;;;;;;:::i;103128:152::-;;;;;;;;;;-1:-1:-1;103128:152:0;;;;;:::i;:::-;;:::i;111673:122::-;;;;;;;;;;;;;:::i;93038:49::-;;;;;;;;;;;;;;;95428:1425;;;;;;;;;;-1:-1:-1;95428:1425:0;;;;;:::i;:::-;;:::i;106708:157::-;;;;;;;;;;;;;:::i;84287:44::-;;;;;;;;;;-1:-1:-1;84287:44:0;;;;;:::i;:::-;;;;;;;;;;;;;;106230:208;;;;;;;;;;-1:-1:-1;106230:208:0;;;;;:::i;:::-;;:::i;110678:99::-;;;;;;;;;;;;;:::i;107202:474::-;;;;;;;;;;-1:-1:-1;107202:474:0;;;;;:::i;:::-;;:::i;121552:255::-;;;;;;;;;;-1:-1:-1;121552:255:0;;;;;:::i;:::-;;:::i;97994:112::-;;;;;;;;;;;;;:::i;98601:468::-;;;;;;;;;;-1:-1:-1;98601:468:0;;;;;:::i;:::-;;:::i;92936:47::-;;;;;;;;;;;;92977:6;92936:47;;109863:199;;;;;;;;;;-1:-1:-1;109863:199:0;;;;;:::i;:::-;;:::i;112278:126::-;;;;;;;;;;;;;:::i;110894:120::-;;;;;;;;;;;;;:::i;112511:112::-;;;;;;;;;;;;;:::i;111908:103::-;;;;;;;;;;;;;:::i;96970:157::-;;;;;;;;;;;;;:::i;105868:129::-;;;;;;;;;;;;;:::i;82708:41::-;;;;;;;;;;;;;;;;102812:135;;;;;;;;;;;;;:::i;102564:240::-;;;;;;;;;;;;;:::i;92877:52::-;;;;;;;;;;;;92923:6;92877:52;;121815:101;;;;;;;;;;-1:-1:-1;121870:7:0;121815:101;;109064:149;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;100759:127::-;;;;;;;;;;;;;:::i;99675:1076::-;;;;;;;;;;;;;:::i;104176:212::-;;;;;;;;;;-1:-1:-1;104176:212:0;;;;;:::i;:::-;;:::i;106873:118::-;;;;;;;;;;;;;:::i;110276:130::-;;;;;;;;;;;;;:::i;99272:166::-;;;;;;;;;;-1:-1:-1;99272:166:0;;;;;:::i;:::-;;:::i;84063:50::-;;;;;;;;;;-1:-1:-1;84063:50:0;;;;;:::i;:::-;;;;;;;;;;;;;;109379:476;;;;;;;;;;;;;:::i;82815:26::-;;;;;;;;;;-1:-1:-1;82815:26:0;;;;;;;;101088:286;;;;;;;;;;-1:-1:-1;101088:286:0;;;;;:::i;:::-;;:::i;104638:202::-;;;;;;;;;;;;;:::i;93094:38::-;;;;;;;;;;;;;;;94886:147;;;:::i;105632:228::-;;;;;;;;;;;;;:::i;103516:323::-;;;;;;;;;;;;;:::i;101751:137::-;;;;;;;;;;;;;:::i;103847:127::-;;;;;;;;;;;;;:::i;83888:51::-;;;;;;;;;;-1:-1:-1;83888:51:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;83888:51:0;;;101620:123;;;;;;;;;;;;;:::i;107684:1372::-;;;;;;;;;;-1:-1:-1;107684:1372:0;;;;;:::i;:::-;;:::i;111282:114::-;;;;;;;;;;;;;:::i;84005:51::-;;;;;;;;;;-1:-1:-1;84005:51:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;84005:51:0;;;92992:39;;;;;;;;;;;;;;;82670:31;;;;;;;;;;;;;;;;82784:24;;;;;;;;;;;;;;;;91020:108;91074:12;91106:14;:12;:14::i;:::-;91099:21;;91020:108;:::o;111022:132::-;-1:-1:-1;;;111075:9:0;111114:31;:16;:31;;;;-1:-1:-1;;;;;111114:31:0;;111022:132::o;97430:419::-;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;97539:20:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;97539:20:0::1;::::0;::::1;::::0;97527:10;97519:41:::1;;;;-1:-1:-1::0;;;97519:41:0::1;;;;;;;;:::i;:::-;;97589:4;;;;;;;;;-1:-1:-1::0;;;;;97589:4:0::1;-1:-1:-1::0;;;;;97579:24:0::1;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;97607:21;;;;;;;;;;;;;;;;;97571:58;;;;;-1:-1:-1::0;;;97571:58:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;97640:23:0::1;-1:-1:-1::0;;;;;97666:7:0::1;:18;;97693:4;97640:23:::0;97666:50:::1;::::0;-1:-1:-1;;;;;;97666:50:0::1;::::0;;;;;;-1:-1:-1;;;;;5012:15:1;;;97666:50:0::1;::::0;::::1;4994:34:1::0;5064:15;;5044:18;;;5037:43;4929:18;;97666:50:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;97640:76;;97745:15;97735:6;:25;;97762:26;;;;;;;;;;;;;-1:-1:-1::0;;;97762:26:0::1;;::::0;97727:62:::1;;;;;-1:-1:-1::0;;;97727:62:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;97800:7:0::1;:16;;121870:7:::0;97800:41:::1;::::0;-1:-1:-1;;;;;;97800:41:0::1;::::0;;;;;;-1:-1:-1;;;;;5472:32:1;;;97800:41:0::1;::::0;::::1;5454:51:1::0;5521:18;;;5514:34;;;5427:18;;97800:41:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;97508:341;97430:419:::0;:::o;104848:141::-;104914:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;104938:43:::1;-1:-1:-1::0;;;104938:19:0::1;:43::i;102087:233::-:0;102176:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;102193:54:::1;102213:15;:13;:15::i;:::-;102230:16;102193:19;:54::i;:::-;102265:47;-1:-1:-1::0;;;102295:16:0::1;102265:8;:47::i;:::-;102258:54:::0;102087:233;-1:-1:-1;;102087:233:0:o;105173:221::-;105256:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;105273:54:::1;105293:13;105308:18;:16;:18::i;:::-;105273:19;:54::i;:::-;105345:41;-1:-1:-1::0;;;105372:13:0::1;105345:8;:41::i;98228:116::-:0;98291:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;98315:21:::1;:19;:21::i;103128:152::-:0;103209:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;103233:39:::1;-1:-1:-1::0;;;103259:12:0::1;103233:8;:39::i;111673:122::-:0;-1:-1:-1;;;111723:7:0;111750:37;:15;:37;;;;;111673:122::o;95428:1425::-;93333:4;;95510;;-1:-1:-1;;;;;93333:4:0;93319:10;:18;;:74;;;93341:14;:12;:14::i;:::-;-1:-1:-1;;;;;93341:22:0;;-1:-1:-1;;;93382:10:0;93341:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93408:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;93408:25:0;;;93297:147;;;;;-1:-1:-1;;;93297:147:0;;;;;;;;:::i;:::-;;95527:18:::1;95548:13;:11;:13::i;:::-;95527:34:::0;-1:-1:-1;122636:21:0;95642:29;;::::1;95638:1150;;;-1:-1:-1::0;;;;;95692:31:0;::::1;95688:49;;-1:-1:-1::0;95732:5:0::1;::::0;102087:233;-1:-1:-1;;;102087:233:0:o;95688:49::-:1;95752:17;95772:8;-1:-1:-1::0;;;;;95772:16:0::1;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;95752:38:::0;-1:-1:-1;95805:26:0::1;95834:29;95843:20:::0;95834:6;:29:::1;:::i;:::-;95805:58;;95905:9;95884:18;:30;95880:48;;;-1:-1:-1::0;95923:5:0::1;::::0;102087:233;-1:-1:-1;;;;;102087:233:0:o;95880:48::-:1;96016:17;96036:65;96079:21;:19;:21::i;:::-;96037:30;96049:18:::0;96037:9;:30:::1;:::i;:::-;96036:42:::0;::::1;:65::i;:::-;96016:85:::0;-1:-1:-1;96116:20:0::1;96139:21;96016:85:::0;96139:9;:21:::1;:::i;:::-;96175:31;::::0;-1:-1:-1;;;96175:31:0;;::::1;::::0;::::1;1176:25:1::0;;;96116:44:0;;-1:-1:-1;;;;;;96175:17:0;::::1;::::0;::::1;::::0;1149:18:1;;96175:31:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;96240:52;96261:16;;96279:12;96240:20;:52::i;:::-;96221:16;:71:::0;-1:-1:-1;95638:1150:0::1;::::0;-1:-1:-1;;;95638:1150:0::1;;96325:27;-1:-1:-1::0;;;;;96375:31:0;::::1;::::0;96371:105:::1;;96457:8;-1:-1:-1::0;;;;;96447:27:0::1;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;96425:51;;96371:105;96596:26;::::0;96491:23:::1;::::0;96517:59:::1;96557:19:::0;96517:20;:59:::1;:::i;:::-;:105;;;;:::i;:::-;96491:131:::0;-1:-1:-1;96637:36:0::1;96676:24;96694:6:::0;96491:131;96676:24:::1;:::i;:::-;96637:63;;96715:61;96726:28;96756:19;96715:10;:61::i;:::-;;96310:478;;;95638:1150;96810:4;::::0;96800:23:::1;::::0;-1:-1:-1;;;;;96810:4:0::1;96816:6:::0;96800:9:::1;:23::i;:::-;-1:-1:-1::0;96841:4:0::1;::::0;95428:1425;-1:-1:-1;;;95428:1425:0:o;106708:157::-;106750:7;106770:13;106786:27;-1:-1:-1;;;106786:15:0;:27::i;:::-;106770:43;;106824:10;:8;:10::i;:::-;106852:5;106708:157;-1:-1:-1;106708:157:0:o;106230:208::-;106303:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;-1:-1:-1;106361:20:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;106361:20:0::1;::::0;::::1;::::0;92923:6:::1;106328:31:::0;::::1;;106320:62;;;;-1:-1:-1::0;;;106320:62:0::1;;;;;;;;:::i;:::-;;106400:30;-1:-1:-1::0;;;106421:8:0::1;106400;:30::i;110678:99::-:0;93552:4;;110735;;-1:-1:-1;;;;;93552:4:0;93538:10;:18;;:75;;;93560:14;:12;:14::i;:::-;-1:-1:-1;;;;;93560:22:0;;-1:-1:-1;;;93602:10:0;93560:53;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93628:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;93628:25:0;;;93516:148;;;;;-1:-1:-1;;;93516:148:0;;;;;;;;:::i;:::-;;110759:10:::1;:8;:10::i;107202:474::-:0;107281:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;107298:18:::1;107319:13;:11;:13::i;:::-;107298:34:::0;-1:-1:-1;;;;;;107347:31:0;::::1;107343:49;;-1:-1:-1::0;107387:5:0::1;::::0;102087:233;-1:-1:-1;;102087:233:0:o;107343:49::-:1;107428:6;107407:8;-1:-1:-1::0;;;;;107407:16:0::1;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:27;107403:45;;;-1:-1:-1::0;107443:5:0::1;::::0;102087:233;-1:-1:-1;;102087:233:0:o;107403:45::-:1;107459:18;122636:21:::0;107513:25:::1;::::0;-1:-1:-1;;;107513:25:0;;::::1;::::0;::::1;1176::1::0;;;107459:43:0;;-1:-1:-1;;;;;;107513:17:0;::::1;::::0;::::1;::::0;1149:18:1;;107513:25:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;122636:21:0;107623:23:::1;107636:10:::0;122636:21;107623:23:::1;:::i;:::-;107603:16;::::0;:43:::1;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;107664:4:0::1;::::0;107202:474;-1:-1:-1;;;;;;107202:474:0:o;121552:255::-;25491:13;;;;;;;:48;;25527:12;;;;25526:13;25491:48;;;26294:4;17067:19;:23;25507:16;25483:107;;;;-1:-1:-1;;;25483:107:0;;6156:2:1;25483:107:0;;;6138:21:1;6195:2;6175:18;;;6168:30;6234:34;6214:18;;;6207:62;-1:-1:-1;;;6285:18:1;;;6278:44;6339:19;;25483:107:0;5954:410:1;25483:107:0;25626:13;;;;;;;25625:14;25650:101;;;;25685:13;:20;;-1:-1:-1;;25720:19:0;;;;;25650:101;121742:57:::1;121754:5;121761:10;121773:17;121792:6;121742:11;:57::i;:::-;25781:14:::0;25777:68;;;25812:13;:21;;-1:-1:-1;;25812:21:0;;;25777:68;25198:654;121552:255;;;;:::o;97994:112::-;98055:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;98079:19:::1;:17;:19::i;98601:468::-:0;98690:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;-1:-1:-1;;;;98758:1:0::1;98715:31:::0;:16:::1;:31;::::0;;;;;;98762:25;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;98762:25:0;;::::1;::::0;;;;-1:-1:-1;;;;;98715:31:0::1;:45:::0;98707:81:::1;;;;-1:-1:-1::0;;;98707:81:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;98832:30:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;98832:30:0::1;::::0;::::1;::::0;-1:-1:-1;;;;;98807:23:0;::::1;98799:64;;;;-1:-1:-1::0;;;98799:64:0::1;;;;;;;;:::i;:::-;;98874:36;-1:-1:-1::0;;;98900:9:0::1;98874:10;:36::i;:::-;;98921:19;:17;:19::i;:::-;;99004:1;-1:-1:-1::0;;;;;98959:47:0::1;98969:9;-1:-1:-1::0;;;;;98959:31:0::1;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;98959:47:0::1;;;99008:30;;;;;;;;;;;;;-1:-1:-1::0;;;99008:30:0::1;;::::0;98951:88:::1;;;;;-1:-1:-1::0;;;98951:88:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;99057:4:0::1;::::0;98601:468;-1:-1:-1;;98601:468:0:o;109863:199::-;109980:7;110012:42;:28;110045:8;110012:32;:42::i;112278:126::-;-1:-1:-1;;;112330:7:0;112357:39;:15;:39;;;;;112278:126::o;110894:120::-;-1:-1:-1;;;110943:7:0;110970:36;:15;:36;;;;;110894:120::o;112511:112::-;-1:-1:-1;;;112556:7:0;112583:32;:15;:32;;;;;112511:112::o;111908:103::-;-1:-1:-1;;;111949:7:0;111976:27;:15;:27;;;;;111908:103::o;96970:157::-;93333:4;;-1:-1:-1;;;;;93333:4:0;93319:10;:18;;:74;;;93341:14;:12;:14::i;:::-;-1:-1:-1;;;;;93341:22:0;;-1:-1:-1;;;93382:10:0;93341:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93408:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;93408:25:0;;;93297:147;;;;;-1:-1:-1;;;93297:147:0;;;;;;;;:::i;:::-;;97043:26:::1;:24;:26::i;:::-;-1:-1:-1::0;97090:4:0::1;::::0;97080:39:::1;::::0;-1:-1:-1;;;;;97090:4:0::1;122636:21:::0;97080:9:::1;:39::i;:::-;96970:157::o:0;105868:129::-;105928:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;105952:37:::1;-1:-1:-1::0;;;105952:19:0::1;:37::i;102812:135::-:0;102875:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;102899:40:::1;-1:-1:-1::0;;;102899:19:0::1;:40::i;102564:240::-:0;102614:7;102634:24;102661:36;-1:-1:-1;;;102661:15:0;:36::i;:::-;102634:63;;102708:54;102728:15;:13;:15::i;:::-;102745:16;102708:19;:54::i;109064:149::-;109129:16;109165:40;:28;:38;:40::i;100759:127::-;100820:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;100844:34:::1;-1:-1:-1::0;;;100844:19:0::1;:34::i;99675:1076::-:0;99723:7;99743:31;-1:-1:-1;;;99743:16:0;:31::i;:::-;99785:18;99806:13;:11;:13::i;:::-;99785:34;-1:-1:-1;;;;;;99834:31:0;;;99830:594;;99882:10;:8;:10::i;:::-;;99907:8;-1:-1:-1;;;;;99907:17:0;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;99941:8;-1:-1:-1;;;;;99941:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;100126:32;100161:8;-1:-1:-1;;;;;100161:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;100126:53;-1:-1:-1;100198:28:0;;100194:219;;100247:77;:28;100288:8;100299:24;100247:32;:77::i;:::-;;100373:24;100343:26;;:54;;;;;;;:::i;:::-;;;;-1:-1:-1;;100194:219:0;99867:557;99830:594;100434:21;:19;:21::i;:::-;-1:-1:-1;100485:1:0;100466:20;;;100497:9;:13;;;-1:-1:-1;;;100543:31:0;;;;:16;:31;;;;-1:-1:-1;;;;;100543:31:0;;100585:38;;100543:31;100585:10;:38::i;:::-;-1:-1:-1;;;;;;100640:25:0;;;100636:77;;100682:19;:17;:19::i;:::-;;100732:11;99675:1076;-1:-1:-1;;99675:1076:0:o;104176:212::-;104298:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;104327:53:::1;-1:-1:-1::0;;;104360:19:0::1;104327:8;:53::i;106873:118::-:0;106928:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;106952:31:::1;-1:-1:-1::0;;;106952:19:0::1;:31::i;110276:130::-:0;93333:4;;110348;;-1:-1:-1;;;;;93333:4:0;93319:10;:18;;:74;;;93341:14;:12;:14::i;:::-;-1:-1:-1;;;;;93341:22:0;;-1:-1:-1;;;93382:10:0;93341:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93408:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;93408:25:0;;;93297:147;;;;;-1:-1:-1;;;93297:147:0;;;;;;;;:::i;:::-;;110372:26:::1;:24;:26::i;99272:166::-:0;99354:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;99378:52:::1;-1:-1:-1::0;;;99402:11:0::1;92977:6;99378:8;:52::i;109379:476::-:0;109441:7;122636:21;109441:7;109539:13;:11;:13::i;:::-;-1:-1:-1;;;;;109531:36:0;;109527:96;;;109591:20;109379:476;-1:-1:-1;109379:476:0:o;109527:96::-;109635:21;109727:26;;109695:16;;109659:20;:52;;;;:::i;:::-;:94;;;;:::i;:::-;109635:118;;109781:13;109768:9;;:26;109764:64;;109819:9;;109803:25;;:13;:25;:::i;:::-;109796:32;;;;109379:476;:::o;109764:64::-;109846:1;109839:8;;;;109379:476;:::o;101088:286::-;101206:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;-1:-1:-1;101278:20:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;101278:20:0::1;::::0;::::1;::::0;92864:6:::1;101236:40:::0;::::1;;101228:71;;;;-1:-1:-1::0;;;101228:71:0::1;;;;;;;;:::i;:::-;;101317:49;-1:-1:-1::0;;;101348:17:0::1;101317:8;:49::i;104638:202::-:0;104691:7;104711:24;104738:39;-1:-1:-1;;;104738:15:0;:39::i;94886:147::-;93552:4;;-1:-1:-1;;;;;93552:4:0;93538:10;:18;;:75;;;93560:14;:12;:14::i;:::-;-1:-1:-1;;;;;93560:22:0;;-1:-1:-1;;;93602:10:0;93560:53;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93628:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;93628:25:0;;;93516:148;;;;;-1:-1:-1;;;93516:148:0;;;;;;;;:::i;:::-;;95015:10:::1;:8;:10::i;105632:228::-:0;105679:7;105699:21;105723:33;-1:-1:-1;;;105723:15:0;:33::i;:::-;105699:57;;105767:54;105787:13;105802:18;:16;:18::i;103516:323::-;103562:7;103582:17;103602:32;-1:-1:-1;;;103602:15:0;:32::i;:::-;103582:52;;103645:26;103674:37;103701:9;103674:16;;:26;;:37;;;;:::i;:::-;103645:66;;103739:18;103726:9;;:31;103722:83;;103774:19;:17;:19::i;:::-;-1:-1:-1;103822:9:0;103516:323;-1:-1:-1;103516:323:0:o;101751:137::-;101815:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;101839:41:::1;-1:-1:-1::0;;;101839:19:0::1;:41::i;103847:127::-:0;103906:4;90261:14;:12;:14::i;:::-;-1:-1:-1;;;;;90261:22:0;;-1:-1:-1;;;90302:10:0;90261:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90315:25;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;90315:25:0;;;90253:88;;;;;-1:-1:-1;;;90253:88:0;;;;;;;;:::i;:::-;;103930:36:::1;-1:-1:-1::0;;;103930:19:0::1;:36::i;101620:123::-:0;101671:7;101698:37;-1:-1:-1;;;101698:15:0;:37::i;107684:1372::-;107767:7;;;107822:45;:28;107858:8;107822:35;:45::i;:::-;107787:80;;;;107886:6;107894:29;;;;;;;;;;;;;;;;;107878:46;;;;;-1:-1:-1;;;107878:46:0;;;;;;;;:::i;:::-;;107937:19;107969:8;107937:41;;107991:9;-1:-1:-1;;;;;107991:17:0;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;108021:17;108041:9;-1:-1:-1;;;;;108041:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;108115:26;;108021:43;;-1:-1:-1;108156:40:0;;;108152:204;;108242:1;108213:26;:30;108152:204;;;108305:39;108335:9;108305:27;:39;:::i;:::-;108276:26;:68;108152:204;108384:9;108372;:21;108368:432;;;108410:14;108427:21;108439:9;108427;:21;:::i;:::-;108410:38;;108463:23;108489:49;108500:37;108517:19;:17;:19::i;:::-;108500:6;;:16;:37::i;:::-;108489:10;:49::i;:::-;108463:75;-1:-1:-1;108557:19:0;;108553:115;;108597:55;108612:15;108629:9;-1:-1:-1;;;;;108629:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;108597:14;:55::i;:::-;108715:18;;108694:1;;-1:-1:-1;108694:1:0;;108723:6;;108715:18;;108694:1;;108715:18;108395:350;;108368:432;;;108766:22;108779:9;108766:22;;:::i;:::-;;;108368:432;108816:9;-1:-1:-1;;;;;108816:17:0;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;108812:208;;108857:55;:28;108901:9;108857:35;:55::i;:::-;;108812:208;;;108945:63;:28;108986:9;108998;108945:32;:63::i;:::-;;108812:208;-1:-1:-1;109039:9:0;107684:1372;-1:-1:-1;;;;;107684:1372:0:o;111282:114::-;-1:-1:-1;;;111328:7:0;111355:33;:15;:33;;;;;111282:114::o;82134:186::-;82253:58;;-1:-1:-1;;;82253:58:0;;-1:-1:-1;;;82253:58:0;;;1176:25:1;82208:12:0;;-1:-1:-1;;;;;82253:19:0;;;;;1149:18:1;;82253:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;81124:190::-;81246:59;;-1:-1:-1;;;81246:59:0;;-1:-1:-1;;;81246:59:0;;;1176:25:1;81199:13:0;;-1:-1:-1;;;;;81246:19:0;;;;;1149:18:1;;81246:59:0;1030:177:1;91483:109:0;91571:13;;91483:109::o;86157:256::-;86217:4;86242:14;;;:9;:14;;;;;;;;;86263:23;;;;;;;;;;;-1:-1:-1;;;86263:23:0;;;;;;;;86234:53;;;;-1:-1:-1;;;86234:53:0;;;;;;;;:::i;:::-;-1:-1:-1;86315:1:0;86298:14;;;:9;:14;;;;;;;;:18;;;86327:15;:20;;;;;;:24;;;86367:16;86308:3;;86367:16;;;-1:-1:-1;86401:4:0;;86157:256;-1:-1:-1;86157:256:0:o;119627:254::-;42121:4;119746:26;119759:13;119746:10;:26;:::i;:::-;:44;;119724:149;;;;-1:-1:-1;;;119724:149:0;;7009:2:1;119724:149:0;;;6991:21:1;7048:2;7028:18;;;7021:30;7087:34;7067:18;;;7060:62;7158:25;7138:18;;;7131:53;7201:19;;119724:149:0;6807:419:1;119724:149:0;119627:254;;:::o;85195:128::-;85259:4;85283:32;85292:3;85297:5;83873:6;85283:8;:32::i;:::-;85276:39;85195:128;-1:-1:-1;;;85195:128:0:o;118637:223::-;118708:14;;118686:4;;118708:14;;118703:33;;-1:-1:-1;118731:5:0;;118637:223::o;118703:33::-;118749:14;:22;;-1:-1:-1;;118749:22:0;;;118815:13;:11;:13::i;:::-;-1:-1:-1;;;;;118787:43:0;;;;;;;;;;;-1:-1:-1;118848:4:0;;118637:223::o;42221:122::-;42285:7;42012:4;42313:5;42317:1;42313;:5;:::i;:::-;42312:23;;;;:::i;119368:251::-;119486:7;119527:9;119515;:21;119511:82;;;119560:21;119572:9;119560;:21;:::i;:::-;119553:28;;;;119511:82;-1:-1:-1;119610:1:0;119368:251;;;;:::o;119889:1337::-;120025:14;;119998:4;;120025:14;;120020:33;;-1:-1:-1;120048:5:0;120041:12;;120020:33;120064:24;120091:21;:19;:21::i;:::-;120064:48;;120125:18;120146:13;:11;:13::i;:::-;120125:34;;120170:13;120186:10;:8;:10::i;:::-;120170:26;-1:-1:-1;120209:14:0;120226:43;:15;120252:16;120226:25;:43::i;:::-;120209:60;-1:-1:-1;120280:18:0;120301:21;;:52;;120329:24;120348:5;120329:16;:24;:::i;:::-;120301:52;;;120325:1;120301:52;120280:73;;42121:4;120377:10;:27;:57;;120424:10;120377:57;;;42121:4;120377:57;120364:70;;120445:18;120474:16;120466:5;:24;:55;;120497:24;120516:5;120497:16;:24;:::i;:::-;120466:55;;;120493:1;120466:55;120445:76;-1:-1:-1;120558:37:0;:15;120584:10;120558:25;:37::i;:::-;120536:19;:59;120532:665;;;120657:22;120682:28;120704:6;120682:19;:28;:::i;:::-;120725:33;;-1:-1:-1;;;120725:33:0;;;;;1176:25:1;;;120657:53:0;;-1:-1:-1;;;;;;120725:17:0;;;;;1149:18:1;;120725:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;120794:54;120815:16;;120833:14;120794:20;:54::i;:::-;120775:16;:73;-1:-1:-1;120532:665:0;;;120892:37;:15;120918:10;120892:25;:37::i;:::-;120870:19;:59;120866:331;;;120994:21;121018:28;121027:19;121018:6;:28;:::i;:::-;120994:52;;121061:43;121079:8;121090:13;121061:9;:43::i;:::-;121139:13;121119:16;;:33;;;;;;;:::i;:::-;;;;;;;;121167:8;-1:-1:-1;;;;;121167:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;120931:266;120866:331;-1:-1:-1;121214:4:0;;119889:1337;-1:-1:-1;;;;;;;;119889:1337:0:o;121924:112::-;122000:28;;-1:-1:-1;;;;;122000:20:0;;;:28;;;;;122021:6;;122000:28;;;;122021:6;122000:20;:28;;;;;;;;;;;;;;;;;;;87353:217;87409:7;87429:21;87446:3;87429:16;:21::i;:::-;87461:16;87480:20;;;:15;:20;;;;;;87511:25;87496:3;87480:20;87511:10;:25::i;116380:381::-;116425:14;;;;116420:28;;116380:381::o;116420:28::-;116460:27;116490:13;:11;:13::i;:::-;-1:-1:-1;;;;;116490:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;116460:53;;116524:23;116623:26;;116588:19;116550:22;122636:21;;122545:120;116550:22;:57;;;;:::i;:::-;:99;;;;:::i;:::-;116524:125;-1:-1:-1;116666:20:0;116662:33;;116688:7;;116380:381::o;116662:33::-;116705:48;116716:15;116733:19;116705:10;:48::i;113014:1781::-;113052:4;113069:18;113090:13;:11;:13::i;:::-;113069:34;-1:-1:-1;;;;;;113118:31:0;;113114:76;;113173:5;113166:12;;;113014:1781;:::o;113114:76::-;113202:8;-1:-1:-1;;;;;113202:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;113233:23;113273:27;113303:8;-1:-1:-1;;;;;113303:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;113332:23;113358:16;113407:9;;113273:48;;-1:-1:-1;113358:16:0;113433:37;;;113429:1156;;;113519:14;113536:37;113558:15;113536:19;:37;:::i;:::-;113519:54;;113603:11;113594:6;:20;113590:312;;;113639:15;;113635:123;;113679:21;113689:11;113679:21;;:::i;:::-;;;113737:1;113723:15;;113635:123;113804:20;113817:6;113804:12;:20::i;:::-;113776:48;-1:-1:-1;113776:48:0;-1:-1:-1;113590:312:0;;;113865:21;113880:6;113865:21;;:::i;:::-;;;113590:312;113921:18;;113937:1;;113929:6;;113921:18;;113937:1;;113921:18;113472:479;113429:1156;;;113983:15;113961:19;:37;113957:628;;;114046:12;114061:37;114079:19;114061:15;:37;:::i;:::-;114046:52;-1:-1:-1;114113:19:0;114046:52;114113:19;;:::i;:::-;;;114213:17;114233:14;:12;:14::i;:::-;114213:34;-1:-1:-1;114262:26:0;114291:36;:15;114213:34;114291:25;:36::i;:::-;114262:65;;114360:18;114346:11;:32;114342:117;;;114413:30;114431:11;114413:17;:30::i;:::-;114399:44;;114342:117;114478:16;;114489:4;;114486:1;;114478:16;;114486:1;;114478:16;114000:506;;;113957:628;;;114569:4;114562:11;;;;;;;113014:1781;:::o;113957:628::-;114609:11;114597:9;:23;;;;114650:8;-1:-1:-1;;;;;114650:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;114631:16;:37;114685:19;;114681:83;;114721:31;114736:15;114721:14;:31::i;94047:756::-;94247:20;;;;;;;;;;;;-1:-1:-1;;;94247:20:0;;;;42121:4;94217:28;;;94209:59;;;;-1:-1:-1;;;94209:59:0;;;;;;;;:::i;:::-;-1:-1:-1;94324:20:0;;;;;;;;;;;;-1:-1:-1;;;94324:20:0;;;;42121:4;94287:35;;;94279:66;;;;-1:-1:-1;;;94279:66:0;;;;;;;;:::i;:::-;-1:-1:-1;94395:20:0;;;;;;;;;;;;-1:-1:-1;;;94395:20:0;;;;92923:6;94364:29;;;94356:60;;;;-1:-1:-1;;;94356:60:0;;;;;;;;:::i;:::-;-1:-1:-1;94429:4:0;:12;;-1:-1:-1;;;;;;94429:12:0;-1:-1:-1;;;;;94429:12:0;;;;;94454:39;-1:-1:-1;;;94482:10:0;94454;:39::i;:::-;;94504:53;-1:-1:-1;;;94539:17:0;94504:10;:53::i;:::-;;94568:30;-1:-1:-1;;;94591:6:0;94568:10;:30::i;:::-;;94609:50;-1:-1:-1;;;92676:7:0;94609:10;:50::i;:::-;;94670:56;-1:-1:-1;;;92742:6:0;94670:10;:56::i;:::-;;94737:58;-1:-1:-1;;;92808:1:0;94737:10;:58::i;112711:295::-;112758:4;112775:18;112796:13;:11;:13::i;:::-;112775:34;-1:-1:-1;;;;;;112824:31:0;;112820:49;;112864:5;112857:12;;;112711:295;:::o;112820:49::-;112882:14;:21;;-1:-1:-1;;112882:21:0;112899:4;112882:21;;;112919:36;;-1:-1:-1;;;;;112919:36:0;;;;;112882:14;;112919:36;112966:10;:8;:10::i;:::-;112994:4;112987:11;;;112711:295;:::o;88028:329::-;88094:7;88133:21;;;:16;:21;;;;;;;;;;-1:-1:-1;;;;;;88165:29:0;;;-1:-1:-1;;;;;88165:29:0;;;;;;;;;88205:16;:21;;;;;:34;;;;;;;;88250:9;:14;;;;;:18;;;88284:42;;88133:21;;;;4994:34:1;;;5044:18;;;5037:43;88133:21:0;;88284:42;;4929:18:1;88284:42:0;;;;;;;;-1:-1:-1;88344:5:0;;88028:329;-1:-1:-1;;88028:329:0:o;71991:171::-;72070:7;72105:48;72110:3;-1:-1:-1;;;;;72130:21:0;;72105:4;:48::i;114803:536::-;114857:4;114874:18;114895:13;:11;:13::i;:::-;114874:34;-1:-1:-1;;;;;;114923:31:0;;114919:49;;114963:5;114956:12;;;114803:536;:::o;114919:49::-;114979:10;:8;:10::i;:::-;-1:-1:-1;115000:18:0;122636:21;115000:43;;115054:8;-1:-1:-1;;;;;115054:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;122636:21:0;115087:18;115167:23;115180:10;122636:21;115167:23;:::i;:::-;115141:49;;115222:55;115243:16;;115261:15;115222:20;:55::i;:::-;115203:16;:74;115288:21;:19;:21::i;:::-;;115327:4;115320:11;;;;;;114803:536;:::o;77784:360::-;77901:16;77935:11;77949:12;:3;:10;:12::i;:::-;77935:26;;77972:23;78012:3;77998:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77998:18:0;;77972:44;;78032:9;78027:86;78051:3;78047:1;:7;78027:86;;;78088:13;78094:3;78099:1;78088:5;:13::i;:::-;78076:6;78083:1;78076:9;;;;;;;;:::i;:::-;-1:-1:-1;;;;;78076:25:0;;;:9;;;;;;;;;;;:25;78056:3;;;;:::i;:::-;;;;78027:86;;;-1:-1:-1;78130:6:0;77784:360;-1:-1:-1;;;77784:360:0:o;86511:266::-;86571:4;86596:14;;;:9;:14;;;;;;;;;86617:23;;;;;;;;;;;-1:-1:-1;;;86617:23:0;;;;;;;;86588:53;;;;-1:-1:-1;;;86588:53:0;;;;;;;;:::i;:::-;-1:-1:-1;86669:1:0;86652:14;;;:9;:14;;;;;;;;:18;;;86681:16;:21;;;;;;:34;;-1:-1:-1;;;;;;86681:34:0;;;86731:16;86662:3;;86731:16;;;-1:-1:-1;86765:4:0;;86511:266;-1:-1:-1;86511:266:0:o;86860:261::-;86919:16;86938:9;:14;86948:3;86938:14;;;;;;;;;;;;86919:33;;86990:8;86971:15;:27;;87000:26;;;;;;;;;;;;;;;;;86963:64;;;;;-1:-1:-1;;;86963:64:0;;;;;;;;:::i;:::-;-1:-1:-1;87061:22:0;;;;;;;;;;;;-1:-1:-1;;;87061:22:0;;;;87046:13;87038:46;;;;-1:-1:-1;;;87038:46:0;;;;;;;;:::i;:::-;-1:-1:-1;;87112:1:0;87095:14;;;:9;:14;;;;;:18;86860:261::o;69743:219::-;69866:4;69890:64;69895:3;-1:-1:-1;;;;;69915:21:0;;69947:5;69890:4;:64::i;:::-;69883:71;69743:219;-1:-1:-1;;;;69743:219:0:o;85537:284::-;85650:4;85667:28;85684:3;85689:5;85667:16;:28::i;:::-;85706:21;;;;:16;:21;;;;;;;;;:29;;-1:-1:-1;;;;;;85706:29:0;-1:-1:-1;;;;;85706:29:0;;;;;;;;85751:40;;5454:51:1;;;5521:18;;;5514:34;;;85706:21:0;;85751:40;;5427:18:1;85751:40:0;;;;;;;;-1:-1:-1;85809:4:0;85537:284;;;;;:::o;115840:229::-;115911:9;;115889:19;115949:28;115911:9;115949:17;:28::i;:::-;115931:46;;116007:7;115992:11;:22;115988:74;;116031:9;:19;-1:-1:-1;115840:229:0:o;71556:274::-;71665:4;;;;71728:51;71736:3;-1:-1:-1;;;;;71756:21:0;;71728:7;:51::i;:::-;71696:83;;-1:-1:-1;71696:83:0;-1:-1:-1;;;71556:274:0;;;;;;:::o;117179:489::-;117241:7;117261:23;117287:44;117312:18;:16;:18::i;117287:44::-;117261:70;;117344:20;117367:41;117392:15;:13;:15::i;:::-;117367:14;;:24;:41::i;:::-;117344:64;-1:-1:-1;117419:21:0;117344:64;117443:32;117460:15;117443:14;:32;:::i;:::-;:47;;;;:::i;:::-;117419:71;;117503:31;117521:12;117503:17;:31::i;:::-;117549:17;;117545:83;;117583:33;117602:13;117583:18;:33::i;:::-;-1:-1:-1;117645:15:0;;117179:489;-1:-1:-1;;;117179:489:0:o;122327:210::-;-1:-1:-1;;;;;122420:24:0;;122416:37;;122327:210;;:::o;122416:37::-;122478:4;;122463:66;;-1:-1:-1;;;122463:66:0;;-1:-1:-1;;;;;5472:32:1;;;122463:66:0;;;5454:51:1;5521:18;;;5514:34;;;122478:4:0;;;;122463:31;;122502:6;;5427:18:1;;122463:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;70128:160::-;70205:4;70229:51;70237:3;-1:-1:-1;;;;;70257:21:0;;70229:7;:51::i;84802:282::-;84915:4;84932:28;84949:3;84954:5;84932:16;:28::i;:::-;84971:20;;;;:15;:20;;;;;;;;;:28;;;85015:39;;8204:25:1;;;8245:18;;;8238:34;;;84971:20:0;;85015:39;;8177:18:1;85015:39:0;8030:248:1;88365:316:0;88431:7;88470:20;;;:15;:20;;;;;;;;;;88501:28;;;;88540:15;:20;;;;;:24;;;88575:9;:14;;;;;:18;;;88609:41;;8204:25:1;;;8245:18;;;8238:34;;;88470:20:0;;;88609:41;;8177:18:1;88609:41:0;8030:248:1;116769:402:0;116825:7;116834;116854:22;116879:37;116896:19;:17;:19::i;116879:37::-;116854:62;-1:-1:-1;116854:62:0;122636:21;116931:39;116927:110;;;116987:13;:11;:13::i;:::-;-1:-1:-1;;;;;116987:22:0;;117010:14;116987:38;;;;;;;;;;;;;1176:25:1;;1164:2;1149:18;;1030:177;116987:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;116927:110;117047:23;117073:26;117084:14;117073:10;:26::i;:::-;117047:52;-1:-1:-1;117121:23:0;117130:14;117121:6;:23;:::i;:::-;117112:51;117147:15;;-1:-1:-1;116769:402:0;-1:-1:-1;;;116769:402:0:o;115347:485::-;115413:7;;-1:-1:-1;;;;;115462:7:0;:18;;115489:4;115413:7;115462:50;;-1:-1:-1;;;;;;115462:50:0;;;;;;;-1:-1:-1;;;;;5012:15:1;;;115462:50:0;;;4994:34:1;5064:15;;5044:18;;;5037:43;4929:18;;115462:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;115433:79;;115541:18;115527:11;:32;115523:273;;;115576:34;115591:18;115576:14;:34::i;:::-;115523:273;;;115632:34;;-1:-1:-1;;;115632:34:0;;115660:4;115632:34;;;181:51:1;115632:7:0;-1:-1:-1;;;;;115632:19:0;;;;154:18:1;;115632:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;115628:168;;;-1:-1:-1;;;;;115683:7:0;:16;;121870:7;115683:46;;-1:-1:-1;;;;;;115683:46:0;;;;;;;-1:-1:-1;;;;;5472:32:1;;;115683:46:0;;;5454:51:1;5521:18;;;5514:34;;;5427:18;;115683:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;115758:1;115744:15;;115774:10;:8;:10::i;:::-;-1:-1:-1;115813:11:0;;115347:485;-1:-1:-1;115347:485:0:o;118868:118::-;118928:50;118943:6;118951:13;:11;:13::i;:::-;-1:-1:-1;;;;;118951:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;118928:50;118868:118;:::o;66341:236::-;66407:7;66443:16;;;:11;;;:16;;;;;;66478:10;;;;:33;;;66492:19;66502:3;66507;66492:9;:19::i;:::-;66470:76;;;;-1:-1:-1;;;66470:76:0;;8485:2:1;66470:76:0;;;8467:21:1;8524:2;8504:18;;;8497:30;8563:32;8543:18;;;8536:60;8613:18;;66470:76:0;8283:354:1;70629:123:0;70698:7;70725:19;70733:3;70725:7;:19::i;76369:213::-;76497:7;;76540:13;:3;76547:5;76540:6;:13::i;:::-;-1:-1:-1;76522:31:0;76369:213;-1:-1:-1;;;;76369:213:0:o;64264:195::-;64374:4;64391:16;;;:11;;;:16;;;;;:24;;;64433:18;64391:3;64403;64433:13;:18::i;84340:248::-;84422:9;:14;84432:3;84422:14;;;;;;;;;;;;84440:1;84422:19;84443:23;;;;;;;;;;;;;-1:-1:-1;;;84443:23:0;;;84414:53;;;;;-1:-1:-1;;;84414:53:0;;;;;;;;:::i;:::-;-1:-1:-1;84507:21:0;;;;;;;;;;;;;;;;;83873:6;84486:19;;;84478:51;;;;-1:-1:-1;;;84478:51:0;;;;;;;;:::i;:::-;-1:-1:-1;84557:23:0;84575:5;84557:15;:23;:::i;:::-;84540:14;;;;:9;:14;;;;;;:40;;;;-1:-1:-1;84340:248:0:o;65890:290::-;65959:4;66001:16;;;:11;;;:16;;;;;;65959:4;;66032:19;66028:145;;66076:19;66086:3;66091;66076:9;:19::i;:::-;66068:40;-1:-1:-1;66105:1:0;;-1:-1:-1;66068:40:0;;-1:-1:-1;66068:40:0;66028:145;66149:4;;-1:-1:-1;66155:5:0;-1:-1:-1;66141:20:0;;122044:131;122116:51;;-1:-1:-1;;;122116:51:0;;121440:1;122116:51;;;5454::1;5521:18;;;5514:34;;;122116:7:0;-1:-1:-1;;;;;122116:15:0;;;;122139:6;;5427:18:1;;122116:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;122183:136::-;122264:29;:15;-1:-1:-1;;;;;122264:27:0;;:29::i;:::-;-1:-1:-1;;;;;122256:47:0;:55;122304:6;122256:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64634:151;64698:4;64722:16;;;:11;;;:16;;;;;64715:23;;;64756:21;64722:3;64734;64756:16;:21::i;117676:797::-;117810:17;117830:13;:11;:13::i;:::-;-1:-1:-1;;;;;117830:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;117810:47;;117870:18;117891:49;117912:16;;117930:9;117891:20;:49::i;:::-;117957:34;;-1:-1:-1;;;117957:34:0;;117985:4;117957:34;;;181:51:1;117870:70:0;;-1:-1:-1;117957:7:0;-1:-1:-1;;;;;117957:19:0;;;;154:18:1;;117957:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;117953:428;;;118098:10;118076:18;:32;118072:298;;-1:-1:-1;;;;;118129:7:0;:16;;121870:7;118129:45;;-1:-1:-1;;;;;;118129:45:0;;;;;;;-1:-1:-1;;;;;5472:32:1;;;118129:45:0;;;5454:51:1;5521:18;;;5514:34;;;5427:18;;118129:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;118072:298;;;118200:22;;118196:174;;-1:-1:-1;;;;;118301:7:0;:16;;121870:7;118301:53;;-1:-1:-1;;;;;;118301:53:0;;;;;;;-1:-1:-1;;;;;5472:32:1;;;118301:53:0;;;5454:51:1;5521:18;;;5514:34;;;5427:18;;118301:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;118196:174;118444:21;:19;:21::i;:::-;;117737:736;;117676:797;:::o;64869:126::-;64940:4;64964:23;:3;64983;64964:18;:23::i;65090:109::-;65146:7;65173:18;:3;:16;:18::i;71100:268::-;71207:7;;;;71272:22;71276:3;71288:5;71272:3;:22::i;56169:125::-;56239:4;56263:23;56268:3;56280:5;56263:4;:23::i;80662:160::-;80760:54;;-1:-1:-1;;;80760:54:0;;-1:-1:-1;;;80760:54:0;;;1176:25:1;80733:7:0;;-1:-1:-1;;;;;80760:19:0;;;;;1149:18:1;;80760:54:0;1030:177:1;56470:131:0;56543:4;56567:26;56575:3;56587:5;56567:7;:26::i;56687:140::-;56767:4;54553:19;;;:12;;;:19;;;;;;:24;;56791:28;54456:129;56913:117;56976:7;57003:19;57011:3;54754:18;;54671:109;65564:178;65631:7;;;65674:19;:3;65687:5;65674:12;:19::i;:::-;65717:16;;;;:11;;;;;:16;;;;;;;;;65564:178;-1:-1:-1;;;;65564:178:0:o;52360:414::-;52423:4;54553:19;;;:12;;;:19;;;;;;52440:327;;-1:-1:-1;52483:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;52666:18;;52644:19;;;:12;;;:19;;;;;;:40;;;;52699:11;;52440:327;-1:-1:-1;52750:5:0;52743:12;;52950:1420;53016:4;53155:19;;;:12;;;:19;;;;;;53191:15;;53187:1176;;53566:21;53590:14;53603:1;53590:10;:14;:::i;:::-;53639:18;;53566:38;;-1:-1:-1;53619:17:0;;53639:22;;53660:1;;53639:22;:::i;:::-;53619:42;;53695:13;53682:9;:26;53678:405;;53729:17;53749:3;:11;;53761:9;53749:22;;;;;;;;:::i;:::-;;;;;;;;;53729:42;;53903:9;53874:3;:11;;53886:13;53874:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;53988:23;;;:12;;;:23;;;;;:36;;;53678:405;54164:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;54259:3;:12;;:19;54272:5;54259:19;;;;;;;;;;;54252:26;;;54302:4;54295:11;;;;;;;53187:1176;54346:5;54339:12;;;;;57384:131;57458:7;57485:22;57489:3;57501:5;55201:7;55228:3;:11;;55240:5;55228:18;;;;;;;;:::i;:::-;;;;;;;;;55221:25;;55134:120;;;;:::o;468:180:1:-;527:6;580:2;568:9;559:7;555:23;551:32;548:52;;;596:1;593;586:12;548:52;-1:-1:-1;619:23:1;;468:180;-1:-1:-1;468:180:1:o;1653:131::-;-1:-1:-1;;;;;1728:31:1;;1718:42;;1708:70;;1774:1;1771;1764:12;1789:452;1875:6;1883;1891;1899;1952:3;1940:9;1931:7;1927:23;1923:33;1920:53;;;1969:1;1966;1959:12;1920:53;2008:9;1995:23;2027:31;2052:5;2027:31;:::i;:::-;2077:5;2129:2;2114:18;;2101:32;;-1:-1:-1;2180:2:1;2165:18;;2152:32;;2231:2;2216:18;2203:32;;-1:-1:-1;1789:452:1;-1:-1:-1;;;1789:452:1:o;2246:247::-;2305:6;2358:2;2346:9;2337:7;2333:23;2329:32;2326:52;;;2374:1;2371;2364:12;2326:52;2413:9;2400:23;2432:31;2457:5;2432:31;:::i;2498:658::-;2669:2;2721:21;;;2791:13;;2694:18;;;2813:22;;;2640:4;;2669:2;2892:15;;;;2866:2;2851:18;;;2640:4;2935:195;2949:6;2946:1;2943:13;2935:195;;;3014:13;;-1:-1:-1;;;;;3010:39:1;2998:52;;3105:15;;;;3070:12;;;;3046:1;2964:9;2935:195;;;-1:-1:-1;3147:3:1;;2498:658;-1:-1:-1;;;;;;2498:658:1:o;3619:274::-;3793:25;;;-1:-1:-1;;;;;3854:32:1;3849:2;3834:18;;3827:60;3781:2;3766:18;;3619:274::o;3898:277::-;3965:6;4018:2;4006:9;3997:7;3993:23;3989:32;3986:52;;;4034:1;4031;4024:12;3986:52;4066:9;4060:16;4119:5;4112:13;4105:21;4098:5;4095:32;4085:60;;4141:1;4138;4131:12;4180:597;4292:4;4321:2;4350;4339:9;4332:21;4382:6;4376:13;4425:6;4420:2;4409:9;4405:18;4398:34;4450:1;4460:140;4474:6;4471:1;4468:13;4460:140;;;4569:14;;;4565:23;;4559:30;4535:17;;;4554:2;4531:26;4524:66;4489:10;;4460:140;;;4618:6;4615:1;4612:13;4609:91;;;4688:1;4683:2;4674:6;4663:9;4659:22;4655:31;4648:42;4609:91;-1:-1:-1;4761:2:1;4740:15;-1:-1:-1;;4736:29:1;4721:45;;;;4768:2;4717:54;;4180:597;-1:-1:-1;;;4180:597:1:o;5091:184::-;5161:6;5214:2;5202:9;5193:7;5189:23;5185:32;5182:52;;;5230:1;5227;5220:12;5182:52;-1:-1:-1;5253:16:1;;5091:184;-1:-1:-1;5091:184:1:o;5559:127::-;5620:10;5615:3;5611:20;5608:1;5601:31;5651:4;5648:1;5641:15;5675:4;5672:1;5665:15;5691:125;5731:4;5759:1;5756;5753:8;5750:34;;;5764:18;;:::i;:::-;-1:-1:-1;5801:9:1;;5691:125::o;5821:128::-;5861:3;5892:1;5888:6;5885:1;5882:13;5879:39;;;5898:18;;:::i;:::-;-1:-1:-1;5934:9:1;;5821:128::o;6369:251::-;6439:6;6492:2;6480:9;6471:7;6467:23;6463:32;6460:52;;;6508:1;6505;6498:12;6460:52;6540:9;6534:16;6559:31;6584:5;6559:31;:::i;7231:168::-;7271:7;7337:1;7333;7329:6;7325:14;7322:1;7319:21;7314:1;7307:9;7300:17;7296:45;7293:71;;;7344:18;;:::i;:::-;-1:-1:-1;7384:9:1;;7231:168::o;7404:217::-;7444:1;7470;7460:132;;7514:10;7509:3;7505:20;7502:1;7495:31;7549:4;7546:1;7539:15;7577:4;7574:1;7567:15;7460:132;-1:-1:-1;7606:9:1;;7404:217::o;7626:127::-;7687:10;7682:3;7678:20;7675:1;7668:31;7718:4;7715:1;7708:15;7742:4;7739:1;7732:15;7758:127;7819:10;7814:3;7810:20;7807:1;7800:31;7850:4;7847:1;7840:15;7874:4;7871:1;7864:15;7890:135;7929:3;-1:-1:-1;;7950:17:1;;7947:43;;;7970:18;;:::i;:::-;-1:-1:-1;8017:1:1;8006:13;;7890:135::o;8642:127::-;8703:10;8698:3;8694:20;8691:1;8684:31;8734:4;8731:1;8724:15;8758:4;8755:1;8748:15
Swarm Source
ipfs://fc706e7436a7324f36c875278d8608814f2e5d3165c906971dbf304d8b43a28e
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.