Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 75 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Rebalance | 17520653 | 994 days ago | IN | 0 ETH | 0.02405975 | ||||
| Rebalance | 17477659 | 1000 days ago | IN | 0 ETH | 0.03328226 | ||||
| Rebalance | 17449823 | 1004 days ago | IN | 0 ETH | 0.03606247 | ||||
| Rebalance | 17378610 | 1014 days ago | IN | 0 ETH | 0.0807477 | ||||
| Rebalance | 17307203 | 1024 days ago | IN | 0 ETH | 0.05544051 | ||||
| Rebalance | 17236320 | 1034 days ago | IN | 0 ETH | 0.16787484 | ||||
| Rebalance | 17164843 | 1044 days ago | IN | 0 ETH | 0.08457875 | ||||
| Rebalance | 17093340 | 1054 days ago | IN | 0 ETH | 0.06846047 | ||||
| Rebalance | 16990222 | 1069 days ago | IN | 0 ETH | 0.04603387 | ||||
| Rebalance | 16987902 | 1069 days ago | IN | 0 ETH | 0.04905668 | ||||
| Rebalance | 16938332 | 1076 days ago | IN | 0 ETH | 0.05329318 | ||||
| Rebalance | 16888518 | 1083 days ago | IN | 0 ETH | 0.02211571 | ||||
| Rebalance | 16838686 | 1090 days ago | IN | 0 ETH | 0.0302495 | ||||
| Rebalance | 16788917 | 1097 days ago | IN | 0 ETH | 0.04688912 | ||||
| Rebalance | 16739449 | 1104 days ago | IN | 0 ETH | 0.0384315 | ||||
| Rebalance | 16689963 | 1111 days ago | IN | 0 ETH | 0.04970582 | ||||
| Rebalance | 16640559 | 1118 days ago | IN | 0 ETH | 0.05226614 | ||||
| Rebalance | 16598144 | 1124 days ago | IN | 0 ETH | 0.0315606 | ||||
| Rebalance | 16568007 | 1128 days ago | IN | 0 ETH | 0.03066652 | ||||
| Rebalance | 16517780 | 1135 days ago | IN | 0 ETH | 0.02941407 | ||||
| Rebalance | 16475228 | 1141 days ago | IN | 0 ETH | 0.02507916 | ||||
| Rebalance | 16425376 | 1148 days ago | IN | 0 ETH | 0.03673289 | ||||
| Rebalance | 16376157 | 1155 days ago | IN | 0 ETH | 0.03019937 | ||||
| Rebalance | 16326486 | 1162 days ago | IN | 0 ETH | 0.02931526 | ||||
| Rebalance | 16291982 | 1167 days ago | IN | 0 ETH | 0.04758138 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Convex2PlainPool
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "../../curve/2Pool/Curve2PlainPool.sol";
import "../ConvexBase.sol";
/// @title This strategy will deposit collateral token in a Curve 2Pool and stake lp token to convex.
contract Convex2PlainPool is Curve2PlainPool, ConvexBase {
using SafeERC20 for IERC20;
constructor(
address pool_,
address crvPool_,
uint256 crvSlippage_,
address masterOracle_,
address swapper_,
uint256 collateralIdx_,
uint256 convexPoolId_,
string memory _name
)
Curve2PlainPool(pool_, crvPool_, crvSlippage_, masterOracle_, swapper_, collateralIdx_, _name)
ConvexBase(convexPoolId_)
{
(address _lp, , , , , ) = BOOSTER.poolInfo(convexPoolId_);
require(_lp == address(crvLp), "incorrect-lp-token");
}
function lpBalanceStaked() public view override returns (uint256 _total) {
_total = cvxCrvRewards.balanceOf(address(this));
}
function _approveToken(uint256 amount_) internal virtual override {
crvLp.safeApprove(address(BOOSTER), amount_);
super._approveToken(amount_);
}
function _claimRewards() internal override {
require(cvxCrvRewards.getReward(address(this), true), "reward-claim-failed");
}
function _stakeAllLp() internal override {
uint256 _balance = crvLp.balanceOf(address(this));
if (_balance > 0) {
require(BOOSTER.deposit(convexPoolId, _balance, true), "booster-deposit-failed");
}
}
/**
* @notice Unstake all LPs
* @dev This function is called by `_beforeMigration()` hook
* Should claim rewards that will be swept later
*/
function _unstakeAllLp() internal override {
cvxCrvRewards.withdrawAllAndUnwrap(true);
}
/**
* @notice Unstake LPs
* Don't claiming rewards because `_claimRewards()` already does that
*/
function _unstakeLp(uint256 amount_) internal override {
if (amount_ > 0) {
require(cvxCrvRewards.withdrawAndUnwrap(amount_, false), "withdraw-and-unwrap-failed");
}
}
/// @dev convex pool can add new rewards. This method refresh list.
function setRewardTokens(
address[] memory /*_rewardTokens*/
) external override onlyKeeper {
// Claims all rewards, if any, before updating the reward list
_claimRewardsAndConvertTo(address(collateralToken));
rewardTokens = _getRewardTokens();
_approveToken(0);
_approveToken(MAX_UINT_VALUE);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
interface IStrategy {
function rebalance()
external
returns (
uint256 _profit,
uint256 _loss,
uint256 _payback
);
function sweepERC20(address _fromToken) external;
function withdraw(uint256 _amount) external;
function feeCollector() external view returns (address);
function isReservedToken(address _token) external view returns (bool);
function keepers() external view returns (address[] memory);
function migrate(address _newStrategy) external;
function token() external view returns (address);
function pool() external view returns (address);
// solhint-disable-next-line func-name-mixedcase
function VERSION() external view returns (string memory);
function collateral() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
// solhint-disable-next-line max-line-length
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow, so we distribute
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCast {
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits.
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128) {
require(value >= -2**127 && value < 2**127, "SafeCast: value doesn\'t fit in 128 bits");
return int128(value);
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64) {
require(value >= -2**63 && value < 2**63, "SafeCast: value doesn\'t fit in 64 bits");
return int64(value);
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32) {
require(value >= -2**31 && value < 2**31, "SafeCast: value doesn\'t fit in 32 bits");
return int32(value);
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16) {
require(value >= -2**15 && value < 2**15, "SafeCast: value doesn\'t fit in 16 bits");
return int16(value);
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits.
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8) {
require(value >= -2**7 && value < 2**7, "SafeCast: value doesn\'t fit in 8 bits");
return int8(value);
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*/
function toInt256(uint256 value) internal pure returns (int256) {
require(value < 2**255, "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}// SPDX-License-Identifier: MIT
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;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
/**
* @notice Governable interface
*/
interface IGovernable {
function governor() external view returns (address _governor);
function transferGovernorship(address _proposedGovernor) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
/**
* @notice Pausable interface
*/
interface IPausable {
function paused() external view returns (bool);
function stopEverything() external view returns (bool);
function pause() external;
function unpause() external;
function shutdown() external;
function open() external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "../../dependencies/openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "./IGovernable.sol";
import "./IPausable.sol";
interface IVesperPool is IGovernable, IPausable, IERC20Metadata {
function calculateUniversalFee(uint256 _profit) external view returns (uint256 _fee);
function deposit(uint256 _share) external;
function multiTransfer(address[] memory _recipients, uint256[] memory _amounts) external returns (bool);
function excessDebt(address _strategy) external view returns (uint256);
function poolAccountant() external view returns (address);
function poolRewards() external view returns (address);
function reportEarning(
uint256 _profit,
uint256 _loss,
uint256 _payback
) external;
function reportLoss(uint256 _loss) external;
function sweepERC20(address _fromToken) external;
function withdraw(uint256 _amount) external;
function keepers() external view returns (address[] memory);
function isKeeper(address _address) external view returns (bool);
function maintainers() external view returns (address[] memory);
function isMaintainer(address _address) external view returns (bool);
function pricePerShare() external view returns (uint256);
function strategy(address _strategy)
external
view
returns (
bool _active,
uint256 _interestFee, // Obsolete
uint256 _debtRate, // Obsolete
uint256 _lastRebalance,
uint256 _totalDebt,
uint256 _totalLoss,
uint256 _totalProfit,
uint256 _debtRatio,
uint256 _externalDepositFee
);
function token() external view returns (IERC20);
function tokensHere() external view returns (uint256);
function totalDebtOf(address _strategy) external view returns (uint256);
function totalValue() external view returns (uint256);
function totalDebt() external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
interface IConvex {
function poolInfo(uint256)
external
view
returns (
address,
address,
address,
address,
address,
bool
);
// deposit lp tokens and stake
function deposit(
uint256 _pid,
uint256 _amount,
bool _stake
) external returns (bool);
// deposit all lp tokens and stake
function depositAll(uint256 _pid, bool _stake) external returns (bool);
// withdraw lp tokens
function withdraw(uint256 _pid, uint256 _amount) external returns (bool);
// withdraw all lp tokens
function withdrawAll(uint256 _pid) external returns (bool);
// claim crv + extra rewards
function earmarkRewards(uint256 _pid) external returns (bool);
// claim rewards on stash (msg.sender == stash)
function claimRewards(uint256 _pid, address _gauge) external returns (bool);
// delegate address votes on dao (needs to be voteDelegate)
function vote(
uint256 _voteId,
address _votingAddress,
bool _support
) external returns (bool);
function voteGaugeWeight(address[] calldata _gauge, uint256[] calldata _weight) external returns (bool);
}
interface Rewards {
function pid() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function earned(address account) external view returns (uint256);
function extraRewardsLength() external view returns (uint256);
function extraRewards(uint256) external view returns (address);
function rewardPerToken() external view returns (uint256);
function rewardPerTokenStored() external view returns (uint256);
function rewardRate() external view returns (uint256);
function rewardToken() external view returns (address);
function rewards(address) external view returns (uint256);
function userRewardPerTokenPaid(address) external view returns (uint256);
function stakingToken() external view returns (address);
function stake(uint256) external returns (bool);
function stakeAll() external returns (bool);
function stakeFor(address, uint256) external returns (bool);
function withdraw(uint256 amount, bool claim) external returns (bool);
function withdrawAll(bool claim) external returns (bool);
function withdrawAndUnwrap(uint256 amount, bool claim) external returns (bool);
function withdrawAllAndUnwrap(bool claim) external;
function getReward() external returns (bool);
function getReward(address _account, bool _claimExtras) external returns (bool);
function donate(uint256 _amount) external returns (bool);
function queuedRewards() external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
interface IConvexToken {
function maxSupply() external view returns (uint256);
function totalSupply() external view returns (uint256);
function reductionPerCliff() external view returns (uint256);
}// SPDX-License-Identifier: MIT
/* solhint-disable */
pragma solidity 0.8.9;
interface IAddressProvider {
function get_registry() external view returns (address);
function get_address(uint256 i) external view returns (address);
}// SPDX-License-Identifier: MIT
/* solhint-disable */
pragma solidity 0.8.9;
import "vesper-pools/contracts/dependencies/openzeppelin/contracts/token/ERC20/IERC20.sol";
// Not a complete interface, but should have what we need
interface ILiquidityGaugeV2 is IERC20 {
function deposit(uint256 _value) external;
function deposit(uint256 _value, address addr) external;
function withdraw(uint256 _value) external;
function claim_rewards(address addr) external;
function claim_rewards() external;
function claimable_tokens(address addr) external returns (uint256);
function claimable_reward(address, address) external returns (uint256);
function integrate_fraction(address addr) external view returns (uint256);
function user_checkpoint(address addr) external returns (bool);
function reward_integral(address) external view returns (uint256);
function reward_integral_for(address, address) external view returns (uint256);
function lp_token() external view returns (address);
function reward_count() external view returns (uint256);
function reward_tokens(uint256 _i) external view returns (address);
}
interface ILiquidityGaugeV3 is ILiquidityGaugeV2 {
function claimable_reward(address addr, address token) external view override returns (uint256);
function claimable_reward_write(address addr, address token) external returns (uint256);
}
/* solhint-enable */// SPDX-License-Identifier: MIT
/* solhint-disable func-name-mixedcase*/
pragma solidity 0.8.9;
interface IMetapoolFactory {
function get_underlying_coins(address pool) external view returns (address[8] memory);
function get_underlying_decimals(address pool) external view returns (uint256[8] memory);
function get_coins(address pool) external view returns (address[4] memory);
function get_n_coins(address pool) external view returns (uint256);
function get_meta_n_coins(address pool) external view returns (uint256[2] memory);
function get_decimals(address pool) external view returns (uint256[4] memory);
function get_gauge(address pool) external view returns (address);
function is_meta(address pool) external view returns (bool);
}// SPDX-License-Identifier: MIT
/* solhint-disable */
pragma solidity 0.8.9;
interface IRegistry {
function get_pool_from_lp_token() external view returns (address);
function get_lp_token(address pool) external view returns (address);
function get_n_coins(address pool) external view returns (uint256[2] memory);
function get_underlying_coins(address pool) external view returns (address[8] memory);
function get_underlying_decimals(address pool) external view returns (uint256[8] memory);
function get_gauges(address pool) external view returns (address[10] memory);
}// SPDX-License-Identifier: MIT
/* solhint-disable */
pragma solidity 0.8.9;
// Not a complete interface, but should have what we need
interface IStableSwap {
function coins(uint256 i) external view returns (address);
function fee() external view returns (uint256); // fee * 1e10
function lp_token() external view returns (address);
function A() external view returns (uint256);
function A_precise() external view returns (uint256);
function balances(uint256 i) external view returns (uint256);
function get_virtual_price() external view returns (uint256);
function get_dy(
int128 i,
int128 j,
uint256 dx
) external view returns (uint256);
function get_dy_underlying(
int128 i,
int128 j,
uint256 dx
) external view returns (uint256);
function exchange(
int128 i,
int128 j,
uint256 dx,
uint256 min_dy
) external returns (uint256);
function calc_withdraw_one_coin(uint256 _token_amount, int128 i) external view returns (uint256);
function remove_liquidity_one_coin(
uint256 _token_amount,
int128 i,
uint256 _min_amount
) external;
}
interface IStableSwapV2 {
function coins(int128 i) external view returns (address);
}
interface IStableSwapUnderlying is IStableSwap {
function underlying_coins(uint256 i) external view returns (address);
function exchange_underlying(
int128 i,
int128 j,
uint256 dx,
uint256 min_dy
) external;
function remove_liquidity_one_coin(
uint256 _token_amount,
int128 i,
uint256 _min_amount,
bool _use_underlying
) external;
}
interface IStableSwap2x is IStableSwap {
function calc_token_amount(uint256[2] memory _amounts, bool is_deposit) external view returns (uint256);
function add_liquidity(uint256[2] memory _amounts, uint256 _min_mint_amount) external;
function remove_liquidity(uint256 _amount, uint256[2] memory _min_amounts) external;
function remove_liquidity_imbalance(uint256[2] memory _amounts, uint256 _max_burn_amount)
external
returns (uint256);
}
interface IStableSwap3x is IStableSwap {
function calc_token_amount(uint256[3] memory _amounts, bool is_deposit) external view returns (uint256);
function add_liquidity(uint256[3] memory _amounts, uint256 _min_mint_amount) external;
function remove_liquidity(uint256 _amount, uint256[3] memory _min_amounts) external;
function remove_liquidity_imbalance(uint256[3] memory _amounts, uint256 _max_burn_amount)
external
returns (uint256);
}
interface IStableSwap4x is IStableSwap {
function calc_token_amount(uint256[4] memory _amounts, bool is_deposit) external view returns (uint256);
function add_liquidity(uint256[4] memory _amounts, uint256 _min_mint_amount) external;
function remove_liquidity(uint256 _amount, uint256[4] memory _min_amounts) external;
function remove_liquidity_imbalance(uint256[4] memory _amounts, uint256 _max_burn_amount)
external
returns (uint256);
}
interface IStableSwap2xUnderlying is IStableSwap2x, IStableSwapUnderlying {
function add_liquidity(
uint256[2] calldata amounts,
uint256 min_mint_amount,
bool use_underlying
) external;
function remove_liquidity_imbalance(
uint256[2] calldata amounts,
uint256 max_burn_amount,
bool use_underlying
) external;
function remove_liquidity(
uint256 amount,
uint256[2] calldata min_amounts,
bool use_underlying
) external;
}
interface IStableSwap3xUnderlying is IStableSwap3x, IStableSwapUnderlying {
function add_liquidity(
uint256[3] calldata amounts,
uint256 min_mint_amount,
bool use_underlying
) external;
function remove_liquidity_imbalance(
uint256[3] calldata amounts,
uint256 max_burn_amount,
bool use_underlying
) external;
function remove_liquidity(
uint256 amount,
uint256[3] calldata min_amounts,
bool use_underlying
) external;
}
interface IStableSwap4xUnderlying is IStableSwap4x, IStableSwapUnderlying {
function add_liquidity(
uint256[4] calldata amounts,
uint256 min_mint_amount,
bool use_underlying
) external;
function remove_liquidity_imbalance(
uint256[4] calldata amounts,
uint256 max_burn_amount,
bool use_underlying
) external;
function remove_liquidity(
uint256 amount,
uint256[4] calldata min_amounts,
bool use_underlying
) external;
}
/* solhint-enable */// SPDX-License-Identifier: MIT
/* solhint-disable */
pragma solidity 0.8.9;
// Not a complete interface, but should have what we need
interface ITokenMinter {
function minted(address arg0, address arg1) external view returns (uint256);
function mint(address gauge_addr) external;
}
/* solhint-enable */// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
interface IMasterOracle {
function getPriceInUsd(address token_) external view returns (uint256 _priceInUsd);
function quote(
address tokenIn_,
address tokenOut_,
uint256 amountIn_
) external view returns (uint256 _amountOut);
function quoteTokenToUsd(address token_, uint256 amountIn_) external view returns (uint256 amountOut_);
function quoteUsdToToken(address token_, uint256 amountIn_) external view returns (uint256 _amountOut);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
/**
* @notice Routed Swapper interface
* @dev This contract doesn't support native coins (e.g. ETH, AVAX, MATIC, etc) use wrapper tokens instead
*/
interface IRoutedSwapper {
/**
* @notice The list of supported DEXes
* @dev This function is gas intensive
*/
function getAllExchanges() external view returns (address[] memory);
/**
* @notice Get *spot* quote
* It will return the swap amount based on the current reserves of the best pair/path found (i.e. spot price).
* @dev It shouldn't be used as oracle!!!
*/
function getAmountIn(
address tokenIn_,
address tokenOut_,
uint256 amountOut_
) external returns (uint256 _amountIn);
/**
* @notice Get *spot* quote
* It will return the swap amount based on the current reserves of the best pair/path found (i.e. spot price).
* @dev It shouldn't be used as oracle!!!
*/
function getAmountOut(
address tokenIn_,
address tokenOut_,
uint256 amountIn_
) external returns (uint256 _amountOut);
/**
* @notice Perform an exact input swap - will revert if there is no default routing
*/
function swapExactInput(
address tokenIn_,
address tokenOut_,
uint256 amountIn_,
uint256 amountOutMin_,
address _receiver
) external returns (uint256 _amountOut);
/**
* @notice Perform an exact output swap - will revert if there is no default routing
*/
function swapExactOutput(
address tokenIn_,
address tokenOut_,
uint256 amountOut_,
uint256 amountInMax_,
address receiver_
) external returns (uint256 _amountIn);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "vesper-pools/contracts/interfaces/vesper/IVesperPool.sol";
import "vesper-pools/contracts/dependencies/openzeppelin/contracts/token/ERC20/IERC20.sol";
import "vesper-pools/contracts/dependencies/openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "vesper-pools/contracts/dependencies/openzeppelin/contracts/utils/Context.sol";
import "vesper-pools/contracts/dependencies/openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "vesper-pools/contracts/dependencies/openzeppelin/contracts/utils/math/Math.sol";
import "vesper-commons/contracts/interfaces/vesper/IStrategy.sol";
import "../interfaces/swapper/IRoutedSwapper.sol";
abstract contract Strategy is IStrategy, Context {
using SafeERC20 for IERC20;
using EnumerableSet for EnumerableSet.AddressSet;
IERC20 public immutable collateralToken;
address public receiptToken;
address public immutable override pool;
address public override feeCollector;
IRoutedSwapper public swapper;
address internal constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
uint256 internal constant MAX_UINT_VALUE = type(uint256).max;
EnumerableSet.AddressSet private _keepers;
event UpdatedFeeCollector(address indexed previousFeeCollector, address indexed newFeeCollector);
event UpdatedSwapper(IRoutedSwapper indexed oldSwapper, IRoutedSwapper indexed newSwapper);
constructor(
address _pool,
address _swapper,
address _receiptToken
) {
require(_pool != address(0), "pool-address-is-zero");
require(_swapper != address(0), "swapper-address-is-zero");
swapper = IRoutedSwapper(_swapper);
pool = _pool;
collateralToken = IVesperPool(_pool).token();
receiptToken = _receiptToken;
require(_keepers.add(_msgSender()), "add-keeper-failed");
}
modifier onlyGovernor() {
require(_msgSender() == IVesperPool(pool).governor(), "caller-is-not-the-governor");
_;
}
modifier onlyKeeper() {
require(_keepers.contains(_msgSender()), "caller-is-not-a-keeper");
_;
}
modifier onlyPool() {
require(_msgSender() == pool, "caller-is-not-vesper-pool");
_;
}
/**
* @notice Add given address in keepers list.
* @param _keeperAddress keeper address to add.
*/
function addKeeper(address _keeperAddress) external onlyGovernor {
require(_keepers.add(_keeperAddress), "add-keeper-failed");
}
/// @dev Approve all required tokens
function approveToken() external onlyKeeper {
_approveToken(0);
_approveToken(MAX_UINT_VALUE);
}
/// @notice Check whether given token is reserved or not. Reserved tokens are not allowed to sweep.
function isReservedToken(address _token) public view virtual override returns (bool);
/// @notice Return list of keepers
function keepers() external view override returns (address[] memory) {
return _keepers.values();
}
/**
* @notice Migrate all asset and vault ownership,if any, to new strategy
* @dev _beforeMigration hook can be implemented in child strategy to do extra steps.
* @param _newStrategy Address of new strategy
*/
function migrate(address _newStrategy) external virtual override onlyPool {
require(_newStrategy != address(0), "new-strategy-address-is-zero");
require(IStrategy(_newStrategy).pool() == pool, "not-valid-new-strategy");
_beforeMigration(_newStrategy);
IERC20(receiptToken).safeTransfer(_newStrategy, IERC20(receiptToken).balanceOf(address(this)));
collateralToken.safeTransfer(_newStrategy, collateralToken.balanceOf(address(this)));
}
/**
* @notice OnlyKeeper: Rebalance profit, loss and investment of this strategy.
* Calculate profit, loss and payback of this strategy and realize profit/loss and
* withdraw fund for payback, if any, and submit this report to pool.
* @return _profit Realized profit in collateral.
* @return _loss Realized loss, if any, in collateral.
* @return _payback If strategy has any excess debt, we have to liquidate asset to payback excess debt.
*/
function rebalance()
external
onlyKeeper
returns (
uint256 _profit,
uint256 _loss,
uint256 _payback
)
{
return _rebalance();
}
/**
* @notice Remove given address from keepers list.
* @param _keeperAddress keeper address to remove.
*/
function removeKeeper(address _keeperAddress) external onlyGovernor {
require(_keepers.remove(_keeperAddress), "remove-keeper-failed");
}
/**
* @notice sweep given token to feeCollector of strategy
* @param _fromToken token address to sweep
*/
function sweepERC20(address _fromToken) external override onlyKeeper {
require(feeCollector != address(0), "fee-collector-not-set");
require(_fromToken != address(collateralToken), "not-allowed-to-sweep-collateral");
require(!isReservedToken(_fromToken), "not-allowed-to-sweep");
if (_fromToken == ETH) {
Address.sendValue(payable(feeCollector), address(this).balance);
} else {
uint256 _amount = IERC20(_fromToken).balanceOf(address(this));
IERC20(_fromToken).safeTransfer(feeCollector, _amount);
}
}
/// @notice Returns address of token correspond to receipt token
function token() external view override returns (address) {
return receiptToken;
}
/// @notice Returns address of token correspond to collateral token
function collateral() external view override returns (address) {
return address(collateralToken);
}
/// @notice Returns total collateral locked in the strategy
function tvl() external view virtual returns (uint256);
/**
* @notice Update fee collector
* @param _feeCollector fee collector address
*/
function updateFeeCollector(address _feeCollector) external onlyGovernor {
require(_feeCollector != address(0), "fee-collector-address-is-zero");
require(_feeCollector != feeCollector, "fee-collector-is-same");
emit UpdatedFeeCollector(feeCollector, _feeCollector);
feeCollector = _feeCollector;
}
/**
* @notice Update swapper
* @param _swapper swapper address
*/
function updateSwapper(IRoutedSwapper _swapper) external onlyGovernor {
require(address(_swapper) != address(0), "swapper-address-is-zero");
require(_swapper != swapper, "swapper-is-same");
emit UpdatedSwapper(swapper, _swapper);
swapper = _swapper;
}
/**
* @notice Withdraw collateral token from end protocol.
* @param _amount Amount of collateral token
*/
function withdraw(uint256 _amount) external override onlyPool {
uint256 _collateralHere = collateralToken.balanceOf(address(this));
if (_collateralHere >= _amount) {
collateralToken.safeTransfer(pool, _amount);
} else {
_withdrawHere(_amount - _collateralHere);
// Do not assume _withdrawHere() will withdraw exact amount. Check balance again and transfer to pool
_collateralHere = collateralToken.balanceOf(address(this));
collateralToken.safeTransfer(pool, Math.min(_amount, _collateralHere));
}
}
function _approveToken(uint256 _amount) internal virtual {
collateralToken.safeApprove(pool, _amount);
}
/**
* @dev some strategy may want to prepare before doing migration.
* Example In Maker old strategy want to give vault ownership to new strategy
* @param _newStrategy .
*/
function _beforeMigration(address _newStrategy) internal virtual;
function _rebalance()
internal
virtual
returns (
uint256 _profit,
uint256 _loss,
uint256 _payback
);
function _swapExactInput(
address _tokenIn,
address _tokenOut,
uint256 _amountIn
) internal returns (uint256 _amountOut) {
_amountOut = swapper.swapExactInput(_tokenIn, _tokenOut, _amountIn, 1, address(this));
}
function _safeSwapExactInput(
address _tokenIn,
address _tokenOut,
uint256 _amountIn
) internal {
try swapper.swapExactInput(_tokenIn, _tokenOut, _amountIn, 1, address(this)) {} catch {} //solhint-disable no-empty-blocks
}
// These methods must be implemented by the inheriting strategy
function _withdrawHere(uint256 _amount) internal virtual;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "vesper-pools/contracts/dependencies/openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../../interfaces/convex/IConvex.sol";
import "../../interfaces/convex/IConvexToken.sol";
// Convex Strategies common variables and helper functions
abstract contract ConvexBase {
using SafeERC20 for IERC20;
address public constant CVX = 0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B;
address private constant CRV = 0xD533a949740bb3306d119CC777fa900bA034cd52;
IConvex public constant BOOSTER = IConvex(0xF403C135812408BFbE8713b5A23a04b3D48AAE31);
Rewards public immutable cvxCrvRewards;
uint256 public immutable convexPoolId;
struct ClaimableRewardInfo {
address token;
uint256 amount;
}
constructor(uint256 convexPoolId_) {
(, , , address _reward, , ) = BOOSTER.poolInfo(convexPoolId_);
cvxCrvRewards = Rewards(_reward);
convexPoolId = convexPoolId_;
}
/**
* @notice Add reward tokens
* The Convex pools have CRV and CVX as base rewards and may have others tokens as extra rewards
* In some cases, CVX is also added as extra reward, reason why we have to ensure to not add it twice
* @return _rewardTokens The array of reward tokens (both base and extra rewards)
*/
function _getRewardTokens() internal view returns (address[] memory _rewardTokens) {
uint256 _extraRewardCount;
uint256 _length = cvxCrvRewards.extraRewardsLength();
for (uint256 i; i < _length; i++) {
address _rewardToken = Rewards(cvxCrvRewards.extraRewards(i)).rewardToken();
// Some pool has CVX as extra rewards but other do not. CVX still reward token
if (_rewardToken != CRV && _rewardToken != CVX) {
_extraRewardCount++;
}
}
_rewardTokens = new address[](_extraRewardCount + 2);
_rewardTokens[0] = CRV;
_rewardTokens[1] = CVX;
uint256 _nextIdx = 2;
for (uint256 i; i < _length; i++) {
address _rewardToken = Rewards(cvxCrvRewards.extraRewards(i)).rewardToken();
// CRV and CVX already added in array
if (_rewardToken != CRV && _rewardToken != CVX) {
_rewardTokens[_nextIdx++] = _rewardToken;
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "../CurvePoolBase.sol";
// solhint-disable no-empty-blocks
/// @title This strategy will deposit collateral token in a Curve 2Pool and earn interest.
contract Curve2PlainPool is CurvePoolBase {
constructor(
address pool_,
address crvPool_,
uint256 crvSlippage_,
address masterOracle_,
address swapper_,
uint256 collateralIdx_,
string memory name_
) CurvePoolBase(pool_, crvPool_, crvSlippage_, masterOracle_, swapper_, collateralIdx_, name_) {}
function _depositToCurve(uint256 coinAmountIn_) internal virtual override {
if (coinAmountIn_ > 0) {
uint256[2] memory _depositAmounts;
_depositAmounts[collateralIdx] = coinAmountIn_;
uint256 _lpAmountOutMin = _calculateAmountOutMin(address(collateralToken), address(crvLp), coinAmountIn_);
IStableSwap2x(crvPool).add_liquidity(_depositAmounts, _lpAmountOutMin);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "vesper-pools/contracts/dependencies/openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "vesper-pools/contracts/dependencies/openzeppelin/contracts/utils/math/SafeCast.sol";
import "vesper-pools/contracts/dependencies/openzeppelin/contracts/utils/math/Math.sol";
import "vesper-pools/contracts/dependencies/openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "../../interfaces/curve/IStableSwap.sol";
import "../../interfaces/curve/ILiquidityGauge.sol";
import "../../interfaces/curve/ITokenMinter.sol";
import "../../interfaces/curve/IMetapoolFactory.sol";
import "../../interfaces/curve/IRegistry.sol";
import "../../interfaces/curve/IAddressProvider.sol";
import "../../interfaces/one-oracle/IMasterOracle.sol";
import "../Strategy.sol";
/// @title This strategy will deposit collateral token in a Curve Pool and earn interest.
// solhint-disable no-empty-blocks
abstract contract CurvePoolBase is Strategy {
using SafeERC20 for IERC20;
string public constant VERSION = "5.0.0";
uint256 internal constant MAX_BPS = 10_000;
ITokenMinter public constant CRV_MINTER = ITokenMinter(0xd061D61a4d941c39E5453435B6345Dc261C2fcE0); // This contract only exists on mainnet
IAddressProvider public constant ADDRESS_PROVIDER = IAddressProvider(0x0000000022D53366457F9d5E68Ec105046FC4383); // Same address to all chains
uint256 private constant FACTORY_ADDRESS_ID = 3;
// Note: Same as `receiptToken` but using this in order to save gas since it's `immutable` and `receiptToken` isn't
IERC20 public immutable crvLp;
address public immutable crvPool;
ILiquidityGaugeV2 public immutable crvGauge;
// solhint-disable-next-line var-name-mixedcase
address public CRV = 0xD533a949740bb3306d119CC777fa900bA034cd52; // Mainnet
// solhint-disable-next-line var-name-mixedcase
string public NAME;
uint256 public immutable collateralIdx;
uint256 public crvSlippage;
IMasterOracle public masterOracle;
address[] public rewardTokens;
event CrvSlippageUpdated(uint256 oldCrvSlippage, uint256 newCrvSlippage);
event MasterOracleUpdated(IMasterOracle oldMasterOracle, IMasterOracle newMasterOracle);
constructor(
address pool_,
address crvPool_,
uint256 crvSlippage_,
address masterOracle_,
address swapper_,
uint256 collateralIdx_,
string memory name_
) Strategy(pool_, swapper_, address(0)) {
if (block.chainid == 43114) {
// Avalanche
CRV = 0x47536F17F4fF30e64A96a7555826b8f9e66ec468;
} else if (block.chainid == 137) {
// Polygon
CRV = 0x172370d5Cd63279eFa6d502DAB29171933a610AF;
} else if (block.chainid == 42161) {
// Arbitrum
CRV = 0x11cDb42B0EB46D95f990BeDD4695A6e3fA034978;
}
address _crvLp;
address _crvGauge;
address _collateral;
IRegistry _registry = IRegistry(ADDRESS_PROVIDER.get_registry());
_crvLp = _registry.get_lp_token(crvPool_);
bool _isFactoryPool = _crvLp == address(0);
if (!_isFactoryPool) {
require(collateralIdx_ < _registry.get_n_coins(crvPool_)[1], "invalid-collateral");
_collateral = _registry.get_underlying_coins(crvPool_)[collateralIdx_];
_crvGauge = _registry.get_gauges(crvPool_)[0]; // TODO: Check other gauges?
// Note: The Curve's `Registry` is returning null when calling `get_gauges()` for the FRAX-USDC pool
// See more: https://github.com/curvefi/curve-pool-registry/issues/36
if (_crvGauge == address(0) && crvPool_ == 0xDcEF968d416a41Cdac0ED8702fAC8128A64241A2) {
// Address get from https://curve.fi/contracts page
_crvGauge = 0xCFc25170633581Bf896CB6CDeE170e3E3Aa59503;
}
} else {
IMetapoolFactory _factory = IMetapoolFactory(ADDRESS_PROVIDER.get_address(FACTORY_ADDRESS_ID));
if (_factory.is_meta(crvPool_)) {
require(collateralIdx_ < _factory.get_meta_n_coins(crvPool_)[1], "invalid-collateral");
_collateral = _factory.get_underlying_coins(crvPool_)[collateralIdx_];
} else {
require(collateralIdx_ < _factory.get_n_coins(crvPool_), "invalid-collateral");
_collateral = _factory.get_coins(crvPool_)[collateralIdx_];
}
_crvLp = crvPool_;
_crvGauge = _factory.get_gauge(crvPool_);
}
require(_collateral == address(IVesperPool(pool_).token()), "collateral-mismatch");
require(crvPool_ != address(0), "pool-is-null");
require(_crvLp != address(0), "lp-is-null");
require(_crvGauge != address(0), "gauge-is-null");
crvPool = crvPool_;
crvLp = IERC20(_crvLp);
crvGauge = ILiquidityGaugeV2(_crvGauge);
crvSlippage = crvSlippage_;
receiptToken = _crvLp;
collateralIdx = collateralIdx_;
NAME = name_;
masterOracle = IMasterOracle(masterOracle_);
rewardTokens.push(CRV);
}
/// @dev Check whether given token is reserved or not. Reserved tokens are not allowed to sweep.
function isReservedToken(address token_) public view override returns (bool) {
return token_ == address(crvLp) || token_ == address(collateralToken);
}
// Gets LP value not staked in gauge
function lpBalanceHere() public view virtual returns (uint256 _lpHere) {
_lpHere = crvLp.balanceOf(address(this));
}
function lpBalanceHereAndStaked() public view virtual returns (uint256 _lpHereAndStaked) {
_lpHereAndStaked = crvLp.balanceOf(address(this)) + lpBalanceStaked();
}
function lpBalanceStaked() public view virtual returns (uint256 _lpStaked) {
_lpStaked = crvGauge.balanceOf(address(this));
}
/// @notice Returns collateral balance + collateral deposited to curve
function tvl() external view override returns (uint256) {
return
collateralToken.balanceOf(address(this)) +
_quoteLpToCoin(lpBalanceHereAndStaked(), SafeCast.toInt128(int256(collateralIdx)));
}
function _approveToken(uint256 amount_) internal virtual override {
super._approveToken(amount_);
address _swapper = address(swapper);
collateralToken.safeApprove(crvPool, amount_);
collateralToken.safeApprove(_swapper, amount_);
uint256 _rewardTokensLength = rewardTokens.length;
for (uint256 i; i < _rewardTokensLength; i++) {
IERC20(rewardTokens[i]).safeApprove(_swapper, amount_);
}
crvLp.safeApprove(address(crvGauge), amount_);
}
/// @notice Unstake LP tokens in order to transfer to the new strategy
function _beforeMigration(address newStrategy_) internal override {
require(IStrategy(newStrategy_).collateral() == address(collateralToken), "wrong-collateral-token");
require(IStrategy(newStrategy_).token() == address(crvLp), "wrong-receipt-token");
_unstakeAllLp();
}
function _calculateAmountOutMin(
address tokenIn_,
address tokenOut_,
uint256 amountIn_
) internal view returns (uint256 _amountOutMin) {
_amountOutMin = (masterOracle.quote(tokenIn_, tokenOut_, amountIn_) * (MAX_BPS - crvSlippage)) / MAX_BPS;
}
function _claimRewards() internal virtual {
try CRV_MINTER.mint(address(crvGauge)) {} catch {
// This call may fail in some scenarios
// e.g. Side-chains don't have minter contract
}
try crvGauge.claim_rewards() {} catch {
// This call may fail in some scenarios
// e.g. 3Crv gauge doesn't have such function
}
}
/**
* @notice Curve pool may have more than one reward token. Child contract should override _claimRewards
*/
function _claimRewardsAndConvertTo(address tokenOut_) internal virtual {
_claimRewards();
uint256 _rewardTokensLength = rewardTokens.length;
for (uint256 i; i < _rewardTokensLength; i++) {
address _rewardToken = rewardTokens[i];
uint256 _amountIn = IERC20(_rewardToken).balanceOf(address(this));
if (_amountIn > 0) {
try swapper.swapExactInput(_rewardToken, tokenOut_, _amountIn, 1, address(this)) {} catch {
// Note: It may fail under some conditions
// For instance: 'UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT'
}
}
}
}
function _deposit() internal {
_depositToCurve(collateralToken.balanceOf(address(this)));
_stakeAllLp();
}
function _depositToCurve(uint256 amount_) internal virtual;
function _generateReport()
internal
virtual
returns (
uint256 _profit,
uint256 _loss,
uint256 _payback
)
{
uint256 _excessDebt = IVesperPool(pool).excessDebt(address(this));
uint256 _strategyDebt = IVesperPool(pool).totalDebtOf(address(this));
_claimRewardsAndConvertTo(address(collateralToken));
int128 _i = SafeCast.toInt128(int256(collateralIdx));
uint256 _lpHere = lpBalanceHere();
uint256 _totalLp = _lpHere + lpBalanceStaked();
uint256 _collateralInCurve = _quoteLpToCoin(_totalLp, _i);
uint256 _collateralHere = collateralToken.balanceOf(address(this));
uint256 _totalCollateral = _collateralHere + _collateralInCurve;
if (_totalCollateral > _strategyDebt) {
_profit = _totalCollateral - _strategyDebt;
} else {
_loss = _strategyDebt - _totalCollateral;
}
uint256 _profitAndExcessDebt = _profit + _excessDebt;
if (_profitAndExcessDebt > _collateralHere) {
uint256 _totalAmountToWithdraw = Math.min((_profitAndExcessDebt - _collateralHere), _collateralInCurve);
if (_totalAmountToWithdraw > 0) {
uint256 _lpToBurn = Math.min((_totalAmountToWithdraw * _totalLp) / _collateralInCurve, _totalLp);
if (_lpToBurn > 0) {
if (_lpToBurn > _lpHere) {
_unstakeLp(_lpToBurn - _lpHere);
}
_withdrawFromCurve(
_lpToBurn,
_calculateAmountOutMin(receiptToken, address(collateralToken), _lpToBurn),
_i
);
_collateralHere = collateralToken.balanceOf(address(this));
}
}
}
// Make sure _collateralHere >= _payback + profit. set actual payback first and then profit
_payback = Math.min(_collateralHere, _excessDebt);
_profit = _collateralHere > _payback ? Math.min((_collateralHere - _payback), _profit) : 0;
}
function _quoteLpToCoin(uint256 amountIn_, int128 toIdx_) internal view virtual returns (uint256 amountOut) {
if (amountIn_ > 0) {
amountOut = IStableSwap(crvPool).calc_withdraw_one_coin(amountIn_, toIdx_);
}
}
function _rebalance()
internal
virtual
override
returns (
uint256 _profit,
uint256 _loss,
uint256 _payback
)
{
(_profit, _loss, _payback) = _generateReport();
IVesperPool(pool).reportEarning(_profit, _loss, _payback);
_deposit();
}
// Requires that gauge has approval for lp token
function _stakeAllLp() internal virtual {
uint256 _balance = crvLp.balanceOf(address(this));
if (_balance > 0) {
crvGauge.deposit(_balance);
}
}
function _unstakeAllLp() internal virtual {
_unstakeLp(crvGauge.balanceOf(address(this)));
}
function _unstakeLp(uint256 amount_) internal virtual {
if (amount_ > 0) {
crvGauge.withdraw(amount_);
}
}
function _withdrawFromCurve(
uint256 lpToBurn_,
uint256 minCoinAmountOut_,
int128 coinIdx_
) internal virtual {
IStableSwap(crvPool).remove_liquidity_one_coin(lpToBurn_, coinIdx_, minCoinAmountOut_);
}
function _withdrawHere(uint256 coinAmountOut_) internal override {
int128 _i = SafeCast.toInt128(int256(collateralIdx));
uint256 _lpHere = lpBalanceHere();
uint256 _totalLp = _lpHere + lpBalanceStaked();
uint256 _lpToBurn = Math.min((coinAmountOut_ * _totalLp) / _quoteLpToCoin(_totalLp, _i), _totalLp);
if (_lpToBurn == 0) return;
if (_lpToBurn > _lpHere) {
_unstakeLp(_lpToBurn - _lpHere);
}
uint256 _coinAmountOutMin = _calculateAmountOutMin(address(crvLp), address(collateralToken), _lpToBurn);
_withdrawFromCurve(_lpToBurn, _coinAmountOutMin, _i);
}
/// @dev Rewards token in gauge can be updated any time. Governor can set reward tokens
/// Different version of gauge has different method to read reward tokens better governor set it
function setRewardTokens(address[] memory rewardTokens_) external virtual onlyGovernor {
rewardTokens = rewardTokens_;
address _receiptToken = receiptToken;
uint256 _rewardTokensLength = rewardTokens.length;
for (uint256 i; i < _rewardTokensLength; i++) {
require(
rewardTokens_[i] != _receiptToken &&
rewardTokens_[i] != address(collateralToken) &&
rewardTokens_[i] != pool &&
rewardTokens_[i] != address(crvLp),
"Invalid reward token"
);
}
_approveToken(0);
_approveToken(MAX_UINT_VALUE);
}
function updateCrvSlippage(uint256 newCrvSlippage_) external onlyGovernor {
require(newCrvSlippage_ < MAX_BPS, "invalid-slippage-value");
emit CrvSlippageUpdated(crvSlippage, newCrvSlippage_);
crvSlippage = newCrvSlippage_;
}
function updateMasterOracle(IMasterOracle newMasterOracle_) external onlyGovernor {
emit MasterOracleUpdated(masterOracle, newMasterOracle_);
masterOracle = newMasterOracle_;
}
}{
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 100
},
"remappings": [],
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"pool_","type":"address"},{"internalType":"address","name":"crvPool_","type":"address"},{"internalType":"uint256","name":"crvSlippage_","type":"uint256"},{"internalType":"address","name":"masterOracle_","type":"address"},{"internalType":"address","name":"swapper_","type":"address"},{"internalType":"uint256","name":"collateralIdx_","type":"uint256"},{"internalType":"uint256","name":"convexPoolId_","type":"uint256"},{"internalType":"string","name":"_name","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldCrvSlippage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCrvSlippage","type":"uint256"}],"name":"CrvSlippageUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IMasterOracle","name":"oldMasterOracle","type":"address"},{"indexed":false,"internalType":"contract IMasterOracle","name":"newMasterOracle","type":"address"}],"name":"MasterOracleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousFeeCollector","type":"address"},{"indexed":true,"internalType":"address","name":"newFeeCollector","type":"address"}],"name":"UpdatedFeeCollector","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IRoutedSwapper","name":"oldSwapper","type":"address"},{"indexed":true,"internalType":"contract IRoutedSwapper","name":"newSwapper","type":"address"}],"name":"UpdatedSwapper","type":"event"},{"inputs":[],"name":"ADDRESS_PROVIDER","outputs":[{"internalType":"contract IAddressProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BOOSTER","outputs":[{"internalType":"contract IConvex","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CRV","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CRV_MINTER","outputs":[{"internalType":"contract ITokenMinter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CVX","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NAME","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_keeperAddress","type":"address"}],"name":"addKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"approveToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collateral","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateralIdx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateralToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"convexPoolId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crvGauge","outputs":[{"internalType":"contract ILiquidityGaugeV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crvLp","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crvPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crvSlippage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cvxCrvRewards","outputs":[{"internalType":"contract Rewards","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"}],"name":"isReservedToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keepers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpBalanceHere","outputs":[{"internalType":"uint256","name":"_lpHere","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpBalanceHereAndStaked","outputs":[{"internalType":"uint256","name":"_lpHereAndStaked","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpBalanceStaked","outputs":[{"internalType":"uint256","name":"_total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"masterOracle","outputs":[{"internalType":"contract IMasterOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newStrategy","type":"address"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebalance","outputs":[{"internalType":"uint256","name":"_profit","type":"uint256"},{"internalType":"uint256","name":"_loss","type":"uint256"},{"internalType":"uint256","name":"_payback","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"receiptToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_keeperAddress","type":"address"}],"name":"removeKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"","type":"address[]"}],"name":"setRewardTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapper","outputs":[{"internalType":"contract IRoutedSwapper","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromToken","type":"address"}],"name":"sweepERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tvl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newCrvSlippage_","type":"uint256"}],"name":"updateCrvSlippage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeCollector","type":"address"}],"name":"updateFeeCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IMasterOracle","name":"newMasterOracle_","type":"address"}],"name":"updateMasterOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IRoutedSwapper","name":"_swapper","type":"address"}],"name":"updateSwapper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
610180604052600580546001600160a01b03191673d533a949740bb3306d119cc777fa900ba034cd521790553480156200003857600080fd5b50604051620054df380380620054df8339810160408190526200005b9162001049565b818888888888888786868686868686868360006001600160a01b038316620000ca5760405162461bcd60e51b815260206004820152601460248201527f706f6f6c2d616464726573732d69732d7a65726f00000000000000000000000060448201526064015b60405180910390fd5b6001600160a01b038216620001225760405162461bcd60e51b815260206004820152601760248201527f737761707065722d616464726573732d69732d7a65726f0000000000000000006044820152606401620000c1565b600280546001600160a01b0319166001600160a01b0384811691909117909155831660a081905260408051637e062a3560e11b8152905163fc0c546a91600480820192602092909190829003018186803b1580156200018057600080fd5b505afa15801562000195573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001bb91906200117f565b6001600160a01b03908116608052600080546001600160a01b03191691831691909117905562000202620001ec3390565b600362000ecf60201b62001a0d1790919060201c565b620002445760405162461bcd60e51b81526020600482015260116024820152701859190b5ad9595c195c8b59985a5b1959607a1b6044820152606401620000c1565b5050504661a86a14156200027e57600580546001600160a01b0319167347536f17f4ff30e64a96a7555826b8f9e66ec468179055620002e6565b4660891415620002b457600580546001600160a01b03191673172370d5cd63279efa6d502dab29171933a610af179055620002e6565b4661a4b11415620002e657600580546001600160a01b0319167311cdb42b0eb46d95f990bedd4695a6e3fa0349781790555b6000806000806f22d53366457f9d5e68ec105046fc43836001600160a01b031663a262904b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200033657600080fd5b505afa1580156200034b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200037191906200117f565b604051633795104960e01b81526001600160a01b038c811660048301529192509082169063379510499060240160206040518083038186803b158015620003b757600080fd5b505afa158015620003cc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003f291906200117f565b93506001600160a01b03841615806200063e5760405163940494f160e01b81526001600160a01b038c8116600483015283169063940494f190602401604080518083038186803b1580156200044657600080fd5b505afa1580156200045b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004819190620011a6565b602001518710620004ca5760405162461bcd60e51b81526020600482015260126024820152711a5b9d985b1a590b58dbdb1b185d195c985b60721b6044820152606401620000c1565b60405163a77576ef60e01b81526001600160a01b038c8116600483015283169063a77576ef906024016101006040518083038186803b1580156200050d57600080fd5b505afa15801562000522573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000548919062001243565b87600881106200055c576200055c6200122d565b60200201516040516356059ffb60e01b81526001600160a01b038d81166004830152919450908316906356059ffb906024016101406040518083038186803b158015620005a857600080fd5b505afa158015620005bd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005e39190620012d4565b5193506001600160a01b0384161580156200061a575073dcef968d416a41cdac0ed8702fac8128a64241a26001600160a01b038c16145b15620006385773cfc25170633581bf896cb6cdee170e3e3aa5950393505b62000a8e565b60405163124fd3dd60e21b8152600360048201526000906f22d53366457f9d5e68ec105046fc43839063493f4f749060240160206040518083038186803b1580156200068957600080fd5b505afa1580156200069e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006c491906200117f565b60405163e4d332a960e01b81526001600160a01b038e811660048301529192509082169063e4d332a99060240160206040518083038186803b1580156200070a57600080fd5b505afa1580156200071f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000745919062001370565b15620008af5760405163eb73f37d60e01b81526001600160a01b038d8116600483015282169063eb73f37d90602401604080518083038186803b1580156200078c57600080fd5b505afa158015620007a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007c79190620011a6565b602001518810620008105760405162461bcd60e51b81526020600482015260126024820152711a5b9d985b1a590b58dbdb1b185d195c985b60721b6044820152606401620000c1565b60405163a77576ef60e01b81526001600160a01b038d8116600483015282169063a77576ef906024016101006040518083038186803b1580156200085357600080fd5b505afa15801562000868573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200088e919062001243565b8860088110620008a257620008a26200122d565b6020020151935062000a0a565b60405163940494f160e01b81526001600160a01b038d8116600483015282169063940494f19060240160206040518083038186803b158015620008f157600080fd5b505afa15801562000906573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200092c91906200138e565b8810620009715760405162461bcd60e51b81526020600482015260126024820152711a5b9d985b1a590b58dbdb1b185d195c985b60721b6044820152606401620000c1565b604051639ac90d3d60e01b81526001600160a01b038d81166004830152821690639ac90d3d9060240160806040518083038186803b158015620009b357600080fd5b505afa158015620009c8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620009ee9190620013a8565b886004811062000a025762000a026200122d565b602002015193505b60405163daf297b960e01b81526001600160a01b03808e1660048301528d975082169063daf297b99060240160206040518083038186803b15801562000a4f57600080fd5b505afa15801562000a64573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a8a91906200117f565b9450505b8b6001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000ac857600080fd5b505afa15801562000add573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b0391906200117f565b6001600160a01b0316836001600160a01b03161462000b655760405162461bcd60e51b815260206004820152601360248201527f636f6c6c61746572616c2d6d69736d61746368000000000000000000000000006044820152606401620000c1565b6001600160a01b038b1662000bac5760405162461bcd60e51b815260206004820152600c60248201526b1c1bdbdb0b5a5ccb5b9d5b1b60a21b6044820152606401620000c1565b6001600160a01b03851662000bf15760405162461bcd60e51b815260206004820152600a6024820152691b1c0b5a5ccb5b9d5b1b60b21b6044820152606401620000c1565b6001600160a01b03841662000c395760405162461bcd60e51b815260206004820152600d60248201526c19d85d59d94b5a5ccb5b9d5b1b609a1b6044820152606401620000c1565b6001600160a01b03808c1660e05285811660c08190529085166101005260078b9055600080546001600160a01b0319169091179055610120879052855162000c8990600690602089019062000f41565b5088600860006101000a8154816001600160a01b0302191690836001600160a01b031602179055506009600560009054906101000a90046001600160a01b03169080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b0316021790555050505050505050505050505050505050505050600073f403c135812408bfbe8713b5a23a04b3d48aae316001600160a01b0316631526fe27836040518263ffffffff1660e01b815260040162000d6791815260200190565b60c06040518083038186803b15801562000d8057600080fd5b505afa15801562000d95573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000dbb91906200142d565b50506001600160a01b0316610140525050506101609190915250604051631526fe2760e01b81526004810183905260009073f403c135812408bfbe8713b5a23a04b3d48aae3190631526fe279060240160c06040518083038186803b15801562000e2457600080fd5b505afa15801562000e39573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e5f91906200142d565b5050505050905060c0516001600160a01b0316816001600160a01b03161462000ec05760405162461bcd60e51b815260206004820152601260248201527134b731b7b93932b1ba16b63816ba37b5b2b760711b6044820152606401620000c1565b505050505050505050620014f9565b600062000ee6836001600160a01b03841662000eef565b90505b92915050565b600081815260018301602052604081205462000f385750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000ee9565b50600062000ee9565b82805462000f4f90620014bc565b90600052602060002090601f01602090048101928262000f73576000855562000fbe565b82601f1062000f8e57805160ff191683800117855562000fbe565b8280016001018555821562000fbe579182015b8281111562000fbe57825182559160200191906001019062000fa1565b5062000fcc92915062000fd0565b5090565b5b8082111562000fcc576000815560010162000fd1565b6001600160a01b038116811462000ffd57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171562001041576200104162001000565b604052919050565b600080600080600080600080610100898b0312156200106757600080fd5b8851620010748162000fe7565b809850506020808a0151620010898162000fe7565b60408b015160608c01519199509750620010a38162000fe7565b60808b0151909650620010b68162000fe7565b60a08b015160c08c015160e08d015192975090955093506001600160401b0380821115620010e357600080fd5b818c0191508c601f830112620010f857600080fd5b8151818111156200110d576200110d62001000565b62001121601f8201601f1916850162001016565b91508082528d848285010111156200113857600080fd5b60005b81811015620011585783810185015183820186015284016200113b565b818111156200116a5760008583850101525b50508093505050509295985092959890939650565b6000602082840312156200119257600080fd5b81516200119f8162000fe7565b9392505050565b600060408284031215620011b957600080fd5b82601f830112620011c957600080fd5b604080519081016001600160401b0381118282101715620011ee57620011ee62001000565b80604052508060408401858111156200120657600080fd5b845b818110156200122257805183526020928301920162001208565b509195945050505050565b634e487b7160e01b600052603260045260246000fd5b60006101008083850312156200125857600080fd5b83601f8401126200126857600080fd5b6040518181016001600160401b03811182821017156200128c576200128c62001000565b604052908301908085831115620012a257600080fd5b845b83811015620012c9578051620012ba8162000fe7565b825260209182019101620012a4565b509095945050505050565b6000610140808385031215620012e957600080fd5b83601f840112620012f957600080fd5b6040518181016001600160401b03811182821017156200131d576200131d62001000565b6040529083019080858311156200133357600080fd5b845b83811015620012c95780516200134b8162000fe7565b82526020918201910162001335565b805180151581146200136b57600080fd5b919050565b6000602082840312156200138357600080fd5b62000ee6826200135a565b600060208284031215620013a157600080fd5b5051919050565b600060808284031215620013bb57600080fd5b82601f830112620013cb57600080fd5b604051608081016001600160401b0381118282101715620013f057620013f062001000565b6040528060808401858111156200140657600080fd5b845b81811015620012225780516200141e8162000fe7565b83526020928301920162001408565b60008060008060008060c087890312156200144757600080fd5b8651620014548162000fe7565b6020880151909650620014678162000fe7565b60408801519095506200147a8162000fe7565b60608801519094506200148d8162000fe7565b6080880151909350620014a08162000fe7565b9150620014b060a088016200135a565b90509295509295509295565b600181811c90821680620014d157607f821691505b60208210811415620014f357634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e05161010051610120516101405161016051613dce620017116000396000818161059e01526136770152600081816104780152818161103601528181611bdd01528181611c9201528181611ef40152818161288501528181612ca60152613414015260008181610348015281816119980152818161214b0152818161303801526134ef0152600081816106040152612b8c0152600081816104d9015281816126a501528181612aaf01528181612e5a015261358a01526000818161040c01528181610c9c01528181610d2b015281816116dc0152818161209d015281816121eb015281816123fa01528181612b6a0152818161354b01526135db0152600081816102850152818161064c015281816107a10152818161093801528181610a5401528181610b3201528181610b8e01528181610ef40152818161106e0152818161110b01528181611337015281816115000152818161229501528181612ecc01528181612f6c01526134a90152600081816104b20152818161055a015281816108df0152818161099701528181610a3201528181610aa601528181610b6501528181610cd70152818161129b015281816117e2015281816119d80152818161220c0152818161231001528181612a8d01528181612ae10152818161300d01528181613092015281816131ea0152818161322c0152818161331001528181613487015261352a0152613dce6000f3fe608060405234801561001057600080fd5b50600436106102535760003560e01c8063a3f4df7e11610146578063d572fd7f116100c3578063e5328e0611610087578063e5328e06146105c0578063eaada382146105c8578063ec78e832146105db578063fc0c546a146105ee578063fd57a4df146105ff578063ffa1ad741461062657600080fd5b8063d572fd7f1461054f578063d8dfeb4514610558578063de603fdc1461057e578063e00af4a714610586578063e529ee951461059957600080fd5b8063c415b95c1161010a578063c415b95c146104fb578063c965fa8a1461050e578063ce5494bb14610516578063d2c35ce814610529578063d3033c391461053c57600080fd5b8063a3f4df7e1461045e578063a7404b7014610473578063abc9b45e1461049a578063b2016bd4146104ad578063b20fdc0d146104d457600080fd5b806374db9ad4116101d45780637d7c2a1c116101985780637d7c2a1c146103e45780637f44579b14610407578063945c91421461042e578063951dc22c1461044157806399b71d5c1461045657600080fd5b806374db9ad414610378578063759cb53b1461039357806375b0ffd1146103ae578063795dae66146103c95780637bb7bed1146103d157600080fd5b80632b3297f91161021b5780632b3297f9146102e75780632e1a7d4d146102fa5780634032b72b1461030d578063440d72481461032057806348cd2ddd1461034357600080fd5b806304f4efc51461025857806314ae9f2e1461026d57806316f0115b146102805780631848effa146102bd578063201e81a8146102d4575b600080fd5b61026b610266366004613954565b61064a565b005b61026b61027b366004613992565b61079f565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b6040516102b491906139af565b60405180910390f35b6102a76f22d53366457f9d5e68ec105046fc438381565b61026b6102e23660046139d9565b6108b1565b6002546102a7906001600160a01b031681565b61026b610308366004613954565b610935565b61026b61031b366004613992565b610b8c565b61033361032e366004613992565b610c98565b60405190151581526020016102b4565b61036a7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016102b4565b6102a773d061d61a4d941c39e5453435b6345dc261c2fce081565b6102a7734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b81565b6102a773f403c135812408bfbe8713b5a23a04b3d48aae3181565b61036a610d11565b6102a76103df366004613954565b610db5565b6103ec610ddf565b604080519384526020840192909252908201526060016102b4565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b6005546102a7906001600160a01b031681565b610449610e1c565b6040516102b49190613a9e565b61026b610e28565b610466610e64565b6040516102b49190613b17565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b61026b6104a8366004613992565b610ef2565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b6001546102a7906001600160a01b031681565b61036a61101c565b61026b610524366004613992565b61106b565b61026b610537366004613992565b611335565b61026b61054a366004613992565b6114fe565b61036a60075481565b7f00000000000000000000000000000000000000000000000000000000000000006102a7565b61036a6116bb565b61026b610594366004613992565b61176b565b61036a7f000000000000000000000000000000000000000000000000000000000000000081565b61036a611986565b6008546102a7906001600160a01b031681565b6000546102a7906001600160a01b031681565b6000546001600160a01b03166102a7565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b610466604051806040016040528060058152602001640352e302e360dc1b81525081565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b1580156106a357600080fd5b505afa1580156106b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106db9190613b4a565b6001600160a01b0316336001600160a01b0316146107145760405162461bcd60e51b815260040161070b90613b67565b60405180910390fd5b612710811061075e5760405162461bcd60e51b8152602060048201526016602482015275696e76616c69642d736c6970706167652d76616c756560501b604482015260640161070b565b60075460408051918252602082018390527f43a94473b3422f31e660358900c02b907f22142a3224beace1f2b9f1fa079a9e910160405180910390a1600755565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b1580156107f857600080fd5b505afa15801561080c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108309190613b4a565b6001600160a01b0316336001600160a01b0316146108605760405162461bcd60e51b815260040161070b90613b67565b61086b600382611a29565b6108ae5760405162461bcd60e51b81526020600482015260146024820152731c995b5bdd994b5ad9595c195c8b59985a5b195960621b604482015260640161070b565b50565b6108be335b600390611a3e565b6108da5760405162461bcd60e51b815260040161070b90613b9e565b6109037f0000000000000000000000000000000000000000000000000000000000000000611a60565b61090b611bd6565b805161091f916009916020909101906138c0565b5061092a6000612090565b6108ae600019612090565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161461097d5760405162461bcd60e51b815260040161070b90613bce565b6040516370a0823160e01b81526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a08231906109cc9030906004016139af565b60206040518083038186803b1580156109e457600080fd5b505afa1580156109f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1c9190613c01565b9050818110610a7d57610a796001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000846120e1565b5050565b610a8f610a8a8284613c30565b612144565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190610adb9030906004016139af565b60206040518083038186803b158015610af357600080fd5b505afa158015610b07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2b9190613c01565b9050610a797f0000000000000000000000000000000000000000000000000000000000000000610b5b8484612246565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691906120e1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b158015610be557600080fd5b505afa158015610bf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1d9190613b4a565b6001600160a01b0316336001600160a01b031614610c4d5760405162461bcd60e51b815260040161070b90613b67565b610c58600382611a0d565b6108ae5760405162461bcd60e51b81526020600482015260116024820152701859190b5ad9595c195c8b59985a5b1959607a1b604482015260640161070b565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480610d0b57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316145b92915050565b6040516370a0823160e01b81526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190610d609030906004016139af565b60206040518083038186803b158015610d7857600080fd5b505afa158015610d8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db09190613c01565b905090565b60098181548110610dc557600080fd5b6000918252602090912001546001600160a01b0316905081565b60008080610dec336108b6565b610e085760405162461bcd60e51b815260040161070b90613b9e565b610e1061225c565b9250925092505b909192565b6060610db06003612301565b610e31336108b6565b610e4d5760405162461bcd60e51b815260040161070b90613b9e565b610e576000612090565b610e62600019612090565b565b60068054610e7190613c47565b80601f0160208091040260200160405190810160405280929190818152602001828054610e9d90613c47565b8015610eea5780601f10610ebf57610100808354040283529160200191610eea565b820191906000526020600020905b815481529060010190602001808311610ecd57829003601f168201915b505050505081565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b158015610f4b57600080fd5b505afa158015610f5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f839190613b4a565b6001600160a01b0316336001600160a01b031614610fb35760405162461bcd60e51b815260040161070b90613b67565b600854604080516001600160a01b03928316815291831660208301527fc96bca3f57d35a1057a3357bced51fac157918147faa56845639671c516ec69c910160405180910390a1600880546001600160a01b0319166001600160a01b0392909216919091179055565b6040516370a0823160e01b81526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190610d609030906004016139af565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146110b35760405162461bcd60e51b815260040161070b90613bce565b6001600160a01b0381166111095760405162461bcd60e51b815260206004820152601c60248201527f6e65772d73747261746567792d616464726573732d69732d7a65726f00000000604482015260640161070b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b03166316f0115b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561116c57600080fd5b505afa158015611180573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a49190613b4a565b6001600160a01b0316146111f35760405162461bcd60e51b81526020600482015260166024820152756e6f742d76616c69642d6e65772d737472617465677960501b604482015260640161070b565b6111fc8161230e565b6000546040516370a0823160e01b81526112959183916001600160a01b03909116906370a08231906112329030906004016139af565b60206040518083038186803b15801561124a57600080fd5b505afa15801561125e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112829190613c01565b6000546001600160a01b031691906120e1565b6108ae817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016112e591906139af565b60206040518083038186803b1580156112fd57600080fd5b505afa158015611311573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5b9190613c01565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561138e57600080fd5b505afa1580156113a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c69190613b4a565b6001600160a01b0316336001600160a01b0316146113f65760405162461bcd60e51b815260040161070b90613b67565b6001600160a01b03811661144c5760405162461bcd60e51b815260206004820152601d60248201527f6665652d636f6c6c6563746f722d616464726573732d69732d7a65726f000000604482015260640161070b565b6001546001600160a01b03828116911614156114a25760405162461bcd60e51b81526020600482015260156024820152746665652d636f6c6c6563746f722d69732d73616d6560581b604482015260640161070b565b6001546040516001600160a01b038084169216907f0f06062680f9bd68e786e9980d9bb03d73d5620fc3b345e417b6eacb310b970690600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561155757600080fd5b505afa15801561156b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158f9190613b4a565b6001600160a01b0316336001600160a01b0316146115bf5760405162461bcd60e51b815260040161070b90613b67565b6001600160a01b03811661160f5760405162461bcd60e51b8152602060048201526017602482015276737761707065722d616464726573732d69732d7a65726f60481b604482015260640161070b565b6002546001600160a01b038281169116141561165f5760405162461bcd60e51b815260206004820152600f60248201526e737761707065722d69732d73616d6560881b604482015260640161070b565b6002546040516001600160a01b038084169216907f6c953b7ec311055c20b96a42cea31e89528e375b1bf953a503db40854b3188fe90600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b60006116c561101c565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a08231906117119030906004016139af565b60206040518083038186803b15801561172957600080fd5b505afa15801561173d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117619190613c01565b610db09190613c82565b611774336108b6565b6117905760405162461bcd60e51b815260040161070b90613b9e565b6001546001600160a01b03166117e05760405162461bcd60e51b81526020600482015260156024820152741999594b58dbdb1b1958dd1bdc8b5b9bdd0b5cd95d605a1b604482015260640161070b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614156118625760405162461bcd60e51b815260206004820152601f60248201527f6e6f742d616c6c6f7765642d746f2d73776565702d636f6c6c61746572616c00604482015260640161070b565b61186b81610c98565b156118af5760405162461bcd60e51b815260206004820152601460248201527306e6f742d616c6c6f7765642d746f2d73776565760641b604482015260640161070b565b6001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156118ea576001546108ae906001600160a01b0316476124e7565b6040516370a0823160e01b81526000906001600160a01b038316906370a08231906119199030906004016139af565b60206040518083038186803b15801561193157600080fd5b505afa158015611945573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119699190613c01565b600154909150610a79906001600160a01b038481169116836120e1565b60006119c16119936116bb565b6119bc7f0000000000000000000000000000000000000000000000000000000000000000612600565b61267d565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a08231906117119030906004016139af565b6000611a22836001600160a01b038416612727565b9392505050565b6000611a22836001600160a01b038416612776565b6001600160a01b03811660009081526001830160205260408120541515611a22565b611a68612869565b60095460005b81811015611bd157600060098281548110611a8b57611a8b613c9a565b60009182526020822001546040516370a0823160e01b81526001600160a01b03909116925082906370a0823190611ac69030906004016139af565b60206040518083038186803b158015611ade57600080fd5b505afa158015611af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b169190613c01565b90508015611bbc57600254604051636ccb2b0160e01b81526001600160a01b0384811660048301528781166024830152604482018490526001606483015230608483015290911690636ccb2b019060a401602060405180830381600087803b158015611b8157600080fd5b505af1925050508015611bb1575060408051601f3d908101601f19168201909252611bae91810190613c01565b60015b611bba57611bbc565b505b50508080611bc990613cb0565b915050611a6e565b505050565b60606000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d55a23f46040518163ffffffff1660e01b815260040160206040518083038186803b158015611c3457600080fd5b505afa158015611c48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c6c9190613c01565b905060005b81811015611df657604051632061aa2360e11b8152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906340c354469060240160206040518083038186803b158015611cdc57600080fd5b505afa158015611cf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d149190613b4a565b6001600160a01b031663f7c618c16040518163ffffffff1660e01b815260040160206040518083038186803b158015611d4c57600080fd5b505afa158015611d60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d849190613b4a565b90506001600160a01b03811673d533a949740bb3306d119cc777fa900ba034cd5214801590611dd057506001600160a01b038116734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b14155b15611de35783611ddf81613cb0565b9450505b5080611dee81613cb0565b915050611c71565b50611e02826002613c82565b67ffffffffffffffff811115611e1a57611e1a6139c3565b604051908082528060200260200182016040528015611e43578160200160208202803683370190505b50925073d533a949740bb3306d119cc777fa900ba034cd5283600081518110611e6e57611e6e613c9a565b60200260200101906001600160a01b031690816001600160a01b031681525050734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b83600181518110611eb657611eb6613c9a565b6001600160a01b0390921660209283029190910190910152600260005b8281101561208957604051632061aa2360e11b8152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906340c354469060240160206040518083038186803b158015611f3e57600080fd5b505afa158015611f52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f769190613b4a565b6001600160a01b031663f7c618c16040518163ffffffff1660e01b815260040160206040518083038186803b158015611fae57600080fd5b505afa158015611fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe69190613b4a565b90506001600160a01b03811673d533a949740bb3306d119cc777fa900ba034cd521480159061203257506001600160a01b038116734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b14155b156120765780868461204381613cb0565b95508151811061205557612055613c9a565b60200260200101906001600160a01b031690816001600160a01b0316815250505b508061208181613cb0565b915050611ed3565b5050505090565b6120d86001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001673f403c135812408bfbe8713b5a23a04b3d48aae318361294b565b6108ae81612a6f565b6040516001600160a01b038316602482015260448101829052611bd190849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612bb1565b600061216f7f0000000000000000000000000000000000000000000000000000000000000000612600565b9050600061217b610d11565b9050600061218761101c565b6121919083613c82565b905060006121bc6121a2838661267d565b6121ac8488613ccb565b6121b69190613cea565b83612246565b9050806121ca575050505050565b828111156121e4576121e46121df8483613c30565b612c83565b60006122317f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000084612d76565b905061223e828287612e33565b505050505050565b60008183106122555781611a22565b5090919050565b6000806000612269612ec4565b6040516302df682360e11b815260048101849052602481018390526044810182905292955090935091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906305bed04690606401600060405180830381600087803b1580156122e157600080fd5b505af11580156122f5573d6000803e3d6000fd5b50505050610e176132f5565b60606000611a22836133a2565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b15801561237157600080fd5b505afa158015612385573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a99190613b4a565b6001600160a01b0316146123f85760405162461bcd60e51b81526020600482015260166024820152753bb937b73396b1b7b63630ba32b930b616ba37b5b2b760511b604482015260640161070b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561245b57600080fd5b505afa15801561246f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124939190613b4a565b6001600160a01b0316146124df5760405162461bcd60e51b81526020600482015260136024820152723bb937b73396b932b1b2b4b83a16ba37b5b2b760691b604482015260640161070b565b6108ae6133fe565b804710156125375760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161070b565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612584576040519150601f19603f3d011682016040523d82523d6000602084013e612589565b606091505b5050905080611bd15760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161070b565b600060016001607f1b0319821215801561261d57506001607f1b82125b6126795760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b606482015260840161070b565b5090565b60008215610d0b5760405163cc2b27d760e01b815260048101849052600f83900b60248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063cc2b27d79060440160206040518083038186803b1580156126ef57600080fd5b505afa158015612703573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a229190613c01565b600081815260018301602052604081205461276e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d0b565b506000610d0b565b6000818152600183016020526040812054801561285f57600061279a600183613c30565b85549091506000906127ae90600190613c30565b90508181146128135760008660000182815481106127ce576127ce613c9a565b90600052602060002001549050808760000184815481106127f1576127f1613c9a565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061282457612824613d0c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d0b565b6000915050610d0b565b604051637050ccd960e01b8152306004820152600160248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690637050ccd990604401602060405180830381600087803b1580156128d157600080fd5b505af11580156128e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129099190613d22565b610e625760405162461bcd60e51b81526020600482015260136024820152721c995dd85c990b58db185a5b4b59985a5b1959606a1b604482015260640161070b565b8015806129d45750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561299a57600080fd5b505afa1580156129ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129d29190613c01565b155b612a3f5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161070b565b6040516001600160a01b038316602482015260448101829052611bd190849063095ea7b360e01b9060640161210d565b612a788161347a565b6002546001600160a01b0390811690612ad4907f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000008461294b565b612b086001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016828461294b565b60095460005b81811015612b5c57612b4a838560098481548110612b2e57612b2e613c9a565b6000918252602090912001546001600160a01b0316919061294b565b80612b5481613cb0565b915050612b0e565b50611bd16001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000008561294b565b6000612c06826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134ce9092919063ffffffff16565b805190915015611bd15780806020019051810190612c249190613d22565b611bd15760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161070b565b80156108ae57604051636197390160e11b815260048101829052600060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c32e720290604401602060405180830381600087803b158015612cf257600080fd5b505af1158015612d06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d2a9190613d22565b6108ae5760405162461bcd60e51b815260206004820152601a60248201527f77697468647261772d616e642d756e777261702d6661696c6564000000000000604482015260640161070b565b6000612710600754612710612d8b9190613c30565b600854604051632d9198e160e21b81526001600160a01b0388811660048301528781166024830152604482018790529091169063b64663849060640160206040518083038186803b158015612ddf57600080fd5b505afa158015612df3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e179190613c01565b612e219190613ccb565b612e2b9190613cea565b949350505050565b604051630d2680e960e11b815260048101849052600f82900b6024820152604481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631a4d01d2906064015b600060405180830381600087803b158015612ea757600080fd5b505af1158015612ebb573d6000803e3d6000fd5b50505050505050565b6000806000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d53ddc26306040518263ffffffff1660e01b8152600401612f1691906139af565b60206040518083038186803b158015612f2e57600080fd5b505afa158015612f42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f669190613c01565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639f2b2833306040518263ffffffff1660e01b8152600401612fb691906139af565b60206040518083038186803b158015612fce57600080fd5b505afa158015612fe2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130069190613c01565b90506130317f0000000000000000000000000000000000000000000000000000000000000000611a60565b600061305c7f0000000000000000000000000000000000000000000000000000000000000000612600565b90506000613068610d11565b9050600061307461101c565b61307e9083613c82565b9050600061308c828561267d565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016130dc91906139af565b60206040518083038186803b1580156130f457600080fd5b505afa158015613108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312c9190613c01565b9050600061313a8383613c82565b9050868111156131555761314e8782613c30565b9a50613162565b61315f8188613c30565b99505b600061316e898d613c82565b9050828111156132b857600061318d6131878584613c30565b86612246565b905080156132b65760006131b5866131a58985613ccb565b6131af9190613cea565b88612246565b905080156132b457878111156131d2576131d26121df8983613c30565b60005461321590829061320f906001600160a01b03167f000000000000000000000000000000000000000000000000000000000000000083612d76565b8b612e33565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a08231906132619030906004016139af565b60206040518083038186803b15801561327957600080fd5b505afa15801561328d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b19190613c01565b94505b505b505b6132c2838a612246565b99508983116132d25760006132e5565b6132e56132df8b85613c30565b8d612246565b9b50505050505050505050909192565b6040516370a0823160e01b815261339a906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a08231906133459030906004016139af565b60206040518083038186803b15801561335d57600080fd5b505afa158015613371573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133959190613c01565b6134dd565b610e626135c1565b6060816000018054806020026020016040519081016040528092919081815260200182805480156133f257602002820191906000526020600020905b8154815260200190600101908083116133de575b50505050509050919050565b6040516324f81cd160e11b8152600160048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906349f039a290602401600060405180830381600087803b15801561346057600080fd5b505af1158015613474573d6000803e3d6000fd5b50505050565b6108ae6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000008361294b565b6060612e2b848460008561375f565b80156108ae576134eb613921565b81817f00000000000000000000000000000000000000000000000000000000000000006002811061351e5761351e613c9a565b602002015260006135707f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000085612d76565b604051630b4c7e4d60e01b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630b4c7e4d90612e8d9085908590600401613d44565b6040516370a0823160e01b81526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a08231906136109030906004016139af565b60206040518083038186803b15801561362857600080fd5b505afa15801561363c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136609190613c01565b905080156108ae576040516321d0683360e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290526001604482015273f403c135812408bfbe8713b5a23a04b3d48aae31906343a0d06690606401602060405180830381600087803b1580156136e257600080fd5b505af11580156136f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371a9190613d22565b6108ae5760405162461bcd60e51b8152602060048201526016602482015275189bdbdcdd195c8b59195c1bdcda5d0b59985a5b195960521b604482015260640161070b565b6060824710156137c05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161070b565b843b61380e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161070b565b600080866001600160a01b0316858760405161382a9190613d7c565b60006040518083038185875af1925050503d8060008114613867576040519150601f19603f3d011682016040523d82523d6000602084013e61386c565b606091505b509150915061387c828286613887565b979650505050505050565b60608315613896575081611a22565b8251156138a65782518084602001fd5b8160405162461bcd60e51b815260040161070b9190613b17565b828054828255906000526020600020908101928215613915579160200282015b8281111561391557825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906138e0565b5061267992915061393f565b60405180604001604052806002906020820280368337509192915050565b5b808211156126795760008155600101613940565b60006020828403121561396657600080fd5b5035919050565b6001600160a01b03811681146108ae57600080fd5b803561398d8161396d565b919050565b6000602082840312156139a457600080fd5b8135611a228161396d565b6001600160a01b0391909116815260200190565b634e487b7160e01b600052604160045260246000fd5b600060208083850312156139ec57600080fd5b823567ffffffffffffffff80821115613a0457600080fd5b818501915085601f830112613a1857600080fd5b813581811115613a2a57613a2a6139c3565b8060051b604051601f19603f83011681018181108582111715613a4f57613a4f6139c3565b604052918252848201925083810185019188831115613a6d57600080fd5b938501935b82851015613a9257613a8385613982565b84529385019392850192613a72565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613adf5783516001600160a01b031683529284019291840191600101613aba565b50909695505050505050565b60005b83811015613b06578181015183820152602001613aee565b838111156134745750506000910152565b6020815260008251806020840152613b36816040850160208701613aeb565b601f01601f19169190910160400192915050565b600060208284031215613b5c57600080fd5b8151611a228161396d565b6020808252601a908201527f63616c6c65722d69732d6e6f742d7468652d676f7665726e6f72000000000000604082015260600190565b60208082526016908201527531b0b63632b916b4b996b737ba16b096b5b2b2b832b960511b604082015260600190565b60208082526019908201527818d85b1b195c8b5a5ccb5b9bdd0b5d995cdc195c8b5c1bdbdb603a1b604082015260600190565b600060208284031215613c1357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015613c4257613c42613c1a565b500390565b600181811c90821680613c5b57607f821691505b60208210811415613c7c57634e487b7160e01b600052602260045260246000fd5b50919050565b60008219821115613c9557613c95613c1a565b500190565b634e487b7160e01b600052603260045260246000fd5b6000600019821415613cc457613cc4613c1a565b5060010190565b6000816000190483118215151615613ce557613ce5613c1a565b500290565b600082613d0757634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603160045260246000fd5b600060208284031215613d3457600080fd5b81518015158114611a2257600080fd5b60608101818460005b6002811015613d6c578151835260209283019290910190600101613d4d565b5050508260408301529392505050565b60008251613d8e818460208701613aeb565b919091019291505056fea26469706673582212209120bdb297341817579e73659cb82099f7b828dd41f725911538d7ddd2a5bb8764736f6c63430008090033000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba5000000000000000000000000dcef968d416a41cdac0ed8702fac8128a64241a20000000000000000000000000000000000000000000000000000000000000032000000000000000000000000db2d0baae78f1dc2a8504b471f3cea257b2c37660000000000000000000000008f156189a3cd28dfc8fb7bbbace58f98f09c0bb30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000014436f6e7665785f66726178757364635f46524158000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102535760003560e01c8063a3f4df7e11610146578063d572fd7f116100c3578063e5328e0611610087578063e5328e06146105c0578063eaada382146105c8578063ec78e832146105db578063fc0c546a146105ee578063fd57a4df146105ff578063ffa1ad741461062657600080fd5b8063d572fd7f1461054f578063d8dfeb4514610558578063de603fdc1461057e578063e00af4a714610586578063e529ee951461059957600080fd5b8063c415b95c1161010a578063c415b95c146104fb578063c965fa8a1461050e578063ce5494bb14610516578063d2c35ce814610529578063d3033c391461053c57600080fd5b8063a3f4df7e1461045e578063a7404b7014610473578063abc9b45e1461049a578063b2016bd4146104ad578063b20fdc0d146104d457600080fd5b806374db9ad4116101d45780637d7c2a1c116101985780637d7c2a1c146103e45780637f44579b14610407578063945c91421461042e578063951dc22c1461044157806399b71d5c1461045657600080fd5b806374db9ad414610378578063759cb53b1461039357806375b0ffd1146103ae578063795dae66146103c95780637bb7bed1146103d157600080fd5b80632b3297f91161021b5780632b3297f9146102e75780632e1a7d4d146102fa5780634032b72b1461030d578063440d72481461032057806348cd2ddd1461034357600080fd5b806304f4efc51461025857806314ae9f2e1461026d57806316f0115b146102805780631848effa146102bd578063201e81a8146102d4575b600080fd5b61026b610266366004613954565b61064a565b005b61026b61027b366004613992565b61079f565b6102a77f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba581565b6040516102b491906139af565b60405180910390f35b6102a76f22d53366457f9d5e68ec105046fc438381565b61026b6102e23660046139d9565b6108b1565b6002546102a7906001600160a01b031681565b61026b610308366004613954565b610935565b61026b61031b366004613992565b610b8c565b61033361032e366004613992565b610c98565b60405190151581526020016102b4565b61036a7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016102b4565b6102a773d061d61a4d941c39e5453435b6345dc261c2fce081565b6102a7734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b81565b6102a773f403c135812408bfbe8713b5a23a04b3d48aae3181565b61036a610d11565b6102a76103df366004613954565b610db5565b6103ec610ddf565b604080519384526020840192909252908201526060016102b4565b6102a77f0000000000000000000000003175df0976dfa876431c2e9ee6bc45b65d3473cc81565b6005546102a7906001600160a01b031681565b610449610e1c565b6040516102b49190613a9e565b61026b610e28565b610466610e64565b6040516102b49190613b17565b6102a77f0000000000000000000000007e880867363a7e321f5d260cade2b0bb2f717b0281565b61026b6104a8366004613992565b610ef2565b6102a77f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e81565b6102a77f000000000000000000000000dcef968d416a41cdac0ed8702fac8128a64241a281565b6001546102a7906001600160a01b031681565b61036a61101c565b61026b610524366004613992565b61106b565b61026b610537366004613992565b611335565b61026b61054a366004613992565b6114fe565b61036a60075481565b7f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e6102a7565b61036a6116bb565b61026b610594366004613992565b61176b565b61036a7f000000000000000000000000000000000000000000000000000000000000006481565b61036a611986565b6008546102a7906001600160a01b031681565b6000546102a7906001600160a01b031681565b6000546001600160a01b03166102a7565b6102a77f000000000000000000000000cfc25170633581bf896cb6cdee170e3e3aa5950381565b610466604051806040016040528060058152602001640352e302e360dc1b81525081565b7f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba56001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b1580156106a357600080fd5b505afa1580156106b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106db9190613b4a565b6001600160a01b0316336001600160a01b0316146107145760405162461bcd60e51b815260040161070b90613b67565b60405180910390fd5b612710811061075e5760405162461bcd60e51b8152602060048201526016602482015275696e76616c69642d736c6970706167652d76616c756560501b604482015260640161070b565b60075460408051918252602082018390527f43a94473b3422f31e660358900c02b907f22142a3224beace1f2b9f1fa079a9e910160405180910390a1600755565b7f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba56001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b1580156107f857600080fd5b505afa15801561080c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108309190613b4a565b6001600160a01b0316336001600160a01b0316146108605760405162461bcd60e51b815260040161070b90613b67565b61086b600382611a29565b6108ae5760405162461bcd60e51b81526020600482015260146024820152731c995b5bdd994b5ad9595c195c8b59985a5b195960621b604482015260640161070b565b50565b6108be335b600390611a3e565b6108da5760405162461bcd60e51b815260040161070b90613b9e565b6109037f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e611a60565b61090b611bd6565b805161091f916009916020909101906138c0565b5061092a6000612090565b6108ae600019612090565b337f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba56001600160a01b03161461097d5760405162461bcd60e51b815260040161070b90613bce565b6040516370a0823160e01b81526000906001600160a01b037f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e16906370a08231906109cc9030906004016139af565b60206040518083038186803b1580156109e457600080fd5b505afa1580156109f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1c9190613c01565b9050818110610a7d57610a796001600160a01b037f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e167f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba5846120e1565b5050565b610a8f610a8a8284613c30565b612144565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e16906370a0823190610adb9030906004016139af565b60206040518083038186803b158015610af357600080fd5b505afa158015610b07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2b9190613c01565b9050610a797f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba5610b5b8484612246565b6001600160a01b037f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e1691906120e1565b7f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba56001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b158015610be557600080fd5b505afa158015610bf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1d9190613b4a565b6001600160a01b0316336001600160a01b031614610c4d5760405162461bcd60e51b815260040161070b90613b67565b610c58600382611a0d565b6108ae5760405162461bcd60e51b81526020600482015260116024820152701859190b5ad9595c195c8b59985a5b1959607a1b604482015260640161070b565b60007f0000000000000000000000003175df0976dfa876431c2e9ee6bc45b65d3473cc6001600160a01b0316826001600160a01b03161480610d0b57507f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e6001600160a01b0316826001600160a01b0316145b92915050565b6040516370a0823160e01b81526000906001600160a01b037f0000000000000000000000003175df0976dfa876431c2e9ee6bc45b65d3473cc16906370a0823190610d609030906004016139af565b60206040518083038186803b158015610d7857600080fd5b505afa158015610d8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db09190613c01565b905090565b60098181548110610dc557600080fd5b6000918252602090912001546001600160a01b0316905081565b60008080610dec336108b6565b610e085760405162461bcd60e51b815260040161070b90613b9e565b610e1061225c565b9250925092505b909192565b6060610db06003612301565b610e31336108b6565b610e4d5760405162461bcd60e51b815260040161070b90613b9e565b610e576000612090565b610e62600019612090565b565b60068054610e7190613c47565b80601f0160208091040260200160405190810160405280929190818152602001828054610e9d90613c47565b8015610eea5780601f10610ebf57610100808354040283529160200191610eea565b820191906000526020600020905b815481529060010190602001808311610ecd57829003601f168201915b505050505081565b7f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba56001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b158015610f4b57600080fd5b505afa158015610f5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f839190613b4a565b6001600160a01b0316336001600160a01b031614610fb35760405162461bcd60e51b815260040161070b90613b67565b600854604080516001600160a01b03928316815291831660208301527fc96bca3f57d35a1057a3357bced51fac157918147faa56845639671c516ec69c910160405180910390a1600880546001600160a01b0319166001600160a01b0392909216919091179055565b6040516370a0823160e01b81526000906001600160a01b037f0000000000000000000000007e880867363a7e321f5d260cade2b0bb2f717b0216906370a0823190610d609030906004016139af565b337f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba56001600160a01b0316146110b35760405162461bcd60e51b815260040161070b90613bce565b6001600160a01b0381166111095760405162461bcd60e51b815260206004820152601c60248201527f6e65772d73747261746567792d616464726573732d69732d7a65726f00000000604482015260640161070b565b7f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba56001600160a01b0316816001600160a01b03166316f0115b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561116c57600080fd5b505afa158015611180573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a49190613b4a565b6001600160a01b0316146111f35760405162461bcd60e51b81526020600482015260166024820152756e6f742d76616c69642d6e65772d737472617465677960501b604482015260640161070b565b6111fc8161230e565b6000546040516370a0823160e01b81526112959183916001600160a01b03909116906370a08231906112329030906004016139af565b60206040518083038186803b15801561124a57600080fd5b505afa15801561125e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112829190613c01565b6000546001600160a01b031691906120e1565b6108ae817f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e6001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016112e591906139af565b60206040518083038186803b1580156112fd57600080fd5b505afa158015611311573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5b9190613c01565b7f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba56001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561138e57600080fd5b505afa1580156113a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c69190613b4a565b6001600160a01b0316336001600160a01b0316146113f65760405162461bcd60e51b815260040161070b90613b67565b6001600160a01b03811661144c5760405162461bcd60e51b815260206004820152601d60248201527f6665652d636f6c6c6563746f722d616464726573732d69732d7a65726f000000604482015260640161070b565b6001546001600160a01b03828116911614156114a25760405162461bcd60e51b81526020600482015260156024820152746665652d636f6c6c6563746f722d69732d73616d6560581b604482015260640161070b565b6001546040516001600160a01b038084169216907f0f06062680f9bd68e786e9980d9bb03d73d5620fc3b345e417b6eacb310b970690600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b7f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba56001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561155757600080fd5b505afa15801561156b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158f9190613b4a565b6001600160a01b0316336001600160a01b0316146115bf5760405162461bcd60e51b815260040161070b90613b67565b6001600160a01b03811661160f5760405162461bcd60e51b8152602060048201526017602482015276737761707065722d616464726573732d69732d7a65726f60481b604482015260640161070b565b6002546001600160a01b038281169116141561165f5760405162461bcd60e51b815260206004820152600f60248201526e737761707065722d69732d73616d6560881b604482015260640161070b565b6002546040516001600160a01b038084169216907f6c953b7ec311055c20b96a42cea31e89528e375b1bf953a503db40854b3188fe90600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b60006116c561101c565b6040516370a0823160e01b81526001600160a01b037f0000000000000000000000003175df0976dfa876431c2e9ee6bc45b65d3473cc16906370a08231906117119030906004016139af565b60206040518083038186803b15801561172957600080fd5b505afa15801561173d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117619190613c01565b610db09190613c82565b611774336108b6565b6117905760405162461bcd60e51b815260040161070b90613b9e565b6001546001600160a01b03166117e05760405162461bcd60e51b81526020600482015260156024820152741999594b58dbdb1b1958dd1bdc8b5b9bdd0b5cd95d605a1b604482015260640161070b565b7f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e6001600160a01b0316816001600160a01b031614156118625760405162461bcd60e51b815260206004820152601f60248201527f6e6f742d616c6c6f7765642d746f2d73776565702d636f6c6c61746572616c00604482015260640161070b565b61186b81610c98565b156118af5760405162461bcd60e51b815260206004820152601460248201527306e6f742d616c6c6f7765642d746f2d73776565760641b604482015260640161070b565b6001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156118ea576001546108ae906001600160a01b0316476124e7565b6040516370a0823160e01b81526000906001600160a01b038316906370a08231906119199030906004016139af565b60206040518083038186803b15801561193157600080fd5b505afa158015611945573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119699190613c01565b600154909150610a79906001600160a01b038481169116836120e1565b60006119c16119936116bb565b6119bc7f0000000000000000000000000000000000000000000000000000000000000000612600565b61267d565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e16906370a08231906117119030906004016139af565b6000611a22836001600160a01b038416612727565b9392505050565b6000611a22836001600160a01b038416612776565b6001600160a01b03811660009081526001830160205260408120541515611a22565b611a68612869565b60095460005b81811015611bd157600060098281548110611a8b57611a8b613c9a565b60009182526020822001546040516370a0823160e01b81526001600160a01b03909116925082906370a0823190611ac69030906004016139af565b60206040518083038186803b158015611ade57600080fd5b505afa158015611af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b169190613c01565b90508015611bbc57600254604051636ccb2b0160e01b81526001600160a01b0384811660048301528781166024830152604482018490526001606483015230608483015290911690636ccb2b019060a401602060405180830381600087803b158015611b8157600080fd5b505af1925050508015611bb1575060408051601f3d908101601f19168201909252611bae91810190613c01565b60015b611bba57611bbc565b505b50508080611bc990613cb0565b915050611a6e565b505050565b60606000807f0000000000000000000000007e880867363a7e321f5d260cade2b0bb2f717b026001600160a01b031663d55a23f46040518163ffffffff1660e01b815260040160206040518083038186803b158015611c3457600080fd5b505afa158015611c48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c6c9190613c01565b905060005b81811015611df657604051632061aa2360e11b8152600481018290526000907f0000000000000000000000007e880867363a7e321f5d260cade2b0bb2f717b026001600160a01b0316906340c354469060240160206040518083038186803b158015611cdc57600080fd5b505afa158015611cf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d149190613b4a565b6001600160a01b031663f7c618c16040518163ffffffff1660e01b815260040160206040518083038186803b158015611d4c57600080fd5b505afa158015611d60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d849190613b4a565b90506001600160a01b03811673d533a949740bb3306d119cc777fa900ba034cd5214801590611dd057506001600160a01b038116734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b14155b15611de35783611ddf81613cb0565b9450505b5080611dee81613cb0565b915050611c71565b50611e02826002613c82565b67ffffffffffffffff811115611e1a57611e1a6139c3565b604051908082528060200260200182016040528015611e43578160200160208202803683370190505b50925073d533a949740bb3306d119cc777fa900ba034cd5283600081518110611e6e57611e6e613c9a565b60200260200101906001600160a01b031690816001600160a01b031681525050734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b83600181518110611eb657611eb6613c9a565b6001600160a01b0390921660209283029190910190910152600260005b8281101561208957604051632061aa2360e11b8152600481018290526000907f0000000000000000000000007e880867363a7e321f5d260cade2b0bb2f717b026001600160a01b0316906340c354469060240160206040518083038186803b158015611f3e57600080fd5b505afa158015611f52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f769190613b4a565b6001600160a01b031663f7c618c16040518163ffffffff1660e01b815260040160206040518083038186803b158015611fae57600080fd5b505afa158015611fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe69190613b4a565b90506001600160a01b03811673d533a949740bb3306d119cc777fa900ba034cd521480159061203257506001600160a01b038116734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b14155b156120765780868461204381613cb0565b95508151811061205557612055613c9a565b60200260200101906001600160a01b031690816001600160a01b0316815250505b508061208181613cb0565b915050611ed3565b5050505090565b6120d86001600160a01b037f0000000000000000000000003175df0976dfa876431c2e9ee6bc45b65d3473cc1673f403c135812408bfbe8713b5a23a04b3d48aae318361294b565b6108ae81612a6f565b6040516001600160a01b038316602482015260448101829052611bd190849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612bb1565b600061216f7f0000000000000000000000000000000000000000000000000000000000000000612600565b9050600061217b610d11565b9050600061218761101c565b6121919083613c82565b905060006121bc6121a2838661267d565b6121ac8488613ccb565b6121b69190613cea565b83612246565b9050806121ca575050505050565b828111156121e4576121e46121df8483613c30565b612c83565b60006122317f0000000000000000000000003175df0976dfa876431c2e9ee6bc45b65d3473cc7f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e84612d76565b905061223e828287612e33565b505050505050565b60008183106122555781611a22565b5090919050565b6000806000612269612ec4565b6040516302df682360e11b815260048101849052602481018390526044810182905292955090935091507f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba56001600160a01b0316906305bed04690606401600060405180830381600087803b1580156122e157600080fd5b505af11580156122f5573d6000803e3d6000fd5b50505050610e176132f5565b60606000611a22836133a2565b7f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e6001600160a01b0316816001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b15801561237157600080fd5b505afa158015612385573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a99190613b4a565b6001600160a01b0316146123f85760405162461bcd60e51b81526020600482015260166024820152753bb937b73396b1b7b63630ba32b930b616ba37b5b2b760511b604482015260640161070b565b7f0000000000000000000000003175df0976dfa876431c2e9ee6bc45b65d3473cc6001600160a01b0316816001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561245b57600080fd5b505afa15801561246f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124939190613b4a565b6001600160a01b0316146124df5760405162461bcd60e51b81526020600482015260136024820152723bb937b73396b932b1b2b4b83a16ba37b5b2b760691b604482015260640161070b565b6108ae6133fe565b804710156125375760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161070b565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612584576040519150601f19603f3d011682016040523d82523d6000602084013e612589565b606091505b5050905080611bd15760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161070b565b600060016001607f1b0319821215801561261d57506001607f1b82125b6126795760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b606482015260840161070b565b5090565b60008215610d0b5760405163cc2b27d760e01b815260048101849052600f83900b60248201527f000000000000000000000000dcef968d416a41cdac0ed8702fac8128a64241a26001600160a01b03169063cc2b27d79060440160206040518083038186803b1580156126ef57600080fd5b505afa158015612703573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a229190613c01565b600081815260018301602052604081205461276e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d0b565b506000610d0b565b6000818152600183016020526040812054801561285f57600061279a600183613c30565b85549091506000906127ae90600190613c30565b90508181146128135760008660000182815481106127ce576127ce613c9a565b90600052602060002001549050808760000184815481106127f1576127f1613c9a565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061282457612824613d0c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d0b565b6000915050610d0b565b604051637050ccd960e01b8152306004820152600160248201527f0000000000000000000000007e880867363a7e321f5d260cade2b0bb2f717b026001600160a01b031690637050ccd990604401602060405180830381600087803b1580156128d157600080fd5b505af11580156128e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129099190613d22565b610e625760405162461bcd60e51b81526020600482015260136024820152721c995dd85c990b58db185a5b4b59985a5b1959606a1b604482015260640161070b565b8015806129d45750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561299a57600080fd5b505afa1580156129ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129d29190613c01565b155b612a3f5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161070b565b6040516001600160a01b038316602482015260448101829052611bd190849063095ea7b360e01b9060640161210d565b612a788161347a565b6002546001600160a01b0390811690612ad4907f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e167f000000000000000000000000dcef968d416a41cdac0ed8702fac8128a64241a28461294b565b612b086001600160a01b037f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e16828461294b565b60095460005b81811015612b5c57612b4a838560098481548110612b2e57612b2e613c9a565b6000918252602090912001546001600160a01b0316919061294b565b80612b5481613cb0565b915050612b0e565b50611bd16001600160a01b037f0000000000000000000000003175df0976dfa876431c2e9ee6bc45b65d3473cc167f000000000000000000000000cfc25170633581bf896cb6cdee170e3e3aa595038561294b565b6000612c06826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134ce9092919063ffffffff16565b805190915015611bd15780806020019051810190612c249190613d22565b611bd15760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161070b565b80156108ae57604051636197390160e11b815260048101829052600060248201527f0000000000000000000000007e880867363a7e321f5d260cade2b0bb2f717b026001600160a01b03169063c32e720290604401602060405180830381600087803b158015612cf257600080fd5b505af1158015612d06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d2a9190613d22565b6108ae5760405162461bcd60e51b815260206004820152601a60248201527f77697468647261772d616e642d756e777261702d6661696c6564000000000000604482015260640161070b565b6000612710600754612710612d8b9190613c30565b600854604051632d9198e160e21b81526001600160a01b0388811660048301528781166024830152604482018790529091169063b64663849060640160206040518083038186803b158015612ddf57600080fd5b505afa158015612df3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e179190613c01565b612e219190613ccb565b612e2b9190613cea565b949350505050565b604051630d2680e960e11b815260048101849052600f82900b6024820152604481018390527f000000000000000000000000dcef968d416a41cdac0ed8702fac8128a64241a26001600160a01b031690631a4d01d2906064015b600060405180830381600087803b158015612ea757600080fd5b505af1158015612ebb573d6000803e3d6000fd5b50505050505050565b6000806000807f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba56001600160a01b031663d53ddc26306040518263ffffffff1660e01b8152600401612f1691906139af565b60206040518083038186803b158015612f2e57600080fd5b505afa158015612f42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f669190613c01565b905060007f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba56001600160a01b0316639f2b2833306040518263ffffffff1660e01b8152600401612fb691906139af565b60206040518083038186803b158015612fce57600080fd5b505afa158015612fe2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130069190613c01565b90506130317f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e611a60565b600061305c7f0000000000000000000000000000000000000000000000000000000000000000612600565b90506000613068610d11565b9050600061307461101c565b61307e9083613c82565b9050600061308c828561267d565b905060007f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e6001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016130dc91906139af565b60206040518083038186803b1580156130f457600080fd5b505afa158015613108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312c9190613c01565b9050600061313a8383613c82565b9050868111156131555761314e8782613c30565b9a50613162565b61315f8188613c30565b99505b600061316e898d613c82565b9050828111156132b857600061318d6131878584613c30565b86612246565b905080156132b65760006131b5866131a58985613ccb565b6131af9190613cea565b88612246565b905080156132b457878111156131d2576131d26121df8983613c30565b60005461321590829061320f906001600160a01b03167f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e83612d76565b8b612e33565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e16906370a08231906132619030906004016139af565b60206040518083038186803b15801561327957600080fd5b505afa15801561328d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b19190613c01565b94505b505b505b6132c2838a612246565b99508983116132d25760006132e5565b6132e56132df8b85613c30565b8d612246565b9b50505050505050505050909192565b6040516370a0823160e01b815261339a906001600160a01b037f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e16906370a08231906133459030906004016139af565b60206040518083038186803b15801561335d57600080fd5b505afa158015613371573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133959190613c01565b6134dd565b610e626135c1565b6060816000018054806020026020016040519081016040528092919081815260200182805480156133f257602002820191906000526020600020905b8154815260200190600101908083116133de575b50505050509050919050565b6040516324f81cd160e11b8152600160048201527f0000000000000000000000007e880867363a7e321f5d260cade2b0bb2f717b026001600160a01b0316906349f039a290602401600060405180830381600087803b15801561346057600080fd5b505af1158015613474573d6000803e3d6000fd5b50505050565b6108ae6001600160a01b037f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e167f000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba58361294b565b6060612e2b848460008561375f565b80156108ae576134eb613921565b81817f00000000000000000000000000000000000000000000000000000000000000006002811061351e5761351e613c9a565b602002015260006135707f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e7f0000000000000000000000003175df0976dfa876431c2e9ee6bc45b65d3473cc85612d76565b604051630b4c7e4d60e01b81529091506001600160a01b037f000000000000000000000000dcef968d416a41cdac0ed8702fac8128a64241a21690630b4c7e4d90612e8d9085908590600401613d44565b6040516370a0823160e01b81526000906001600160a01b037f0000000000000000000000003175df0976dfa876431c2e9ee6bc45b65d3473cc16906370a08231906136109030906004016139af565b60206040518083038186803b15801561362857600080fd5b505afa15801561363c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136609190613c01565b905080156108ae576040516321d0683360e11b81527f00000000000000000000000000000000000000000000000000000000000000646004820152602481018290526001604482015273f403c135812408bfbe8713b5a23a04b3d48aae31906343a0d06690606401602060405180830381600087803b1580156136e257600080fd5b505af11580156136f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371a9190613d22565b6108ae5760405162461bcd60e51b8152602060048201526016602482015275189bdbdcdd195c8b59195c1bdcda5d0b59985a5b195960521b604482015260640161070b565b6060824710156137c05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161070b565b843b61380e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161070b565b600080866001600160a01b0316858760405161382a9190613d7c565b60006040518083038185875af1925050503d8060008114613867576040519150601f19603f3d011682016040523d82523d6000602084013e61386c565b606091505b509150915061387c828286613887565b979650505050505050565b60608315613896575081611a22565b8251156138a65782518084602001fd5b8160405162461bcd60e51b815260040161070b9190613b17565b828054828255906000526020600020908101928215613915579160200282015b8281111561391557825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906138e0565b5061267992915061393f565b60405180604001604052806002906020820280368337509192915050565b5b808211156126795760008155600101613940565b60006020828403121561396657600080fd5b5035919050565b6001600160a01b03811681146108ae57600080fd5b803561398d8161396d565b919050565b6000602082840312156139a457600080fd5b8135611a228161396d565b6001600160a01b0391909116815260200190565b634e487b7160e01b600052604160045260246000fd5b600060208083850312156139ec57600080fd5b823567ffffffffffffffff80821115613a0457600080fd5b818501915085601f830112613a1857600080fd5b813581811115613a2a57613a2a6139c3565b8060051b604051601f19603f83011681018181108582111715613a4f57613a4f6139c3565b604052918252848201925083810185019188831115613a6d57600080fd5b938501935b82851015613a9257613a8385613982565b84529385019392850192613a72565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613adf5783516001600160a01b031683529284019291840191600101613aba565b50909695505050505050565b60005b83811015613b06578181015183820152602001613aee565b838111156134745750506000910152565b6020815260008251806020840152613b36816040850160208701613aeb565b601f01601f19169190910160400192915050565b600060208284031215613b5c57600080fd5b8151611a228161396d565b6020808252601a908201527f63616c6c65722d69732d6e6f742d7468652d676f7665726e6f72000000000000604082015260600190565b60208082526016908201527531b0b63632b916b4b996b737ba16b096b5b2b2b832b960511b604082015260600190565b60208082526019908201527818d85b1b195c8b5a5ccb5b9bdd0b5d995cdc195c8b5c1bdbdb603a1b604082015260600190565b600060208284031215613c1357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015613c4257613c42613c1a565b500390565b600181811c90821680613c5b57607f821691505b60208210811415613c7c57634e487b7160e01b600052602260045260246000fd5b50919050565b60008219821115613c9557613c95613c1a565b500190565b634e487b7160e01b600052603260045260246000fd5b6000600019821415613cc457613cc4613c1a565b5060010190565b6000816000190483118215151615613ce557613ce5613c1a565b500290565b600082613d0757634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603160045260246000fd5b600060208284031215613d3457600080fd5b81518015158114611a2257600080fd5b60608101818460005b6002811015613d6c578151835260209283019290910190600101613d4d565b5050508260408301529392505050565b60008251613d8e818460208701613aeb565b919091019291505056fea26469706673582212209120bdb297341817579e73659cb82099f7b828dd41f725911538d7ddd2a5bb8764736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba5000000000000000000000000dcef968d416a41cdac0ed8702fac8128a64241a20000000000000000000000000000000000000000000000000000000000000032000000000000000000000000db2d0baae78f1dc2a8504b471f3cea257b2c37660000000000000000000000008f156189a3cd28dfc8fb7bbbace58f98f09c0bb30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000014436f6e7665785f66726178757364635f46524158000000000000000000000000
-----Decoded View---------------
Arg [0] : pool_ (address): 0xc14900dFB1Aa54e7674e1eCf9ce02b3b35157ba5
Arg [1] : crvPool_ (address): 0xDcEF968d416a41Cdac0ED8702fAC8128A64241A2
Arg [2] : crvSlippage_ (uint256): 50
Arg [3] : masterOracle_ (address): 0xdB2D0baae78f1dc2A8504B471F3cea257b2C3766
Arg [4] : swapper_ (address): 0x8f156189A3CD28dFc8FB7BbbAce58F98F09c0bB3
Arg [5] : collateralIdx_ (uint256): 0
Arg [6] : convexPoolId_ (uint256): 100
Arg [7] : _name (string): Convex_fraxusdc_FRAX
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 000000000000000000000000c14900dfb1aa54e7674e1ecf9ce02b3b35157ba5
Arg [1] : 000000000000000000000000dcef968d416a41cdac0ed8702fac8128a64241a2
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000032
Arg [3] : 000000000000000000000000db2d0baae78f1dc2a8504b471f3cea257b2c3766
Arg [4] : 0000000000000000000000008f156189a3cd28dfc8fb7bbbace58f98f09c0bb3
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [9] : 436f6e7665785f66726178757364635f46524158000000000000000000000000
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.