More Info
Private Name Tags
ContractCreator
Latest 5 from a total of 5 transactions
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
AaveV2Strategy
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 20000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import './Manager.sol'; import '../interfaces/managers/IStrategyManager.sol'; import '../interfaces/aaveV2/ILendingPool.sol'; import '../interfaces/aaveV2/ILendingPoolAddressesProvider.sol'; import '../interfaces/aaveV2/IAaveIncentivesController.sol'; import '../interfaces/aaveV2/IStakeAave.sol'; import '../interfaces/aaveV2/IAToken.sol'; // This contract contains logic for depositing staker funds into Aave V2 as a yield strategy contract AaveV2Strategy is IStrategyManager, Manager { using SafeERC20 for IERC20; // Need to call a provider because Aave has the ability to change the lending pool address ILendingPoolAddressesProvider public constant LP_ADDRESS_PROVIDER = ILendingPoolAddressesProvider(0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5); // Aave contract that controls stkAAVE rewards IAaveIncentivesController public immutable aaveIncentivesController; // This is the token being deposited (USDC) IERC20 public immutable override want; // This is the receipt token Aave gives in exchange for a token deposit (aUSDC) IAToken public immutable aWant; // Address to receive stkAAVE rewards address public immutable aaveLmReceiver; // Constructor takes the aUSDC address and the rewards receiver address (a Sherlock address) as args constructor(IAToken _aWant, address _aaveLmReceiver) { if (address(_aWant) == address(0)) revert ZeroArgument(); if (_aaveLmReceiver == address(0)) revert ZeroArgument(); aWant = _aWant; // This gets the underlying token associated with aUSDC (USDC) want = IERC20(_aWant.UNDERLYING_ASSET_ADDRESS()); // Gets the specific rewards controller for this token type aaveIncentivesController = _aWant.getIncentivesController(); aaveLmReceiver = _aaveLmReceiver; } // Returns the current Aave lending pool address that should be used function getLp() internal view returns (ILendingPool) { return ILendingPool(LP_ADDRESS_PROVIDER.getLendingPool()); } /// @notice Checks the aUSDC balance in this contract function balanceOf() public view override returns (uint256) { return aWant.balanceOf(address(this)); } /// @notice Deposits all USDC held in this contract into Aave's lending pool function deposit() external override whenNotPaused { ILendingPool lp = getLp(); // Checking the USDC balance of this contract uint256 amount = want.balanceOf(address(this)); if (amount == 0) revert InvalidConditions(); // If allowance for this contract is too low, approve the max allowance if (want.allowance(address(this), address(lp)) < amount) { want.safeIncreaseAllowance(address(lp), type(uint256).max); } // Deposits the full balance of USDC held in this contract into Aave's lending pool lp.deposit(address(want), amount, address(this), 0); } /// @notice Withdraws all USDC from Aave's lending pool back into the Sherlock core contract /// @dev Only callable by the Sherlock core contract /// @return The final amount withdrawn function withdrawAll() external override onlySherlockCore returns (uint256) { ILendingPool lp = getLp(); if (balanceOf() == 0) { return 0; } // Withdraws all USDC from Aave's lending pool and sends it to the Sherlock core contract (msg.sender) return lp.withdraw(address(want), type(uint256).max, msg.sender); } /// @notice Withdraws a specific amount of USDC from Aave's lending pool back into the Sherlock core contract /// @param _amount Amount of USDC to withdraw function withdraw(uint256 _amount) external override onlySherlockCore { // Ensures that it doesn't execute a withdrawAll() call // AAVE V2 uses uint256.max as a magic number to withdraw max amount if (_amount == type(uint256).max) revert InvalidArgument(); ILendingPool lp = getLp(); // Withdraws _amount of USDC and sends it to the Sherlock core contract // If the amount withdrawn is not equal to _amount, it reverts if (lp.withdraw(address(want), _amount, msg.sender) != _amount) revert InvalidConditions(); } // Claims the stkAAVE rewards and sends them to the receiver address function claimRewards() external whenNotPaused { // Creates an array with one slot address[] memory assets = new address[](1); // Sets the slot equal to the address of aUSDC assets[0] = address(aWant); // Claims all the rewards on aUSDC and sends them to the aaveLmReceiver (an address controlled by governance) // Tokens are NOT meant to be (directly) distributed to stakers. aaveIncentivesController.claimRewards(assets, type(uint256).max, aaveLmReceiver); } /// @notice Function used to check if this is the current active yield strategy /// @return Boolean indicating it's active /// @dev If inactive the owner can pull all ERC20s and ETH /// @dev Will be checked by calling the sherlock contract function isActive() public view returns (bool) { return address(sherlockCore.yieldStrategy()) == address(this); } // Only contract owner can call this // Sends all specified tokens in this contract to the receiver's address (as well as ETH) function sweep(address _receiver, IERC20[] memory _extraTokens) external onlyOwner { if (_receiver == address(0)) revert ZeroArgument(); // This contract must NOT be the current assigned yield strategy contract if (isActive()) revert InvalidConditions(); // Executes the sweep for ERC-20s specified in _extraTokens as well as for ETH _sweep(_receiver, _extraTokens); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; import '@openzeppelin/contracts/access/Ownable.sol'; import '@openzeppelin/contracts/security/Pausable.sol'; import '../interfaces/managers/IManager.sol'; abstract contract Manager is IManager, Ownable, Pausable { using SafeERC20 for IERC20; address private constant DEPLOYER = 0x1C11bE636415973520DdDf1b03822b4e2930D94A; ISherlock internal sherlockCore; modifier onlySherlockCore() { if (msg.sender != address(sherlockCore)) revert InvalidSender(); _; } /// @notice Set sherlock core address /// @param _sherlock Current core contract /// @dev Only deployer is able to set core address on all chains except Hardhat network /// @dev One time function, will revert once `sherlock` != address(0) /// @dev This contract will be deployed first, passed on as argument in core constuctor /// @dev emits `SherlockCoreSet` function setSherlockCoreAddress(ISherlock _sherlock) external override { if (address(_sherlock) == address(0)) revert ZeroArgument(); // 31337 is of the Hardhat network blockchain if (block.chainid != 31337 && msg.sender != DEPLOYER) revert InvalidSender(); if (address(sherlockCore) != address(0)) revert InvalidConditions(); sherlockCore = _sherlock; emit SherlockCoreSet(_sherlock); } // Internal function to send tokens remaining in a contract to the receiver address function _sweep(address _receiver, IERC20[] memory _extraTokens) internal { // Loops through the extra tokens (ERC20) provided and sends all of them to the receiver address for (uint256 i; i < _extraTokens.length; i++) { IERC20 token = _extraTokens[i]; token.safeTransfer(_receiver, token.balanceOf(address(this))); } // Sends any remaining ETH to the receiver address (as long as receiver address is payable) (bool success, ) = _receiver.call{ value: address(this).balance }(''); if (success == false) revert InvalidConditions(); } function pause() external onlySherlockCore { _pause(); } function unpause() external onlySherlockCore { _unpause(); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import './IManager.sol'; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; interface IStrategyManager is IManager { /// @return Returns the token type being deposited into a strategy function want() external view returns (IERC20); /// @notice Withdraws all USDC from the strategy back into the Sherlock core contract /// @dev Only callable by the Sherlock core contract /// @return The final amount withdrawn function withdrawAll() external returns (uint256); /// @notice Withdraws a specific amount of USDC from the strategy back into the Sherlock core contract /// @param _amount Amount of USDC to withdraw function withdraw(uint256 _amount) external; /// @notice Deposits all USDC held in this contract into the strategy function deposit() external; /// @return Returns the USDC balance in this contract function balanceOf() external view returns (uint256); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.8.10; pragma experimental ABIEncoderV2; import { ILendingPoolAddressesProvider } from './ILendingPoolAddressesProvider.sol'; import { DataTypes } from './DataTypes.sol'; interface ILendingPool { /** * @dev Emitted on deposit() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the deposit * @param onBehalfOf The beneficiary of the deposit, receiving the aTokens * @param amount The amount deposited * @param referral The referral code used **/ event Deposit( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referral ); /** * @dev Emitted on withdraw() * @param reserve The address of the underlyng asset being withdrawn * @param user The address initiating the withdrawal, owner of aTokens * @param to Address that will receive the underlying * @param amount The amount to be withdrawn **/ event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); /** * @dev Emitted on borrow() and flashLoan() when debt needs to be opened * @param reserve The address of the underlying asset being borrowed * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just * initiator of the transaction on flashLoan() * @param onBehalfOf The address that will be getting the debt * @param amount The amount borrowed out * @param borrowRateMode The rate mode: 1 for Stable, 2 for Variable * @param borrowRate The numeric rate at which the user has borrowed * @param referral The referral code used **/ event Borrow( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint256 borrowRateMode, uint256 borrowRate, uint16 indexed referral ); /** * @dev Emitted on repay() * @param reserve The address of the underlying asset of the reserve * @param user The beneficiary of the repayment, getting his debt reduced * @param repayer The address of the user initiating the repay(), providing the funds * @param amount The amount repaid **/ event Repay( address indexed reserve, address indexed user, address indexed repayer, uint256 amount ); /** * @dev Emitted on swapBorrowRateMode() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user swapping his rate mode * @param rateMode The rate mode that the user wants to swap to **/ event Swap(address indexed reserve, address indexed user, uint256 rateMode); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral **/ event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral **/ event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); /** * @dev Emitted on rebalanceStableBorrowRate() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user for which the rebalance has been executed **/ event RebalanceStableBorrowRate(address indexed reserve, address indexed user); /** * @dev Emitted on flashLoan() * @param target The address of the flash loan receiver contract * @param initiator The address initiating the flash loan * @param asset The address of the asset being flash borrowed * @param amount The amount flash borrowed * @param premium The fee flash borrowed * @param referralCode The referral code used **/ event FlashLoan( address indexed target, address indexed initiator, address indexed asset, uint256 amount, uint256 premium, uint16 referralCode ); /** * @dev Emitted when the pause is triggered. */ event Paused(); /** * @dev Emitted when the pause is lifted. */ event Unpaused(); /** * @dev Emitted when a borrower is liquidated. This event is emitted by the LendingPool via * LendingPoolCollateral manager using a DELEGATECALL * This allows to have the events in the generated ABI for LendingPool. * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param liquidatedCollateralAmount The amount of collateral received by the liiquidator * @param liquidator The address of the liquidator * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly **/ event LiquidationCall( address indexed collateralAsset, address indexed debtAsset, address indexed user, uint256 debtToCover, uint256 liquidatedCollateralAmount, address liquidator, bool receiveAToken ); /** * @dev Emitted when the state of a reserve is updated. NOTE: This event is actually declared * in the ReserveLogic library and emitted in the updateInterestRates() function. Since the function is internal, * the event will actually be fired by the LendingPool contract. The event is therefore replicated here so it * gets added to the LendingPool ABI * @param reserve The address of the underlying asset of the reserve * @param liquidityRate The new liquidity rate * @param stableBorrowRate The new stable borrow rate * @param variableBorrowRate The new variable borrow rate * @param liquidityIndex The new liquidity index * @param variableBorrowIndex The new variable borrow index **/ event ReserveDataUpdated( address indexed reserve, uint256 liquidityRate, uint256 stableBorrowRate, uint256 variableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex ); /** * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User deposits 100 USDC and gets in return 100 aUSDC * @param asset The address of the underlying asset to deposit * @param amount The amount to be deposited * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man **/ function deposit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; /** * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC * @param asset The address of the underlying asset to withdraw * @param amount The underlying amount to be withdrawn * - Send the value type(uint256).max in order to withdraw the whole aToken balance * @param to Address that will receive the underlying, same as msg.sender if the user * wants to receive it on his own wallet, or a different address if the beneficiary is a * different wallet * @return The final amount withdrawn **/ function withdraw( address asset, uint256 amount, address to ) external returns (uint256); /** * @dev Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower * already deposited enough collateral, or he was given enough allowance by a credit delegator on the * corresponding debt token (StableDebtToken or VariableDebtToken) * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet * and 100 stable/variable debt tokens, depending on the `interestRateMode` * @param asset The address of the underlying asset to borrow * @param amount The amount to be borrowed * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param onBehalfOf Address of the user who will receive the debt. Should be the address of the borrower itself * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator * if he has been given credit delegation allowance **/ function borrow( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf ) external; /** * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @return The final amount repaid **/ function repay( address asset, uint256 amount, uint256 rateMode, address onBehalfOf ) external returns (uint256); /** * @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa * @param asset The address of the underlying asset borrowed * @param rateMode The rate mode that the user wants to swap to **/ function swapBorrowRateMode(address asset, uint256 rateMode) external; /** * @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. * - Users can be rebalanced if the following conditions are satisfied: * 1. Usage ratio is above 95% * 2. the current deposit APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too much has been * borrowed at a stable rate and depositors are not earning enough * @param asset The address of the underlying asset borrowed * @param user The address of the user to be rebalanced **/ function rebalanceStableBorrowRate(address asset, address user) external; /** * @dev Allows depositors to enable/disable a specific deposited asset as collateral * @param asset The address of the underlying asset deposited * @param useAsCollateral `true` if the user wants to use the deposit as collateral, `false` otherwise **/ function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; /** * @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly **/ function liquidationCall( address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external; /** * @dev Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept into consideration. * For further details please visit https://developers.aave.com * @param receiverAddress The address of the contract receiving the funds, implementing the IFlashLoanReceiver interface * @param assets The addresses of the assets being flash-borrowed * @param amounts The amounts amounts being flash-borrowed * @param modes Types of the debt to open if the flash loan is not returned: * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver * 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2 * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man **/ function flashLoan( address receiverAddress, address[] calldata assets, uint256[] calldata amounts, uint256[] calldata modes, address onBehalfOf, bytes calldata params, uint16 referralCode ) external; /** * @dev Returns the user account data across all the reserves * @param user The address of the user * @return totalCollateralETH the total collateral in ETH of the user * @return totalDebtETH the total debt in ETH of the user * @return availableBorrowsETH the borrowing power left of the user * @return currentLiquidationThreshold the liquidation threshold of the user * @return ltv the loan to value of the user * @return healthFactor the current health factor of the user **/ function getUserAccountData(address user) external view returns ( uint256 totalCollateralETH, uint256 totalDebtETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); function initReserve( address reserve, address aTokenAddress, address stableDebtAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; function setReserveInterestRateStrategyAddress(address reserve, address rateStrategyAddress) external; function setConfiguration(address reserve, uint256 configuration) external; /** * @dev Returns the configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The configuration of the reserve **/ function getConfiguration(address asset) external view returns (DataTypes.ReserveConfigurationMap memory); /** * @dev Returns the configuration of the user across all the reserves * @param user The user address * @return The configuration of the user **/ function getUserConfiguration(address user) external view returns (DataTypes.UserConfigurationMap memory); /** * @dev Returns the normalized income normalized income of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve's normalized income */ function getReserveNormalizedIncome(address asset) external view returns (uint256); /** * @dev Returns the normalized variable debt per unit of asset * @param asset The address of the underlying asset of the reserve * @return The reserve normalized variable debt */ function getReserveNormalizedVariableDebt(address asset) external view returns (uint256); /** * @dev Returns the state and configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The state of the reserve **/ function getReserveData(address asset) external view returns (DataTypes.ReserveData memory); function finalizeTransfer( address asset, address from, address to, uint256 amount, uint256 balanceFromAfter, uint256 balanceToBefore ) external; function getReservesList() external view returns (address[] memory); function getAddressesProvider() external view returns (ILendingPoolAddressesProvider); function setPause(bool val) external; function paused() external view returns (bool); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.8.10; /** * @title LendingPoolAddressesProvider contract * @dev Main registry of addresses part of or connected to the protocol, including permissioned roles * - Acting also as factory of proxies and admin of those, so with right to change its implementations * - Owned by the Aave Governance * @author Aave **/ interface ILendingPoolAddressesProvider { event MarketIdSet(string newMarketId); event LendingPoolUpdated(address indexed newAddress); event ConfigurationAdminUpdated(address indexed newAddress); event EmergencyAdminUpdated(address indexed newAddress); event LendingPoolConfiguratorUpdated(address indexed newAddress); event LendingPoolCollateralManagerUpdated(address indexed newAddress); event PriceOracleUpdated(address indexed newAddress); event LendingRateOracleUpdated(address indexed newAddress); event ProxyCreated(bytes32 id, address indexed newAddress); event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy); function getMarketId() external view returns (string memory); function setMarketId(string calldata marketId) external; function setAddress(bytes32 id, address newAddress) external; function setAddressAsProxy(bytes32 id, address impl) external; function getAddress(bytes32 id) external view returns (address); function getLendingPool() external view returns (address); function setLendingPoolImpl(address pool) external; function getLendingPoolConfigurator() external view returns (address); function setLendingPoolConfiguratorImpl(address configurator) external; function getLendingPoolCollateralManager() external view returns (address); function setLendingPoolCollateralManager(address manager) external; function getPoolAdmin() external view returns (address); function setPoolAdmin(address admin) external; function getEmergencyAdmin() external view returns (address); function setEmergencyAdmin(address admin) external; function getPriceOracle() external view returns (address); function setPriceOracle(address priceOracle) external; function getLendingRateOracle() external view returns (address); function setLendingRateOracle(address lendingRateOracle) external; }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.8.10; pragma experimental ABIEncoderV2; import { IAaveDistributionManager } from './IAaveDistributionManager.sol'; interface IAaveIncentivesController is IAaveDistributionManager { event RewardsAccrued(address indexed user, uint256 amount); event RewardsClaimed( address indexed user, address indexed to, address indexed claimer, uint256 amount ); event ClaimerSet(address indexed user, address indexed claimer); /** * @dev Whitelists an address to claim the rewards on behalf of another address * @param user The address of the user * @param claimer The address of the claimer */ function setClaimer(address user, address claimer) external; /** * @dev Returns the whitelisted claimer for a certain address (0x0 if not set) * @param user The address of the user * @return The claimer address */ function getClaimer(address user) external view returns (address); /** * @dev Configure assets for a certain rewards emission * @param assets The assets to incentivize * @param emissionsPerSecond The emission for each asset */ function configureAssets(address[] calldata assets, uint256[] calldata emissionsPerSecond) external; /** * @dev Called by the corresponding asset on any update that affects the rewards distribution * @param asset The address of the user * @param userBalance The balance of the user of the asset in the lending pool * @param totalSupply The total supply of the asset in the lending pool **/ function handleAction( address asset, uint256 userBalance, uint256 totalSupply ) external; /** * @dev Returns the total of rewards of an user, already accrued + not yet accrued * @param user The address of the user * @return The rewards **/ function getRewardsBalance(address[] calldata assets, address user) external view returns (uint256); /** * @dev Claims reward for an user, on all the assets of the lending pool, accumulating the pending rewards * @param amount Amount of rewards to claim * @param to Address that will be receiving the rewards * @return Rewards claimed **/ function claimRewards( address[] calldata assets, uint256 amount, address to ) external returns (uint256); /** * @dev Claims reward for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards. The caller must * be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager * @param amount Amount of rewards to claim * @param user Address to check and claim rewards * @param to Address that will be receiving the rewards * @return Rewards claimed **/ function claimRewardsOnBehalf( address[] calldata assets, uint256 amount, address user, address to ) external returns (uint256); /** * @dev returns the unclaimed rewards of the user * @param user the address of the user * @return the unclaimed user rewards */ function getUserUnclaimedRewards(address user) external view returns (uint256); /** * @dev for backward compatibility with previous implementation of the Incentives controller */ function REWARD_TOKEN() external view returns (address); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; interface IStakeAave is IERC20 { function cooldown() external; function claimRewards(address to, uint256 amount) external; function redeem(address to, uint256 amount) external; function getTotalRewardsBalance(address staker) external view returns (uint256); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.8.10; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import './IAaveIncentivesController.sol'; interface IAToken is IERC20 { /** * @dev Emitted after the mint action * @param from The address performing the mint * @param value The amount being * @param index The new liquidity index of the reserve **/ event Mint(address indexed from, uint256 value, uint256 index); /** * @dev Mints `amount` aTokens to `user` * @param user The address receiving the minted tokens * @param amount The amount of tokens getting minted * @param index The new liquidity index of the reserve * @return `true` if the the previous balance of the user was 0 */ function mint( address user, uint256 amount, uint256 index ) external returns (bool); /** * @dev Emitted after aTokens are burned * @param from The owner of the aTokens, getting them burned * @param target The address that will receive the underlying * @param value The amount being burned * @param index The new liquidity index of the reserve **/ event Burn(address indexed from, address indexed target, uint256 value, uint256 index); /** * @dev Emitted during the transfer action * @param from The user whose tokens are being transferred * @param to The recipient * @param value The amount being transferred * @param index The new liquidity index of the reserve **/ event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index); /** * @dev Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying` * @param user The owner of the aTokens, getting them burned * @param receiverOfUnderlying The address that will receive the underlying * @param amount The amount being burned * @param index The new liquidity index of the reserve **/ function burn( address user, address receiverOfUnderlying, uint256 amount, uint256 index ) external; /** * @dev Mints aTokens to the reserve treasury * @param amount The amount of tokens getting minted * @param index The new liquidity index of the reserve */ function mintToTreasury(uint256 amount, uint256 index) external; /** * @dev Transfers aTokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken * @param from The address getting liquidated, current owner of the aTokens * @param to The recipient * @param value The amount of tokens getting transferred **/ function transferOnLiquidation( address from, address to, uint256 value ) external; /** * @dev Transfers the underlying asset to `target`. Used by the LendingPool to transfer * assets in borrow(), withdraw() and flashLoan() * @param user The recipient of the underlying * @param amount The amount getting transferred * @return The amount transferred **/ function transferUnderlyingTo(address user, uint256 amount) external returns (uint256); /** * @dev Invoked to execute actions on the aToken side after a repayment. * @param user The user executing the repayment * @param amount The amount getting repaid **/ function handleRepayment(address user, uint256 amount) external; /** * @dev Returns the address of the incentives controller contract **/ function getIncentivesController() external view returns (IAaveIncentivesController); /** * @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH) **/ function UNDERLYING_ASSET_ADDRESS() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) 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' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import '../ISherlock.sol'; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; interface IManager { // An address or other value passed in is equal to zero (and shouldn't be) error ZeroArgument(); // Occurs when a value already holds the desired property, or is not whitelisted error InvalidArgument(); // If a required condition for executing the function is not met, it reverts and throws this error error InvalidConditions(); // Throws if the msg.sender is not the required address error InvalidSender(); event SherlockCoreSet(ISherlock sherlock); /// @notice Set sherlock core address where premiums should be send too /// @param _sherlock Current core contract /// @dev Only deployer is able to set core address on all chains except Hardhat network /// @dev One time function, will revert once `sherlock` != address(0) /// @dev This contract will be deployed first, passed on as argument in core constuctor /// @dev ^ that's needed for tvl accounting, once core is deployed this function is called /// @dev emits `SherlockCoreSet` function setSherlockCoreAddress(ISherlock _sherlock) external; /// @notice Pause external functions in contract function pause() external; /// @notice Unpause external functions in contract function unpause() external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `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 // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) 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; 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"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import '@openzeppelin/contracts/token/ERC721/IERC721.sol'; import './ISherlockStake.sol'; import './ISherlockGov.sol'; import './ISherlockPayout.sol'; import './ISherlockStrategy.sol'; interface ISherlock is ISherlockStake, ISherlockGov, ISherlockPayout, ISherlockStrategy, IERC721 { // msg.sender is not authorized to call this function error Unauthorized(); // An address or other value passed in is equal to zero (and shouldn't be) error ZeroArgument(); // Occurs when a value already holds the desired property, or is not whitelisted error InvalidArgument(); // Required conditions are not true/met error InvalidConditions(); // If the SHER tokens held in a contract are not the value they are supposed to be error InvalidSherAmount(uint256 expected, uint256 actual); // Checks the ERC-721 functions _exists() to see if an NFT ID actually exists and errors if not error NonExistent(); event ArbRestaked(uint256 indexed tokenID, uint256 reward); event Restaked(uint256 indexed tokenID); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ /// @title Sherlock core interface for stakers /// @author Evert Kors interface ISherlockStake { /// @notice View the current lockup end timestamp of `_tokenID` /// @return Timestamp when NFT position unlocks function lockupEnd(uint256 _tokenID) external view returns (uint256); /// @notice View the current SHER reward of `_tokenID` /// @return Amount of SHER rewarded to owner upon reaching the end of the lockup function sherRewards(uint256 _tokenID) external view returns (uint256); /// @notice View the current token balance claimable upon reaching end of the lockup /// @return Amount of tokens assigned to owner when unstaking position function tokenBalanceOf(uint256 _tokenID) external view returns (uint256); /// @notice View the current TVL for all stakers /// @return Total amount of tokens staked /// @dev Adds principal + strategy + premiums /// @dev Will calculate the most up to date value for each piece function totalTokenBalanceStakers() external view returns (uint256); /// @notice Stakes `_amount` of tokens and locks up for `_period` seconds, `_receiver` will receive the NFT receipt /// @param _amount Amount of tokens to stake /// @param _period Period of time, in seconds, to lockup your funds /// @param _receiver Address that will receive the NFT representing the position /// @return _id ID of the position /// @return _sher Amount of SHER tokens to be released to this ID after `_period` ends /// @dev `_period` needs to be whitelisted function initialStake( uint256 _amount, uint256 _period, address _receiver ) external returns (uint256 _id, uint256 _sher); /// @notice Redeem NFT `_id` and receive `_amount` of tokens /// @param _id TokenID of the position /// @return _amount Amount of tokens (USDC) owed to NFT ID /// @dev Only the owner of `_id` will be able to redeem their position /// @dev The SHER rewards are sent to the NFT owner /// @dev Can only be called after lockup `_period` has ended function redeemNFT(uint256 _id) external returns (uint256 _amount); /// @notice Owner restakes position with ID: `_id` for `_period` seconds /// @param _id ID of the position /// @param _period Period of time, in seconds, to lockup your funds /// @return _sher Amount of SHER tokens to be released to owner address after `_period` ends /// @dev Only the owner of `_id` will be able to restake their position using this call /// @dev `_period` needs to be whitelisted /// @dev Can only be called after lockup `_period` has ended function ownerRestake(uint256 _id, uint256 _period) external returns (uint256 _sher); /// @notice Allows someone who doesn't own the position (an arbitrager) to restake the position for 26 weeks (ARB_RESTAKE_PERIOD) /// @param _id ID of the position /// @return _sher Amount of SHER tokens to be released to position owner on expiry of the 26 weeks lockup /// @return _arbReward Amount of tokens (USDC) sent to caller (the arbitrager) in return for calling the function /// @dev Can only be called after lockup `_period` is more than 2 weeks in the past (assuming ARB_RESTAKE_WAIT_TIME is 2 weeks) /// @dev Max 20% (ARB_RESTAKE_MAX_PERCENTAGE) of tokens associated with a position are used to incentivize arbs (x) /// @dev During a 2 week period the reward ratio will move from 0% to 100% (* x) function arbRestake(uint256 _id) external returns (uint256 _sher, uint256 _arbReward); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import './managers/ISherDistributionManager.sol'; import './managers/ISherlockProtocolManager.sol'; import './managers/ISherlockClaimManager.sol'; import './managers/IStrategyManager.sol'; /// @title Sherlock core interface for governance /// @author Evert Kors interface ISherlockGov { event ClaimPayout(address receiver, uint256 amount); event YieldStrategyUpdateWithdrawAllError(bytes error); event YieldStrategyUpdated(IStrategyManager previous, IStrategyManager current); event ProtocolManagerUpdated(ISherlockProtocolManager previous, ISherlockProtocolManager current); event ClaimManagerUpdated(ISherlockClaimManager previous, ISherlockClaimManager current); event NonStakerAddressUpdated(address previous, address current); event SherDistributionManagerUpdated( ISherDistributionManager previous, ISherDistributionManager current ); event StakingPeriodEnabled(uint256 period); event StakingPeriodDisabled(uint256 period); /// @notice Allows stakers to stake for `_period` of time /// @param _period Period of time, in seconds, /// @dev should revert if already enabled function enableStakingPeriod(uint256 _period) external; /// @notice Disallow stakers to stake for `_period` of time /// @param _period Period of time, in seconds, /// @dev should revert if already disabled function disableStakingPeriod(uint256 _period) external; /// @notice View if `_period` is a valid period /// @return Boolean indicating if period is valid function stakingPeriods(uint256 _period) external view returns (bool); /// @notice Update SHER distribution manager contract /// @param _sherDistributionManager New adddress of the manager function updateSherDistributionManager(ISherDistributionManager _sherDistributionManager) external; /// @notice Deletes the SHER distribution manager altogether (if Sherlock decides to no longer pay out SHER rewards) function removeSherDistributionManager() external; /// @notice Read SHER distribution manager /// @return Address of current SHER distribution manager function sherDistributionManager() external view returns (ISherDistributionManager); /// @notice Update address eligible for non staker rewards from protocol premiums /// @param _nonStakers Address eligible for non staker rewards function updateNonStakersAddress(address _nonStakers) external; /// @notice View current non stakers address /// @return Current non staker address /// @dev Is able to pull funds out of the contract function nonStakersAddress() external view returns (address); /// @notice View current address able to manage protocols /// @return Protocol manager implemenation function sherlockProtocolManager() external view returns (ISherlockProtocolManager); /// @notice Transfer protocol manager implementation address /// @param _protocolManager new implementation address function updateSherlockProtocolManager(ISherlockProtocolManager _protocolManager) external; /// @notice View current address able to pull payouts /// @return Address able to pull payouts function sherlockClaimManager() external view returns (ISherlockClaimManager); /// @notice Transfer claim manager role to different address /// @param _claimManager New address of claim manager function updateSherlockClaimManager(ISherlockClaimManager _claimManager) external; /// @notice Update yield strategy /// @param _yieldStrategy New address of the strategy /// @dev try a yieldStrategyWithdrawAll() on old, ignore failure function updateYieldStrategy(IStrategyManager _yieldStrategy) external; /// @notice Update yield strategy ignoring current state /// @param _yieldStrategy New address of the strategy /// @dev tries a yieldStrategyWithdrawAll() on old strategy, ignore failure function updateYieldStrategyForce(IStrategyManager _yieldStrategy) external; /// @notice Read current strategy /// @return Address of current strategy /// @dev can never be address(0) function yieldStrategy() external view returns (IStrategyManager); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ /// @title Sherlock interface for payout manager /// @author Evert Kors interface ISherlockPayout { /// @notice Initiate a payout of `_amount` to `_receiver` /// @param _receiver Receiver of payout /// @param _amount Amount to send /// @dev only payout manager should call this /// @dev should pull money out of strategy function payoutClaim(address _receiver, uint256 _amount) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import './managers/IStrategyManager.sol'; /// @title Sherlock core interface for yield strategy /// @author Evert Kors interface ISherlockStrategy { /// @notice Deposit `_amount` into active strategy /// @param _amount Amount of tokens /// @dev gov only function yieldStrategyDeposit(uint256 _amount) external; /// @notice Withdraw `_amount` from active strategy /// @param _amount Amount of tokens /// @dev gov only function yieldStrategyWithdraw(uint256 _amount) external; /// @notice Withdraw all funds from active strategy /// @dev gov only function yieldStrategyWithdrawAll() external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import './IManager.sol'; interface ISherDistributionManager is IManager { // anyone can just send token to this contract to fund rewards event Initialized(uint256 maxRewardsEndTVL, uint256 zeroRewardsStartTVL, uint256 maxRewardRate); /// @notice Caller will receive `_sher` SHER tokens based on `_amount` and `_period` /// @param _amount Amount of tokens (in USDC) staked /// @param _period Period of time for stake, in seconds /// @param _id ID for this NFT position /// @param _receiver Address that will be linked to this position /// @return _sher Amount of SHER tokens sent to Sherlock core contract /// @dev Calling contract will depend on before + after balance diff and return value /// @dev INCLUDES stake in calculation, function expects the `_amount` to be deposited already /// @dev If tvl=50 and amount=50, this means it is calculating SHER rewards for the first 50 tokens going in function pullReward( uint256 _amount, uint256 _period, uint256 _id, address _receiver ) external returns (uint256 _sher); /// @notice Calculates how many `_sher` SHER tokens are owed to a stake position based on `_amount` and `_period` /// @param _tvl TVL to use for reward calculation (pre-stake TVL) /// @param _amount Amount of tokens (USDC) staked /// @param _period Stake period (in seconds) /// @return _sher Amount of SHER tokens owed to this stake position /// @dev EXCLUDES `_amount` of stake, this will be added on top of TVL (_tvl is excluding _amount) /// @dev If tvl=0 and amount=50, it would calculate for the first 50 tokens going in (different from pullReward()) function calcReward( uint256 _tvl, uint256 _amount, uint256 _period ) external view returns (uint256 _sher); /// @notice Function used to check if this is the current active distribution manager /// @return Boolean indicating it's active /// @dev If inactive the owner can pull all ERC20s and ETH /// @dev Will be checked by calling the sherlock contract function isActive() external view returns (bool); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import './IManager.sol'; /// @title Sherlock core interface for protocols /// @author Evert Kors interface ISherlockProtocolManager is IManager { // msg.sender is not authorized to call this function error Unauthorized(); // If a protocol was never instantiated or was removed and the claim deadline has passed, this error is returned error ProtocolNotExists(bytes32 protocol); // When comparing two arrays and the lengths are not equal (but are supposed to be equal) error UnequalArrayLength(); // If there is not enough balance in the contract for the amount requested (after any requirements are met), this is returned error InsufficientBalance(bytes32 protocol); event MinBalance(uint256 previous, uint256 current); event AccountingError(bytes32 indexed protocol, uint256 amount, uint256 insufficientTokens); event ProtocolAdded(bytes32 indexed protocol); event ProtocolRemovedByArb(bytes32 indexed protocol, address arb, uint256 profit); event ProtocolRemoved(bytes32 indexed protocol); event ProtocolUpdated( bytes32 indexed protocol, bytes32 coverage, uint256 nonStakers, uint256 coverageAmount ); event ProtocolAgentTransfer(bytes32 indexed protocol, address from, address to); event ProtocolBalanceDeposited(bytes32 indexed protocol, uint256 amount); event ProtocolBalanceWithdrawn(bytes32 indexed protocol, uint256 amount); event ProtocolPremiumChanged(bytes32 indexed protocol, uint256 oldPremium, uint256 newPremium); /// @notice View current amount of all premiums that are owed to stakers /// @return Premiums claimable /// @dev Will increase every block /// @dev base + (now - last_settled) * ps function claimablePremiums() external view returns (uint256); /// @notice Transfer current claimable premiums (for stakers) to core Sherlock address /// @dev Callable by everyone /// @dev Funds will be transferred to Sherlock core contract function claimPremiumsForStakers() external; /// @notice View current protocolAgent of `_protocol` /// @param _protocol Protocol identifier /// @return Address able to submit claims function protocolAgent(bytes32 _protocol) external view returns (address); /// @notice View current premium of protocol /// @param _protocol Protocol identifier /// @return Amount of premium `_protocol` pays per second function premium(bytes32 _protocol) external view returns (uint256); /// @notice View current active balance of covered protocol /// @param _protocol Protocol identifier /// @return Active balance /// @dev Accrued debt is subtracted from the stored active balance function activeBalance(bytes32 _protocol) external view returns (uint256); /// @notice View seconds of coverage left for `_protocol` before it runs out of active balance /// @param _protocol Protocol identifier /// @return Seconds of coverage left function secondsOfCoverageLeft(bytes32 _protocol) external view returns (uint256); /// @notice Add a new protocol to Sherlock /// @param _protocol Protocol identifier /// @param _protocolAgent Address able to submit a claim on behalf of the protocol /// @param _coverage Hash referencing the active coverage agreement /// @param _nonStakers Percentage of premium payments to nonstakers, scaled by 10**18 /// @param _coverageAmount Max amount claimable by this protocol /// @dev Adding a protocol allows the `_protocolAgent` to submit a claim /// @dev Coverage is not started yet as the protocol doesn't pay a premium at this point /// @dev `_nonStakers` is scaled by 10**18 /// @dev Only callable by governance function protocolAdd( bytes32 _protocol, address _protocolAgent, bytes32 _coverage, uint256 _nonStakers, uint256 _coverageAmount ) external; /// @notice Update info regarding a protocol /// @param _protocol Protocol identifier /// @param _coverage Hash referencing the active coverage agreement /// @param _nonStakers Percentage of premium payments to nonstakers, scaled by 10**18 /// @param _coverageAmount Max amount claimable by this protocol /// @dev Only callable by governance function protocolUpdate( bytes32 _protocol, bytes32 _coverage, uint256 _nonStakers, uint256 _coverageAmount ) external; /// @notice Remove a protocol from coverage /// @param _protocol Protocol identifier /// @dev Before removing a protocol the premium must be 0 /// @dev Removing a protocol basically stops the `_protocolAgent` from being active (can still submit claims until claim deadline though) /// @dev Pays off debt + sends remaining balance to protocol agent /// @dev This call should be subject to a timelock /// @dev Only callable by governance function protocolRemove(bytes32 _protocol) external; /// @notice Remove a protocol with insufficient active balance /// @param _protocol Protocol identifier function forceRemoveByActiveBalance(bytes32 _protocol) external; /// @notice Removes a protocol with insufficent seconds of coverage left /// @param _protocol Protocol identifier function forceRemoveBySecondsOfCoverage(bytes32 _protocol) external; /// @notice View minimal balance needed before liquidation can start /// @return Minimal balance needed function minActiveBalance() external view returns (uint256); /// @notice Sets the minimum active balance before an arb can remove a protocol /// @param _minActiveBalance Minimum balance needed (in USDC) /// @dev Only gov function setMinActiveBalance(uint256 _minActiveBalance) external; /// @notice Set premium of `_protocol` to `_premium` /// @param _protocol Protocol identifier /// @param _premium Amount of premium `_protocol` pays per second /// @dev The value 0 would mean inactive coverage /// @dev Only callable by governance function setProtocolPremium(bytes32 _protocol, uint256 _premium) external; /// @notice Set premium of multiple protocols /// @param _protocol Array of protocol identifiers /// @param _premium Array of premium amounts protocols pay per second /// @dev The value 0 would mean inactive coverage /// @dev Only callable by governance function setProtocolPremiums(bytes32[] calldata _protocol, uint256[] calldata _premium) external; /// @notice Deposits `_amount` of token to the active balance of `_protocol` /// @param _protocol Protocol identifier /// @param _amount Amount of tokens to deposit /// @dev Approval should be made before calling function depositToActiveBalance(bytes32 _protocol, uint256 _amount) external; /// @notice Withdraws `_amount` of token from the active balance of `_protocol` /// @param _protocol Protocol identifier /// @param _amount Amount of tokens to withdraw /// @dev Only protocol agent is able to withdraw /// @dev Balance can be withdrawn up until 7 days worth of active balance function withdrawActiveBalance(bytes32 _protocol, uint256 _amount) external; /// @notice Transfer protocol agent role /// @param _protocol Protocol identifier /// @param _protocolAgent Account able to submit a claim on behalf of the protocol /// @dev Only the active protocolAgent is able to transfer the role function transferProtocolAgent(bytes32 _protocol, address _protocolAgent) external; /// @notice View the amount nonstakers can claim from this protocol /// @param _protocol Protocol identifier /// @return Amount of tokens claimable by nonstakers /// @dev this reads from a storage variable + (now-lastsettled) * premiums function nonStakersClaimable(bytes32 _protocol) external view returns (uint256); /// @notice Choose an `_amount` of tokens that nonstakers (`_receiver` address) will receive from `_protocol` /// @param _protocol Protocol identifier /// @param _amount Amount of tokens /// @param _receiver Address to receive tokens /// @dev Only callable by nonstakers role function nonStakersClaim( bytes32 _protocol, uint256 _amount, address _receiver ) external; /// @param _protocol Protocol identifier /// @return current and previous are the current and previous coverage amounts for this protocol function coverageAmounts(bytes32 _protocol) external view returns (uint256 current, uint256 previous); /// @notice Function used to check if this is the current active protocol manager /// @return Boolean indicating it's active /// @dev If inactive the owner can pull all ERC20s and ETH /// @dev Will be checked by calling the sherlock contract function isActive() external view returns (bool); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import './callbacks/ISherlockClaimManagerCallbackReceiver.sol'; import '../UMAprotocol/OptimisticRequester.sol'; import './IManager.sol'; interface ISherlockClaimManager is IManager, OptimisticRequester { // Doesn't allow a new claim to be submitted by a protocol agent if a claim is already active for that protocol error ClaimActive(); // If the current state of a claim does not match the expected state, this error is thrown error InvalidState(); event ClaimCreated( uint256 claimID, bytes32 indexed protocol, uint256 amount, address receiver, bool previousCoverageUsed ); event CallbackAdded(ISherlockClaimManagerCallbackReceiver callback); event CallbackRemoved(ISherlockClaimManagerCallbackReceiver callback); event ClaimStatusChanged(uint256 indexed claimID, State previousState, State currentState); event ClaimPayout(uint256 claimID, address receiver, uint256 amount); event ClaimHalted(uint256 claimID); event UMAHORenounced(); enum State { NonExistent, // Claim doesn't exist (this is the default state on creation) SpccPending, // Claim is created, SPCC is able to set state to valid SpccApproved, // Final state, claim is valid SpccDenied, // Claim denied by SPCC, claim can be escalated within 4 weeks UmaPriceProposed, // Price is proposed but not escalated ReadyToProposeUmaDispute, // Price is proposed, callback received, ready to submit dispute UmaDisputeProposed, // Escalation is done, waiting for confirmation UmaPending, // Claim is escalated, in case Spcc denied or didn't act within 7 days. UmaApproved, // Final state, claim is valid, claim can be enacted after 1 day, umaHaltOperator has 1 day to change to denied UmaDenied, // Final state, claim is invalid Halted, // UMAHO can halt claim if state is UmaApproved Cleaned // Claim is removed by protocol agent } struct Claim { uint256 created; uint256 updated; address initiator; bytes32 protocol; uint256 amount; address receiver; uint32 timestamp; State state; bytes ancillaryData; } // requestAndProposePriceFor() --> proposer = sherlockCore (address to receive BOND if UMA denies claim) // disputePriceFor() --> disputer = protocolAgent // priceSettled will be the the callback that contains the main data // Assume BOND = 9600, UMA's final fee = 1500. // Claim initiator (Sherlock) has to pay 22.2k to dispute a claim, // so we will execute a safeTransferFrom(claimInitiator, address(this), 22.2k). // We need to approve the contract 22.2k as it will be transferred from address(this). // The 22.2k consists of 2 * (BOND + final fee charged by UMA), as follows: // 1. On requestAndProposePriceFor(), the fee will be 10k: 9600 BOND + 1500 UMA's final fee; // 2. On disputePriceFor(), the fee will be the same 10k. // note that half of the BOND (4800) + UMA's final fee (1500) is "burnt" and sent to UMA // UMA's final fee can be changed in the future, which may result in lower or higher required staked amounts for escalating a claim. // On settle, either the protocolAgent (dispute success) or sherlockCore (dispute failure) // will receive 9600 + 4800 + 1500 = 15900. In addition, the protocolAgent will be entitled to // the claimAmount if the dispute is successful/ // lastClaimID <-- starts with 0, so initial id = 1 // have claim counter, easy to identify certain claims by their number // but use hash(callback.request.propose + callback.timestamp) as the internal UUID to handle the callbacks // So SPCC and UMAHO are hardcoded (UMAHO can be renounced) // In case these need to be updated, deploy different contract and upgrade it on the sherlock gov side. // On price proposed callback --> call disputePriceFor with callbackdata + sherlock.strategyManager() and address(this) /// @notice `SHERLOCK_CLAIM` in utf8 function UMA_IDENTIFIER() external view returns (bytes32); function sherlockProtocolClaimsCommittee() external view returns (address); /// @notice operator is able to deny approved UMA claims function umaHaltOperator() external view returns (address); /// @notice gov is able to renounce the role function renounceUmaHaltOperator() external; function claim(uint256 _claimID) external view returns (Claim memory); /// @notice Initiate a claim for a specific protocol as the protocol agent /// @param _protocol protocol ID (different from the internal or public claim ID fields) /// @param _amount amount of USDC which is being claimed by the protocol /// @param _receiver address to receive the amount of USDC being claimed /// @param _timestamp timestamp at which the exploit first occurred /// @param ancillaryData other data associated with the claim, such as the coverage agreement /// @dev The protocol agent that starts a claim will be the protocol agent during the claims lifecycle /// @dev Even if the protocol agent role is tranferred during the lifecycle function startClaim( bytes32 _protocol, uint256 _amount, address _receiver, uint32 _timestamp, bytes memory ancillaryData ) external; function spccApprove(uint256 _claimID) external; function spccRefuse(uint256 _claimID) external; /// @notice Callable by protocol agent /// @param _claimID Public claim ID /// @param _amount Bond amount sent by protocol agent /// @dev Use hardcoded USDC address /// @dev Use hardcoded bond amount /// @dev Use hardcoded liveness 7200 (2 hours) /// @dev proposedPrice = _amount function escalate(uint256 _claimID, uint256 _amount) external; /// @notice Execute claim, storage will be removed after /// @param _claimID Public ID of the claim /// @dev Needs to be SpccApproved or UmaApproved && >UMAHO_TIME /// @dev Funds will be pulled from core function payoutClaim(uint256 _claimID) external; /// @notice UMAHO is able to execute a halt if the state is UmaApproved and state was updated less than UMAHO_TIME ago function executeHalt(uint256 _claimID) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ interface ISherlockClaimManagerCallbackReceiver { /// @notice Calls this function on approved contracts and passes args /// @param _protocol The protocol that is receiving the payout /// @param _claimID The claim ID that is receiving the payout /// @param _amount The amount of USDC being paid out for this claim function PreCorePayoutCallback( bytes32 _protocol, uint256 _claimID, uint256 _amount ) external; }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; import './SkinnyOptimisticOracleInterface.sol'; /** * @title Optimistic Requester. * @notice Optional interface that requesters can implement to receive callbacks. * @dev This contract does _not_ work with ERC777 collateral currencies or any others that call into the receiver on * transfer(). Using an ERC777 token would allow a user to maliciously grief other participants (while also losing * money themselves). */ interface OptimisticRequester { /** * @notice Callback for proposals. * @param identifier price identifier being requested. * @param timestamp timestamp of the price being requested. * @param ancillaryData ancillary data of the price being requested. * @param request request params after proposal. */ function priceProposed( bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, SkinnyOptimisticOracleInterface.Request memory request ) external; /** * @notice Callback for disputes. * @param identifier price identifier being requested. * @param timestamp timestamp of the price being requested. * @param ancillaryData ancillary data of the price being requested. * @param request request params after dispute. */ function priceDisputed( bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, SkinnyOptimisticOracleInterface.Request memory request ) external; /** * @notice Callback for settlement. * @param identifier price identifier being requested. * @param timestamp timestamp of the price being requested. * @param ancillaryData ancillary data of the price being requested. * @param request request params after settlement. */ function priceSettled( bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, SkinnyOptimisticOracleInterface.Request memory request ) external; }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import './OptimisticOracleInterface.sol'; /** * @title Interface for the gas-cost-reduced version of the OptimisticOracle. * @notice Differences from normal OptimisticOracle: * - refundOnDispute: flag is removed, by default there are no refunds on disputes. * - customizing request parameters: In the OptimisticOracle, parameters like `bond` and `customLiveness` can be reset * after a request is already made via `requestPrice`. In the SkinnyOptimisticOracle, these parameters can only be * set in `requestPrice`, which has an expanded input set. * - settleAndGetPrice: Replaced by `settle`, which can only be called once per settleable request. The resolved price * can be fetched via the `Settle` event or the return value of `settle`. * - general changes to interface: Functions that interact with existing requests all require the parameters of the * request to modify to be passed as input. These parameters must match with the existing request parameters or the * function will revert. This change reflects the internal refactor to store hashed request parameters instead of the * full request struct. * @dev Interface used by financial contracts to interact with the Oracle. Voters will use a different interface. */ abstract contract SkinnyOptimisticOracleInterface { event RequestPrice( address indexed requester, bytes32 indexed identifier, uint32 timestamp, bytes ancillaryData, Request request ); event ProposePrice( address indexed requester, bytes32 indexed identifier, uint32 timestamp, bytes ancillaryData, Request request ); event DisputePrice( address indexed requester, bytes32 indexed identifier, uint32 timestamp, bytes ancillaryData, Request request ); event Settle( address indexed requester, bytes32 indexed identifier, uint32 timestamp, bytes ancillaryData, Request request ); // Struct representing a price request. Note that this differs from the OptimisticOracleInterface's Request struct // in that refundOnDispute is removed. struct Request { address proposer; // Address of the proposer. address disputer; // Address of the disputer. IERC20 currency; // ERC20 token used to pay rewards and fees. bool settled; // True if the request is settled. int256 proposedPrice; // Price that the proposer submitted. int256 resolvedPrice; // Price resolved once the request is settled. uint256 expirationTime; // Time at which the request auto-settles without a dispute. uint256 reward; // Amount of the currency to pay to the proposer on settlement. uint256 finalFee; // Final fee to pay to the Store upon request to the DVM. uint256 bond; // Bond that the proposer and disputer must pay on top of the final fee. uint256 customLiveness; // Custom liveness value set by the requester. } // This value must be <= the Voting contract's `ancillaryBytesLimit` value otherwise it is possible // that a price can be requested to this contract successfully, but cannot be disputed because the DVM refuses // to accept a price request made with ancillary data length over a certain size. uint256 public constant ancillaryBytesLimit = 8192; /** * @notice Requests a new price. * @param identifier price identifier being requested. * @param timestamp timestamp of the price being requested. * @param ancillaryData ancillary data representing additional args being passed with the price request. * @param currency ERC20 token used for payment of rewards and fees. Must be approved for use with the DVM. * @param reward reward offered to a successful proposer. Will be pulled from the caller. Note: this can be 0, * which could make sense if the contract requests and proposes the value in the same call or * provides its own reward system. * @param bond custom proposal bond to set for request. If set to 0, defaults to the final fee. * @param customLiveness custom proposal liveness to set for request. * @return totalBond default bond + final fee that the proposer and disputer will be required to pay. */ function requestPrice( bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, IERC20 currency, uint256 reward, uint256 bond, uint256 customLiveness ) external virtual returns (uint256 totalBond); /** * @notice Proposes a price value on another address' behalf. Note: this address will receive any rewards that come * from this proposal. However, any bonds are pulled from the caller. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters whose hash must match the request that the caller wants to * propose a price for. * @param proposer address to set as the proposer. * @param proposedPrice price being proposed. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the proposer once settled if the proposal is correct. */ function proposePriceFor( address requester, bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request, address proposer, int256 proposedPrice ) public virtual returns (uint256 totalBond); /** * @notice Proposes a price value where caller is the proposer. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters whose hash must match the request that the caller wants to * propose a price for. * @param proposedPrice price being proposed. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the proposer once settled if the proposal is correct. */ function proposePrice( address requester, bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request, int256 proposedPrice ) external virtual returns (uint256 totalBond); /** * @notice Combines logic of requestPrice and proposePrice while taking advantage of gas savings from not having to * overwrite Request params that a normal requestPrice() => proposePrice() flow would entail. Note: The proposer * will receive any rewards that come from this proposal. However, any bonds are pulled from the caller. * @dev The caller is the requester, but the proposer can be customized. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param currency ERC20 token used for payment of rewards and fees. Must be approved for use with the DVM. * @param reward reward offered to a successful proposer. Will be pulled from the caller. Note: this can be 0, * which could make sense if the contract requests and proposes the value in the same call or * provides its own reward system. * @param bond custom proposal bond to set for request. If set to 0, defaults to the final fee. * @param customLiveness custom proposal liveness to set for request. * @param proposer address to set as the proposer. * @param proposedPrice price being proposed. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the proposer once settled if the proposal is correct. */ function requestAndProposePriceFor( bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, IERC20 currency, uint256 reward, uint256 bond, uint256 customLiveness, address proposer, int256 proposedPrice ) external virtual returns (uint256 totalBond); /** * @notice Disputes a price request with an active proposal on another address' behalf. Note: this address will * receive any rewards that come from this dispute. However, any bonds are pulled from the caller. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters whose hash must match the request that the caller wants to * dispute. * @param disputer address to set as the disputer. * @param requester sender of the initial price request. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the disputer once settled if the dispute was valid (the proposal was incorrect). */ function disputePriceFor( bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request, address disputer, address requester ) public virtual returns (uint256 totalBond); /** * @notice Disputes a price request with an active proposal where caller is the disputer. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters whose hash must match the request that the caller wants to * dispute. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the disputer once settled if the dispute was valid (the proposal was incorrect). */ function disputePrice( address requester, bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request ) external virtual returns (uint256 totalBond); /** * @notice Attempts to settle an outstanding price request. Will revert if it isn't settleable. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters whose hash must match the request that the caller wants to * settle. * @return payout the amount that the "winner" (proposer or disputer) receives on settlement. This amount includes * the returned bonds as well as additional rewards. * @return resolvedPrice the price that the request settled to. */ function settle( address requester, bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request ) external virtual returns (uint256 payout, int256 resolvedPrice); /** * @notice Computes the current state of a price request. See the State enum for more details. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters. * @return the State. */ function getState( address requester, bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request ) external virtual returns (OptimisticOracleInterface.State); /** * @notice Checks if a given request has resolved, expired or been settled (i.e the optimistic oracle has a price). * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters. The hash of these parameters must match with the request hash that is * associated with the price request unique ID {requester, identifier, timestamp, ancillaryData}, or this method * will revert. * @return boolean indicating true if price exists and false if not. */ function hasPrice( address requester, bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request ) public virtual returns (bool); /** * @notice Generates stamped ancillary data in the format that it would be used in the case of a price dispute. * @param ancillaryData ancillary data of the price being requested. * @param requester sender of the initial price request. * @return the stamped ancillary bytes. */ function stampAncillaryData(bytes memory ancillaryData, address requester) public pure virtual returns (bytes memory); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; /** * @title Financial contract facing Oracle interface. * @dev Interface used by financial contracts to interact with the Oracle. Voters will use a different interface. */ abstract contract OptimisticOracleInterface { // Struct representing the state of a price request. enum State { Invalid, // Never requested. Requested, // Requested, no other actions taken. Proposed, // Proposed, but not expired or disputed yet. Expired, // Proposed, not disputed, past liveness. Disputed, // Disputed, but no DVM price returned yet. Resolved, // Disputed and DVM price is available. Settled // Final price has been set in the contract (can get here from Expired or Resolved). } // Struct representing a price request. struct Request { address proposer; // Address of the proposer. address disputer; // Address of the disputer. IERC20 currency; // ERC20 token used to pay rewards and fees. bool settled; // True if the request is settled. bool refundOnDispute; // True if the requester should be refunded their reward on dispute. int256 proposedPrice; // Price that the proposer submitted. int256 resolvedPrice; // Price resolved once the request is settled. uint256 expirationTime; // Time at which the request auto-settles without a dispute. uint256 reward; // Amount of the currency to pay to the proposer on settlement. uint256 finalFee; // Final fee to pay to the Store upon request to the DVM. uint256 bond; // Bond that the proposer and disputer must pay on top of the final fee. uint256 customLiveness; // Custom liveness value set by the requester. } // This value must be <= the Voting contract's `ancillaryBytesLimit` value otherwise it is possible // that a price can be requested to this contract successfully, but cannot be disputed because the DVM refuses // to accept a price request made with ancillary data length over a certain size. uint256 public constant ancillaryBytesLimit = 8192; /** * @notice Requests a new price. * @param identifier price identifier being requested. * @param timestamp timestamp of the price being requested. * @param ancillaryData ancillary data representing additional args being passed with the price request. * @param currency ERC20 token used for payment of rewards and fees. Must be approved for use with the DVM. * @param reward reward offered to a successful proposer. Will be pulled from the caller. Note: this can be 0, * which could make sense if the contract requests and proposes the value in the same call or * provides its own reward system. * @return totalBond default bond (final fee) + final fee that the proposer and disputer will be required to pay. * This can be changed with a subsequent call to setBond(). */ function requestPrice( bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, IERC20 currency, uint256 reward ) external virtual returns (uint256 totalBond); /** * @notice Set the proposal bond associated with a price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param bond custom bond amount to set. * @return totalBond new bond + final fee that the proposer and disputer will be required to pay. This can be * changed again with a subsequent call to setBond(). */ function setBond( bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, uint256 bond ) external virtual returns (uint256 totalBond); /** * @notice Sets the request to refund the reward if the proposal is disputed. This can help to "hedge" the caller * in the event of a dispute-caused delay. Note: in the event of a dispute, the winner still receives the other's * bond, so there is still profit to be made even if the reward is refunded. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. */ function setRefundOnDispute( bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) external virtual; /** * @notice Sets a custom liveness value for the request. Liveness is the amount of time a proposal must wait before * being auto-resolved. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param customLiveness new custom liveness. */ function setCustomLiveness( bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, uint256 customLiveness ) external virtual; /** * @notice Proposes a price value on another address' behalf. Note: this address will receive any rewards that come * from this proposal. However, any bonds are pulled from the caller. * @param proposer address to set as the proposer. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param proposedPrice price being proposed. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the proposer once settled if the proposal is correct. */ function proposePriceFor( address proposer, address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, int256 proposedPrice ) public virtual returns (uint256 totalBond); /** * @notice Proposes a price value for an existing price request. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param proposedPrice price being proposed. * @return totalBond the amount that's pulled from the proposer's wallet as a bond. The bond will be returned to * the proposer once settled if the proposal is correct. */ function proposePrice( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, int256 proposedPrice ) external virtual returns (uint256 totalBond); /** * @notice Disputes a price request with an active proposal on another address' behalf. Note: this address will * receive any rewards that come from this dispute. However, any bonds are pulled from the caller. * @param disputer address to set as the disputer. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the disputer once settled if the dispute was value (the proposal was incorrect). */ function disputePriceFor( address disputer, address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) public virtual returns (uint256 totalBond); /** * @notice Disputes a price value for an existing price request with an active proposal. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return totalBond the amount that's pulled from the disputer's wallet as a bond. The bond will be returned to * the disputer once settled if the dispute was valid (the proposal was incorrect). */ function disputePrice( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) external virtual returns (uint256 totalBond); /** * @notice Retrieves a price that was previously requested by a caller. Reverts if the request is not settled * or settleable. Note: this method is not view so that this call may actually settle the price request if it * hasn't been settled. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return resolved price. */ function settleAndGetPrice( bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) external virtual returns (int256); /** * @notice Attempts to settle an outstanding price request. Will revert if it isn't settleable. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return payout the amount that the "winner" (proposer or disputer) receives on settlement. This amount includes * the returned bonds as well as additional rewards. */ function settle( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) external virtual returns (uint256 payout); /** * @notice Gets the current data structure containing all information about a price request. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return the Request data structure. */ function getRequest( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) public view virtual returns (Request memory); /** * @notice Returns the state of a price request. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return the State enum value. */ function getState( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) public view virtual returns (State); /** * @notice Checks if a given request has resolved or been settled (i.e the optimistic oracle has a price). * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return true if price has resolved or settled, false otherwise. */ function hasPrice( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) public view virtual returns (bool); function stampAncillaryData(bytes memory ancillaryData, address requester) public view virtual returns (bytes memory); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.8.10; library DataTypes { // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. struct ReserveData { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; //the current stable borrow rate. Expressed in ray uint128 currentStableBorrowRate; uint40 lastUpdateTimestamp; //tokens addresses address aTokenAddress; address stableDebtTokenAddress; address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the id of the reserve. Represents the position in the list of the active reserves uint8 id; } struct ReserveConfigurationMap { //bit 0-15: LTV //bit 16-31: Liq. threshold //bit 32-47: Liq. bonus //bit 48-55: Decimals //bit 56: Reserve is active //bit 57: reserve is frozen //bit 58: borrowing is enabled //bit 59: stable rate borrowing enabled //bit 60-63: reserved //bit 64-79: reserve factor uint256 data; } struct UserConfigurationMap { uint256 data; } enum InterestRateMode { NONE, STABLE, VARIABLE } }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.8.10; pragma experimental ABIEncoderV2; library DistributionTypes { struct AssetConfigInput { uint104 emissionPerSecond; uint256 totalStaked; address underlyingAsset; } struct UserStakeInput { address underlyingAsset; uint256 stakedByUser; uint256 totalStaked; } } interface IAaveDistributionManager { event AssetConfigUpdated(address indexed asset, uint256 emission); event AssetIndexUpdated(address indexed asset, uint256 index); event UserIndexUpdated(address indexed user, address indexed asset, uint256 index); event DistributionEndUpdated(uint256 newDistributionEnd); /** * @dev Sets the end date for the distribution * @param distributionEnd The end date timestamp **/ function setDistributionEnd(uint256 distributionEnd) external; /** * @dev Gets the end date for the distribution * @return The end of the distribution **/ function getDistributionEnd() external view returns (uint256); /** * @dev for backwards compatibility with the previous DistributionManager used * @return The end of the distribution **/ function DISTRIBUTION_END() external view returns (uint256); /** * @dev Returns the data of an user on a distribution * @param user Address of the user * @param asset The address of the reference asset of the distribution * @return The new index **/ function getUserAssetData(address user, address asset) external view returns (uint256); /** * @dev Returns the configuration of the distribution for a certain asset * @param asset The address of the reference asset of the distribution * @return The asset index, the emission per second and the last updated timestamp **/ function getAssetData(address asset) external view returns ( uint256, uint256, uint256 ); }
{ "optimizer": { "enabled": true, "runs": 20000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IAToken","name":"_aWant","type":"address"},{"internalType":"address","name":"_aaveLmReceiver","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidArgument","type":"error"},{"inputs":[],"name":"InvalidConditions","type":"error"},{"inputs":[],"name":"InvalidSender","type":"error"},{"inputs":[],"name":"ZeroArgument","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract ISherlock","name":"sherlock","type":"address"}],"name":"SherlockCoreSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"LP_ADDRESS_PROVIDER","outputs":[{"internalType":"contract ILendingPoolAddressesProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aWant","outputs":[{"internalType":"contract IAToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aaveIncentivesController","outputs":[{"internalType":"contract IAaveIncentivesController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aaveLmReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISherlock","name":"_sherlock","type":"address"}],"name":"setSherlockCoreAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"contract IERC20[]","name":"_extraTokens","type":"address[]"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"want","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101006040523480156200001257600080fd5b50604051620021fe380380620021fe83398101604081905262000035916200020e565b6200004033620001a5565b6000805460ff60a01b191690556001600160a01b038216620000755760405163b7852ebb60e01b815260040160405180910390fd5b6001600160a01b0381166200009d5760405163b7852ebb60e01b815260040160405180910390fd5b6001600160a01b03821660c0819052604080516358b50cef60e11b8152905163b16a19de916004808201926020929091908290030181865afa158015620000e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010e91906200024d565b6001600160a01b031660a0816001600160a01b031681525050816001600160a01b03166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000166573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200018c91906200024d565b6001600160a01b039081166080521660e0525062000274565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200020b57600080fd5b50565b600080604083850312156200022257600080fd5b82516200022f81620001f5565b60208401519092506200024281620001f5565b809150509250929050565b6000602082840312156200026057600080fd5b81516200026d81620001f5565b9392505050565b60805160a05160c05160e051611f0a620002f46000396000818161022b015261071c0152600081816101c40152818161064c015261089e01526000818161015b015281816104dc01528181610a2d01528181610e3601528181610f2701528181610fb4015261103801526000818161027501526106c90152611f0a6000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c80635f2475ca116100cd5780638a179be411610081578063ca70fb7611610066578063ca70fb76146102f6578063d0e30db014610309578063f2fde38b1461031157600080fd5b80638a179be4146102c55780638da5cb5b146102d857600080fd5b8063722713f7116100b2578063722713f71461029f5780638456cb59146102b5578063853828b6146102bd57600080fd5b80635f2475ca14610270578063715018a61461029757600080fd5b806335509c50116101245780633f4ba83a116101095780633f4ba83a1461021e57806351c499ae146102265780635c975abb1461024d57600080fd5b806335509c50146101fb578063372500ab1461021657600080fd5b80631f1fcd511461015657806322f3e2d4146101a75780632ac08115146101bf5780632e1a7d4d146101e6575b600080fd5b61017d7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101af610324565b604051901515815260200161019e565b61017d7f000000000000000000000000000000000000000000000000000000000000000081565b6101f96101f4366004611b27565b6103ea565b005b61017d73b53c1a33016b2dc2ff3653530bff1848a515c8c581565b6101f961059e565b6101f9610787565b61017d7f000000000000000000000000000000000000000000000000000000000000000081565b60005474010000000000000000000000000000000000000000900460ff166101af565b61017d7f000000000000000000000000000000000000000000000000000000000000000081565b6101f96107e2565b6102a761086d565b60405190815260200161019e565b6101f9610923565b6102a761097c565b6101f96102d3366004611ba1565b610ad4565b60005473ffffffffffffffffffffffffffffffffffffffff1661017d565b6101f9610304366004611c99565b610beb565b6101f9610d5e565b6101f961031f366004611c99565b6110b4565b60003073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166313f14fee6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ce9190611cb6565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331461043b576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811415610495576040517fa9cb9e0d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061049f6111e4565b6040517f69328dec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820185905233604483015291925083918316906369328dec906064016020604051808303816000875af115801561053f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105639190611cd3565b1461059a576040517f3af36e0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60005474010000000000000000000000000000000000000000900460ff1615610628576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064015b60405180910390fd5b604080516001808252818301909252600091602080830190803683370190505090507f00000000000000000000000000000000000000000000000000000000000000008160008151811061067e5761067e611cec565b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920101526040517f3111e7b30000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000090911690633111e7b3906107449084907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff907f000000000000000000000000000000000000000000000000000000000000000090600401611d1b565b6020604051808303816000875af1158015610763573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a9190611cd3565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107d8576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107e0611269565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061f565b6107e06000611362565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156108fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611cd3565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314610974576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107e06113d7565b60015460009073ffffffffffffffffffffffffffffffffffffffff1633146109d0576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109da6111e4565b90506109e461086d565b6109f057600091505090565b6040517f69328dec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248301523360448301528216906369328dec906064016020604051808303816000875af1158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace9190611cd3565b91505090565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061f565b73ffffffffffffffffffffffffffffffffffffffff8216610ba2576040517fb7852ebb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610baa610324565b15610be1576040517f3af36e0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61059a82826114c3565b73ffffffffffffffffffffffffffffffffffffffff8116610c38576040517fb7852ebb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b46617a6914158015610c5e575033731c11be636415973520dddf1b03822b4e2930d94a14155b15610c95576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015473ffffffffffffffffffffffffffffffffffffffff1615610ce5576040517f3af36e0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527ff200116515c6d70d53a45299bb7eba08ef985ec08bfe0baf31ad73907308a3189060200160405180910390a150565b60005474010000000000000000000000000000000000000000900460ff1615610de3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161061f565b6000610ded6111e4565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610e7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea19190611cd3565b905080610eda576040517f3af36e0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015282917f00000000000000000000000000000000000000000000000000000000000000009091169063dd62ed3e90604401602060405180830381865afa158015610f70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f949190611cd3565b1015610ffb57610ffb73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611657565b6040517fe8eda9df00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018390523060448301526000606483015283169063e8eda9df90608401600060405180830381600087803b15801561109857600080fd5b505af11580156110ac573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061f565b73ffffffffffffffffffffffffffffffffffffffff81166111d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161061f565b6111e181611362565b50565b600073b53c1a33016b2dc2ff3653530bff1848a515c8c573ffffffffffffffffffffffffffffffffffffffff16630261bf8b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611245573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611cb6565b60005474010000000000000000000000000000000000000000900460ff166112ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161061f565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005474010000000000000000000000000000000000000000900460ff161561145c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161061f565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586113383390565b60005b81518110156115b65760008282815181106114e3576114e3611cec565b60209081029190910101516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529091506115a390859073ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611561573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115859190611cd3565b73ffffffffffffffffffffffffffffffffffffffff841691906117d9565b50806115ae81611dc8565b9150506114c6565b5060008273ffffffffffffffffffffffffffffffffffffffff164760405160006040518083038185875af1925050503d8060008114611611576040519150601f19603f3d011682016040523d82523d6000602084013e611616565b606091505b509091505080611652576040517f3af36e0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156116ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f29190611cd3565b6116fc9190611e01565b60405173ffffffffffffffffffffffffffffffffffffffff85166024820152604481018290529091506117d39085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261182f565b50505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526116529084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401611751565b6000611891826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661193b9092919063ffffffff16565b80519091501561165257808060200190518101906118af9190611e19565b611652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161061f565b606061194a8484600085611954565b90505b9392505050565b6060824710156119e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161061f565b843b611a4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161061f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611a779190611e67565b60006040518083038185875af1925050503d8060008114611ab4576040519150601f19603f3d011682016040523d82523d6000602084013e611ab9565b606091505b5091509150611ac9828286611ad4565b979650505050505050565b60608315611ae357508161194d565b825115611af35782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161061f9190611e83565b600060208284031215611b3957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146111e157600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8035611b9c81611b40565b919050565b60008060408385031215611bb457600080fd5b8235611bbf81611b40565b915060208381013567ffffffffffffffff80821115611bdd57600080fd5b818601915086601f830112611bf157600080fd5b813581811115611c0357611c03611b62565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715611c4657611c46611b62565b604052918252848201925083810185019189831115611c6457600080fd5b938501935b82851015611c8957611c7a85611b91565b84529385019392850192611c69565b8096505050505050509250929050565b600060208284031215611cab57600080fd5b813561194d81611b40565b600060208284031215611cc857600080fd5b815161194d81611b40565b600060208284031215611ce557600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b606080825284519082018190526000906020906080840190828801845b82811015611d6a57815173ffffffffffffffffffffffffffffffffffffffff1684529284019290840190600101611d38565b505050908301949094525073ffffffffffffffffffffffffffffffffffffffff91909116604090910152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611dfa57611dfa611d99565b5060010190565b60008219821115611e1457611e14611d99565b500190565b600060208284031215611e2b57600080fd5b8151801515811461194d57600080fd5b60005b83811015611e56578181015183820152602001611e3e565b838111156117d35750506000910152565b60008251611e79818460208701611e3b565b9190910192915050565b6020815260008251806020840152611ea2816040850160208701611e3b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122053271a37a46c8240d6d1fe8bdf5e341c9996da6724d14221ce41833c8487fefb64736f6c634300080a0033000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f13161
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101515760003560e01c80635f2475ca116100cd5780638a179be411610081578063ca70fb7611610066578063ca70fb76146102f6578063d0e30db014610309578063f2fde38b1461031157600080fd5b80638a179be4146102c55780638da5cb5b146102d857600080fd5b8063722713f7116100b2578063722713f71461029f5780638456cb59146102b5578063853828b6146102bd57600080fd5b80635f2475ca14610270578063715018a61461029757600080fd5b806335509c50116101245780633f4ba83a116101095780633f4ba83a1461021e57806351c499ae146102265780635c975abb1461024d57600080fd5b806335509c50146101fb578063372500ab1461021657600080fd5b80631f1fcd511461015657806322f3e2d4146101a75780632ac08115146101bf5780632e1a7d4d146101e6575b600080fd5b61017d7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101af610324565b604051901515815260200161019e565b61017d7f000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c81565b6101f96101f4366004611b27565b6103ea565b005b61017d73b53c1a33016b2dc2ff3653530bff1848a515c8c581565b6101f961059e565b6101f9610787565b61017d7f000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f1316181565b60005474010000000000000000000000000000000000000000900460ff166101af565b61017d7f000000000000000000000000d784927ff2f95ba542bfc824c8a8a98f3495f6b581565b6101f96107e2565b6102a761086d565b60405190815260200161019e565b6101f9610923565b6102a761097c565b6101f96102d3366004611ba1565b610ad4565b60005473ffffffffffffffffffffffffffffffffffffffff1661017d565b6101f9610304366004611c99565b610beb565b6101f9610d5e565b6101f961031f366004611c99565b6110b4565b60003073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166313f14fee6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ce9190611cb6565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331461043b576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811415610495576040517fa9cb9e0d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061049f6111e4565b6040517f69328dec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48811660048301526024820185905233604483015291925083918316906369328dec906064016020604051808303816000875af115801561053f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105639190611cd3565b1461059a576040517f3af36e0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60005474010000000000000000000000000000000000000000900460ff1615610628576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064015b60405180910390fd5b604080516001808252818301909252600091602080830190803683370190505090507f000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c8160008151811061067e5761067e611cec565b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920101526040517f3111e7b30000000000000000000000000000000000000000000000000000000081527f000000000000000000000000d784927ff2f95ba542bfc824c8a8a98f3495f6b590911690633111e7b3906107449084907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff907f000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f1316190600401611d1b565b6020604051808303816000875af1158015610763573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a9190611cd3565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107d8576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107e0611269565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061f565b6107e06000611362565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c73ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156108fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611cd3565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314610974576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107e06113d7565b60015460009073ffffffffffffffffffffffffffffffffffffffff1633146109d0576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109da6111e4565b90506109e461086d565b6109f057600091505090565b6040517f69328dec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48811660048301527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248301523360448301528216906369328dec906064016020604051808303816000875af1158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace9190611cd3565b91505090565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061f565b73ffffffffffffffffffffffffffffffffffffffff8216610ba2576040517fb7852ebb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610baa610324565b15610be1576040517f3af36e0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61059a82826114c3565b73ffffffffffffffffffffffffffffffffffffffff8116610c38576040517fb7852ebb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b46617a6914158015610c5e575033731c11be636415973520dddf1b03822b4e2930d94a14155b15610c95576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015473ffffffffffffffffffffffffffffffffffffffff1615610ce5576040517f3af36e0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527ff200116515c6d70d53a45299bb7eba08ef985ec08bfe0baf31ad73907308a3189060200160405180910390a150565b60005474010000000000000000000000000000000000000000900460ff1615610de3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161061f565b6000610ded6111e4565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816906370a0823190602401602060405180830381865afa158015610e7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea19190611cd3565b905080610eda576040517f3af36e0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015282917f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489091169063dd62ed3e90604401602060405180830381865afa158015610f70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f949190611cd3565b1015610ffb57610ffb73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611657565b6040517fe8eda9df00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881166004830152602482018390523060448301526000606483015283169063e8eda9df90608401600060405180830381600087803b15801561109857600080fd5b505af11580156110ac573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061f565b73ffffffffffffffffffffffffffffffffffffffff81166111d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161061f565b6111e181611362565b50565b600073b53c1a33016b2dc2ff3653530bff1848a515c8c573ffffffffffffffffffffffffffffffffffffffff16630261bf8b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611245573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611cb6565b60005474010000000000000000000000000000000000000000900460ff166112ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161061f565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005474010000000000000000000000000000000000000000900460ff161561145c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161061f565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586113383390565b60005b81518110156115b65760008282815181106114e3576114e3611cec565b60209081029190910101516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529091506115a390859073ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611561573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115859190611cd3565b73ffffffffffffffffffffffffffffffffffffffff841691906117d9565b50806115ae81611dc8565b9150506114c6565b5060008273ffffffffffffffffffffffffffffffffffffffff164760405160006040518083038185875af1925050503d8060008114611611576040519150601f19603f3d011682016040523d82523d6000602084013e611616565b606091505b509091505080611652576040517f3af36e0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156116ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f29190611cd3565b6116fc9190611e01565b60405173ffffffffffffffffffffffffffffffffffffffff85166024820152604481018290529091506117d39085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261182f565b50505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526116529084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401611751565b6000611891826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661193b9092919063ffffffff16565b80519091501561165257808060200190518101906118af9190611e19565b611652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161061f565b606061194a8484600085611954565b90505b9392505050565b6060824710156119e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161061f565b843b611a4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161061f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611a779190611e67565b60006040518083038185875af1925050503d8060008114611ab4576040519150601f19603f3d011682016040523d82523d6000602084013e611ab9565b606091505b5091509150611ac9828286611ad4565b979650505050505050565b60608315611ae357508161194d565b825115611af35782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161061f9190611e83565b600060208284031215611b3957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146111e157600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8035611b9c81611b40565b919050565b60008060408385031215611bb457600080fd5b8235611bbf81611b40565b915060208381013567ffffffffffffffff80821115611bdd57600080fd5b818601915086601f830112611bf157600080fd5b813581811115611c0357611c03611b62565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715611c4657611c46611b62565b604052918252848201925083810185019189831115611c6457600080fd5b938501935b82851015611c8957611c7a85611b91565b84529385019392850192611c69565b8096505050505050509250929050565b600060208284031215611cab57600080fd5b813561194d81611b40565b600060208284031215611cc857600080fd5b815161194d81611b40565b600060208284031215611ce557600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b606080825284519082018190526000906020906080840190828801845b82811015611d6a57815173ffffffffffffffffffffffffffffffffffffffff1684529284019290840190600101611d38565b505050908301949094525073ffffffffffffffffffffffffffffffffffffffff91909116604090910152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611dfa57611dfa611d99565b5060010190565b60008219821115611e1457611e14611d99565b500190565b600060208284031215611e2b57600080fd5b8151801515811461194d57600080fd5b60005b83811015611e56578181015183820152602001611e3e565b838111156117d35750506000910152565b60008251611e79818460208701611e3b565b9190910192915050565b6020815260008251806020840152611ea2816040850160208701611e3b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122053271a37a46c8240d6d1fe8bdf5e341c9996da6724d14221ce41833c8487fefb64736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f13161
-----Decoded View---------------
Arg [0] : _aWant (address): 0xBcca60bB61934080951369a648Fb03DF4F96263C
Arg [1] : _aaveLmReceiver (address): 0x666B8EbFbF4D5f0CE56962a25635CfF563F13161
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c
Arg [1] : 000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f13161
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.