Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Multi Chain
Multichain Addresses
1 address found via
Latest 4 from a total of 4 transactions
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
AaveStrategy
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 './base/BaseStrategy.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 as a yield strategy contract AaveStrategy is BaseStrategy { 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 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 /// @param _initialParent Contract that will be the parent in the tree structure /// @param _aWant aUSDC addresss /// @param _aaveLmReceiver Receiving address of the stkAAVE tokens earned by staking constructor( IMaster _initialParent, IAToken _aWant, address _aaveLmReceiver ) BaseNode(_initialParent) { if (address(_aWant) == address(0)) revert ZeroArg(); if (_aaveLmReceiver == address(0)) revert ZeroArg(); aWant = _aWant; // Gets the specific rewards controller for this token type aaveIncentivesController = _aWant.getIncentivesController(); aaveLmReceiver = _aaveLmReceiver; } /// @notice Signal if strategy is ready to be used /// @return Boolean indicating if strategy is ready function setupCompleted() external view override returns (bool) { return true; } /// @return The current Aave lending pool address that should be used function getLp() internal view returns (ILendingPool) { return ILendingPool(LP_ADDRESS_PROVIDER.getLendingPool()); } /// @notice View the current balance of this strategy in USDC /// @dev Will return wrong balance if this contract somehow has USDC instead of only aUSDC /// @return Amount of USDC in this strategy function _balanceOf() internal view override returns (uint256) { // 1 aUSDC = 1 USDC return aWant.balanceOf(address(this)); } /// @notice Deposits all USDC held in this contract into Aave's lending pool /// @notice Works under the assumption this contract contains USDC function _deposit() internal override whenNotPaused { ILendingPool lp = getLp(); // Checking the USDC balance of this contract uint256 amount = want.balanceOf(address(this)); if (amount == 0) revert InvalidState(); // If allowance for this contract is too low, approve the max allowance // Will occur if the `lp` address changes if (want.allowance(address(this), address(lp)) < amount) { // `safeIncreaseAllowance` can fail if it adds `type(uint256).max` to a non-zero value // This is very unlikely as we have to have an ungodly amount of USDC pass this system for // The allowance to reach a human interpretable number 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 core /// @return Amount of USDC withdrawn function _withdrawAll() internal override returns (uint256) { ILendingPool lp = getLp(); if (_balanceOf() == 0) { return 0; } // Withdraws all USDC from Aave's lending pool and sends it to core return lp.withdraw(address(want), type(uint256).max, core); } /// @notice Withdraws a specific amount of USDC from Aave's lending pool back into core /// @param _amount Amount of USDC to withdraw function _withdraw(uint256 _amount) internal override { // Ensures that it doesn't execute a withdrawAll() call // AAVE uses uint256.max as a magic number to withdraw max amount if (_amount == type(uint256).max) revert InvalidArg(); ILendingPool lp = getLp(); // Withdraws _amount of USDC and sends it to core // If the amount withdrawn is not equal to _amount, it reverts if (lp.withdraw(address(want), _amount, core) != _amount) revert InvalidState(); } // Claims the stkAAVE rewards and sends them to the receiver address function claimReward() external { // 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); } }
// 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/access/Ownable.sol'; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; import '@openzeppelin/contracts/security/Pausable.sol'; import '../../interfaces/strategy/INode.sol'; import '../../interfaces/strategy/IStrategy.sol'; import './BaseNode.sol'; abstract contract BaseStrategy is IStrategy, BaseNode, Pausable { using SafeERC20 for IERC20; /// @dev Return balance of this strategy function prepareBalanceCache() external override onlyParent returns (uint256) { return _balanceOf(); } /// @dev No cache is used in strategies function expireBalanceCache() external override onlyParent {} function pause() external virtual onlyOwner { _pause(); } function unpause() external virtual onlyOwner { _unpause(); } function remove() external virtual override onlyOwner { _withdrawAll(); if (_balanceOf() != 0) revert NonZeroBalance(); parent.childRemoved(); } function replace(INode _newNode) external virtual override onlyOwner { _withdrawAll(); if (_balanceOf() != 0) revert NonZeroBalance(); _replace(_newNode); } function replaceForce(INode _newNode) external virtual override onlyOwner { _replace(_newNode); emit ForceReplace(); } }
// 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 (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 (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 (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 (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 '@openzeppelin/contracts/token/ERC20/IERC20.sol'; interface INode { event AdminWithdraw(uint256 amount); event ReplaceAsChild(); event ParentUpdate(IMaster previous, IMaster current); event Obsolete(INode implementation); event ForceReplace(); event Replace(INode newAddress); error NotImplemented(bytes4 func); error SenderNotParent(); error SenderNotChild(); error InvalidParent(); error InvalidCore(); error InvalidWant(); error InvalidState(); error ZeroArg(); error InvalidArg(); error NotSetup(); error IsMaster(); error BothChild(); error NotChild(); error InvalidParentAddress(); error SetupNotCompleted(INode instance); error NonZeroBalance(); /*////////////////////////////////////////////////////////////// CONSTRUCTOR VARIABLES //////////////////////////////////////////////////////////////*/ /// @return Returns the token type being deposited into a node function want() external view returns (IERC20); /// @notice Parent will always inherit IMaster interface. /// @notice Parent of root node will inherit IStrategyManager function parent() external view returns (IMaster); /// @notice View core controller of funds function core() external view returns (address); /*////////////////////////////////////////////////////////////// TREE STRUCTURE LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Replace the node /// @notice If this is executed on a strategy, the funds will be withdrawn /// @notice If this is executed on a splitter, the children are expected to be the same function replace(INode _node) external; /// @notice Replace the node /// @notice If this is executed on a strategy, attempt is made to withdraw the funds /// @notice If this is executed on a splitter, check of children is skipped function replaceForce(INode _node) external; function setupCompleted() external view returns (bool); /// @notice Move the current node as the child of `_node` function replaceAsChild(ISplitter _node) external; /// @notice Update parent of node /// @dev Can only be called by current parent function updateParent(IMaster _node) external; function siblingRemoved() external; /*////////////////////////////////////////////////////////////// YIELD STRATEGY LOGIC //////////////////////////////////////////////////////////////*/ /// @return Returns the token balance managed by this contract /// @dev For Splitter this will be the sum of balances of the children function balanceOf() external view returns (uint256); /// @notice Withdraws all tokens back into core. /// @return The final amount withdrawn function withdrawAll() external returns (uint256); /// @notice Withdraws all token from the node back into core /// @return The final amount withdrawn function withdrawAllByAdmin() external returns (uint256); /// @notice Withdraws a specific amount of tokens from the node back into core /// @param _amount Amount of tokens to withdraw function withdraw(uint256 _amount) external; /// @notice Withdraws a specific amount of tokens from the node back into core /// @param _amount Amount of tokens to withdraw function withdrawByAdmin(uint256 _amount) external; /// @notice Deposits all tokens held in this contract into the children on strategy /// @dev Splitter will deposit the tokens in their children /// @dev Strategy will deposit the tokens into a yield strategy function deposit() external; function prepareBalanceCache() external returns (uint256); function expireBalanceCache() external; } interface IMaster is INode { event ChildOneUpdate(INode previous, INode current); /// @notice Call by child if it's needs to be updated function updateChild(INode _node) external; /// @notice Call by child if removed function childRemoved() external; function isMaster() external view returns (bool); function childOne() external view returns (INode); function setInitialChildOne(INode _child) external; } interface ISplitter is IMaster { event ChildTwoUpdate(INode previous, INode current); error InvalidChildOne(); error InvalidChildTwo(); function childTwo() external view returns (INode); function setInitialChildTwo(INode _child) 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 './INode.sol'; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; interface IStrategy is INode { /// @notice remove a strategy function remove() 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 '@openzeppelin/contracts/access/Ownable.sol'; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; import '../../interfaces/strategy/INode.sol'; // Interface used by every node abstract contract BaseNode is INode, Ownable { using SafeERC20 for IERC20; // Parent node IMaster public override parent; // Which token the strategy uses (USDC) IERC20 public immutable override want; // Reference to core (Sherlock.sol) address public immutable override core; /// @param _initialParent The initial parent of this node constructor(IMaster _initialParent) { if (address(_initialParent) == address(0)) revert ZeroArg(); IERC20 _want = _initialParent.want(); address _core = _initialParent.core(); if (address(_want) == address(0)) revert InvalidWant(); if (address(_core) == address(0)) revert InvalidCore(); want = _want; core = _core; parent = _initialParent; emit ParentUpdate(IMaster(address(0)), _initialParent); } modifier onlyParent() { if (msg.sender != address(parent)) revert SenderNotParent(); _; } /*////////////////////////////////////////////////////////////// TREE STRUCTURE LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Replace this node to be a child of `_newParent` /// @param _newParent address of the new parent /// @dev Replace as child ensures that (this) is the child of the `_newParent` /// @dev It will also enfore a `_executeParentUpdate` to make that relation bi-directional /// @dev For the other child is does minimal checks, it only checks if it isn't the same as address(this) function replaceAsChild(ISplitter _newParent) external virtual override onlyOwner { /* m | this m | 1 / \ z this */ // Gas savings IMaster _currentParent = parent; // Revert is parent is master // The master is always at the root of the tree if (_newParent.isMaster()) revert IsMaster(); // Verify if the new parent has the right connections _verifyParentUpdate(_currentParent, _newParent); // Verify is childs of newParent are correct INode otherChild = _verifyNewParent(_newParent); // Revert if otherchild = 0 // Revert if the other child has the right parent reference too // Check if `z` has the right parent (referencing comment on top function) if (otherChild.parent() != _newParent) revert InvalidParent(); // Check if `_newParent` references our currentParent as their parent // Check if `m` == `1`.parent() (referencing comment on top function) if (_currentParent != _newParent.parent()) revert InvalidParent(); // Make sure the parent recognizes the new child // Make sure `m` references `1` as it's child (referencing comment on top function) _currentParent.updateChild(_newParent); // Update parent _executeParentUpdate(_currentParent, _newParent); emit ReplaceAsChild(); } /// @notice Replace parent of this node /// @param _newParent Address of the new parent /// @dev Only callable by current parent function updateParent(IMaster _newParent) external virtual override onlyParent { // Verify if the parent can be updated _verifyParentUpdate(IMaster(msg.sender), _newParent); _verifyNewParent(_newParent); // Update parent _executeParentUpdate(IMaster(msg.sender), _newParent); } /// @notice Get notified by parent that your sibling is removed /// @dev This contract will take the position of the parent /// @dev Only callable by current parent function siblingRemoved() external override onlyParent { // Get current parent of parent IMaster _newParent = parent.parent(); // Take position of current parent _verifyParentUpdate(IMaster(msg.sender), _newParent); // NOTE: _verifyNewParent() is skipped on this call // As address(this) should be added as a child after the function returns _executeParentUpdate(IMaster(msg.sender), _newParent); } /// @notice Verify if `_newParent` is able to be our new parent /// @param _newParent Address of the new parent /// @return otherChild Address of the child that isn't address(this) function _verifyNewParent(IMaster _newParent) internal view returns (INode otherChild) { // The setup needs to be completed of parent if (_newParent.setupCompleted() == false) revert SetupNotCompleted(_newParent); // get first child INode firstChild = _newParent.childOne(); INode secondChild; // is address(this) childOne? bool isFirstChild = address(firstChild) == address(this); bool isSecondChild = false; // Parent only has a childTwo if it isn't master if (!_newParent.isMaster()) { // get second child secondChild = ISplitter(address(_newParent)).childTwo(); // is address(this) childTwo? isSecondChild = address(secondChild) == address(this); } // Check if address(this) is referenced as both childs if (isFirstChild && isSecondChild) revert BothChild(); // Check if address(this) isn't referenced at all if (!isFirstChild && !isSecondChild) revert NotChild(); // return child that isn't address(this) if (isFirstChild) { return secondChild; } return firstChild; } /// @notice Verify if `_newParent` can replace `_currentParent` /// @param _currentParent Address of our current `parent` /// @param _newParent Address of our future `parent` function _verifyParentUpdate(IMaster _currentParent, IMaster _newParent) internal view { // Revert if it's the same address if (address(_newParent) == address(this)) revert InvalidParentAddress(); // Revert if the address is parent if (address(_newParent) == address(_currentParent)) revert InvalidParentAddress(); // Revert if core is invalid if (_currentParent.core() != _newParent.core()) revert InvalidCore(); // Revert if want is invalid if (_currentParent.want() != _newParent.want()) revert InvalidWant(); } /// @notice Set parent in storage /// @param _currentParent Address of our current `parent` /// @param _newParent Address of our future `parent` function _executeParentUpdate(IMaster _currentParent, IMaster _newParent) internal { // Make `_newParent` our new parent parent = _newParent; emit ParentUpdate(_currentParent, _newParent); } /// @notice Replace address(this) with `_newNode` function _replace(INode _newNode) internal { if (address(_newNode) == address(0)) revert ZeroArg(); if (_newNode.setupCompleted() == false) revert SetupNotCompleted(_newNode); if (address(_newNode) == address(this)) revert InvalidArg(); if (_newNode.parent() != parent) revert InvalidParent(); if (_newNode.core() != core) revert InvalidCore(); if (_newNode.want() != want) revert InvalidWant(); // Make sure our parent references `_newNode` as it's child parent.updateChild(_newNode); emit Replace(_newNode); emit Obsolete(INode(address(this))); } /*////////////////////////////////////////////////////////////// YIELD STRATEGY LOGIC //////////////////////////////////////////////////////////////*/ function balanceOf() external view override returns (uint256 amount) { return _balanceOf(); } function withdrawAll() external override onlyParent returns (uint256 amount) { amount = _withdrawAll(); } function withdrawAllByAdmin() external override onlyOwner returns (uint256 amount) { amount = _withdrawAll(); emit AdminWithdraw(amount); } function withdraw(uint256 _amount) external override onlyParent { if (_amount == 0) revert ZeroArg(); _withdraw(_amount); } function withdrawByAdmin(uint256 _amount) external override onlyOwner { if (_amount == 0) revert ZeroArg(); _withdraw(_amount); emit AdminWithdraw(_amount); } function deposit() external override onlyParent { _deposit(); } function _balanceOf() internal view virtual returns (uint256 amount) {} function _withdrawAll() internal virtual returns (uint256 amount) {} function _withdraw(uint256 _amount) internal virtual {} function _deposit() internal virtual {} }
// 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: 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: 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 IMaster","name":"_initialParent","type":"address"},{"internalType":"contract IAToken","name":"_aWant","type":"address"},{"internalType":"address","name":"_aaveLmReceiver","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BothChild","type":"error"},{"inputs":[],"name":"InvalidArg","type":"error"},{"inputs":[],"name":"InvalidCore","type":"error"},{"inputs":[],"name":"InvalidParent","type":"error"},{"inputs":[],"name":"InvalidParentAddress","type":"error"},{"inputs":[],"name":"InvalidState","type":"error"},{"inputs":[],"name":"InvalidWant","type":"error"},{"inputs":[],"name":"IsMaster","type":"error"},{"inputs":[],"name":"NonZeroBalance","type":"error"},{"inputs":[],"name":"NotChild","type":"error"},{"inputs":[{"internalType":"bytes4","name":"func","type":"bytes4"}],"name":"NotImplemented","type":"error"},{"inputs":[],"name":"NotSetup","type":"error"},{"inputs":[],"name":"SenderNotChild","type":"error"},{"inputs":[],"name":"SenderNotParent","type":"error"},{"inputs":[{"internalType":"contract INode","name":"instance","type":"address"}],"name":"SetupNotCompleted","type":"error"},{"inputs":[],"name":"ZeroArg","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AdminWithdraw","type":"event"},{"anonymous":false,"inputs":[],"name":"ForceReplace","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract INode","name":"implementation","type":"address"}],"name":"Obsolete","type":"event"},{"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":"contract IMaster","name":"previous","type":"address"},{"indexed":false,"internalType":"contract IMaster","name":"current","type":"address"}],"name":"ParentUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract INode","name":"newAddress","type":"address"}],"name":"Replace","type":"event"},{"anonymous":false,"inputs":[],"name":"ReplaceAsChild","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":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"core","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"expireBalanceCache","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"parent","outputs":[{"internalType":"contract IMaster","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":"prepareBalanceCache","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"remove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract INode","name":"_newNode","type":"address"}],"name":"replace","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISplitter","name":"_newParent","type":"address"}],"name":"replaceAsChild","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract INode","name":"_newNode","type":"address"}],"name":"replaceForce","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setupCompleted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"siblingRemoved","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":[{"internalType":"contract IMaster","name":"_newParent","type":"address"}],"name":"updateParent","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":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAllByAdmin","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawByAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101206040523480156200001257600080fd5b506040516200349338038062003493833981016040819052620000359162000346565b826200004133620002dd565b6001600160a01b03811662000069576040516362c0b8cd60e11b815260040160405180910390fd5b6000816001600160a01b0316631f1fcd516040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000aa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000d091906200039a565b90506000826001600160a01b031663f2f4eb266040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000113573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200013991906200039a565b90506001600160a01b03821662000163576040516341b30e2560e01b815260040160405180910390fd5b6001600160a01b0381166200018b5760405163c5c23c8d60e01b815260040160405180910390fd5b6001600160a01b0382811660805281811660a052600180546001600160a01b0319169185169182179055604080516000815260208101929092527f2a821884f0167e84fc3824c66c12861f8f72abb7c76fd899bf5039be1c4ac7b7910160405180910390a150506001805460ff60a01b19169055506001600160a01b03821662000228576040516362c0b8cd60e11b815260040160405180910390fd5b6001600160a01b03811662000250576040516362c0b8cd60e11b815260040160405180910390fd5b6001600160a01b03821660e0819052604080516375d2641360e01b815290516375d26413916004808201926020929091908290030181865afa1580156200029b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002c191906200039a565b6001600160a01b0390811660c052166101005250620003c19050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200034357600080fd5b50565b6000806000606084860312156200035c57600080fd5b835162000369816200032d565b60208501519093506200037c816200032d565b60408501519092506200038f816200032d565b809150509250925092565b600060208284031215620003ad57600080fd5b8151620003ba816200032d565b9392505050565b60805160a05160c05160e0516101005161302b62000468600039600081816102c5015261102e01526000818161022a01528181610f5e01526115f301526000818161032e0152610fdb01526000818161041001528181611511015281816118b2015261255c0152600081816101d9015281816114e2015281816119a50152818161250e015281816126af015281816127a00152818161282d01526128b1015261302b6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c8063645c044111610104578063a7f43779116100a2578063cabfb93411610071578063cabfb934146103f0578063d0e30db014610403578063f2f4eb261461040b578063f2fde38b1461043257600080fd5b8063a7f43779146103d0578063b88a802f146103d8578063b8efa435146103e0578063bec1c473146103e857600080fd5b80638456cb59116100de5780638456cb591461039a578063853828b6146103a25780638da5cb5b146103aa57806394a368d2146103c857600080fd5b8063645c044114610377578063715018a61461038a578063722713f71461039257600080fd5b80633f4ba83a116101715780635c975abb1161014b5780635c975abb146102fa5780635f2475ca14610329578063609da8971461035057806360f96a8f1461035757600080fd5b80633f4ba83a146102b857806351c499ae146102c0578063562901d9146102e757600080fd5b80632fd20a47116101ad5780632fd20a471461026157806332ce8ccd1461027757806335509c501461028a5780633d8db911146102a557600080fd5b80631f1fcd51146101d45780632ac08115146102255780632e1a7d4d1461024c575b600080fd5b6101fb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101fb7f000000000000000000000000000000000000000000000000000000000000000081565b61025f61025a366004612dc0565b610445565b005b6102696104d9565b60405190815260200161021c565b61025f610285366004612dfb565b61053a565b6101fb73b53c1a33016b2dc2ff3653530bff1848a515c8c581565b61025f6102b3366004612dc0565b6105f5565b61025f6106ed565b6101fb7f000000000000000000000000000000000000000000000000000000000000000081565b61025f6102f5366004612dfb565b610778565b60015474010000000000000000000000000000000000000000900460ff165b604051901515815260200161021c565b6101fb7f000000000000000000000000000000000000000000000000000000000000000081565b6001610319565b6001546101fb9073ffffffffffffffffffffffffffffffffffffffff1681565b61025f610385366004612dfb565b610b3c565b61025f610bab565b610269610c36565b61025f610c40565b610269610cc9565b60005473ffffffffffffffffffffffffffffffffffffffff166101fb565b610269610d25565b61025f610ded565b61025f610f3a565b61025f61109d565b61025f611198565b61025f6103fe366004612dfb565b6111e9565b61025f6112bb565b6101fb7f000000000000000000000000000000000000000000000000000000000000000081565b61025f610440366004612dfb565b611314565b60015473ffffffffffffffffffffffffffffffffffffffff163314610496576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806104cd576040517fc581719a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104d681611441565b50565b60015460009073ffffffffffffffffffffffffffffffffffffffff16331461052d576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105356115c2565b905090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6105c981611673565b6040517f71861b9f192277502a2209dde5e25ecfd52ca83931ffc892ef70282bf7b93a2a90600090a150565b60005473ffffffffffffffffffffffffffffffffffffffff163314610676576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b806106ad576040517fc581719a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106b681611441565b6040518181527f0c19c6325aefe1fa748b9a79e9fc092a292bb370d2a5a0d13f138bb8f46429da906020015b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff16331461076e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b610776611b95565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b600154604080517f6f791d29000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff92831692841691636f791d299160048083019260209291908290030181865afa15801561086b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088f9190612e18565b156108c6576040517fef062dc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108d08183611c8e565b60006108db83611fc6565b90508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff166360f96a8f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561093f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109639190612e3a565b73ffffffffffffffffffffffffffffffffffffffff16146109b0576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff166360f96a8f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109fb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1f9190612e3a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610a83576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fe84b725d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015283169063e84b725d90602401600060405180830381600087803b158015610aec57600080fd5b505af1158015610b00573d6000803e3d6000fd5b50505050610b0e82846122cb565b6040517f1fd0ed0afde2d0281930362705e45b089222803618cdbae0b540a3ad040e845690600090a1505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b8d576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b973382611c8e565b610ba081611fc6565b506104d633826122cb565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b610776600061234f565b60006105356115c2565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b6107766123c4565b60015460009073ffffffffffffffffffffffffffffffffffffffff163314610d1d576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105356124b0565b6000805473ffffffffffffffffffffffffffffffffffffffff163314610da7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b610daf6124b0565b90507f0c19c6325aefe1fa748b9a79e9fc092a292bb370d2a5a0d13f138bb8f46429da81604051610de291815260200190565b60405180910390a190565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b610e766124b0565b50610e7f6115c2565b15610eb6576040517f20b401c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166301d050966040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610f2057600080fd5b505af1158015610f34573d6000803e3d6000fd5b50505050565b604080516001808252818301909252600091602080830190803683370190505090507f000000000000000000000000000000000000000000000000000000000000000081600081518110610f9057610f90612e57565b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920101526040517f3111e7b30000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000090911690633111e7b3906110569084907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff907f000000000000000000000000000000000000000000000000000000000000000090600401612e86565b6020604051808303816000875af1158015611075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110999190612f04565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110ee576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604080517f60f96a8f000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916360f96a8f9160048083019260209291908290030181865afa15801561115e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111829190612e3a565b905061118e3382611c8e565b6104d633826122cb565b60015473ffffffffffffffffffffffffffffffffffffffff163314610776576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461126a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b6112726124b0565b5061127b6115c2565b156112b2576040517f20b401c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104d681611673565b60015473ffffffffffffffffffffffffffffffffffffffff16331461130c576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107766125d7565b60005473ffffffffffffffffffffffffffffffffffffffff163314611395576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b73ffffffffffffffffffffffffffffffffffffffff8116611438576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016105b7565b6104d68161234f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81141561149b576040517fd30917ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114a561292d565b6040517f69328dec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018590527f00000000000000000000000000000000000000000000000000000000000000008116604483015291925083918316906369328dec906064016020604051808303816000875af1158015611567573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158b9190612f04565b14611099576040517fbaf3f0f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561164f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105359190612f04565b73ffffffffffffffffffffffffffffffffffffffff81166116c0576040517fc581719a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663609da8976040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172f9190612e18565b61177d576040517f1034170c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105b7565b73ffffffffffffffffffffffffffffffffffffffff81163014156117cd576040517fd30917ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604080517f60f96a8f000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff928316928416916360f96a8f9160048083019260209291908290030181865afa15801561183f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118639190612e3a565b73ffffffffffffffffffffffffffffffffffffffff16146118b0576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1663f2f4eb266040518163ffffffff1660e01b8152600401602060405180830381865afa158015611932573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119569190612e3a565b73ffffffffffffffffffffffffffffffffffffffff16146119a3576040517fc5c23c8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16631f1fcd516040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a499190612e3a565b73ffffffffffffffffffffffffffffffffffffffff1614611a96576040517f41b30e2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546040517fe84b725d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301529091169063e84b725d90602401600060405180830381600087803b158015611b0357600080fd5b505af1158015611b17573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff841681527f2220a12ec67ab06fa89ad2bf6522745af04a8f29b466b9c896da126dc95e21839250602001905060405180910390a16040513081527fe3bee2269179dff609bde2667db864c00a1529211302f765535fd788510b629c906020016106e2565b60015474010000000000000000000000000000000000000000900460ff16611c19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016105b7565b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b73ffffffffffffffffffffffffffffffffffffffff8116301415611cde576040517f3073085f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611d44576040517f3073085f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663f2f4eb266040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db39190612e3a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663f2f4eb266040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e389190612e3a565b73ffffffffffffffffffffffffffffffffffffffff1614611e85576040517fc5c23c8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16631f1fcd516040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ed0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef49190612e3a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16631f1fcd516040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f799190612e3a565b73ffffffffffffffffffffffffffffffffffffffff1614611099576040517f41b30e2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1663609da8976040518163ffffffff1660e01b8152600401602060405180830381865afa158015612013573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120379190612e18565b612085576040517f1034170c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105b7565b60008273ffffffffffffffffffffffffffffffffffffffff1663d921f2ee6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f69190612e3a565b90506000803073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614905060008573ffffffffffffffffffffffffffffffffffffffff16636f791d296040518163ffffffff1660e01b8152600401602060405180830381865afa158015612179573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061219d9190612e18565b61222d578573ffffffffffffffffffffffffffffffffffffffff1663f947d5c96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122109190612e3a565b92505073ffffffffffffffffffffffffffffffffffffffff821630145b8180156122375750805b1561226e576040517fbb0897ee00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115801561227a575080155b156122b1576040517f1e203c1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156122c1575090949350505050565b5091949350505050565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560408051928516835260208301919091527f2a821884f0167e84fc3824c66c12861f8f72abb7c76fd899bf5039be1c4ac7b7910160405180910390a15050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60015474010000000000000000000000000000000000000000900460ff1615612449576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016105b7565b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611c643390565b6000806124bb61292d565b90506124c56115c2565b6124d157600091505090565b6040517f69328dec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248301527f0000000000000000000000000000000000000000000000000000000000000000811660448301528216906369328dec906064016020604051808303816000875af11580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d19190612f04565b91505090565b60015474010000000000000000000000000000000000000000900460ff161561265c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016105b7565b600061266661292d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156126f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271a9190612f04565b905080612753576040517fbaf3f0f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015282917f00000000000000000000000000000000000000000000000000000000000000009091169063dd62ed3e90604401602060405180830381865afa1580156127e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280d9190612f04565b10156128745761287473ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6129b2565b6040517fe8eda9df00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018390523060448301526000606483015283169063e8eda9df90608401600060405180830381600087803b15801561291157600080fd5b505af1158015612925573d6000803e3d6000fd5b505050505050565b600073b53c1a33016b2dc2ff3653530bff1848a515c8c573ffffffffffffffffffffffffffffffffffffffff16630261bf8b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561298e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105359190612e3a565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015612a29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4d9190612f04565b612a579190612f1d565b6040805173ffffffffffffffffffffffffffffffffffffffff868116602483015260448083018590528351808403909101815260649092018352602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490840152929350610f34928792600091612b2591908516908490612bd4565b805190915015612bcf5780806020019051810190612b439190612e18565b612bcf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016105b7565b505050565b6060612be38484600085612bed565b90505b9392505050565b606082471015612c7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016105b7565b843b612ce7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105b7565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612d109190612f88565b60006040518083038185875af1925050503d8060008114612d4d576040519150601f19603f3d011682016040523d82523d6000602084013e612d52565b606091505b5091509150612d62828286612d6d565b979650505050505050565b60608315612d7c575081612be6565b825115612d8c5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b79190612fa4565b600060208284031215612dd257600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146104d657600080fd5b600060208284031215612e0d57600080fd5b8135612be681612dd9565b600060208284031215612e2a57600080fd5b81518015158114612be657600080fd5b600060208284031215612e4c57600080fd5b8151612be681612dd9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b606080825284519082018190526000906020906080840190828801845b82811015612ed557815173ffffffffffffffffffffffffffffffffffffffff1684529284019290840190600101612ea3565b505050908301949094525073ffffffffffffffffffffffffffffffffffffffff91909116604090910152919050565b600060208284031215612f1657600080fd5b5051919050565b60008219821115612f57577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b60005b83811015612f77578181015183820152602001612f5f565b83811115610f345750506000910152565b60008251612f9a818460208701612f5c565b9190910192915050565b6020815260008251806020840152612fc3816040850160208701612f5c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212208c9193f32d76b6a9af65f543ad36585b0b51ad762ad64c1e702d368771428e7364736f6c634300080a00330000000000000000000000001e8be946370a99019e323998acd37a1206bdd507000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f13161
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c8063645c044111610104578063a7f43779116100a2578063cabfb93411610071578063cabfb934146103f0578063d0e30db014610403578063f2f4eb261461040b578063f2fde38b1461043257600080fd5b8063a7f43779146103d0578063b88a802f146103d8578063b8efa435146103e0578063bec1c473146103e857600080fd5b80638456cb59116100de5780638456cb591461039a578063853828b6146103a25780638da5cb5b146103aa57806394a368d2146103c857600080fd5b8063645c044114610377578063715018a61461038a578063722713f71461039257600080fd5b80633f4ba83a116101715780635c975abb1161014b5780635c975abb146102fa5780635f2475ca14610329578063609da8971461035057806360f96a8f1461035757600080fd5b80633f4ba83a146102b857806351c499ae146102c0578063562901d9146102e757600080fd5b80632fd20a47116101ad5780632fd20a471461026157806332ce8ccd1461027757806335509c501461028a5780633d8db911146102a557600080fd5b80631f1fcd51146101d45780632ac08115146102255780632e1a7d4d1461024c575b600080fd5b6101fb7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101fb7f000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c81565b61025f61025a366004612dc0565b610445565b005b6102696104d9565b60405190815260200161021c565b61025f610285366004612dfb565b61053a565b6101fb73b53c1a33016b2dc2ff3653530bff1848a515c8c581565b61025f6102b3366004612dc0565b6105f5565b61025f6106ed565b6101fb7f000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f1316181565b61025f6102f5366004612dfb565b610778565b60015474010000000000000000000000000000000000000000900460ff165b604051901515815260200161021c565b6101fb7f000000000000000000000000d784927ff2f95ba542bfc824c8a8a98f3495f6b581565b6001610319565b6001546101fb9073ffffffffffffffffffffffffffffffffffffffff1681565b61025f610385366004612dfb565b610b3c565b61025f610bab565b610269610c36565b61025f610c40565b610269610cc9565b60005473ffffffffffffffffffffffffffffffffffffffff166101fb565b610269610d25565b61025f610ded565b61025f610f3a565b61025f61109d565b61025f611198565b61025f6103fe366004612dfb565b6111e9565b61025f6112bb565b6101fb7f0000000000000000000000000865a889183039689034da55c1fd12af5083eabf81565b61025f610440366004612dfb565b611314565b60015473ffffffffffffffffffffffffffffffffffffffff163314610496576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806104cd576040517fc581719a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104d681611441565b50565b60015460009073ffffffffffffffffffffffffffffffffffffffff16331461052d576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105356115c2565b905090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6105c981611673565b6040517f71861b9f192277502a2209dde5e25ecfd52ca83931ffc892ef70282bf7b93a2a90600090a150565b60005473ffffffffffffffffffffffffffffffffffffffff163314610676576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b806106ad576040517fc581719a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106b681611441565b6040518181527f0c19c6325aefe1fa748b9a79e9fc092a292bb370d2a5a0d13f138bb8f46429da906020015b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff16331461076e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b610776611b95565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b600154604080517f6f791d29000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff92831692841691636f791d299160048083019260209291908290030181865afa15801561086b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088f9190612e18565b156108c6576040517fef062dc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108d08183611c8e565b60006108db83611fc6565b90508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff166360f96a8f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561093f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109639190612e3a565b73ffffffffffffffffffffffffffffffffffffffff16146109b0576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff166360f96a8f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109fb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1f9190612e3a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610a83576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fe84b725d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015283169063e84b725d90602401600060405180830381600087803b158015610aec57600080fd5b505af1158015610b00573d6000803e3d6000fd5b50505050610b0e82846122cb565b6040517f1fd0ed0afde2d0281930362705e45b089222803618cdbae0b540a3ad040e845690600090a1505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b8d576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b973382611c8e565b610ba081611fc6565b506104d633826122cb565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b610776600061234f565b60006105356115c2565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b6107766123c4565b60015460009073ffffffffffffffffffffffffffffffffffffffff163314610d1d576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105356124b0565b6000805473ffffffffffffffffffffffffffffffffffffffff163314610da7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b610daf6124b0565b90507f0c19c6325aefe1fa748b9a79e9fc092a292bb370d2a5a0d13f138bb8f46429da81604051610de291815260200190565b60405180910390a190565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b610e766124b0565b50610e7f6115c2565b15610eb6576040517f20b401c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166301d050966040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610f2057600080fd5b505af1158015610f34573d6000803e3d6000fd5b50505050565b604080516001808252818301909252600091602080830190803683370190505090507f000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c81600081518110610f9057610f90612e57565b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920101526040517f3111e7b30000000000000000000000000000000000000000000000000000000081527f000000000000000000000000d784927ff2f95ba542bfc824c8a8a98f3495f6b590911690633111e7b3906110569084907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff907f000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f1316190600401612e86565b6020604051808303816000875af1158015611075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110999190612f04565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110ee576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604080517f60f96a8f000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916360f96a8f9160048083019260209291908290030181865afa15801561115e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111829190612e3a565b905061118e3382611c8e565b6104d633826122cb565b60015473ffffffffffffffffffffffffffffffffffffffff163314610776576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461126a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b6112726124b0565b5061127b6115c2565b156112b2576040517f20b401c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104d681611673565b60015473ffffffffffffffffffffffffffffffffffffffff16331461130c576040517fb70e2d7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107766125d7565b60005473ffffffffffffffffffffffffffffffffffffffff163314611395576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b7565b73ffffffffffffffffffffffffffffffffffffffff8116611438576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016105b7565b6104d68161234f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81141561149b576040517fd30917ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114a561292d565b6040517f69328dec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881166004830152602482018590527f0000000000000000000000000865a889183039689034da55c1fd12af5083eabf8116604483015291925083918316906369328dec906064016020604051808303816000875af1158015611567573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158b9190612f04565b14611099576040517fbaf3f0f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c73ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561164f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105359190612f04565b73ffffffffffffffffffffffffffffffffffffffff81166116c0576040517fc581719a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663609da8976040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172f9190612e18565b61177d576040517f1034170c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105b7565b73ffffffffffffffffffffffffffffffffffffffff81163014156117cd576040517fd30917ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604080517f60f96a8f000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff928316928416916360f96a8f9160048083019260209291908290030181865afa15801561183f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118639190612e3a565b73ffffffffffffffffffffffffffffffffffffffff16146118b0576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000865a889183039689034da55c1fd12af5083eabf73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1663f2f4eb266040518163ffffffff1660e01b8152600401602060405180830381865afa158015611932573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119569190612e3a565b73ffffffffffffffffffffffffffffffffffffffff16146119a3576040517fc5c23c8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16631f1fcd516040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a499190612e3a565b73ffffffffffffffffffffffffffffffffffffffff1614611a96576040517f41b30e2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546040517fe84b725d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301529091169063e84b725d90602401600060405180830381600087803b158015611b0357600080fd5b505af1158015611b17573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff841681527f2220a12ec67ab06fa89ad2bf6522745af04a8f29b466b9c896da126dc95e21839250602001905060405180910390a16040513081527fe3bee2269179dff609bde2667db864c00a1529211302f765535fd788510b629c906020016106e2565b60015474010000000000000000000000000000000000000000900460ff16611c19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016105b7565b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b73ffffffffffffffffffffffffffffffffffffffff8116301415611cde576040517f3073085f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611d44576040517f3073085f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663f2f4eb266040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db39190612e3a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663f2f4eb266040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e389190612e3a565b73ffffffffffffffffffffffffffffffffffffffff1614611e85576040517fc5c23c8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16631f1fcd516040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ed0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef49190612e3a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16631f1fcd516040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f799190612e3a565b73ffffffffffffffffffffffffffffffffffffffff1614611099576040517f41b30e2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1663609da8976040518163ffffffff1660e01b8152600401602060405180830381865afa158015612013573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120379190612e18565b612085576040517f1034170c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105b7565b60008273ffffffffffffffffffffffffffffffffffffffff1663d921f2ee6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f69190612e3a565b90506000803073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614905060008573ffffffffffffffffffffffffffffffffffffffff16636f791d296040518163ffffffff1660e01b8152600401602060405180830381865afa158015612179573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061219d9190612e18565b61222d578573ffffffffffffffffffffffffffffffffffffffff1663f947d5c96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122109190612e3a565b92505073ffffffffffffffffffffffffffffffffffffffff821630145b8180156122375750805b1561226e576040517fbb0897ee00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115801561227a575080155b156122b1576040517f1e203c1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156122c1575090949350505050565b5091949350505050565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560408051928516835260208301919091527f2a821884f0167e84fc3824c66c12861f8f72abb7c76fd899bf5039be1c4ac7b7910160405180910390a15050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60015474010000000000000000000000000000000000000000900460ff1615612449576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016105b7565b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611c643390565b6000806124bb61292d565b90506124c56115c2565b6124d157600091505090565b6040517f69328dec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48811660048301527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248301527f0000000000000000000000000865a889183039689034da55c1fd12af5083eabf811660448301528216906369328dec906064016020604051808303816000875af11580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d19190612f04565b91505090565b60015474010000000000000000000000000000000000000000900460ff161561265c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016105b7565b600061266661292d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816906370a0823190602401602060405180830381865afa1580156126f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271a9190612f04565b905080612753576040517fbaf3f0f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015282917f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489091169063dd62ed3e90604401602060405180830381865afa1580156127e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280d9190612f04565b10156128745761287473ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6129b2565b6040517fe8eda9df00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881166004830152602482018390523060448301526000606483015283169063e8eda9df90608401600060405180830381600087803b15801561291157600080fd5b505af1158015612925573d6000803e3d6000fd5b505050505050565b600073b53c1a33016b2dc2ff3653530bff1848a515c8c573ffffffffffffffffffffffffffffffffffffffff16630261bf8b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561298e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105359190612e3a565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015612a29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4d9190612f04565b612a579190612f1d565b6040805173ffffffffffffffffffffffffffffffffffffffff868116602483015260448083018590528351808403909101815260649092018352602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490840152929350610f34928792600091612b2591908516908490612bd4565b805190915015612bcf5780806020019051810190612b439190612e18565b612bcf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016105b7565b505050565b6060612be38484600085612bed565b90505b9392505050565b606082471015612c7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016105b7565b843b612ce7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105b7565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612d109190612f88565b60006040518083038185875af1925050503d8060008114612d4d576040519150601f19603f3d011682016040523d82523d6000602084013e612d52565b606091505b5091509150612d62828286612d6d565b979650505050505050565b60608315612d7c575081612be6565b825115612d8c5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b79190612fa4565b600060208284031215612dd257600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146104d657600080fd5b600060208284031215612e0d57600080fd5b8135612be681612dd9565b600060208284031215612e2a57600080fd5b81518015158114612be657600080fd5b600060208284031215612e4c57600080fd5b8151612be681612dd9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b606080825284519082018190526000906020906080840190828801845b82811015612ed557815173ffffffffffffffffffffffffffffffffffffffff1684529284019290840190600101612ea3565b505050908301949094525073ffffffffffffffffffffffffffffffffffffffff91909116604090910152919050565b600060208284031215612f1657600080fd5b5051919050565b60008219821115612f57577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b60005b83811015612f77578181015183820152602001612f5f565b83811115610f345750506000910152565b60008251612f9a818460208701612f5c565b9190910192915050565b6020815260008251806020840152612fc3816040850160208701612f5c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212208c9193f32d76b6a9af65f543ad36585b0b51ad762ad64c1e702d368771428e7364736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001e8be946370a99019e323998acd37a1206bdd507000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f13161
-----Decoded View---------------
Arg [0] : _initialParent (address): 0x1E8bE946370a99019E323998Acd37A1206bdD507
Arg [1] : _aWant (address): 0xBcca60bB61934080951369a648Fb03DF4F96263C
Arg [2] : _aaveLmReceiver (address): 0x666B8EbFbF4D5f0CE56962a25635CfF563F13161
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000001e8be946370a99019e323998acd37a1206bdd507
Arg [1] : 000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c
Arg [2] : 000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f13161
Loading...
Loading
Loading...
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.
[ 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.