Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 174 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim And Swap R... | 18603193 | 442 days ago | IN | 0 ETH | 0.00583358 | ||||
Rebalance | 18590785 | 444 days ago | IN | 0 ETH | 0.01486129 | ||||
Rebalance | 18554721 | 449 days ago | IN | 0 ETH | 0.01120102 | ||||
Claim And Swap R... | 18524871 | 453 days ago | IN | 0 ETH | 0.0082998 | ||||
Rebalance | 18518666 | 454 days ago | IN | 0 ETH | 0.01292534 | ||||
Rebalance | 18482698 | 459 days ago | IN | 0 ETH | 0.00757271 | ||||
Claim And Swap R... | 18453179 | 463 days ago | IN | 0 ETH | 0.00411407 | ||||
Rebalance | 18441625 | 465 days ago | IN | 0 ETH | 0.0064326 | ||||
Rebalance | 18405622 | 470 days ago | IN | 0 ETH | 0.0032855 | ||||
Claim And Swap R... | 18374873 | 474 days ago | IN | 0 ETH | 0.00231045 | ||||
Rebalance | 18369579 | 475 days ago | IN | 0 ETH | 0.00284764 | ||||
Rebalance | 18333524 | 480 days ago | IN | 0 ETH | 0.00363389 | ||||
Claim And Swap R... | 18303098 | 484 days ago | IN | 0 ETH | 0.00192535 | ||||
Rebalance | 18297494 | 485 days ago | IN | 0 ETH | 0.00279721 | ||||
Rebalance | 18261433 | 490 days ago | IN | 0 ETH | 0.00518138 | ||||
Rebalance | 18225395 | 495 days ago | IN | 0 ETH | 0.00350112 | ||||
Claim And Swap R... | 18224733 | 495 days ago | IN | 0 ETH | 0.00274969 | ||||
Rebalance | 18184330 | 501 days ago | IN | 0 ETH | 0.0053546 | ||||
Claim And Swap R... | 18153128 | 505 days ago | IN | 0 ETH | 0.00289807 | ||||
Rebalance | 18148491 | 506 days ago | IN | 0 ETH | 0.00374378 | ||||
Rebalance | 18112596 | 511 days ago | IN | 0 ETH | 0.00525267 | ||||
Rebalance | 18076597 | 516 days ago | IN | 0 ETH | 0.00535626 | ||||
Claim And Swap R... | 18075646 | 516 days ago | IN | 0 ETH | 0.00443357 | ||||
Rebalance | 18040591 | 521 days ago | IN | 0 ETH | 0.00583196 | ||||
Rebalance | 18004892 | 526 days ago | IN | 0 ETH | 0.00530654 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
CompoundLeverage
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT // Heavily inspired from CompoundLeverage strategy of Yearn. https://etherscan.io/address/0x4031afd3B0F71Bace9181E554A9E680Ee4AbE7dF#code pragma solidity 0.8.9; import "../../interfaces/compound/ICompound.sol"; import "../Strategy.sol"; import "../FlashLoanHelper.sol"; import "./CompoundLeverageBase.sol"; // solhint-disable no-empty-blocks /// @title This strategy will deposit collateral token in Compound and based on position /// it will borrow same collateral token. It will use borrowed asset as supply and borrow again. contract CompoundLeverage is CompoundLeverageBase, FlashLoanHelper { using SafeERC20 for IERC20; constructor( address _pool, address _swapper, address _comptroller, address _rewardToken, address _aaveAddressesProvider, address _receiptToken, string memory _name ) CompoundLeverageBase(_pool, _swapper, _comptroller, _rewardToken, _receiptToken, _name) FlashLoanHelper(_aaveAddressesProvider) {} /// @notice Approve all required tokens function _approveToken(uint256 _amount) internal virtual override { super._approveToken(_amount); FlashLoanHelper._approveToken(address(collateralToken), _amount); } /** * @dev Aave flash is used only for withdrawal due to high fee compare to DyDx * @param _flashAmount Amount for flash loan * @param _shouldRepay Flag indicating we want to leverage or deleverage * @return Total amount we leverage or deleverage using flash loan */ function _doFlashLoan(uint256 _flashAmount, bool _shouldRepay) internal override returns (uint256) { uint256 _totalFlashAmount; // Due to less fee DyDx is our primary flash loan provider if (isDyDxActive && _flashAmount > 0) { bytes memory _data = abi.encode(_flashAmount, _shouldRepay); _totalFlashAmount = _doDyDxFlashLoan(address(collateralToken), _flashAmount, _data); _flashAmount -= _totalFlashAmount; } if (isAaveActive && _shouldRepay && _flashAmount > 0) { bytes memory _data = abi.encode(_flashAmount, _shouldRepay); _totalFlashAmount += _doAaveFlashLoan(address(collateralToken), _flashAmount, _data); } return _totalFlashAmount; } /** * @notice This function will be called by flash loan * @dev In case of borrow, DyDx is preferred as fee is so low that it does not effect * our collateralRatio and liquidation risk. */ function _flashLoanLogic(bytes memory _data, uint256 _repayAmount) internal override { (uint256 _amount, bool _deficit) = abi.decode(_data, (uint256, bool)); uint256 _collateralHere = collateralToken.balanceOf(address(this)); require(_collateralHere >= _amount, "FLASH_FAILED"); // to stop malicious calls //if in deficit we repay amount and then withdraw if (_deficit) { _repayBorrow(_amount); //if we are withdrawing we take more to cover fee _redeemUnderlying(_repayAmount); } else { _mint(_collateralHere); //borrow more to cover fee _borrowCollateral(_repayAmount); } } /************************************************************************************************ * Governor/admin/keeper function * ***********************************************************************************************/ /// @notice Claim rewardToken and convert rewardToken into collateral token. function claimAndSwapRewards(uint256 _minAmountOut) external onlyKeeper returns (uint256 _amountOut) { uint256 _collateralBefore = collateralToken.balanceOf(address(this)); address[] memory _markets = new address[](1); _markets[0] = address(cToken); comptroller.claimComp(address(this), _markets); uint256 _rewardAmount = IERC20(rewardToken).balanceOf(address(this)); if (_rewardAmount > 0) { _safeSwapExactInput(rewardToken, address(collateralToken), _rewardAmount); _amountOut = collateralToken.balanceOf(address(this)) - _collateralBefore; require(_amountOut >= _minAmountOut, "not-enough-amountOut"); } } function updateAaveStatus(bool _status) external onlyGovernor { _updateAaveStatus(_status); } function updateDyDxStatus(bool _status) external virtual onlyGovernor { _updateDyDxStatus(_status, address(collateralToken)); } }
// 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.9; /// @title Errors library library Errors { string public constant INVALID_COLLATERAL_AMOUNT = "1"; // Collateral must be greater than 0 or > defined limit string public constant INVALID_SHARE_AMOUNT = "2"; // Share must be greater than 0 string public constant INVALID_INPUT_LENGTH = "3"; // Input array length must be greater than 0 string public constant INPUT_LENGTH_MISMATCH = "4"; // Input array length mismatch with another array length string public constant NOT_WHITELISTED_ADDRESS = "5"; // Caller is not whitelisted to withdraw without fee string public constant MULTI_TRANSFER_FAILED = "6"; // Multi transfer of tokens has failed string public constant FEE_COLLECTOR_NOT_SET = "7"; // Fee Collector is not set string public constant NOT_ALLOWED_TO_SWEEP = "8"; // Token is not allowed to sweep string public constant INSUFFICIENT_BALANCE = "9"; // Insufficient balance to performs operations to follow string public constant INPUT_ADDRESS_IS_ZERO = "10"; // Input address is zero string public constant FEE_LIMIT_REACHED = "11"; // Fee must be less than MAX_BPS string public constant ALREADY_INITIALIZED = "12"; // Data structure, contract, or logic already initialized and can not be called again string public constant ADD_IN_LIST_FAILED = "13"; // Cannot add address in address list string public constant REMOVE_FROM_LIST_FAILED = "14"; // Cannot remove address from address list string public constant STRATEGY_IS_ACTIVE = "15"; // Strategy is already active, an inactive strategy is required string public constant STRATEGY_IS_NOT_ACTIVE = "16"; // Strategy is not active, an active strategy is required string public constant INVALID_STRATEGY = "17"; // Given strategy is not a strategy of this pool string public constant DEBT_RATIO_LIMIT_REACHED = "18"; // Debt ratio limit reached. It must be less than MAX_BPS string public constant TOTAL_DEBT_IS_NOT_ZERO = "19"; // Strategy total debt must be 0 string public constant LOSS_TOO_HIGH = "20"; // Strategy reported loss must be less than current debt string public constant INVALID_MAX_BORROW_LIMIT = "21"; // Max borrow limit is beyond range. string public constant MAX_LIMIT_LESS_THAN_MIN = "22"; // Max limit should be greater than min limit. string public constant INVALID_SLIPPAGE = "23"; // Slippage should be less than MAX_BPS string public constant WRONG_RECEIPT_TOKEN = "24"; // Wrong receipt token address string public constant AAVE_FLASH_LOAN_NOT_ACTIVE = "25"; // aave flash loan is not active string public constant DYDX_FLASH_LOAN_NOT_ACTIVE = "26"; // DYDX flash loan is not active string public constant INVALID_FLASH_LOAN = "27"; // invalid-flash-loan string public constant INVALID_INITIATOR = "28"; // "invalid-initiator" string public constant INCORRECT_WITHDRAW_AMOUNT = "29"; // withdrawn amount is not correct string public constant NO_MARKET_ID_FOUND = "30"; // dydx flash loan no marketId found for token string public constant SAME_AS_PREVIOUS = "31"; // Input should not be same as previous value. string public constant INVALID_INPUT = "32"; // Generic invalid input error code }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.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 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; import "vesper-pools/contracts/dependencies/openzeppelin/contracts/token/ERC20/IERC20.sol"; // @dev Interface support both Aave v2 and v3 methods interface PoolAddressesProvider { function getPool() external view returns (address); // Aave v2 method. function getLendingPool() external view returns (address); function getPoolDataProvider() external view returns (address); function getAddress(bytes32 id) external view returns (address); function getPriceOracle() external view returns (address); } interface AaveOracle { function getAssetPrice(address _asset) external view returns (uint256); } interface AToken is IERC20 { /** * @dev Returns the address of the incentives controller contract **/ function getIncentivesController() external view returns (address); function mint( address user, uint256 amount, uint256 index ) external returns (bool); function burn( address user, address receiverOfUnderlying, uint256 amount, uint256 index ) external; //solhint-disable func-name-mixedcase function UNDERLYING_ASSET_ADDRESS() external view returns (address); } interface AaveIncentivesController { function getRewardsBalance(address[] calldata assets, address user) external view returns (uint256); function claimRewards( address[] calldata assets, uint256 amount, address to ) external returns (uint256); function claimAllRewards(address[] calldata assets, address to) external returns (address[] memory rewardsList, uint256[] memory claimedAmounts); function getRewardsList() external view returns (address[] memory); } interface AaveLendingPool { function deposit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; function supply( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; function withdraw( address asset, uint256 amount, address to ) external returns (uint256); function flashLoan( address receiverAddress, address[] calldata assets, uint256[] calldata amounts, uint256[] calldata interestRateModes, address onBehalfOf, bytes calldata params, uint16 referralCode ) external; function borrow( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf ) external; function repay( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf ) external; function getUserAccountData(address _user) external view returns ( uint256 totalCollateralETH, uint256 totalDebtETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); } interface AaveProtocolDataProvider { function getReserveTokensAddresses(address asset) external view returns ( address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress ); function getReserveData(address asset) external view returns ( uint256 availableLiquidity, uint256 totalStableDebt, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, uint256 averageStableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp ); function getReserveConfigurationData(address asset) external view returns ( uint256 decimals, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, uint256 reserveFactor, bool usageAsCollateralEnabled, bool borrowingEnabled, bool stableBorrowRateEnabled, bool isActive, bool isFrozen ); } //solhint-disable func-name-mixedcase interface StakedAave is IERC20 { function claimRewards(address to, uint256 amount) external; function cooldown() external; function stake(address onBehalfOf, uint256 amount) external; function redeem(address to, uint256 amount) external; function getTotalRewardsBalance(address staker) external view returns (uint256); function stakersCooldowns(address staker) external view returns (uint256); function COOLDOWN_SECONDS() external view returns (uint256); function UNSTAKE_WINDOW() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface CToken { function accrueInterest() external returns (uint256); function balanceOf(address owner) external view returns (uint256); function balanceOfUnderlying(address owner) external returns (uint256); function borrowBalanceCurrent(address account) external returns (uint256); function borrowBalanceStored(address account) external view returns (uint256); function exchangeRateCurrent() external returns (uint256); function exchangeRateStored() external view returns (uint256); function getAccountSnapshot(address account) external view returns ( uint256, uint256, uint256, uint256 ); function borrow(uint256 borrowAmount) external returns (uint256); function mint() external payable; // For ETH function mint(uint256 mintAmount) external returns (uint256); // For ERC20 function redeem(uint256 redeemTokens) external returns (uint256); function redeemUnderlying(uint256 redeemAmount) external returns (uint256); function repayBorrow() external payable; // For ETH function repayBorrow(uint256 repayAmount) external returns (uint256); // For ERC20 function transfer(address user, uint256 amount) external returns (bool); function getCash() external view returns (uint256); function transferFrom( address owner, address user, uint256 amount ) external returns (bool); function underlying() external view returns (address); function comptroller() external view returns (address); function totalBorrows() external view returns (uint256); } interface Comptroller { function claimComp(address holder, address[] memory) external; function enterMarkets(address[] memory cTokens) external returns (uint256[] memory); function exitMarket(address cToken) external returns (uint256); function compAccrued(address holder) external view returns (uint256); function getAccountLiquidity(address account) external view returns ( uint256, uint256, uint256 ); function markets(address market) external view returns ( bool isListed, uint256 collateralFactorMantissa, bool isCompted ); function oracle() external view returns (address); function borrowCaps(address market) external view returns (uint256); function compSupplySpeeds(address cToken) external view returns (uint256); } interface VenusComptroller is Comptroller { function claimVenus(address holder, address[] memory) external; } interface Oracle { function getUnderlyingPrice(address cToken) external view returns (uint256); function price(string memory symbol) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; /** In order to keep code/files short, all libraries and interfaces are trimmed as per Vesper need */ library Account { enum Status { Normal, Liquid, Vapor } struct Info { address owner; // The address that owns the account uint256 number; // A nonce that allows a single address to control many accounts } } library Actions { enum ActionType { Deposit, // supply tokens Withdraw, // borrow tokens Transfer, // transfer balance between accounts Buy, // buy an amount of some token (publicly) Sell, // sell an amount of some token (publicly) Trade, // trade tokens against another account Liquidate, // liquidate an undercollateralized or expiring account Vaporize, // use excess tokens to zero-out a completely negative account Call // send arbitrary data to an address } struct ActionArgs { ActionType actionType; uint256 accountId; Types.AssetAmount amount; uint256 primaryMarketId; uint256 secondaryMarketId; address otherAddress; uint256 otherAccountId; bytes data; } } library Types { enum AssetDenomination { Wei, // the amount is denominated in wei Par // the amount is denominated in par } enum AssetReference { Delta, // the amount is given as a delta from the current value Target // the amount is given as an exact number to end up at } struct AssetAmount { bool sign; // true if positive AssetDenomination denomination; AssetReference ref; uint256 value; } } interface ISoloMargin { function getMarketTokenAddress(uint256 marketId) external view returns (address); function getNumMarkets() external view returns (uint256); function operate(Account.Info[] memory accounts, Actions.ActionArgs[] memory actions) external; } /** * @title ICallee * @author dYdX * * Interface that Callees for Solo must implement in order to ingest data. */ interface ICallee { // ============ Public Functions ============ /** * Allows users to send this contract arbitrary data. * * @param sender The msg.sender to Solo * @param accountInfo The account from which the data is being sent * @param data Arbitrary data given by the sender */ function callFunction( address sender, Account.Info memory accountInfo, bytes memory data ) external; }
// 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/dependencies/openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "vesper-pools/contracts/interfaces/vesper/IVesperPool.sol"; import "vesper-pools/contracts/Errors.sol"; import "../interfaces/aave/IAave.sol"; import "../interfaces/dydx/ISoloMargin.sol"; /** * @title FlashLoanHelper:: This contract does all heavy lifting to get flash loan via Aave and DyDx. * @dev End user has to override _flashLoanLogic() function to perform logic after flash loan is done. * Also needs to approve token to aave and dydx via _approveToken function. * 2 utility internal functions are also provided to activate/deactivate flash loan providers. * Utility function are provided as internal so that end user can choose controlled access via public functions. */ abstract contract FlashLoanHelper { using SafeERC20 for IERC20; PoolAddressesProvider internal poolAddressesProvider; address internal constant SOLO = 0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e; uint256 public dyDxMarketId; bytes32 private constant AAVE_PROVIDER_ID = 0x0100000000000000000000000000000000000000000000000000000000000000; bool public isAaveActive = false; bool public isDyDxActive = false; constructor(address _aaveAddressesProvider) { require(_aaveAddressesProvider != address(0), Errors.INPUT_ADDRESS_IS_ZERO); poolAddressesProvider = PoolAddressesProvider(_aaveAddressesProvider); } function _updateAaveStatus(bool _status) internal { isAaveActive = _status; } function _updateDyDxStatus(bool _status, address _token) internal { if (_status) { dyDxMarketId = _getMarketIdFromTokenAddress(SOLO, _token); } isDyDxActive = _status; } /// @notice Approve all required tokens for flash loan function _approveToken(address _token, uint256 _amount) internal { IERC20(_token).safeApprove(SOLO, _amount); IERC20(_token).safeApprove(poolAddressesProvider.getLendingPool(), _amount); } /// @dev Override this function to execute logic which uses flash loan amount function _flashLoanLogic(bytes memory _data, uint256 _repayAmount) internal virtual; /***************************** Aave flash loan functions ***********************************/ bool private awaitingFlash = false; /** * @notice This is entry point for Aave flash loan * @param _token Token for which we are taking flash loan * @param _amountDesired Flash loan amount * @param _data This will be passed downstream for processing. It can be empty. */ function _doAaveFlashLoan( address _token, uint256 _amountDesired, bytes memory _data ) internal returns (uint256 _amount) { require(isAaveActive, Errors.AAVE_FLASH_LOAN_NOT_ACTIVE); AaveLendingPool _aaveLendingPool = AaveLendingPool(poolAddressesProvider.getLendingPool()); AaveProtocolDataProvider _aaveProtocolDataProvider = AaveProtocolDataProvider( poolAddressesProvider.getAddress(AAVE_PROVIDER_ID) ); // Check token liquidity in Aave (uint256 _availableLiquidity, , , , , , , , , ) = _aaveProtocolDataProvider.getReserveData(_token); if (_amountDesired > _availableLiquidity) { _amountDesired = _availableLiquidity; } address[] memory assets = new address[](1); assets[0] = _token; uint256[] memory amounts = new uint256[](1); amounts[0] = _amountDesired; // 0 = no debt, 1 = stable, 2 = variable uint256[] memory modes = new uint256[](1); modes[0] = 0; // Anyone can call aave flash loan to us, so we need some protection awaitingFlash = true; // function params: receiver, assets, amounts, modes, onBehalfOf, data, referralCode _aaveLendingPool.flashLoan(address(this), assets, amounts, modes, address(this), _data, 0); _amount = _amountDesired; awaitingFlash = false; } /// @dev Aave will call this function after doing flash loan function executeOperation( address[] calldata, /*_assets*/ uint256[] calldata _amounts, uint256[] calldata _premiums, address _initiator, bytes calldata _data ) external returns (bool) { require(msg.sender == poolAddressesProvider.getLendingPool(), "!aave-pool"); require(awaitingFlash, Errors.INVALID_FLASH_LOAN); require(_initiator == address(this), Errors.INVALID_INITIATOR); // Flash loan amount + flash loan fee uint256 _repayAmount = _amounts[0] + _premiums[0]; _flashLoanLogic(_data, _repayAmount); return true; } /***************************** Aave flash loan functions ends ***********************************/ /***************************** DyDx flash loan functions ***************************************/ /** * @notice This is entry point for DyDx flash loan * @param _token Token for which we are taking flash loan * @param _amountDesired Flash loan amount * @param _data This will be passed downstream for processing. It can be empty. */ function _doDyDxFlashLoan( address _token, uint256 _amountDesired, bytes memory _data ) internal returns (uint256 _amount) { require(isDyDxActive, Errors.DYDX_FLASH_LOAN_NOT_ACTIVE); // Check token liquidity in DyDx uint256 amountInSolo = IERC20(_token).balanceOf(SOLO); if (_amountDesired > amountInSolo) { _amountDesired = amountInSolo; } // Repay amount, amount with fee, can be 2 wei higher. Consider 2 wei as fee uint256 repayAmount = _amountDesired + 2; // Encode custom data for callFunction bytes memory _callData = abi.encode(_data, repayAmount); // 1. Withdraw _token // 2. Call callFunction(...) which will call loanLogic // 3. Deposit _token back Actions.ActionArgs[] memory operations = new Actions.ActionArgs[](3); operations[0] = _getWithdrawAction(dyDxMarketId, _amountDesired); operations[1] = _getCallAction(_callData); operations[2] = _getDepositAction(dyDxMarketId, repayAmount); Account.Info[] memory accountInfos = new Account.Info[](1); accountInfos[0] = _getAccountInfo(); ISoloMargin(SOLO).operate(accountInfos, operations); _amount = _amountDesired; } /// @dev DyDx calls this function after doing flash loan function callFunction( address _sender, Account.Info memory, /* _account */ bytes memory _callData ) external { (bytes memory _data, uint256 _repayAmount) = abi.decode(_callData, (bytes, uint256)); require(msg.sender == SOLO, "!solo"); require(_sender == address(this), Errors.INVALID_INITIATOR); _flashLoanLogic(_data, _repayAmount); } /********************************* DyDx helper functions *********************************/ function _getAccountInfo() internal view returns (Account.Info memory) { return Account.Info({owner: address(this), number: 1}); } function _getMarketIdFromTokenAddress(address _solo, address token) internal view returns (uint256) { ISoloMargin solo = ISoloMargin(_solo); uint256 numMarkets = solo.getNumMarkets(); address curToken; for (uint256 i = 0; i < numMarkets; i++) { curToken = solo.getMarketTokenAddress(i); if (curToken == token) { return i; } } revert(Errors.NO_MARKET_ID_FOUND); } function _getWithdrawAction(uint256 marketId, uint256 amount) internal view returns (Actions.ActionArgs memory) { return Actions.ActionArgs({ actionType: Actions.ActionType.Withdraw, accountId: 0, amount: Types.AssetAmount({ sign: false, denomination: Types.AssetDenomination.Wei, ref: Types.AssetReference.Delta, value: amount }), primaryMarketId: marketId, secondaryMarketId: 0, otherAddress: address(this), otherAccountId: 0, data: "" }); } function _getCallAction(bytes memory data) internal view returns (Actions.ActionArgs memory) { return Actions.ActionArgs({ actionType: Actions.ActionType.Call, accountId: 0, amount: Types.AssetAmount({ sign: false, denomination: Types.AssetDenomination.Wei, ref: Types.AssetReference.Delta, value: 0 }), primaryMarketId: 0, secondaryMarketId: 0, otherAddress: address(this), otherAccountId: 0, data: data }); } function _getDepositAction(uint256 marketId, uint256 amount) internal view returns (Actions.ActionArgs memory) { return Actions.ActionArgs({ actionType: Actions.ActionType.Deposit, accountId: 0, amount: Types.AssetAmount({ sign: true, denomination: Types.AssetDenomination.Wei, ref: Types.AssetReference.Delta, value: amount }), primaryMarketId: marketId, secondaryMarketId: 0, otherAddress: address(this), otherAccountId: 0, data: "" }); } /***************************** DyDx flash loan functions end *****************************/ }
// 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 // Heavily inspired from CompoundLeverage strategy of Yearn. https://etherscan.io/address/0x4031afd3B0F71Bace9181E554A9E680Ee4AbE7dF#code pragma solidity 0.8.9; import "../../interfaces/compound/ICompound.sol"; import "../Strategy.sol"; /// @title This strategy will deposit collateral token in Compound and based on position /// it will borrow same collateral token. It will use borrowed asset as supply and borrow again. abstract contract CompoundLeverageBase is Strategy { using SafeERC20 for IERC20; // solhint-disable-next-line var-name-mixedcase string public NAME; string public constant VERSION = "5.0.0"; uint256 internal constant MAX_BPS = 10_000; //100% uint256 public minBorrowRatio = 5_000; // 50% uint256 public maxBorrowRatio = 6_000; // 60% uint256 internal constant COLLATERAL_FACTOR_LIMIT = 9_500; // 95% CToken internal cToken; Comptroller public immutable comptroller; address public rewardToken; event UpdatedBorrowRatio( uint256 previousMinBorrowRatio, uint256 newMinBorrowRatio, uint256 previousMaxBorrowRatio, uint256 newMaxBorrowRatio ); constructor( address _pool, address _swapper, address _comptroller, address _rewardToken, address _receiptToken, string memory _name ) Strategy(_pool, _swapper, _receiptToken) { NAME = _name; require(_comptroller != address(0), "comptroller-address-is-zero"); comptroller = Comptroller(_comptroller); rewardToken = _rewardToken; require(_receiptToken != address(0), "cToken-address-is-zero"); cToken = CToken(_receiptToken); } /** * @notice Current borrow ratio, calculated as current borrow divide by max allowed borrow * Return value is based on basis points, i.e. 7500 = 75% ratio */ function currentBorrowRatio() external view returns (uint256) { (uint256 _supply, uint256 _borrow) = getPosition(); return _borrow == 0 ? 0 : (_borrow * MAX_BPS) / _supply; } /// @notice Return supply and borrow position. Position may return few block old value function getPosition() public view returns (uint256 _supply, uint256 _borrow) { (, uint256 _cTokenBalance, uint256 _borrowBalance, uint256 _exchangeRate) = cToken.getAccountSnapshot( address(this) ); _supply = (_cTokenBalance * _exchangeRate) / 1e18; _borrow = _borrowBalance; } /// @inheritdoc Strategy function isReservedToken(address _token) public view virtual override returns (bool) { return _token == address(cToken) || _token == address(collateralToken); } /// @inheritdoc Strategy function tvl() public view virtual override returns (uint256) { (uint256 _supply, uint256 _borrow) = getPosition(); return collateralToken.balanceOf(address(this)) + _supply - _borrow; } /** * @dev Adjust position by normal leverage and deleverage. * @param _adjustBy Amount by which we want to increase or decrease _borrow * @param _shouldRepay True indicate we want to deleverage * @return amount Actual adjusted amount */ function _adjustPosition(uint256 _adjustBy, bool _shouldRepay) internal returns (uint256 amount) { // We can get position via view function, as this function will be called after _calculateDesiredPosition (uint256 _supply, uint256 _borrow) = getPosition(); // If no borrow then there is nothing to deleverage if (_borrow == 0 && _shouldRepay) { return 0; } uint256 collateralFactor = _getCollateralFactor(); if (_shouldRepay) { amount = _normalDeleverage(_adjustBy, _supply, _borrow, collateralFactor); } else { amount = _normalLeverage(_adjustBy, _supply, _borrow, collateralFactor); } } /// @notice Approve all required tokens function _approveToken(uint256 _amount) internal virtual override { super._approveToken(_amount); collateralToken.safeApprove(address(cToken), _amount); IERC20(rewardToken).safeApprove(address(swapper), _amount); } /** * @dev Payback borrow before migration * @param _newStrategy Address of new strategy. */ function _beforeMigration(address _newStrategy) internal virtual override { require(IStrategy(_newStrategy).token() == address(cToken), "wrong-receipt-token"); minBorrowRatio = 0; // It will calculate amount to repay based on borrow limit and payback all _deposit(); } function _borrowCollateral(uint256 _amount) internal virtual { require(cToken.borrow(_amount) == 0, "borrow-from-compound-failed"); } /** * @notice Calculate borrow position based on borrow ratio, current supply, borrow, amount * being deposited or withdrawn. * @param _amount Collateral amount * @param _isDeposit Flag indicating whether we are depositing _amount or withdrawing * @return _position Amount of borrow that need to be adjusted * @return _shouldRepay Flag indicating whether _position is borrow amount or repay amount */ function _calculateDesiredPosition( uint256 _amount, bool _isDeposit ) internal returns (uint256 _position, bool _shouldRepay) { uint256 _totalSupply = cToken.balanceOfUnderlying(address(this)); uint256 _currentBorrow = cToken.borrowBalanceStored(address(this)); // If minimum borrow limit set to 0 then repay borrow if (minBorrowRatio == 0) { return (_currentBorrow, true); } uint256 _supply = _totalSupply - _currentBorrow; // In case of withdraw, _amount can be greater than _supply uint256 _newSupply = _isDeposit ? _supply + _amount : _supply > _amount ? _supply - _amount : 0; // (supply * borrowRatio)/(BPS - borrowRatio) uint256 _borrowUpperBound = (_newSupply * maxBorrowRatio) / (MAX_BPS - maxBorrowRatio); uint256 _borrowLowerBound = (_newSupply * minBorrowRatio) / (MAX_BPS - minBorrowRatio); // If our current borrow is greater than max borrow allowed, then we will have to repay // some to achieve safe position else borrow more. if (_currentBorrow > _borrowUpperBound) { _shouldRepay = true; // If borrow > upperBound then it is greater than lowerBound too. _position = _currentBorrow - _borrowLowerBound; } else if (_currentBorrow < _borrowLowerBound) { _shouldRepay = false; // We can borrow more. _position = _borrowLowerBound - _currentBorrow; } } /// @notice Deposit collateral in Compound and adjust borrow position function _deposit() internal { uint256 _collateralBalance = collateralToken.balanceOf(address(this)); (uint256 _position, bool _shouldRepay) = _calculateDesiredPosition(_collateralBalance, true); // Supply collateral to compound. _mint(_collateralBalance); // During reinvest, _shouldRepay will be false which indicate that we will borrow more. _position -= _doFlashLoan(_position, _shouldRepay); uint256 i; while (_position > 0 && i <= 6) { unchecked { _position -= _adjustPosition(_position, _shouldRepay); i++; } } } /** * @dev Aave flash is used only for withdrawal due to high fee compare to DyDx * @param _flashAmount Amount for flash loan * @param _shouldRepay Flag indicating we want to leverage or deleverage * @return Total amount we leverage or deleverage using flash loan */ function _doFlashLoan(uint256 _flashAmount, bool _shouldRepay) internal virtual returns (uint256); /** * @notice Generate report for pools accounting and also send profit and any payback to pool. * @dev Call claimAndSwapRewards to convert rewards to collateral before calling this function. */ function _generateReport() internal returns (uint256 _profit, uint256 _loss, uint256 _payback) { uint256 _excessDebt = IVesperPool(pool).excessDebt(address(this)); (, , , , uint256 _totalDebt, , , uint256 _debtRatio, ) = IVesperPool(pool).strategy(address(this)); // Invested collateral = supply - borrow uint256 _investedCollateral = cToken.balanceOfUnderlying(address(this)) - cToken.borrowBalanceStored(address(this)); uint256 _collateralHere = collateralToken.balanceOf(address(this)); uint256 _totalCollateral = _investedCollateral + _collateralHere; if (_totalCollateral > _totalDebt) { _profit = _totalCollateral - _totalDebt; } else { _loss = _totalDebt - _totalCollateral; } uint256 _profitAndExcessDebt = _profit + _excessDebt; if (_collateralHere < _profitAndExcessDebt) { uint256 _totalAmountToWithdraw = Math.min((_profitAndExcessDebt - _collateralHere), _investedCollateral); if (_totalAmountToWithdraw > 0) { _withdrawHere(_totalAmountToWithdraw); _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; // Handle scenario if debtRatio is zero and some supply left. // Remaining tokens are profit. if (_debtRatio == 0) { (uint256 _supply, uint256 _borrow) = getPosition(); if (_supply > 0 && _borrow == 0) { // This will redeem all cTokens this strategy has _redeemUnderlying(MAX_UINT_VALUE); _profit += _supply; } } } /** * @notice Get Collateral Factor */ function _getCollateralFactor() internal view virtual returns (uint256 _collateralFactor) { (, _collateralFactor, ) = comptroller.markets(address(cToken)); // Take 95% of collateralFactor to avoid any rounding issue. _collateralFactor = (_collateralFactor * COLLATERAL_FACTOR_LIMIT) / MAX_BPS; } /** * @dev Compound support ETH as collateral not WETH. So ETH strategy can override * below functions and handle wrap/unwrap of WETH. */ function _mint(uint256 _amount) internal virtual { require(cToken.mint(_amount) == 0, "supply-to-compound-failed"); } /** * Deleverage: Reduce borrow to achieve safe position * @param _maxDeleverage Reduce borrow by this amount * @return _deleveragedAmount Amount we actually reduced */ function _normalDeleverage( uint256 _maxDeleverage, uint256 _supply, uint256 _borrow, uint256 _collateralFactor ) internal returns (uint256 _deleveragedAmount) { uint256 _theoreticalSupply; if (_collateralFactor > 0) { // Calculate minimum supply required to support _borrow _theoreticalSupply = (_borrow * 1e18) / _collateralFactor; } _deleveragedAmount = _supply - _theoreticalSupply; if (_deleveragedAmount >= _borrow) { _deleveragedAmount = _borrow; } if (_deleveragedAmount >= _maxDeleverage) { _deleveragedAmount = _maxDeleverage; } _redeemUnderlying(_deleveragedAmount); _repayBorrow(_deleveragedAmount); } /** * Leverage: Borrow more * @param _maxLeverage Max amount to borrow * @return _leveragedAmount Amount we actually borrowed */ function _normalLeverage( uint256 _maxLeverage, uint256 _supply, uint256 _borrow, uint256 _collateralFactor ) internal returns (uint256 _leveragedAmount) { // Calculate maximum we can borrow at current _supply uint256 theoreticalBorrow = (_supply * _collateralFactor) / 1e18; _leveragedAmount = theoreticalBorrow - _borrow; if (_leveragedAmount >= _maxLeverage) { _leveragedAmount = _maxLeverage; } _borrowCollateral(_leveragedAmount); _mint(collateralToken.balanceOf(address(this))); } function _rebalance() internal virtual override returns (uint256 _profit, uint256 _loss, uint256 _payback) { (_profit, _loss, _payback) = _generateReport(); IVesperPool(pool).reportEarning(_profit, _loss, _payback); _deposit(); } function _redeemUnderlying(uint256 _amount) internal virtual { if (_amount == MAX_UINT_VALUE) { // Withdraw all cTokens require(cToken.redeem(cToken.balanceOf(address(this))) == 0, "withdraw-from-compound-failed"); } else { // Withdraw underlying require(cToken.redeemUnderlying(_amount) == 0, "withdraw-from-compound-failed"); } } function _repayBorrow(uint256 _amount) internal virtual { require(cToken.repayBorrow(_amount) == 0, "repay-to-compound-failed"); } /// @dev Withdraw collateral here. function _withdrawHere(uint256 _amount) internal override { (uint256 _position, bool _shouldRepay) = _calculateDesiredPosition(_amount, false); if (_shouldRepay) { // Do deleverage by flash loan _position -= _doFlashLoan(_position, _shouldRepay); // If we still have _position to deleverage do it via normal deleverage uint256 i; while (_position > 0 && i <= 10) { unchecked { _position -= _adjustPosition(_position, true); i++; } } (uint256 _supply, uint256 _borrow) = getPosition(); // If we are not able to deleverage enough if (_position > 0) { // Calculate redeemable at current borrow and supply. uint256 _supplyToSupportBorrow; if (maxBorrowRatio > 0) { _supplyToSupportBorrow = (_borrow * MAX_BPS) / maxBorrowRatio; } // Current supply minus supply required to support _borrow at _maxBorrowRatio uint256 _redeemable = _supply - _supplyToSupportBorrow; if (_amount > _redeemable) { _amount = _redeemable; } } // Position is 0 and amount > supply due to deleverage else if (_amount > _supply) { _amount = _supply; } } _redeemUnderlying(_amount); } /************************************************************************************************ * Governor/admin/keeper function * ***********************************************************************************************/ /** * @notice Update upper and lower borrow ratio * @dev It is possible to set 0 as _minBorrowRatio to not borrow anything * @param _minBorrowRatio Minimum % we want to borrow * @param _maxBorrowRatio Maximum % we want to borrow */ function updateBorrowRatio(uint256 _minBorrowRatio, uint256 _maxBorrowRatio) external onlyGovernor { // CollateralFactor is 1e18 based and borrow ratio is 1e4 based. Hence using 1e14 for conversion. require(_maxBorrowRatio < (_getCollateralFactor() / 1e14), "invalid-max-borrow-limit"); require(_maxBorrowRatio > _minBorrowRatio, "max-should-be-higher-than-min"); emit UpdatedBorrowRatio(minBorrowRatio, _minBorrowRatio, maxBorrowRatio, _maxBorrowRatio); minBorrowRatio = _minBorrowRatio; maxBorrowRatio = _maxBorrowRatio; } }
{ "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
[{"inputs":[{"internalType":"address","name":"_pool","type":"address"},{"internalType":"address","name":"_swapper","type":"address"},{"internalType":"address","name":"_comptroller","type":"address"},{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_aaveAddressesProvider","type":"address"},{"internalType":"address","name":"_receiptToken","type":"address"},{"internalType":"string","name":"_name","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previousMinBorrowRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMinBorrowRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"previousMaxBorrowRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxBorrowRatio","type":"uint256"}],"name":"UpdatedBorrowRatio","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":"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":[{"internalType":"address","name":"_sender","type":"address"},{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"number","type":"uint256"}],"internalType":"struct Account.Info","name":"","type":"tuple"},{"internalType":"bytes","name":"_callData","type":"bytes"}],"name":"callFunction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minAmountOut","type":"uint256"}],"name":"claimAndSwapRewards","outputs":[{"internalType":"uint256","name":"_amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collateral","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateralToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"comptroller","outputs":[{"internalType":"contract Comptroller","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentBorrowRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dyDxMarketId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"_premiums","type":"uint256[]"},{"internalType":"address","name":"_initiator","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"executeOperation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPosition","outputs":[{"internalType":"uint256","name":"_supply","type":"uint256"},{"internalType":"uint256","name":"_borrow","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isAaveActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isDyDxActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"maxBorrowRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newStrategy","type":"address"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minBorrowRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[],"name":"rewardToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"bool","name":"_status","type":"bool"}],"name":"updateAaveStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minBorrowRatio","type":"uint256"},{"internalType":"uint256","name":"_maxBorrowRatio","type":"uint256"}],"name":"updateBorrowRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"updateDyDxStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeCollector","type":"address"}],"name":"updateFeeCollector","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
60e0604052611388600655611770600755600c805462ffffff191690553480156200002957600080fd5b50604051620056e7380380620056e78339810160408190526200004c9162000519565b828787878786868585836001600160a01b038316620000b25760405162461bcd60e51b815260206004820152601460248201527f706f6f6c2d616464726573732d69732d7a65726f00000000000000000000000060448201526064015b60405180910390fd5b6001600160a01b0382166200010a5760405162461bcd60e51b815260206004820152601760248201527f737761707065722d616464726573732d69732d7a65726f0000000000000000006044820152606401620000a9565b600280546001600160a01b0319166001600160a01b0384811691909117909155831660a081905260408051637e062a3560e11b8152905163fc0c546a91600480820192602092909190829003018186803b1580156200016857600080fd5b505afa1580156200017d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001a3919062000655565b6001600160a01b03908116608052600080546001600160a01b031916918316919091179055620001ea620001d43390565b60036200039f60201b62001e871790919060201c565b6200022c5760405162461bcd60e51b81526020600482015260116024820152701859190b5ad9595c195c8b59985a5b1959607a1b6044820152606401620000a9565b50508151620002449150600590602084019062000411565b506001600160a01b0384166200029d5760405162461bcd60e51b815260206004820152601b60248201527f636f6d7074726f6c6c65722d616464726573732d69732d7a65726f00000000006044820152606401620000a9565b6001600160a01b0384811660c052600980546001600160a01b03191685831617905582166200030f5760405162461bcd60e51b815260206004820152601660248201527f63546f6b656e2d616464726573732d69732d7a65726f000000000000000000006044820152606401620000a9565b50600880546001600160a01b0319166001600160a01b03928316179055604080518082019091526002815261031360f41b60208201529450851615159250620003709150505760405162461bcd60e51b8152600401620000a991906200067c565b50600a80546001600160a01b0319166001600160a01b039290921691909117905550620006ee95505050505050565b6000620003b6836001600160a01b038416620003bf565b90505b92915050565b60008181526001830160205260408120546200040857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003b9565b506000620003b9565b8280546200041f90620006b1565b90600052602060002090601f0160209004810192826200044357600085556200048e565b82601f106200045e57805160ff19168380011785556200048e565b828001600101855582156200048e579182015b828111156200048e57825182559160200191906001019062000471565b506200049c929150620004a0565b5090565b5b808211156200049c5760008155600101620004a1565b6001600160a01b0381168114620004cd57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000503578181015183820152602001620004e9565b8381111562000513576000848401525b50505050565b600080600080600080600060e0888a0312156200053557600080fd5b87516200054281620004b7565b60208901519097506200055581620004b7565b60408901519096506200056881620004b7565b60608901519095506200057b81620004b7565b60808901519094506200058e81620004b7565b60a0890151909350620005a181620004b7565b60c08901519092506001600160401b0380821115620005bf57600080fd5b818a0191508a601f830112620005d457600080fd5b815181811115620005e957620005e9620004d0565b604051601f8201601f19908116603f01168101908382118183101715620006145762000614620004d0565b816040528281528d60208487010111156200062e57600080fd5b62000641836020830160208801620004e6565b809550505050505092959891949750929550565b6000602082840312156200066857600080fd5b81516200067581620004b7565b9392505050565b60208152600082518060208401526200069d816040850160208701620004e6565b601f01601f19169190910160400192915050565b600181811c90821680620006c657607f821691505b60208210811415620006e857634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c051614eaa6200083d600039600081816102d501528181610632015261252a0152600081816102210152818161085a0152818161096d01528181610a8901528181610b6701528181610bc301528181610d25015281816112c20152818161135f0152818161158b015281816117540152818161191101528181611cc10152818161214701528181612e5901528181612efa0152613f520152600081816103a10152818161042d015281816105430152818161073a01528181610778015281816109cc01528181610a6701528181610adb01528181610b9a01528181610ce901528181610dea015281816114ef01528181611a5801528181611c11015281816121d2015281816122f701528181612a3801528181612ac4015281816130b7015281816131da015281816132fb015281816136b001528181613e990152613f300152614eaa6000f3fe608060405234801561001057600080fd5b50600436106101dc5760003560e01c8063a3f4df7e11610105578063e00af4a71161009d578063e00af4a714610451578063e5328e0614610464578063ec78e8321461046c578063f23c47221461047f578063f7c618c114610491578063f7c99bea146104a4578063fc0c546a146104ad578063fef395d3146104be578063ffa1ad74146104d157600080fd5b8063a3f4df7e14610387578063b2016bd41461039c578063b9098e3c146103c3578063c415b95c146103cc578063ce5494bb146103df578063d2c35ce8146103f2578063d3033c3914610405578063d333253914610418578063d8dfeb451461042b57600080fd5b80635abda028116101785780635abda028146102c85780635fe3b567146102d05780637398ab18146102f75780637d7c2a1c146103145780638b41871314610337578063920f5c841461034a578063951dc22c1461035d57806399b71d5c146103725780639b7166a91461037a57600080fd5b80631026013a146101e157806314ae9f2e1461020757806316f0115b1461021c5780632a049a21146102505780632b3297f9146102595780632e1a7d4d1461026c5780634032b72b1461027f578063440d724814610292578063599e892a146102b5575b600080fd5b6101f46101ef3660046143a1565b6104f5565b6040519081526020015b60405180910390f35b61021a6102153660046143cf565b610858565b005b6102437f000000000000000000000000000000000000000000000000000000000000000081565b6040516101fe91906143ec565b6101f460075481565b600254610243906001600160a01b031681565b61021a61027a3660046143a1565b61096a565b61021a61028d3660046143cf565b610bc1565b6102a56102a03660046143cf565b610ccd565b60405190151581526020016101fe565b61021a6102c336600461440e565b610d23565b6101f4610e0e565b6102437f000000000000000000000000000000000000000000000000000000000000000081565b6102ff610e4d565b604080519283526020830191909152016101fe565b61031c610f07565b604080519384526020840192909252908201526060016101fe565b61021a6103453660046144c0565b610f44565b6102a56103583660046145d3565b610fff565b6103656111e4565b6040516101fe919061471b565b61021a6111f5565b600c546102a59060ff1681565b61038f611231565b6040516101fe9190614786565b6102437f000000000000000000000000000000000000000000000000000000000000000081565b6101f460065481565b600154610243906001600160a01b031681565b61021a6103ed3660046143cf565b6112bf565b61021a6104003660046143cf565b611589565b61021a6104133660046143cf565b611752565b61021a61042636600461440e565b61190f565b7f0000000000000000000000000000000000000000000000000000000000000000610243565b61021a61045f3660046143cf565b6119e1565b6101f4611bfc565b600054610243906001600160a01b031681565b600c546102a590610100900460ff1681565b600954610243906001600160a01b031681565b6101f4600b5481565b6000546001600160a01b0316610243565b61021a6104cc366004614799565b611cbf565b61038f604051806040016040528060058152602001640352e302e360dc1b81525081565b6000610504335b600390611ea3565b6105295760405162461bcd60e51b8152600401610520906147bb565b60405180910390fd5b6040516370a0823160e01b81526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a08231906105789030906004016143ec565b60206040518083038186803b15801561059057600080fd5b505afa1580156105a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c891906147eb565b6040805160018082528183019092529192506000919060208083019080368337505060085482519293506001600160a01b03169183915060009061060e5761060e614804565b6001600160a01b03928316602091820292909201015260405162e1ed9760e51b81527f000000000000000000000000000000000000000000000000000000000000000090911690631c3db2e09061066b903090859060040161481a565b600060405180830381600087803b15801561068557600080fd5b505af1158015610699573d6000803e3d6000fd5b50506009546040516370a0823160e01b8152600093506001600160a01b0390911691506370a08231906106d09030906004016143ec565b60206040518083038186803b1580156106e857600080fd5b505afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072091906147eb565b905080156108505760095461075f906001600160a01b03167f000000000000000000000000000000000000000000000000000000000000000083611ec5565b6040516370a0823160e01b815283906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a08231906107ad9030906004016143ec565b60206040518083038186803b1580156107c557600080fd5b505afa1580156107d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fd91906147eb565b6108079190614854565b9350848410156108505760405162461bcd60e51b81526020600482015260146024820152731b9bdd0b595b9bdd59da0b585b5bdd5b9d13dd5d60621b6044820152606401610520565b505050919050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b1580156108b157600080fd5b505afa1580156108c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e9919061486b565b6001600160a01b0316336001600160a01b0316146109195760405162461bcd60e51b815260040161052090614888565b610924600382611f68565b6109675760405162461bcd60e51b81526020600482015260146024820152731c995b5bdd994b5ad9595c195c8b59985a5b195960621b6044820152606401610520565b50565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146109b25760405162461bcd60e51b8152600401610520906148bf565b6040516370a0823160e01b81526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190610a019030906004016143ec565b60206040518083038186803b158015610a1957600080fd5b505afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5191906147eb565b9050818110610ab257610aae6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000084611f7d565b5050565b610ac4610abf8284614854565b611fe0565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190610b109030906004016143ec565b60206040518083038186803b158015610b2857600080fd5b505afa158015610b3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6091906147eb565b9050610aae7f0000000000000000000000000000000000000000000000000000000000000000610b9084846120b5565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169190611f7d565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b158015610c1a57600080fd5b505afa158015610c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c52919061486b565b6001600160a01b0316336001600160a01b031614610c825760405162461bcd60e51b815260040161052090614888565b610c8d600382611e87565b6109675760405162461bcd60e51b81526020600482015260116024820152701859190b5ad9595c195c8b59985a5b1959607a1b6044820152606401610520565b6008546000906001600160a01b0383811691161480610d1d57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316145b92915050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b158015610d7c57600080fd5b505afa158015610d90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db4919061486b565b6001600160a01b0316336001600160a01b031614610de45760405162461bcd60e51b815260040161052090614888565b610967817f00000000000000000000000000000000000000000000000000000000000000006120cb565b6000806000610e1b610e4d565b9150915080600014610e435781610e34612710836148f2565b610e3e9190614911565b610e46565b60005b9250505090565b6008546040516361bfb47160e11b815260009182918291829182916001600160a01b03169063c37f68e290610e869030906004016143ec565b60806040518083038186803b158015610e9e57600080fd5b505afa158015610eb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed69190614933565b93509350935050670de0b6b3a76400008184610ef291906148f2565b610efc9190614911565b959194509092505050565b60008080610f14336104fc565b610f305760405162461bcd60e51b8152600401610520906147bb565b610f3861210e565b9250925092505b909192565b60008082806020019051810190610f5b9190614969565b909250905033731e0447b19bb6ecfdae1e4ae1694b0c3659614e4e14610fab5760405162461bcd60e51b815260206004820152600560248201526421736f6c6f60d81b6044820152606401610520565b604080518082019091526002815261064760f31b60208201526001600160a01b0386163014610fed5760405162461bcd60e51b81526004016105209190614786565b50610ff882826121b3565b5050505050565b600a5460408051630261bf8b60e01b815290516000926001600160a01b031691630261bf8b916004808301926020929190829003018186803b15801561104457600080fd5b505afa158015611058573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107c919061486b565b6001600160a01b0316336001600160a01b0316146110c95760405162461bcd60e51b815260206004820152600a6024820152690858585d994b5c1bdbdb60b21b6044820152606401610520565b600c54604080518082019091526002815261323760f01b60208201529062010000900460ff1661110c5760405162461bcd60e51b81526004016105209190614786565b50604080518082019091526002815261064760f31b60208201526001600160a01b038516301461114f5760405162461bcd60e51b81526004016105209190614786565b5060008686600081811061116557611165614804565b905060200201358989600081811061117f5761117f614804565b9050602002013561119091906149e9565b90506111d384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508592506121b3915050565b5060019a9950505050505050505050565b60606111f060036122dc565b905090565b6111fe336104fc565b61121a5760405162461bcd60e51b8152600401610520906147bb565b61122460006122e9565b61122f6000196122e9565b565b6005805461123e90614a01565b80601f016020809104026020016040519081016040528092919081815260200182805461126a90614a01565b80156112b75780601f1061128c576101008083540402835291602001916112b7565b820191906000526020600020905b81548152906001019060200180831161129a57829003601f168201915b505050505081565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146113075760405162461bcd60e51b8152600401610520906148bf565b6001600160a01b03811661135d5760405162461bcd60e51b815260206004820152601c60248201527f6e65772d73747261746567792d616464726573732d69732d7a65726f000000006044820152606401610520565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b03166316f0115b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156113c057600080fd5b505afa1580156113d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f8919061486b565b6001600160a01b0316146114475760405162461bcd60e51b81526020600482015260166024820152756e6f742d76616c69642d6e65772d737472617465677960501b6044820152606401610520565b6114508161231c565b6000546040516370a0823160e01b81526114e99183916001600160a01b03909116906370a08231906114869030906004016143ec565b60206040518083038186803b15801561149e57600080fd5b505afa1580156114b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d691906147eb565b6000546001600160a01b03169190611f7d565b610967817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161153991906143ec565b60206040518083038186803b15801561155157600080fd5b505afa158015611565573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9091906147eb565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b1580156115e257600080fd5b505afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a919061486b565b6001600160a01b0316336001600160a01b03161461164a5760405162461bcd60e51b815260040161052090614888565b6001600160a01b0381166116a05760405162461bcd60e51b815260206004820152601d60248201527f6665652d636f6c6c6563746f722d616464726573732d69732d7a65726f0000006044820152606401610520565b6001546001600160a01b03828116911614156116f65760405162461bcd60e51b81526020600482015260156024820152746665652d636f6c6c6563746f722d69732d73616d6560581b6044820152606401610520565b6001546040516001600160a01b038084169216907f0f06062680f9bd68e786e9980d9bb03d73d5620fc3b345e417b6eacb310b970690600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b1580156117ab57600080fd5b505afa1580156117bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e3919061486b565b6001600160a01b0316336001600160a01b0316146118135760405162461bcd60e51b815260040161052090614888565b6001600160a01b0381166118635760405162461bcd60e51b8152602060048201526017602482015276737761707065722d616464726573732d69732d7a65726f60481b6044820152606401610520565b6002546001600160a01b03828116911614156118b35760405162461bcd60e51b815260206004820152600f60248201526e737761707065722d69732d73616d6560881b6044820152606401610520565b6002546040516001600160a01b038084169216907f6c953b7ec311055c20b96a42cea31e89528e375b1bf953a503db40854b3188fe90600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561196857600080fd5b505afa15801561197c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a0919061486b565b6001600160a01b0316336001600160a01b0316146119d05760405162461bcd60e51b815260040161052090614888565b600c805460ff191682151517905550565b6119ea336104fc565b611a065760405162461bcd60e51b8152600401610520906147bb565b6001546001600160a01b0316611a565760405162461bcd60e51b81526020600482015260156024820152741999594b58dbdb1b1958dd1bdc8b5b9bdd0b5cd95d605a1b6044820152606401610520565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b03161415611ad85760405162461bcd60e51b815260206004820152601f60248201527f6e6f742d616c6c6f7765642d746f2d73776565702d636f6c6c61746572616c006044820152606401610520565b611ae181610ccd565b15611b255760405162461bcd60e51b815260206004820152601460248201527306e6f742d616c6c6f7765642d746f2d73776565760641b6044820152606401610520565b6001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415611b6057600154610967906001600160a01b0316476123f4565b6040516370a0823160e01b81526000906001600160a01b038316906370a0823190611b8f9030906004016143ec565b60206040518083038186803b158015611ba757600080fd5b505afa158015611bbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bdf91906147eb565b600154909150610aae906001600160a01b03848116911683611f7d565b6000806000611c09610e4d565b9150915080827f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611c5b91906143ec565b60206040518083038186803b158015611c7357600080fd5b505afa158015611c87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cab91906147eb565b611cb591906149e9565b610e469190614854565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b158015611d1857600080fd5b505afa158015611d2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d50919061486b565b6001600160a01b0316336001600160a01b031614611d805760405162461bcd60e51b815260040161052090614888565b655af3107a4000611d8f61250d565b611d999190614911565b8110611de25760405162461bcd60e51b81526020600482015260186024820152771a5b9d985b1a590b5b585e0b589bdc9c9bddcb5b1a5b5a5d60421b6044820152606401610520565b818111611e315760405162461bcd60e51b815260206004820152601d60248201527f6d61782d73686f756c642d62652d6869676865722d7468616e2d6d696e0000006044820152606401610520565b6006546007546040805192835260208301859052820152606081018290527f0e68fa4c4a80a75427bcce81b711855825bd765ea0e6e15e330653b2437db78e9060800160405180910390a1600691909155600755565b6000611e9c836001600160a01b0384166125ce565b9392505050565b6001600160a01b03811660009081526001830160205260408120541515611e9c565b600254604051636ccb2b0160e01b81526001600160a01b0385811660048301528481166024830152604482018490526001606483015230608483015290911690636ccb2b019060a401602060405180830381600087803b158015611f2857600080fd5b505af1925050508015611f58575060408051601f3d908101601f19168201909252611f55918101906147eb565b60015b611f6157505050565b505b505050565b6000611e9c836001600160a01b03841661261d565b6040516001600160a01b038316602482015260448101829052611f6390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612710565b600080611fee8360006127e2565b9150915080156120ac5761200282826129e1565b61200c9083614854565b915060005b6000831180156120225750600a8111155b1561203e57612032836001612afd565b90920391600101612011565b600080612049610e4d565b9092509050841561209c576007546000901561207b5760075461206e612710846148f2565b6120789190614911565b90505b60006120878285614854565b905080881115612095578097505b50506120a8565b818611156120a8578195505b5050505b611f6383612b68565b60008183106120c45781611e9c565b5090919050565b81156120f3576120ef731e0447b19bb6ecfdae1e4ae1694b0c3659614e4e82612ce8565b600b555b50600c80549115156101000261ff0019909216919091179055565b600080600061211b612e51565b6040516302df682360e11b815260048101849052602481018390526044810182905292955090935091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906305bed04690606401600060405180830381600087803b15801561219357600080fd5b505af11580156121a7573d6000803e3d6000fd5b50505050610f3f6132e1565b600080838060200190518101906121ca9190614a3c565b9150915060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161221c91906143ec565b60206040518083038186803b15801561223457600080fd5b505afa158015612248573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226c91906147eb565b9050828110156122ad5760405162461bcd60e51b815260206004820152600c60248201526b11931054d217d1905253115160a21b6044820152606401610520565b81156122ca576122bc836133e2565b6122c584612b68565b610ff8565b6122d3816134a8565b610ff88461356f565b60606000611e9c8361363a565b6122f281613696565b6109677f0000000000000000000000000000000000000000000000000000000000000000826136f6565b60085460408051637e062a3560e11b815290516001600160a01b039283169284169163fc0c546a916004808301926020929190829003018186803b15801561236357600080fd5b505afa158015612377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239b919061486b565b6001600160a01b0316146123e75760405162461bcd60e51b81526020600482015260136024820152723bb937b73396b932b1b2b4b83a16ba37b5b2b760691b6044820152606401610520565b60006006556109676132e1565b804710156124445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610520565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612491576040519150601f19603f3d011682016040523d82523d6000602084013e612496565b606091505b5050905080611f635760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610520565b600854604051638e8f294b60e01b81526000916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811692638e8f294b926125609216906004016143ec565b60606040518083038186803b15801561257857600080fd5b505afa15801561258c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b09190614a6c565b50915061271090506125c461251c836148f2565b6111f09190614911565b600081815260018301602052604081205461261557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d1d565b506000610d1d565b60008181526001830160205260408120548015612706576000612641600183614854565b855490915060009061265590600190614854565b90508181146126ba57600086600001828154811061267557612675614804565b906000526020600020015490508087600001848154811061269857612698614804565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806126cb576126cb614aaf565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d1d565b6000915050610d1d565b6000612765826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166137ad9092919063ffffffff16565b805190915015611f6357808060200190518101906127839190614ac5565b611f635760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610520565b600854604051633af9e66960e01b8152600091829182916001600160a01b031690633af9e669906128179030906004016143ec565b602060405180830381600087803b15801561283157600080fd5b505af1158015612845573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286991906147eb565b6008546040516395dd919360e01b81529192506000916001600160a01b03909116906395dd91939061289f9030906004016143ec565b60206040518083038186803b1580156128b757600080fd5b505afa1580156128cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128ef91906147eb565b905060065460001415612909579250600191506129da9050565b60006129158284614854565b905060008661293b5787821161292c576000612945565b6129368883614854565b612945565b61294588836149e9565b905060006007546127106129599190614854565b60075461296690846148f2565b6129709190614911565b905060006006546127106129849190614854565b60065461299190856148f2565b61299b9190614911565b9050818511156129ba57600196506129b38186614854565b97506129d3565b808510156129d357600096506129d08582614854565b97505b5050505050505b9250929050565b600c546000908190610100900460ff1680156129fd5750600084115b15612a6e5760008484604051602001612a229291909182521515602082015260400190565b6040516020818303038152906040529050612a5e7f000000000000000000000000000000000000000000000000000000000000000086836137c4565b9150612a6a8286614854565b9450505b600c5460ff168015612a7d5750825b8015612a895750600084115b15611e9c5760008484604051602001612aae9291909182521515602082015260400190565b6040516020818303038152906040529050612aea7f00000000000000000000000000000000000000000000000000000000000000008683613a85565b612af490836149e9565b95945050505050565b6000806000612b0a610e4d565b91509150806000148015612b1b5750835b15612b2b57600092505050610d1d565b6000612b3561250d565b90508415612b5057612b4986848484613dd6565b9350612b5f565b612b5c86848484613e3c565b93505b50505092915050565b600019811415612cb7576008546040516370a0823160e01b81526001600160a01b039091169063db006a759082906370a0823190612baa9030906004016143ec565b60206040518083038186803b158015612bc257600080fd5b505afa158015612bd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bfa91906147eb565b6040518263ffffffff1660e01b8152600401612c1891815260200190565b602060405180830381600087803b158015612c3257600080fd5b505af1158015612c46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c6a91906147eb565b156109675760405162461bcd60e51b815260206004820152601d60248201527f77697468647261772d66726f6d2d636f6d706f756e642d6661696c65640000006044820152606401610520565b60085460405163852a12e360e01b8152600481018390526001600160a01b039091169063852a12e390602401612c18565b6000808390506000816001600160a01b031663295c39a56040518163ffffffff1660e01b815260040160206040518083038186803b158015612d2957600080fd5b505afa158015612d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6191906147eb565b90506000805b82811015612e205760405163062bd3e960e01b8152600481018290526001600160a01b0385169063062bd3e99060240160206040518083038186803b158015612daf57600080fd5b505afa158015612dc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612de7919061486b565b9150856001600160a01b0316826001600160a01b03161415612e0e579350610d1d92505050565b80612e1881614ae2565b915050612d67565b506040805180820182526002815261033360f41b6020820152905162461bcd60e51b81526105209190600401614786565b6000806000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d53ddc26306040518263ffffffff1660e01b8152600401612ea391906143ec565b60206040518083038186803b158015612ebb57600080fd5b505afa158015612ecf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ef391906147eb565b90506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663228bfd9f306040518263ffffffff1660e01b8152600401612f4491906143ec565b6101206040518083038186803b158015612f5d57600080fd5b505afa158015612f71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f959190614afd565b506008546040516395dd919360e01b8152949a50909850600097506001600160a01b031695506395dd91939450612fd59350309260040191506143ec9050565b60206040518083038186803b158015612fed57600080fd5b505afa158015613001573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061302591906147eb565b600854604051633af9e66960e01b81526001600160a01b0390911690633af9e669906130559030906004016143ec565b602060405180830381600087803b15801561306f57600080fd5b505af1158015613083573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a791906147eb565b6130b19190614854565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161310191906143ec565b60206040518083038186803b15801561311957600080fd5b505afa15801561312d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061315191906147eb565b9050600061315f82846149e9565b90508481111561317a576131738582614854565b9850613187565b6131848186614854565b97505b6000613193878b6149e9565b9050808310156132645760006131b26131ac8584614854565b866120b5565b90508015613262576131c381611fe0565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319061320f9030906004016143ec565b60206040518083038186803b15801561322757600080fd5b505afa15801561323b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061325f91906147eb565b93505b505b61326e83886120b5565b975087831161327e576000613291565b61329161328b8985614854565b8b6120b5565b9950846132d5576000806132a3610e4d565b915091506000821180156132b5575080155b156132d2576132c5600019612b68565b6132cf828d6149e9565b9b505b50505b50505050505050909192565b6040516370a0823160e01b81526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a08231906133309030906004016143ec565b60206040518083038186803b15801561334857600080fd5b505afa15801561335c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061338091906147eb565b90506000806133908360016127e2565b9150915061339d836134a8565b6133a782826129e1565b6133b19083614854565b915060005b6000831180156133c7575060068111155b15611f61576133d68383612afd565b909203916001016133b6565b60085460405163073a938160e11b8152600481018390526001600160a01b0390911690630e75270290602401602060405180830381600087803b15801561342857600080fd5b505af115801561343c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061346091906147eb565b156109675760405162461bcd60e51b81526020600482015260186024820152771c995c185e4b5d1bcb58dbdb5c1bdd5b990b59985a5b195960421b6044820152606401610520565b60085460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401602060405180830381600087803b1580156134ee57600080fd5b505af1158015613502573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061352691906147eb565b156109675760405162461bcd60e51b81526020600482015260196024820152781cdd5c1c1b1e4b5d1bcb58dbdb5c1bdd5b990b59985a5b1959603a1b6044820152606401610520565b60085460405163317afabb60e21b8152600481018390526001600160a01b039091169063c5ebeaec90602401602060405180830381600087803b1580156135b557600080fd5b505af11580156135c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ed91906147eb565b156109675760405162461bcd60e51b815260206004820152601b60248201527f626f72726f772d66726f6d2d636f6d706f756e642d6661696c656400000000006044820152606401610520565b60608160000180548060200260200160405190810160405280929190818152602001828054801561368a57602002820191906000526020600020905b815481526020019060010190808311613676575b50505050509050919050565b61369f81613f23565b6008546136d9906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911683613f73565b600254600954610967916001600160a01b03918216911683613f73565b61371e6001600160a01b038316731e0447b19bb6ecfdae1e4ae1694b0c3659614e4e83613f73565b600a5460408051630261bf8b60e01b81529051610aae926001600160a01b031691630261bf8b916004808301926020929190829003018186803b15801561376457600080fd5b505afa158015613778573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379c919061486b565b6001600160a01b0384169083613f73565b60606137bc8484600085614097565b949350505050565b600c54604080518082019091526002815261191b60f11b6020820152600091610100900460ff166138085760405162461bcd60e51b81526004016105209190614786565b506040516370a0823160e01b81526000906001600160a01b038616906370a082319061384c90731e0447b19bb6ecfdae1e4ae1694b0c3659614e4e906004016143ec565b60206040518083038186803b15801561386457600080fd5b505afa158015613878573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061389c91906147eb565b9050808411156138aa578093505b60006138b78560026149e9565b9050600084826040516020016138ce929190614b71565b60408051808303601f19018152600380845260808401909252925060009190816020015b6138fa61432b565b8152602001906001900390816138f257905050905061391b600b54886141bf565b8160008151811061392e5761392e614804565b602002602001018190525061394282614249565b8160018151811061395557613955614804565b602002602001018190525061396c600b54846142b7565b8160028151811061397f5761397f614804565b6020908102919091010152604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816139a15750506040805180820182526000808252602091820152815180830190925230825260019082015290915081600081518110613a0257613a02614804565b602090810291909101015260405163a67a6a4560e01b8152731e0447b19bb6ecfdae1e4ae1694b0c3659614e4e9063a67a6a4590613a469084908690600401614bf0565b600060405180830381600087803b158015613a6057600080fd5b505af1158015613a74573d6000803e3d6000fd5b50999b9a5050505050505050505050565b600c54604080518082019091526002815261323560f01b602082015260009160ff16613ac45760405162461bcd60e51b81526004016105209190614786565b50600a5460408051630261bf8b60e01b815290516000926001600160a01b031691630261bf8b916004808301926020929190829003018186803b158015613b0a57600080fd5b505afa158015613b1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b42919061486b565b600a546040516321f8a72160e01b8152600160f81b60048201529192506000916001600160a01b03909116906321f8a7219060240160206040518083038186803b158015613b8f57600080fd5b505afa158015613ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bc7919061486b565b90506000816001600160a01b03166335ea6a75886040518263ffffffff1660e01b8152600401613bf791906143ec565b6101406040518083038186803b158015613c1057600080fd5b505afa158015613c24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c489190614d21565b505050505050505050905080861115613c5f578095505b604080516001808252818301909252600091602080830190803683370190505090508781600081518110613c9557613c95614804565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092526000918160200160208202803683370190505090508781600081518110613ce657613ce6614804565b6020908102919091010152604080516001808252818301909252600091816020016020820280368337019050509050600081600081518110613d2a57613d2a614804565b6020026020010181815250506001600c60026101000a81548160ff021916908315150217905550856001600160a01b031663ab9c4b5d30858585308e60006040518863ffffffff1660e01b8152600401613d8a9796959493929190614dda565b600060405180830381600087803b158015613da457600080fd5b505af1158015613db8573d6000803e3d6000fd5b5050600c805462ff00001916905550989a9950505050505050505050565b6000808215613dff5782613df285670de0b6b3a76400006148f2565b613dfc9190614911565b90505b613e098186614854565b9150838210613e16578391505b858210613e21578591505b613e2a82612b68565b613e33826133e2565b50949350505050565b600080670de0b6b3a7640000613e5284876148f2565b613e5c9190614911565b9050613e688482614854565b9150858210613e75578591505b613e7e8261356f565b6040516370a0823160e01b8152613e33906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190613ece9030906004016143ec565b60206040518083038186803b158015613ee657600080fd5b505afa158015613efa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f1e91906147eb565b6134a8565b6109676001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000835b801580613ffc5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015613fc257600080fd5b505afa158015613fd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ffa91906147eb565b155b6140675760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610520565b6040516001600160a01b038316602482015260448101829052611f6390849063095ea7b360e01b90606401611fa9565b6060824710156140f85760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610520565b843b6141465760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610520565b600080866001600160a01b031685876040516141629190614e58565b60006040518083038185875af1925050503d806000811461419f576040519150601f19603f3d011682016040523d82523d6000602084013e6141a4565b606091505b50915091506141b48282866142f2565b979650505050505050565b6141c761432b565b604080516101008101825260018152600060208083018290528351608081018552828152929384019291908201905b81526020016000815260200185815250815260200184815260200160008152602001306001600160a01b031681526020016000815260200160405180602001604052806000815250815250905092915050565b61425161432b565b6040805161010081018252600881526000602080830182905283516080810185528281529293840192919082019081526020016000815260006020918201819052918352820181905260408201819052306060830152608082015260a001929092525090565b6142bf61432b565b604080516101008101825260008082526020808301829052835160808101855260018152929384019291908201906141f6565b60608315614301575081611e9c565b8251156143115782518084602001fd5b8160405162461bcd60e51b81526004016105209190614786565b60408051610100810182526000808252602082015290810161436f604080516080810190915260008082526020820190815260200160008152602001600081525090565b8152602001600081526020016000815260200160006001600160a01b0316815260200160008152602001606081525090565b6000602082840312156143b357600080fd5b5035919050565b6001600160a01b038116811461096757600080fd5b6000602082840312156143e157600080fd5b8135611e9c816143ba565b6001600160a01b0391909116815260200190565b801515811461096757600080fd5b60006020828403121561442057600080fd5b8135611e9c81614400565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156144635761446361442b565b60405290565b604051601f8201601f191681016001600160401b03811182821017156144915761449161442b565b604052919050565b60006001600160401b038211156144b2576144b261442b565b50601f01601f191660200190565b600080600083850360808112156144d657600080fd5b84356144e1816143ba565b935060206040601f19830112156144f757600080fd5b6144ff614441565b91508086013561450e816143ba565b82526040860135818301529092506060850135906001600160401b0382111561453657600080fd5b818601915086601f83011261454a57600080fd5b813561455d61455882614499565b614469565b818152888383860101111561457157600080fd5b81838501848301376000838383010152809450505050509250925092565b60008083601f8401126145a157600080fd5b5081356001600160401b038111156145b857600080fd5b6020830191508360208260051b85010111156129da57600080fd5b600080600080600080600080600060a08a8c0312156145f157600080fd5b89356001600160401b038082111561460857600080fd5b6146148d838e0161458f565b909b50995060208c013591508082111561462d57600080fd5b6146398d838e0161458f565b909950975060408c013591508082111561465257600080fd5b61465e8d838e0161458f565b909750955060608c01359150614673826143ba565b90935060808b0135908082111561468957600080fd5b818c0191508c601f83011261469d57600080fd5b8135818111156146ac57600080fd5b8d60208285010111156146be57600080fd5b6020830194508093505050509295985092959850929598565b600081518084526020808501945080840160005b838110156147105781516001600160a01b0316875295820195908201906001016146eb565b509495945050505050565b602081526000611e9c60208301846146d7565b60005b83811015614749578181015183820152602001614731565b83811115611f615750506000910152565b6000815180845261477281602086016020860161472e565b601f01601f19169290920160200192915050565b602081526000611e9c602083018461475a565b600080604083850312156147ac57600080fd5b50508035926020909101359150565b60208082526016908201527531b0b63632b916b4b996b737ba16b096b5b2b2b832b960511b604082015260600190565b6000602082840312156147fd57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03831681526040602082018190526000906137bc908301846146d7565b634e487b7160e01b600052601160045260246000fd5b6000828210156148665761486661483e565b500390565b60006020828403121561487d57600080fd5b8151611e9c816143ba565b6020808252601a908201527f63616c6c65722d69732d6e6f742d7468652d676f7665726e6f72000000000000604082015260600190565b60208082526019908201527818d85b1b195c8b5a5ccb5b9bdd0b5d995cdc195c8b5c1bdbdb603a1b604082015260600190565b600081600019048311821515161561490c5761490c61483e565b500290565b60008261492e57634e487b7160e01b600052601260045260246000fd5b500490565b6000806000806080858703121561494957600080fd5b505082516020840151604085015160609095015191969095509092509050565b6000806040838503121561497c57600080fd5b82516001600160401b0381111561499257600080fd5b8301601f810185136149a357600080fd5b80516149b161455882614499565b8181528660208385010111156149c657600080fd5b6149d782602083016020860161472e565b60209590950151949694955050505050565b600082198211156149fc576149fc61483e565b500190565b600181811c90821680614a1557607f821691505b60208210811415614a3657634e487b7160e01b600052602260045260246000fd5b50919050565b60008060408385031215614a4f57600080fd5b825191506020830151614a6181614400565b809150509250929050565b600080600060608486031215614a8157600080fd5b8351614a8c81614400565b602085015160408601519194509250614aa481614400565b809150509250925092565b634e487b7160e01b600052603160045260246000fd5b600060208284031215614ad757600080fd5b8151611e9c81614400565b6000600019821415614af657614af661483e565b5060010190565b60008060008060008060008060006101208a8c031215614b1c57600080fd5b8951614b2781614400565b8099505060208a0151975060408a0151965060608a0151955060808a0151945060a08a0151935060c08a0151925060e08a015191506101008a015190509295985092959850929598565b604081526000614b84604083018561475a565b90508260208301529392505050565b634e487b7160e01b600052602160045260246000fd5b6002811061096757610967614b93565b8051151582526020810151614bcd81614ba9565b60208301526040810151614be081614ba9565b6040830152606090810151910152565b6040808252835182820181905260009190606090818501906020808901865b83811015614c3d57815180516001600160a01b03168652830151838601529386019390820190600101614c0f565b50508683038188015287518084528184019250600581901b8401820189830160005b83811015614d1057601f198784030186528151610160815160098110614c8757614c87614b93565b855281870151878601528a820151614ca18c870182614bb9565b508982015160c081818801526080840151915060e0828189015260a08501519250614cd86101008901846001600160a01b03169052565b908401516101208801529092015161014086018290529150614cfc8186018361475a565b978701979450505090840190600101614c5f565b50909b9a5050505050505050505050565b6000806000806000806000806000806101408b8d031215614d4157600080fd5b8a51995060208b0151985060408b0151975060608b0151965060808b0151955060a08b0151945060c08b0151935060e08b015192506101008b015191506101208b015164ffffffffff81168114614d9757600080fd5b809150509295989b9194979a5092959850565b600081518084526020808501945080840160005b8381101561471057815187529582019590820190600101614dbe565b600060018060a01b03808a16835260e06020840152614dfc60e084018a6146d7565b8381036040850152614e0e818a614daa565b90508381036060850152614e228189614daa565b9050818716608085015283810360a0850152614e3e818761475a565b9250505061ffff831660c083015298975050505050505050565b60008251614e6a81846020870161472e565b919091019291505056fea2646970667358221220c5fd0475dccb23bf96e9a8476a97c412a1ca43c6d8588b0e6080c9daba577b9d64736f6c634300080900330000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee0000000000000000000000008f156189a3cd28dfc8fb7bbbace58f98f09c0bb30000000000000000000000003d9819210a31b4961b30ef54be2aed79b9c9cd3b000000000000000000000000c00e94cb662c3520282e6f5717214004a7f26888000000000000000000000000b53c1a33016b2dc2ff3653530bff1848a515c8c50000000000000000000000005d3a536e4d6dbd6114cc1ead35777bab948e364300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000015436f6d706f756e645f4c657665726167655f4441490000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101dc5760003560e01c8063a3f4df7e11610105578063e00af4a71161009d578063e00af4a714610451578063e5328e0614610464578063ec78e8321461046c578063f23c47221461047f578063f7c618c114610491578063f7c99bea146104a4578063fc0c546a146104ad578063fef395d3146104be578063ffa1ad74146104d157600080fd5b8063a3f4df7e14610387578063b2016bd41461039c578063b9098e3c146103c3578063c415b95c146103cc578063ce5494bb146103df578063d2c35ce8146103f2578063d3033c3914610405578063d333253914610418578063d8dfeb451461042b57600080fd5b80635abda028116101785780635abda028146102c85780635fe3b567146102d05780637398ab18146102f75780637d7c2a1c146103145780638b41871314610337578063920f5c841461034a578063951dc22c1461035d57806399b71d5c146103725780639b7166a91461037a57600080fd5b80631026013a146101e157806314ae9f2e1461020757806316f0115b1461021c5780632a049a21146102505780632b3297f9146102595780632e1a7d4d1461026c5780634032b72b1461027f578063440d724814610292578063599e892a146102b5575b600080fd5b6101f46101ef3660046143a1565b6104f5565b6040519081526020015b60405180910390f35b61021a6102153660046143cf565b610858565b005b6102437f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee81565b6040516101fe91906143ec565b6101f460075481565b600254610243906001600160a01b031681565b61021a61027a3660046143a1565b61096a565b61021a61028d3660046143cf565b610bc1565b6102a56102a03660046143cf565b610ccd565b60405190151581526020016101fe565b61021a6102c336600461440e565b610d23565b6101f4610e0e565b6102437f0000000000000000000000003d9819210a31b4961b30ef54be2aed79b9c9cd3b81565b6102ff610e4d565b604080519283526020830191909152016101fe565b61031c610f07565b604080519384526020840192909252908201526060016101fe565b61021a6103453660046144c0565b610f44565b6102a56103583660046145d3565b610fff565b6103656111e4565b6040516101fe919061471b565b61021a6111f5565b600c546102a59060ff1681565b61038f611231565b6040516101fe9190614786565b6102437f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f81565b6101f460065481565b600154610243906001600160a01b031681565b61021a6103ed3660046143cf565b6112bf565b61021a6104003660046143cf565b611589565b61021a6104133660046143cf565b611752565b61021a61042636600461440e565b61190f565b7f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f610243565b61021a61045f3660046143cf565b6119e1565b6101f4611bfc565b600054610243906001600160a01b031681565b600c546102a590610100900460ff1681565b600954610243906001600160a01b031681565b6101f4600b5481565b6000546001600160a01b0316610243565b61021a6104cc366004614799565b611cbf565b61038f604051806040016040528060058152602001640352e302e360dc1b81525081565b6000610504335b600390611ea3565b6105295760405162461bcd60e51b8152600401610520906147bb565b60405180910390fd5b6040516370a0823160e01b81526000906001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f16906370a08231906105789030906004016143ec565b60206040518083038186803b15801561059057600080fd5b505afa1580156105a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c891906147eb565b6040805160018082528183019092529192506000919060208083019080368337505060085482519293506001600160a01b03169183915060009061060e5761060e614804565b6001600160a01b03928316602091820292909201015260405162e1ed9760e51b81527f0000000000000000000000003d9819210a31b4961b30ef54be2aed79b9c9cd3b90911690631c3db2e09061066b903090859060040161481a565b600060405180830381600087803b15801561068557600080fd5b505af1158015610699573d6000803e3d6000fd5b50506009546040516370a0823160e01b8152600093506001600160a01b0390911691506370a08231906106d09030906004016143ec565b60206040518083038186803b1580156106e857600080fd5b505afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072091906147eb565b905080156108505760095461075f906001600160a01b03167f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f83611ec5565b6040516370a0823160e01b815283906001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f16906370a08231906107ad9030906004016143ec565b60206040518083038186803b1580156107c557600080fd5b505afa1580156107d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fd91906147eb565b6108079190614854565b9350848410156108505760405162461bcd60e51b81526020600482015260146024820152731b9bdd0b595b9bdd59da0b585b5bdd5b9d13dd5d60621b6044820152606401610520565b505050919050565b7f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee6001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b1580156108b157600080fd5b505afa1580156108c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e9919061486b565b6001600160a01b0316336001600160a01b0316146109195760405162461bcd60e51b815260040161052090614888565b610924600382611f68565b6109675760405162461bcd60e51b81526020600482015260146024820152731c995b5bdd994b5ad9595c195c8b59985a5b195960621b6044820152606401610520565b50565b337f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee6001600160a01b0316146109b25760405162461bcd60e51b8152600401610520906148bf565b6040516370a0823160e01b81526000906001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f16906370a0823190610a019030906004016143ec565b60206040518083038186803b158015610a1957600080fd5b505afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5191906147eb565b9050818110610ab257610aae6001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f167f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee84611f7d565b5050565b610ac4610abf8284614854565b611fe0565b6040516370a0823160e01b81526001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f16906370a0823190610b109030906004016143ec565b60206040518083038186803b158015610b2857600080fd5b505afa158015610b3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6091906147eb565b9050610aae7f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee610b9084846120b5565b6001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f169190611f7d565b7f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee6001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b158015610c1a57600080fd5b505afa158015610c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c52919061486b565b6001600160a01b0316336001600160a01b031614610c825760405162461bcd60e51b815260040161052090614888565b610c8d600382611e87565b6109675760405162461bcd60e51b81526020600482015260116024820152701859190b5ad9595c195c8b59985a5b1959607a1b6044820152606401610520565b6008546000906001600160a01b0383811691161480610d1d57507f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f6001600160a01b0316826001600160a01b0316145b92915050565b7f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee6001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b158015610d7c57600080fd5b505afa158015610d90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db4919061486b565b6001600160a01b0316336001600160a01b031614610de45760405162461bcd60e51b815260040161052090614888565b610967817f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f6120cb565b6000806000610e1b610e4d565b9150915080600014610e435781610e34612710836148f2565b610e3e9190614911565b610e46565b60005b9250505090565b6008546040516361bfb47160e11b815260009182918291829182916001600160a01b03169063c37f68e290610e869030906004016143ec565b60806040518083038186803b158015610e9e57600080fd5b505afa158015610eb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed69190614933565b93509350935050670de0b6b3a76400008184610ef291906148f2565b610efc9190614911565b959194509092505050565b60008080610f14336104fc565b610f305760405162461bcd60e51b8152600401610520906147bb565b610f3861210e565b9250925092505b909192565b60008082806020019051810190610f5b9190614969565b909250905033731e0447b19bb6ecfdae1e4ae1694b0c3659614e4e14610fab5760405162461bcd60e51b815260206004820152600560248201526421736f6c6f60d81b6044820152606401610520565b604080518082019091526002815261064760f31b60208201526001600160a01b0386163014610fed5760405162461bcd60e51b81526004016105209190614786565b50610ff882826121b3565b5050505050565b600a5460408051630261bf8b60e01b815290516000926001600160a01b031691630261bf8b916004808301926020929190829003018186803b15801561104457600080fd5b505afa158015611058573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107c919061486b565b6001600160a01b0316336001600160a01b0316146110c95760405162461bcd60e51b815260206004820152600a6024820152690858585d994b5c1bdbdb60b21b6044820152606401610520565b600c54604080518082019091526002815261323760f01b60208201529062010000900460ff1661110c5760405162461bcd60e51b81526004016105209190614786565b50604080518082019091526002815261064760f31b60208201526001600160a01b038516301461114f5760405162461bcd60e51b81526004016105209190614786565b5060008686600081811061116557611165614804565b905060200201358989600081811061117f5761117f614804565b9050602002013561119091906149e9565b90506111d384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508592506121b3915050565b5060019a9950505050505050505050565b60606111f060036122dc565b905090565b6111fe336104fc565b61121a5760405162461bcd60e51b8152600401610520906147bb565b61122460006122e9565b61122f6000196122e9565b565b6005805461123e90614a01565b80601f016020809104026020016040519081016040528092919081815260200182805461126a90614a01565b80156112b75780601f1061128c576101008083540402835291602001916112b7565b820191906000526020600020905b81548152906001019060200180831161129a57829003601f168201915b505050505081565b337f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee6001600160a01b0316146113075760405162461bcd60e51b8152600401610520906148bf565b6001600160a01b03811661135d5760405162461bcd60e51b815260206004820152601c60248201527f6e65772d73747261746567792d616464726573732d69732d7a65726f000000006044820152606401610520565b7f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee6001600160a01b0316816001600160a01b03166316f0115b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156113c057600080fd5b505afa1580156113d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f8919061486b565b6001600160a01b0316146114475760405162461bcd60e51b81526020600482015260166024820152756e6f742d76616c69642d6e65772d737472617465677960501b6044820152606401610520565b6114508161231c565b6000546040516370a0823160e01b81526114e99183916001600160a01b03909116906370a08231906114869030906004016143ec565b60206040518083038186803b15801561149e57600080fd5b505afa1580156114b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d691906147eb565b6000546001600160a01b03169190611f7d565b610967817f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161153991906143ec565b60206040518083038186803b15801561155157600080fd5b505afa158015611565573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9091906147eb565b7f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee6001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b1580156115e257600080fd5b505afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a919061486b565b6001600160a01b0316336001600160a01b03161461164a5760405162461bcd60e51b815260040161052090614888565b6001600160a01b0381166116a05760405162461bcd60e51b815260206004820152601d60248201527f6665652d636f6c6c6563746f722d616464726573732d69732d7a65726f0000006044820152606401610520565b6001546001600160a01b03828116911614156116f65760405162461bcd60e51b81526020600482015260156024820152746665652d636f6c6c6563746f722d69732d73616d6560581b6044820152606401610520565b6001546040516001600160a01b038084169216907f0f06062680f9bd68e786e9980d9bb03d73d5620fc3b345e417b6eacb310b970690600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b7f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee6001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b1580156117ab57600080fd5b505afa1580156117bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e3919061486b565b6001600160a01b0316336001600160a01b0316146118135760405162461bcd60e51b815260040161052090614888565b6001600160a01b0381166118635760405162461bcd60e51b8152602060048201526017602482015276737761707065722d616464726573732d69732d7a65726f60481b6044820152606401610520565b6002546001600160a01b03828116911614156118b35760405162461bcd60e51b815260206004820152600f60248201526e737761707065722d69732d73616d6560881b6044820152606401610520565b6002546040516001600160a01b038084169216907f6c953b7ec311055c20b96a42cea31e89528e375b1bf953a503db40854b3188fe90600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b7f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee6001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561196857600080fd5b505afa15801561197c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a0919061486b565b6001600160a01b0316336001600160a01b0316146119d05760405162461bcd60e51b815260040161052090614888565b600c805460ff191682151517905550565b6119ea336104fc565b611a065760405162461bcd60e51b8152600401610520906147bb565b6001546001600160a01b0316611a565760405162461bcd60e51b81526020600482015260156024820152741999594b58dbdb1b1958dd1bdc8b5b9bdd0b5cd95d605a1b6044820152606401610520565b7f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f6001600160a01b0316816001600160a01b03161415611ad85760405162461bcd60e51b815260206004820152601f60248201527f6e6f742d616c6c6f7765642d746f2d73776565702d636f6c6c61746572616c006044820152606401610520565b611ae181610ccd565b15611b255760405162461bcd60e51b815260206004820152601460248201527306e6f742d616c6c6f7765642d746f2d73776565760641b6044820152606401610520565b6001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415611b6057600154610967906001600160a01b0316476123f4565b6040516370a0823160e01b81526000906001600160a01b038316906370a0823190611b8f9030906004016143ec565b60206040518083038186803b158015611ba757600080fd5b505afa158015611bbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bdf91906147eb565b600154909150610aae906001600160a01b03848116911683611f7d565b6000806000611c09610e4d565b9150915080827f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f6001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611c5b91906143ec565b60206040518083038186803b158015611c7357600080fd5b505afa158015611c87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cab91906147eb565b611cb591906149e9565b610e469190614854565b7f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee6001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b158015611d1857600080fd5b505afa158015611d2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d50919061486b565b6001600160a01b0316336001600160a01b031614611d805760405162461bcd60e51b815260040161052090614888565b655af3107a4000611d8f61250d565b611d999190614911565b8110611de25760405162461bcd60e51b81526020600482015260186024820152771a5b9d985b1a590b5b585e0b589bdc9c9bddcb5b1a5b5a5d60421b6044820152606401610520565b818111611e315760405162461bcd60e51b815260206004820152601d60248201527f6d61782d73686f756c642d62652d6869676865722d7468616e2d6d696e0000006044820152606401610520565b6006546007546040805192835260208301859052820152606081018290527f0e68fa4c4a80a75427bcce81b711855825bd765ea0e6e15e330653b2437db78e9060800160405180910390a1600691909155600755565b6000611e9c836001600160a01b0384166125ce565b9392505050565b6001600160a01b03811660009081526001830160205260408120541515611e9c565b600254604051636ccb2b0160e01b81526001600160a01b0385811660048301528481166024830152604482018490526001606483015230608483015290911690636ccb2b019060a401602060405180830381600087803b158015611f2857600080fd5b505af1925050508015611f58575060408051601f3d908101601f19168201909252611f55918101906147eb565b60015b611f6157505050565b505b505050565b6000611e9c836001600160a01b03841661261d565b6040516001600160a01b038316602482015260448101829052611f6390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612710565b600080611fee8360006127e2565b9150915080156120ac5761200282826129e1565b61200c9083614854565b915060005b6000831180156120225750600a8111155b1561203e57612032836001612afd565b90920391600101612011565b600080612049610e4d565b9092509050841561209c576007546000901561207b5760075461206e612710846148f2565b6120789190614911565b90505b60006120878285614854565b905080881115612095578097505b50506120a8565b818611156120a8578195505b5050505b611f6383612b68565b60008183106120c45781611e9c565b5090919050565b81156120f3576120ef731e0447b19bb6ecfdae1e4ae1694b0c3659614e4e82612ce8565b600b555b50600c80549115156101000261ff0019909216919091179055565b600080600061211b612e51565b6040516302df682360e11b815260048101849052602481018390526044810182905292955090935091507f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee6001600160a01b0316906305bed04690606401600060405180830381600087803b15801561219357600080fd5b505af11580156121a7573d6000803e3d6000fd5b50505050610f3f6132e1565b600080838060200190518101906121ca9190614a3c565b9150915060007f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161221c91906143ec565b60206040518083038186803b15801561223457600080fd5b505afa158015612248573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226c91906147eb565b9050828110156122ad5760405162461bcd60e51b815260206004820152600c60248201526b11931054d217d1905253115160a21b6044820152606401610520565b81156122ca576122bc836133e2565b6122c584612b68565b610ff8565b6122d3816134a8565b610ff88461356f565b60606000611e9c8361363a565b6122f281613696565b6109677f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f826136f6565b60085460408051637e062a3560e11b815290516001600160a01b039283169284169163fc0c546a916004808301926020929190829003018186803b15801561236357600080fd5b505afa158015612377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239b919061486b565b6001600160a01b0316146123e75760405162461bcd60e51b81526020600482015260136024820152723bb937b73396b932b1b2b4b83a16ba37b5b2b760691b6044820152606401610520565b60006006556109676132e1565b804710156124445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610520565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612491576040519150601f19603f3d011682016040523d82523d6000602084013e612496565b606091505b5050905080611f635760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610520565b600854604051638e8f294b60e01b81526000916001600160a01b037f0000000000000000000000003d9819210a31b4961b30ef54be2aed79b9c9cd3b811692638e8f294b926125609216906004016143ec565b60606040518083038186803b15801561257857600080fd5b505afa15801561258c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b09190614a6c565b50915061271090506125c461251c836148f2565b6111f09190614911565b600081815260018301602052604081205461261557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d1d565b506000610d1d565b60008181526001830160205260408120548015612706576000612641600183614854565b855490915060009061265590600190614854565b90508181146126ba57600086600001828154811061267557612675614804565b906000526020600020015490508087600001848154811061269857612698614804565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806126cb576126cb614aaf565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d1d565b6000915050610d1d565b6000612765826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166137ad9092919063ffffffff16565b805190915015611f6357808060200190518101906127839190614ac5565b611f635760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610520565b600854604051633af9e66960e01b8152600091829182916001600160a01b031690633af9e669906128179030906004016143ec565b602060405180830381600087803b15801561283157600080fd5b505af1158015612845573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286991906147eb565b6008546040516395dd919360e01b81529192506000916001600160a01b03909116906395dd91939061289f9030906004016143ec565b60206040518083038186803b1580156128b757600080fd5b505afa1580156128cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128ef91906147eb565b905060065460001415612909579250600191506129da9050565b60006129158284614854565b905060008661293b5787821161292c576000612945565b6129368883614854565b612945565b61294588836149e9565b905060006007546127106129599190614854565b60075461296690846148f2565b6129709190614911565b905060006006546127106129849190614854565b60065461299190856148f2565b61299b9190614911565b9050818511156129ba57600196506129b38186614854565b97506129d3565b808510156129d357600096506129d08582614854565b97505b5050505050505b9250929050565b600c546000908190610100900460ff1680156129fd5750600084115b15612a6e5760008484604051602001612a229291909182521515602082015260400190565b6040516020818303038152906040529050612a5e7f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f86836137c4565b9150612a6a8286614854565b9450505b600c5460ff168015612a7d5750825b8015612a895750600084115b15611e9c5760008484604051602001612aae9291909182521515602082015260400190565b6040516020818303038152906040529050612aea7f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f8683613a85565b612af490836149e9565b95945050505050565b6000806000612b0a610e4d565b91509150806000148015612b1b5750835b15612b2b57600092505050610d1d565b6000612b3561250d565b90508415612b5057612b4986848484613dd6565b9350612b5f565b612b5c86848484613e3c565b93505b50505092915050565b600019811415612cb7576008546040516370a0823160e01b81526001600160a01b039091169063db006a759082906370a0823190612baa9030906004016143ec565b60206040518083038186803b158015612bc257600080fd5b505afa158015612bd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bfa91906147eb565b6040518263ffffffff1660e01b8152600401612c1891815260200190565b602060405180830381600087803b158015612c3257600080fd5b505af1158015612c46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c6a91906147eb565b156109675760405162461bcd60e51b815260206004820152601d60248201527f77697468647261772d66726f6d2d636f6d706f756e642d6661696c65640000006044820152606401610520565b60085460405163852a12e360e01b8152600481018390526001600160a01b039091169063852a12e390602401612c18565b6000808390506000816001600160a01b031663295c39a56040518163ffffffff1660e01b815260040160206040518083038186803b158015612d2957600080fd5b505afa158015612d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6191906147eb565b90506000805b82811015612e205760405163062bd3e960e01b8152600481018290526001600160a01b0385169063062bd3e99060240160206040518083038186803b158015612daf57600080fd5b505afa158015612dc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612de7919061486b565b9150856001600160a01b0316826001600160a01b03161415612e0e579350610d1d92505050565b80612e1881614ae2565b915050612d67565b506040805180820182526002815261033360f41b6020820152905162461bcd60e51b81526105209190600401614786565b6000806000807f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee6001600160a01b031663d53ddc26306040518263ffffffff1660e01b8152600401612ea391906143ec565b60206040518083038186803b158015612ebb57600080fd5b505afa158015612ecf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ef391906147eb565b90506000807f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee6001600160a01b031663228bfd9f306040518263ffffffff1660e01b8152600401612f4491906143ec565b6101206040518083038186803b158015612f5d57600080fd5b505afa158015612f71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f959190614afd565b506008546040516395dd919360e01b8152949a50909850600097506001600160a01b031695506395dd91939450612fd59350309260040191506143ec9050565b60206040518083038186803b158015612fed57600080fd5b505afa158015613001573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061302591906147eb565b600854604051633af9e66960e01b81526001600160a01b0390911690633af9e669906130559030906004016143ec565b602060405180830381600087803b15801561306f57600080fd5b505af1158015613083573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a791906147eb565b6130b19190614854565b905060007f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161310191906143ec565b60206040518083038186803b15801561311957600080fd5b505afa15801561312d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061315191906147eb565b9050600061315f82846149e9565b90508481111561317a576131738582614854565b9850613187565b6131848186614854565b97505b6000613193878b6149e9565b9050808310156132645760006131b26131ac8584614854565b866120b5565b90508015613262576131c381611fe0565b6040516370a0823160e01b81526001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f16906370a082319061320f9030906004016143ec565b60206040518083038186803b15801561322757600080fd5b505afa15801561323b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061325f91906147eb565b93505b505b61326e83886120b5565b975087831161327e576000613291565b61329161328b8985614854565b8b6120b5565b9950846132d5576000806132a3610e4d565b915091506000821180156132b5575080155b156132d2576132c5600019612b68565b6132cf828d6149e9565b9b505b50505b50505050505050909192565b6040516370a0823160e01b81526000906001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f16906370a08231906133309030906004016143ec565b60206040518083038186803b15801561334857600080fd5b505afa15801561335c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061338091906147eb565b90506000806133908360016127e2565b9150915061339d836134a8565b6133a782826129e1565b6133b19083614854565b915060005b6000831180156133c7575060068111155b15611f61576133d68383612afd565b909203916001016133b6565b60085460405163073a938160e11b8152600481018390526001600160a01b0390911690630e75270290602401602060405180830381600087803b15801561342857600080fd5b505af115801561343c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061346091906147eb565b156109675760405162461bcd60e51b81526020600482015260186024820152771c995c185e4b5d1bcb58dbdb5c1bdd5b990b59985a5b195960421b6044820152606401610520565b60085460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401602060405180830381600087803b1580156134ee57600080fd5b505af1158015613502573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061352691906147eb565b156109675760405162461bcd60e51b81526020600482015260196024820152781cdd5c1c1b1e4b5d1bcb58dbdb5c1bdd5b990b59985a5b1959603a1b6044820152606401610520565b60085460405163317afabb60e21b8152600481018390526001600160a01b039091169063c5ebeaec90602401602060405180830381600087803b1580156135b557600080fd5b505af11580156135c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ed91906147eb565b156109675760405162461bcd60e51b815260206004820152601b60248201527f626f72726f772d66726f6d2d636f6d706f756e642d6661696c656400000000006044820152606401610520565b60608160000180548060200260200160405190810160405280929190818152602001828054801561368a57602002820191906000526020600020905b815481526020019060010190808311613676575b50505050509050919050565b61369f81613f23565b6008546136d9906001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f8116911683613f73565b600254600954610967916001600160a01b03918216911683613f73565b61371e6001600160a01b038316731e0447b19bb6ecfdae1e4ae1694b0c3659614e4e83613f73565b600a5460408051630261bf8b60e01b81529051610aae926001600160a01b031691630261bf8b916004808301926020929190829003018186803b15801561376457600080fd5b505afa158015613778573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379c919061486b565b6001600160a01b0384169083613f73565b60606137bc8484600085614097565b949350505050565b600c54604080518082019091526002815261191b60f11b6020820152600091610100900460ff166138085760405162461bcd60e51b81526004016105209190614786565b506040516370a0823160e01b81526000906001600160a01b038616906370a082319061384c90731e0447b19bb6ecfdae1e4ae1694b0c3659614e4e906004016143ec565b60206040518083038186803b15801561386457600080fd5b505afa158015613878573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061389c91906147eb565b9050808411156138aa578093505b60006138b78560026149e9565b9050600084826040516020016138ce929190614b71565b60408051808303601f19018152600380845260808401909252925060009190816020015b6138fa61432b565b8152602001906001900390816138f257905050905061391b600b54886141bf565b8160008151811061392e5761392e614804565b602002602001018190525061394282614249565b8160018151811061395557613955614804565b602002602001018190525061396c600b54846142b7565b8160028151811061397f5761397f614804565b6020908102919091010152604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816139a15750506040805180820182526000808252602091820152815180830190925230825260019082015290915081600081518110613a0257613a02614804565b602090810291909101015260405163a67a6a4560e01b8152731e0447b19bb6ecfdae1e4ae1694b0c3659614e4e9063a67a6a4590613a469084908690600401614bf0565b600060405180830381600087803b158015613a6057600080fd5b505af1158015613a74573d6000803e3d6000fd5b50999b9a5050505050505050505050565b600c54604080518082019091526002815261323560f01b602082015260009160ff16613ac45760405162461bcd60e51b81526004016105209190614786565b50600a5460408051630261bf8b60e01b815290516000926001600160a01b031691630261bf8b916004808301926020929190829003018186803b158015613b0a57600080fd5b505afa158015613b1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b42919061486b565b600a546040516321f8a72160e01b8152600160f81b60048201529192506000916001600160a01b03909116906321f8a7219060240160206040518083038186803b158015613b8f57600080fd5b505afa158015613ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bc7919061486b565b90506000816001600160a01b03166335ea6a75886040518263ffffffff1660e01b8152600401613bf791906143ec565b6101406040518083038186803b158015613c1057600080fd5b505afa158015613c24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c489190614d21565b505050505050505050905080861115613c5f578095505b604080516001808252818301909252600091602080830190803683370190505090508781600081518110613c9557613c95614804565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092526000918160200160208202803683370190505090508781600081518110613ce657613ce6614804565b6020908102919091010152604080516001808252818301909252600091816020016020820280368337019050509050600081600081518110613d2a57613d2a614804565b6020026020010181815250506001600c60026101000a81548160ff021916908315150217905550856001600160a01b031663ab9c4b5d30858585308e60006040518863ffffffff1660e01b8152600401613d8a9796959493929190614dda565b600060405180830381600087803b158015613da457600080fd5b505af1158015613db8573d6000803e3d6000fd5b5050600c805462ff00001916905550989a9950505050505050505050565b6000808215613dff5782613df285670de0b6b3a76400006148f2565b613dfc9190614911565b90505b613e098186614854565b9150838210613e16578391505b858210613e21578591505b613e2a82612b68565b613e33826133e2565b50949350505050565b600080670de0b6b3a7640000613e5284876148f2565b613e5c9190614911565b9050613e688482614854565b9150858210613e75578591505b613e7e8261356f565b6040516370a0823160e01b8152613e33906001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f16906370a0823190613ece9030906004016143ec565b60206040518083038186803b158015613ee657600080fd5b505afa158015613efa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f1e91906147eb565b6134a8565b6109676001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f167f0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee835b801580613ffc5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015613fc257600080fd5b505afa158015613fd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ffa91906147eb565b155b6140675760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610520565b6040516001600160a01b038316602482015260448101829052611f6390849063095ea7b360e01b90606401611fa9565b6060824710156140f85760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610520565b843b6141465760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610520565b600080866001600160a01b031685876040516141629190614e58565b60006040518083038185875af1925050503d806000811461419f576040519150601f19603f3d011682016040523d82523d6000602084013e6141a4565b606091505b50915091506141b48282866142f2565b979650505050505050565b6141c761432b565b604080516101008101825260018152600060208083018290528351608081018552828152929384019291908201905b81526020016000815260200185815250815260200184815260200160008152602001306001600160a01b031681526020016000815260200160405180602001604052806000815250815250905092915050565b61425161432b565b6040805161010081018252600881526000602080830182905283516080810185528281529293840192919082019081526020016000815260006020918201819052918352820181905260408201819052306060830152608082015260a001929092525090565b6142bf61432b565b604080516101008101825260008082526020808301829052835160808101855260018152929384019291908201906141f6565b60608315614301575081611e9c565b8251156143115782518084602001fd5b8160405162461bcd60e51b81526004016105209190614786565b60408051610100810182526000808252602082015290810161436f604080516080810190915260008082526020820190815260200160008152602001600081525090565b8152602001600081526020016000815260200160006001600160a01b0316815260200160008152602001606081525090565b6000602082840312156143b357600080fd5b5035919050565b6001600160a01b038116811461096757600080fd5b6000602082840312156143e157600080fd5b8135611e9c816143ba565b6001600160a01b0391909116815260200190565b801515811461096757600080fd5b60006020828403121561442057600080fd5b8135611e9c81614400565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156144635761446361442b565b60405290565b604051601f8201601f191681016001600160401b03811182821017156144915761449161442b565b604052919050565b60006001600160401b038211156144b2576144b261442b565b50601f01601f191660200190565b600080600083850360808112156144d657600080fd5b84356144e1816143ba565b935060206040601f19830112156144f757600080fd5b6144ff614441565b91508086013561450e816143ba565b82526040860135818301529092506060850135906001600160401b0382111561453657600080fd5b818601915086601f83011261454a57600080fd5b813561455d61455882614499565b614469565b818152888383860101111561457157600080fd5b81838501848301376000838383010152809450505050509250925092565b60008083601f8401126145a157600080fd5b5081356001600160401b038111156145b857600080fd5b6020830191508360208260051b85010111156129da57600080fd5b600080600080600080600080600060a08a8c0312156145f157600080fd5b89356001600160401b038082111561460857600080fd5b6146148d838e0161458f565b909b50995060208c013591508082111561462d57600080fd5b6146398d838e0161458f565b909950975060408c013591508082111561465257600080fd5b61465e8d838e0161458f565b909750955060608c01359150614673826143ba565b90935060808b0135908082111561468957600080fd5b818c0191508c601f83011261469d57600080fd5b8135818111156146ac57600080fd5b8d60208285010111156146be57600080fd5b6020830194508093505050509295985092959850929598565b600081518084526020808501945080840160005b838110156147105781516001600160a01b0316875295820195908201906001016146eb565b509495945050505050565b602081526000611e9c60208301846146d7565b60005b83811015614749578181015183820152602001614731565b83811115611f615750506000910152565b6000815180845261477281602086016020860161472e565b601f01601f19169290920160200192915050565b602081526000611e9c602083018461475a565b600080604083850312156147ac57600080fd5b50508035926020909101359150565b60208082526016908201527531b0b63632b916b4b996b737ba16b096b5b2b2b832b960511b604082015260600190565b6000602082840312156147fd57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03831681526040602082018190526000906137bc908301846146d7565b634e487b7160e01b600052601160045260246000fd5b6000828210156148665761486661483e565b500390565b60006020828403121561487d57600080fd5b8151611e9c816143ba565b6020808252601a908201527f63616c6c65722d69732d6e6f742d7468652d676f7665726e6f72000000000000604082015260600190565b60208082526019908201527818d85b1b195c8b5a5ccb5b9bdd0b5d995cdc195c8b5c1bdbdb603a1b604082015260600190565b600081600019048311821515161561490c5761490c61483e565b500290565b60008261492e57634e487b7160e01b600052601260045260246000fd5b500490565b6000806000806080858703121561494957600080fd5b505082516020840151604085015160609095015191969095509092509050565b6000806040838503121561497c57600080fd5b82516001600160401b0381111561499257600080fd5b8301601f810185136149a357600080fd5b80516149b161455882614499565b8181528660208385010111156149c657600080fd5b6149d782602083016020860161472e565b60209590950151949694955050505050565b600082198211156149fc576149fc61483e565b500190565b600181811c90821680614a1557607f821691505b60208210811415614a3657634e487b7160e01b600052602260045260246000fd5b50919050565b60008060408385031215614a4f57600080fd5b825191506020830151614a6181614400565b809150509250929050565b600080600060608486031215614a8157600080fd5b8351614a8c81614400565b602085015160408601519194509250614aa481614400565b809150509250925092565b634e487b7160e01b600052603160045260246000fd5b600060208284031215614ad757600080fd5b8151611e9c81614400565b6000600019821415614af657614af661483e565b5060010190565b60008060008060008060008060006101208a8c031215614b1c57600080fd5b8951614b2781614400565b8099505060208a0151975060408a0151965060608a0151955060808a0151945060a08a0151935060c08a0151925060e08a015191506101008a015190509295985092959850929598565b604081526000614b84604083018561475a565b90508260208301529392505050565b634e487b7160e01b600052602160045260246000fd5b6002811061096757610967614b93565b8051151582526020810151614bcd81614ba9565b60208301526040810151614be081614ba9565b6040830152606090810151910152565b6040808252835182820181905260009190606090818501906020808901865b83811015614c3d57815180516001600160a01b03168652830151838601529386019390820190600101614c0f565b50508683038188015287518084528184019250600581901b8401820189830160005b83811015614d1057601f198784030186528151610160815160098110614c8757614c87614b93565b855281870151878601528a820151614ca18c870182614bb9565b508982015160c081818801526080840151915060e0828189015260a08501519250614cd86101008901846001600160a01b03169052565b908401516101208801529092015161014086018290529150614cfc8186018361475a565b978701979450505090840190600101614c5f565b50909b9a5050505050505050505050565b6000806000806000806000806000806101408b8d031215614d4157600080fd5b8a51995060208b0151985060408b0151975060608b0151965060808b0151955060a08b0151945060c08b0151935060e08b015192506101008b015191506101208b015164ffffffffff81168114614d9757600080fd5b809150509295989b9194979a5092959850565b600081518084526020808501945080840160005b8381101561471057815187529582019590820190600101614dbe565b600060018060a01b03808a16835260e06020840152614dfc60e084018a6146d7565b8381036040850152614e0e818a614daa565b90508381036060850152614e228189614daa565b9050818716608085015283810360a0850152614e3e818761475a565b9250505061ffff831660c083015298975050505050505050565b60008251614e6a81846020870161472e565b919091019291505056fea2646970667358221220c5fd0475dccb23bf96e9a8476a97c412a1ca43c6d8588b0e6080c9daba577b9d64736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee0000000000000000000000008f156189a3cd28dfc8fb7bbbace58f98f09c0bb30000000000000000000000003d9819210a31b4961b30ef54be2aed79b9c9cd3b000000000000000000000000c00e94cb662c3520282e6f5717214004a7f26888000000000000000000000000b53c1a33016b2dc2ff3653530bff1848a515c8c50000000000000000000000005d3a536e4d6dbd6114cc1ead35777bab948e364300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000015436f6d706f756e645f4c657665726167655f4441490000000000000000000000
-----Decoded View---------------
Arg [0] : _pool (address): 0x0538C8bAc84E95A9dF8aC10Aad17DbE81b9E36ee
Arg [1] : _swapper (address): 0x8f156189A3CD28dFc8FB7BbbAce58F98F09c0bB3
Arg [2] : _comptroller (address): 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B
Arg [3] : _rewardToken (address): 0xc00e94Cb662C3520282E6f5717214004A7f26888
Arg [4] : _aaveAddressesProvider (address): 0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5
Arg [5] : _receiptToken (address): 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643
Arg [6] : _name (string): Compound_Leverage_DAI
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 0000000000000000000000000538c8bac84e95a9df8ac10aad17dbe81b9e36ee
Arg [1] : 0000000000000000000000008f156189a3cd28dfc8fb7bbbace58f98f09c0bb3
Arg [2] : 0000000000000000000000003d9819210a31b4961b30ef54be2aed79b9c9cd3b
Arg [3] : 000000000000000000000000c00e94cb662c3520282e6f5717214004a7f26888
Arg [4] : 000000000000000000000000b53c1a33016b2dc2ff3653530bff1848a515c8c5
Arg [5] : 0000000000000000000000005d3a536e4d6dbd6114cc1ead35777bab948e3643
Arg [6] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000015
Arg [8] : 436f6d706f756e645f4c657665726167655f4441490000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.