Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
StakeDataProvider
Compiler Version
v0.8.27+commit.40a35a09
Optimization Enabled:
Yes with 200 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {IUmbrellaStakeToken} from "aave-umbrella/stakeToken/interfaces/IUmbrellaStakeToken.sol"; import {IRewardsController} from "aave-umbrella/rewards/interfaces/IRewardsController.sol"; import {IRewardsStructs} from "aave-umbrella/rewards/interfaces/IRewardsStructs.sol"; import {IUmbrella} from "aave-umbrella/umbrella/interfaces/IUmbrella.sol"; import {IUmbrellaConfiguration} from "aave-umbrella/umbrella/interfaces/IUmbrellaConfiguration.sol"; import {IUmbrellaStkManager} from "aave-umbrella/umbrella/interfaces/IUmbrellaStkManager.sol"; import {IStataTokenFactory} from "aave-v3-origin/contracts/extensions/stata-token/interfaces/IStataTokenFactory.sol"; import {IStataTokenV2} from "aave-v3-origin/contracts/extensions/stata-token/interfaces/IStataTokenV2.sol"; import {IAToken} from "aave-v3-origin/contracts/interfaces/IAToken.sol"; import {IAaveOracle} from "aave-v3-origin/contracts/interfaces/IAaveOracle.sol"; import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import {IERC20Metadata} from "openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import {ApyCalculator} from "./libraries/ApyCalculator.sol"; struct StakeData { // ---stake token data--- address tokenAddress; string name; string symbol; uint256 price; uint256 totalAssets; uint256 targetLiquidity; // ---underlying token data--- address underlyingTokenAddress; string underlyingTokenName; string underlyingTokenSymbol; uint8 underlyingTokenDecimals; // ---other--- uint256 cooldownSeconds; uint256 unstakeWindowSeconds; bool underlyingIsStataToken; StataTokenData stataTokenData; Reward[] rewards; } struct StataTokenData { address asset; string assetName; string assetSymbol; address aToken; string aTokenName; string aTokenSymbol; } struct Reward { address rewardAddress; string rewardName; string rewardSymbol; uint256 price; uint8 decimals; uint256 index; uint256 maxEmissionPerSecond; uint256 distributionEnd; uint256 currentEmissionPerSecond; uint256 apy; } struct StakeUserData { address stakeToken; string stakeTokenName; StakeUserBalances balances; StakeUserCooldown cooldown; address[] rewards; uint256[] rewardsAccrued; } struct StakeUserBalances { uint256 stakeTokenBalance; uint256 stakeTokenRedeemableAmount; uint256 underlyingTokenBalance; uint256 stataTokenAssetBalance; uint256 stataTokenATokenBalance; } struct StakeUserCooldown { uint192 cooldownAmount; uint32 endOfCooldown; uint32 withdrawalWindow; } contract StakeDataProvider { IUmbrellaStkManager public immutable umbrella; IRewardsController public immutable rewardsController; IStataTokenFactory public immutable stataTokenFactory; IAaveOracle public immutable aaveOracle; constructor( IUmbrellaStkManager _umbrella, IRewardsController _rewardsController, IStataTokenFactory _stataTokenFactory, IAaveOracle _aaveOracle ) { umbrella = _umbrella; rewardsController = _rewardsController; stataTokenFactory = _stataTokenFactory; aaveOracle = _aaveOracle; } function getStakeData() public view returns (StakeData[] memory) { address[] memory stkTokens = umbrella.getStkTokens(); StakeData[] memory stakeData = new StakeData[](stkTokens.length); address[] memory stataTokens = stataTokenFactory.getStataTokens(); for (uint256 i = 0; i < stkTokens.length; i++) { IUmbrellaStakeToken stk = IUmbrellaStakeToken(stkTokens[i]); address stkTokenAddress = address(stk); address asset = stk.asset(); uint256 stakeTokenPrice = uint256(IUmbrellaStakeToken(stkTokenAddress).latestAnswer()); Reward[] memory rewards = _getRewards(stkTokenAddress, stakeTokenPrice, stk.decimals(), stk.totalAssets()); StataTokenData memory stataTokenData = _getStataTokenData(asset, stataTokens); bool underlyingIsStataToken = stataTokenData.asset != address(0); stakeData[i] = StakeData({ tokenAddress: stkTokens[i], totalAssets: stk.totalAssets(), targetLiquidity: rewardsController.getAssetData(stkTokens[i]).targetLiquidity, cooldownSeconds: stk.getCooldown(), unstakeWindowSeconds: stk.getUnstakeWindow(), name: stk.name(), symbol: stk.symbol(), underlyingTokenAddress: asset, price: stakeTokenPrice, underlyingIsStataToken: underlyingIsStataToken, stataTokenData: stataTokenData, rewards: rewards, underlyingTokenDecimals: IERC20Metadata(stk.asset()).decimals(), underlyingTokenName: IERC20Metadata(stk.asset()).name(), underlyingTokenSymbol: IERC20Metadata(stk.asset()).symbol() }); } return stakeData; } function getUserStakeData(address user) public view returns (StakeUserData[] memory) { address[] memory stkTokens = umbrella.getStkTokens(); StakeUserData[] memory stakeUserData = new StakeUserData[](stkTokens.length); address[] memory stataTokens = stataTokenFactory.getStataTokens(); for (uint256 i = 0; i < stkTokens.length; i++) { IUmbrellaStakeToken stk = IUmbrellaStakeToken(stkTokens[i]); StakeUserBalances memory balances = _getBalances(user, stk, stataTokens); StakeUserCooldown memory cooldown = _getCooldown(user, stk); (address[] memory rewards, uint256[] memory rewardsAccrued) = rewardsController.calculateCurrentUserRewards(address(stk), user); stakeUserData[i] = StakeUserData({ stakeToken: address(stk), stakeTokenName: stk.name(), balances: balances, cooldown: cooldown, rewards: rewards, rewardsAccrued: rewardsAccrued }); } return stakeUserData; } function _getBalances(address user, IUmbrellaStakeToken stk, address[] memory stataTokens) internal view returns (StakeUserBalances memory) { address asset = stk.asset(); (uint256 assetBalance, uint256 aTokenBalance) = _getStataTokenBalances(user, asset, stataTokens); return StakeUserBalances({ stakeTokenBalance: stk.balanceOf(user), stakeTokenRedeemableAmount: stk.previewRedeem(stk.balanceOf(user)), underlyingTokenBalance: IERC20(asset).balanceOf(user), stataTokenAssetBalance: assetBalance, stataTokenATokenBalance: aTokenBalance }); } function _getCooldown(address user, IUmbrellaStakeToken stk) internal view returns (StakeUserCooldown memory) { IUmbrellaStakeToken.CooldownSnapshot memory cooldown = stk.getStakerCooldown(user); return StakeUserCooldown({ cooldownAmount: cooldown.amount, endOfCooldown: cooldown.endOfCooldown, withdrawalWindow: cooldown.withdrawalWindow }); } function _getStataTokenBalances(address user, address asset, address[] memory stataTokens) internal view returns (uint256 stataTokenAssetBalance, uint256 stataTokenATokenBalance) { if (_checkIsStataToken(asset, stataTokens)) { address stataTokenAsset = IStataTokenV2(asset).asset(); address stataTokenAToken = IStataTokenV2(asset).aToken(); stataTokenAssetBalance = IERC20(stataTokenAsset).balanceOf(user); stataTokenATokenBalance = IERC20(stataTokenAToken).balanceOf(user); } } function _getRewards(address stkTokenAddress, uint256 stkTokenPrice, uint8 stkTokenDecimals, uint256 stkTotalAssets) internal view returns (Reward[] memory) { address[] memory rewardAddresses = rewardsController.getAllRewards(stkTokenAddress); Reward[] memory rewards = new Reward[](rewardAddresses.length); for (uint256 j = 0; j < rewardAddresses.length; j++) { address rewardTokenAddress = rewardAddresses[j]; IRewardsStructs.RewardDataExternal memory rewardData = rewardsController.getRewardData(stkTokenAddress, rewardTokenAddress); uint256 currentEmissionPerSecond = rewardsController.calculateCurrentEmissionScaled(stkTokenAddress, rewardTokenAddress); uint256 price = _getRewardPrice(rewardTokenAddress); rewards[j] = Reward({ rewardAddress: rewardTokenAddress, rewardName: IERC20Metadata(rewardTokenAddress).name(), rewardSymbol: IERC20Metadata(rewardTokenAddress).symbol(), price: price, decimals: IERC20Metadata(rewardTokenAddress).decimals(), index: rewardData.index, maxEmissionPerSecond: rewardData.maxEmissionPerSecond, distributionEnd: rewardData.distributionEnd, currentEmissionPerSecond: currentEmissionPerSecond, apy: ApyCalculator.calculateApy( currentEmissionPerSecond, stkTotalAssets, stkTokenPrice, stkTokenDecimals, price ) }); } return rewards; } function _getRewardPrice(address rewardTokenAddress) internal view returns (uint256) { // Top reward cases: // 1) aToken // 2) Token // 3) StataToken (should be only in rare cases) // return max otherwise, cause source of price isn't known address tokenToAskPriceFor = rewardTokenAddress; uint256 price; // aToken try IAToken(rewardTokenAddress).UNDERLYING_ASSET_ADDRESS() returns (address token) { tokenToAskPriceFor = token; } catch {} // Token || aToken // price of `aToken` is equal to price of `Token`, cause backed 1-1 try IAaveOracle(aaveOracle).getAssetPrice(tokenToAskPriceFor) returns (uint256 reservePrice) { price = reservePrice; } catch { // `StataToken`, if this `Stata` isn't even from this `Pool` it will anyway return actual price try IStataTokenV2(rewardTokenAddress).aToken() { price = uint256(IStataTokenV2(rewardTokenAddress).latestAnswer()); } catch { // Source of price isn't known, it's a `Token/aToken` or another type of `Token` except `StataToken`, that isn't listed on this concrete Aave `Pool` // Don't make revert here, cause it's a normal situation and this price should be get from somewhere else price = type(uint256).max; } } return price; } function _getStataTokenData(address asset, address[] memory stataTokens) internal view returns (StataTokenData memory data) { if (!_checkIsStataToken(asset, stataTokens)) { return data; } IStataTokenV2 stataToken = IStataTokenV2(asset); IERC20Metadata underlying = IERC20Metadata(stataToken.asset()); IERC20Metadata aToken = IERC20Metadata(stataToken.aToken()); return StataTokenData({ asset: address(underlying), assetName: underlying.name(), assetSymbol: underlying.symbol(), aToken: address(aToken), aTokenName: aToken.name(), aTokenSymbol: aToken.symbol() }); } function _checkIsStataToken(address addr, address[] memory stataTokens) internal pure returns (bool) { for (uint256 i = 0; i < stataTokens.length; i++) { if (addr == stataTokens[i]) { return true; } } return false; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {IStakeToken} from './IStakeToken.sol'; import {IOracleToken} from './IOracleToken.sol'; interface IUmbrellaStakeToken is IStakeToken, IOracleToken {}
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {IRewardsDistributor} from './IRewardsDistributor.sol'; interface IRewardsController is IRewardsDistributor { /** * @notice Event is emitted when an asset is initialized. * @param asset Address of the new `asset` added */ event AssetInitialized(address indexed asset); /** * @notice Event is emitted when a `targetLiquidity` of the `asset` is changed. * @param asset Address of the `asset` * @param newTargetLiquidity New amount of `targetLiquidity` set for the `asset` */ event TargetLiquidityUpdated(address indexed asset, uint256 newTargetLiquidity); /** * @notice Event is emitted when a `lastUpdatedTimestamp` of the `asset` is updated. * @param asset Address of the `asset` * @param newTimestamp New value of `lastUpdatedTimestamp` updated for the `asset` */ event LastTimestampUpdated(address indexed asset, uint256 newTimestamp); /** * @notice Event is emitted when a reward is initialized for concrete `asset`. * @param asset Address of the `asset` * @param reward Address of the `reward` */ event RewardInitialized(address indexed asset, address indexed reward); /** * @notice Event is emitted when a reward config is updated. * @param asset Address of the `asset` * @param reward Address of the `reward` * @param maxEmissionPerSecond Amount of maximum possible rewards emission per second * @param distributionEnd Timestamp after which distribution ends * @param rewardPayer Address from where rewards will be transferred */ event RewardConfigUpdated( address indexed asset, address indexed reward, uint256 maxEmissionPerSecond, uint256 distributionEnd, address rewardPayer ); /** * @notice Event is emitted when a `reward` index is updated. * @param asset Address of the `asset` * @param reward Address of the `reward` * @param newIndex New `reward` index updated for certain `asset` */ event RewardIndexUpdated(address indexed asset, address indexed reward, uint256 newIndex); /** * @notice Event is emitted when a user interacts with the asset (transfer, mint, burn) or manually updates the rewards data or claims them * @param asset Address of the `asset` * @param reward Address of the `reward`, which `user` data is updated * @param user Address of the `user` whose `reward` data is updated * @param newIndex Reward index set after update * @param accruedFromLastUpdate Amount of accrued rewards from last update */ event UserDataUpdated( address indexed asset, address indexed reward, address indexed user, uint256 newIndex, uint256 accruedFromLastUpdate ); /** * @notice Event is emitted when a `user` `reward` is claimed. * @param asset Address of the `asset`, whose `reward` was claimed * @param reward Address of the `reward`, which is claimed * @param user Address of the `user` whose `reward` is claimed * @param receiver Address of the funds receiver * @param amount Amount of the received funds */ event RewardClaimed( address indexed asset, address indexed reward, address indexed user, address receiver, uint256 amount ); /** * @dev Attempted to update data on the `asset` before it was initialized. */ error AssetNotInitialized(address asset); /** * @dev Attempted to change the configuration of the `reward` before it was initialized. */ error RewardNotInitialized(address reward); /** * @dev Attempted to set `distributionEnd` less than `block.timestamp` during `reward` initialization. */ error InvalidDistributionEnd(); /** * @dev Attempted to initialize more rewards than limit. */ error MaxRewardsLengthReached(); // DEFAULT_ADMIN_ROLE ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Configures asset: sets `targetLiquidity` and updates `lastUpdatedTimestamp`. * If the asset has already been initialized, then updates the rewards indexes and `lastUpdatedTimestamp`, * also changes `targetLiquidity`, otherwise initializes asset and rewards. * @dev `targetLiquidity` should be greater than 1 whole token. * `maxEmissionPerSecond` inside `rewardConfig` should be less than 1000 tokens and greater than 2 wei. * It must also be greater than `targetLiquidity * 1000 / 1e18`. Check EmissionMath.sol for more info. * if `maxEmissionPerSecond` is zero or `distributionEnd` is less than current `block.timestamp`, * then disable distribution for this `reward` if it was previously initialized. * It can't initialize already disabled reward. * @param asset Address of the `asset` to be configured/initialized * @param targetLiquidity Amount of liquidity where will be the maximum emission of rewards per second applied * @param rewardConfigs Optional array of reward configs, can be empty */ function configureAssetWithRewards( address asset, uint256 targetLiquidity, RewardSetupConfig[] calldata rewardConfigs ) external; // REWARDS_ADMIN_ROLE ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Configures already initialized rewards for certain `asset`: sets `distributionEnd` and `maxEmissionPerSecond`. * If any reward hasn't initialized before then it reverts. * Before setting new configuration updates all rewards indexes for `asset`. * @dev `maxEmissionPerSecond` inside `rewardConfig` should be less than 1000 tokens and greater than 2 wei. * It must also be greater than `targetLiquidity * 1000 / 1e18`. Check EmissionMath.sol for more info. * If `maxEmissionPerSecond` is zero or `distributionEnd` is less than the current `block.timestamp`, * then distribution for this `reward` will be disabled. * @param asset Address of the `asset` whose reward should be configured * @param rewardConfigs Array of structs with params to set */ function configureRewards(address asset, RewardSetupConfig[] calldata rewardConfigs) external; ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Special hook, which is called every time `StakeToken` makes `_update` or `slash`. * Makes an update and calculates new `index` and `accrued`. Also updates `lastUpdateTimestamp`. * @dev All variables are passed here before the actual update. * @param totalSupply Total supply of `StakeToken` * @param totalAssets Total assets of `StakeToken` * @param user User, whose `index` and rewards accrued will be updated, if address is zero then skips user update * @param userBalance Amount of `StakeToken` shares owned by user */ function handleAction( uint256 totalSupply, uint256 totalAssets, address user, uint256 userBalance ) external; /** * @notice Updates all `reward` indexes and `lastUpdateTimestamp` for the `asset`. * @param asset Address of the `asset` whose rewards will be updated */ function updateAsset(address asset) external; /** * @notice Returns an array of all initialized assets (all `StakeTokens`, which are initialized here). * @dev Return zero data if assets aren't set. * @return assets Array of asset addresses */ function getAllAssets() external view returns (address[] memory assets); /** * @notice Returns an array of all initialized rewards for a certain `asset`. * @dev Return zero data if asset or rewards aren't set. * @param asset Address of the `asset` whose rewards should be returned * @return rewards Array of reward addresses */ function getAllRewards(address asset) external view returns (address[] memory rewards); /** * @notice Returns all data about the asset and its rewards. * @dev Return zero data if asset or rewards aren't set. * Function made without some gas optimizations, so it's recommended to avoid calling it often from non-view method or inside batch. * If the emission for a specific reward has ended at the time of the call (i.e., block.timestamp >= distributionEnd), * the function will return a zero emission, even though there may still be remaining rewards. * Note that the actual reward data will be updated the next time someone manually refreshes the data or interacts with the `StakeToken`. * @param asset Address of the `asset` whose params should be returned * @return assetData `targetLiquidity` and `lastUpdatedTimestamp` inside struct * @return rewardsData All data about rewards including addresses and `RewardData` */ function getAssetAndRewardsData( address asset ) external view returns (AssetDataExternal memory assetData, RewardDataExternal[] memory rewardsData); /** * @notice Returns data about the asset. * @dev Return zero data if asset isn't set. * @param asset Address of the `asset` whose params should be returned * @return assetData `targetLiquidity` and `lastUpdatedTimestamp` inside struct */ function getAssetData(address asset) external view returns (AssetDataExternal memory assetData); /** * @notice Returns data about the reward. * @dev Return zero data if asset or rewards aren't set. * If the emission has ended at the time of the call (i.e., block.timestamp >= distributionEnd), the function will return a zero emission, * even though there may still be remaining rewards. * Note that the actual reward data will be updated the next time someone manually refreshes the data or interacts with the `StakeToken`. * @param asset Address of the `asset` whose `reward` params should be returned * @param reward Address of the `reward` whose params should be returned * @return rewardData `index`, `maxEmissionPerSecond` and `distributionEnd` and address inside struct, address is duplicated from external one */ function getRewardData( address asset, address reward ) external view returns (RewardDataExternal memory rewardData); /** * @notice Returns data about the reward emission. * @dev Return zero data if asset or rewards aren't set. * If `maxEmissionPerSecond` is equal to 1 wei, then `flatEmission` will be 0, although in fact it is not 0 and emission is taken into account correctly inside the code. * Here this calculation is made specifically to simplify the function behaviour. * If the emission has ended at the time of the call (i.e., block.timestamp >= distributionEnd), the function will return a zero max and flat emissions, * even though there may still be remaining rewards. * Note that the actual reward data will be updated the next time someone manually refreshes the data or interacts with the `StakeToken`. * @param asset Address of the `asset` whose `reward` emission params should be returned * @param reward Address of the `reward` whose emission params should be returned * @return emissionData `targetLiquidity`, `targetLiquidityExcess`, `maxEmission` and `flatEmission` inside struct */ function getEmissionData( address asset, address reward ) external view returns (EmissionData memory emissionData); /** * @notice Returns `user` `index` and `accrued` for all rewards for certain `asset` at the time of the last user update. * If you want to get current `accrued` of all rewards, see `calculateCurrentUserRewards`. * @dev Return zero data if asset or rewards aren't set. * @param asset Address of the `asset` for which the rewards are accumulated * @param user Address of `user` accumulating rewards * @return rewards Array of `reward` addresses * @return userData `index` and `accrued` inside structs */ function getUserDataByAsset( address asset, address user ) external view returns (address[] memory rewards, UserDataExternal[] memory userData); /** * @notice Returns `user` `index` and `accrued` for certain `asset` and `reward` at the time of the last user update. * If you want to calculate current `accrued` of the `reward`, see `calculateCurrentUserReward`. * @dev Return zero data if asset or rewards aren't set. * @param asset Address of the `asset` for which the `reward` is accumulated * @param reward Address of the accumulating `reward` * @param user Address of `user` accumulating rewards * @return data `index` and `accrued` inside struct */ function getUserDataByReward( address asset, address reward, address user ) external view returns (UserDataExternal memory data); /** * @notice Returns current `reward` indexes for `asset`. * @dev Return zero if asset or rewards aren't set. * Function made without some gas optimizations, so it's recommended to avoid calling it often from non-view method or inside batch. * @param asset Address of the `asset` whose indexes of rewards should be calculated * @return rewards Array of `reward` addresses * @return indexes Current indexes */ function calculateRewardIndexes( address asset ) external view returns (address[] memory rewards, uint256[] memory indexes); /** * @notice Returns current `index` for certain `asset` and `reward`. * @dev Return zero if asset or rewards aren't set. * @param asset Address of the `asset` whose `index` of `reward` should be calculated * @param reward Address of the accumulating `reward` * @return index Current `index` */ function calculateRewardIndex( address asset, address reward ) external view returns (uint256 index); /** * @notice Returns `emissionPerSecondScaled` for certain `asset` and `reward`. Returned value scaled to 18 decimals. * @dev Return zero if asset or rewards aren't set. * @param asset Address of the `asset` which current emission of `reward` should be returned * @param reward Address of the `reward` which `emissionPerSecond` should be returned * @return emissionPerSecondScaled Current amount of rewards distributed every second (scaled to 18 decimals) */ function calculateCurrentEmissionScaled( address asset, address reward ) external view returns (uint256 emissionPerSecondScaled); /** * @notice Returns `emissionPerSecond` for certain `asset` and `reward`. * @dev Return zero if asset or rewards aren't set. * An integer quantity is returned, although the accuracy of the calculations in reality is higher. * @param asset Address of the `asset` which current emission of `reward` should be returned * @param reward Address of the `reward` which `emissionPerSecond` should be returned * @return emissionPerSecond Current amount of rewards distributed every second */ function calculateCurrentEmission( address asset, address reward ) external view returns (uint256 emissionPerSecond); /** * @notice Calculates and returns `user` `accrued` amounts for all rewards for certain `asset`. * @dev Return zero data if asset or rewards aren't set. * Function made without some gas optimizations, so it's recommended to avoid calling it often from non-view method or inside batch. * @param asset Address of the `asset` whose rewards are accumulated * @param user Address of `user` accumulating rewards * @return rewards Array of `reward` addresses * @return rewardsAccrued Array of current calculated `accrued` amounts */ function calculateCurrentUserRewards( address asset, address user ) external view returns (address[] memory rewards, uint256[] memory rewardsAccrued); /** * @notice Calculates and returns `user` `accrued` amount for certain `reward` and `asset`. * @dev Return zero if asset or rewards aren't set. * @param asset Address of the `asset` whose reward is accumulated * @param reward Address of the `reward` that accumulates for the user * @param user Address of `user` accumulating rewards * @return rewardAccrued Amount of current calculated `accrued` amount */ function calculateCurrentUserReward( address asset, address reward, address user ) external view returns (uint256 rewardAccrued); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; /** * @title IRewardsStructs interface * @notice An interface containing structures that can be used externally. * @author BGD labs */ interface IRewardsStructs { struct RewardSetupConfig { /// @notice Reward address address reward; /// @notice Address, from which this reward will be transferred (should give approval to this address) address rewardPayer; /// @notice Maximum possible emission rate of rewards per second uint256 maxEmissionPerSecond; /// @notice End of the rewards distribution uint256 distributionEnd; } struct AssetDataExternal { /// @notice Liquidity value at which there will be maximum emission per second (expected amount of asset to be deposited into `StakeToken`) uint256 targetLiquidity; /// @notice Timestamp of the last update uint256 lastUpdateTimestamp; } struct RewardDataExternal { /// @notice Reward address address addr; /// @notice Liquidity index of the reward set during the last update uint256 index; /// @notice Maximum possible emission rate of rewards per second uint256 maxEmissionPerSecond; /// @notice End of the reward distribution uint256 distributionEnd; } struct EmissionData { /// @notice Liquidity value at which there will be maximum emission per second applied uint256 targetLiquidity; /// @notice Liquidity value after which emission per second will be flat uint256 targetLiquidityExcess; /// @notice Maximum possible emission rate of rewards per second (can be with or without scaling to 18 decimals, depending on usage in code) uint256 maxEmission; /// @notice Flat emission value per second (can be with or without scaling, depending on usage in code) uint256 flatEmission; } struct UserDataExternal { /// @notice Liquidity index of the user reward set during the last update uint256 index; /// @notice Amount of accrued rewards that the user earned at the time of his last index update (pending to claim) uint256 accrued; } struct SignatureParams { uint8 v; bytes32 r; bytes32 s; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; import {IUmbrellaStkManager} from './IUmbrellaStkManager.sol'; interface IUmbrella is IUmbrellaStkManager { /** * @notice Event is emitted whenever the `deficitOffset` is covered on some amount. * @param reserve Reserve which `deficitOffset` is covered * @param amount Amount of covered `deficitOffset` */ event DeficitOffsetCovered(address indexed reserve, uint256 amount); /** * @notice Event is emitted whenever the `pendingDeficit` is covered on some amount. * @param reserve Reserve which `pendingDeficit` is covered * @param amount Amount of covered `pendingDeficit` */ event PendingDeficitCovered(address indexed reserve, uint256 amount); /** * @notice Event is emitted whenever the deficit for untuned inside `Umbrella` reserve is covered on some amount. * @param reserve Reserve which `reserve.deficit` is covered * @param amount Amount of covered `reserve.deficit` */ event ReserveDeficitCovered(address indexed reserve, uint256 amount); /** * @notice Event is emitted when funds are slashed from a `umbrellaStake` to cover a reserve deficit. * @param reserve Reserve address for which funds are slashed * @param umbrellaStake Address of the `UmbrellaStakeToken` from which funds are transferred * @param amount Amount of funds slashed for future deficit elimination * @param fee Additional fee amount slashed on top of the amount */ event StakeTokenSlashed( address indexed reserve, address indexed umbrellaStake, uint256 amount, uint256 fee ); /** * @dev Attempted to change `deficitOffset` for a reserve that does not have a slashing configuration. */ error ReserveCoverageNotSetup(); /** * @dev Attempted to set `deficitOffset` less than possible to avoid immediate slashing. */ error TooMuchDeficitOffsetReduction(); /** * @dev Attempted to cover zero deficit. */ error ZeroDeficitToCover(); /** * @dev Attempted to slash for reserve with zero new deficit or without `SlashingConfig` setup. */ error CannotSlash(); /** * @dev Attempted to slash a basket of `StakeToken`s. Unreachable error in the current version. */ error NotImplemented(); /** * @dev Attempted to call `coverReserveDeficit()` of reserve, which has some configuration. * In this case functions `coverPendingDeficit` or `coverDeficitOffset` should be used instead. */ error ReserveIsConfigured(); // DEFAULT_ADMIN_ROLE ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Sets a new `deficitOffset` value for this `reserve`. * @dev `deficitOffset` can be increased arbitrarily by a value exceeding `poolDeficit - pendingDeficit`. * It can also be decreased, but not less than the same value `poolDeficit - pendingDeficit`. * `deficitOffset` can only be changed for reserves that have at least 1 `SlashingConfig` setup. * @param reserve Reserve address * @param newDeficitOffset New amount of `deficitOffset` to set for this reserve */ function setDeficitOffset(address reserve, uint256 newDeficitOffset) external; // COVERAGE_MANAGER_ROLE ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Pulls funds to resolve `pendingDeficit` **up to** specified amount. * @dev If the amount exceeds the existing `pendingDeficit`, only the `pendingDeficit` will be eliminated. * @param reserve Reserve address * @param amount Amount of `aToken`s (or reserve) to be eliminated * @return The amount of `pendingDeficit` eliminated */ function coverPendingDeficit(address reserve, uint256 amount) external returns (uint256); /** * @notice Pulls funds to resolve `deficitOffset` **up to** specified amount. * @dev If the amount exceeds the existing `deficitOffset`, only the `deficitOffset` will be eliminated. * @param reserve Reserve address * @param amount Amount of `aToken`s (or reserve) to be eliminated * @return The amount of `deficitOffset` eliminated */ function coverDeficitOffset(address reserve, uint256 amount) external returns (uint256); /** * @notice Pulls funds to resolve `reserve.deficit` **up to** specified amount. * @dev If the amount exceeds the existing `reserve.deficit`, only the `reserve.deficit` will be eliminated. * Can only be called if this reserve is not configured within `Umbrella`. * (If the reserve has uncovered `deficitOffset`, `pendingDeficit` or at least one `SlashingConfig` is set, then the function will revert. * In this case, to call this function you must first cover `pendingDeficit` and `deficitOffset`, along with removing all `SlashingConfig`s * or use `coverPendingDeficit/coverDeficitOffset` instead.) * @param reserve Reserve address * @param amount Amount of `aToken`s (or reserve) to be eliminated * @return The amount of `reserve.deficit` eliminated */ function coverReserveDeficit(address reserve, uint256 amount) external returns (uint256); ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Performs a slashing to cover **up to** the `Pool.getReserveDeficit(reserve) - (pendingDeficit + deficitOffset)`. * @param reserve Reserve address * @return New added and covered deficit */ function slash(address reserve) external returns (uint256); /** * @notice Returns an address of token, which should be used to cover reserve deficit. * @param reserve Reserve address * @return Address of token to use for deficit coverage */ function tokenForDeficitCoverage(address reserve) external view returns (address); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; import {IPool} from 'aave-v3-origin/contracts/interfaces/IPool.sol'; import {IPoolAddressesProvider} from 'aave-v3-origin/contracts/interfaces/IPoolAddressesProvider.sol'; interface IUmbrellaConfiguration { struct SlashingConfigUpdate { /// @notice Reserve which configuration should be updated address reserve; /// @notice Address of `UmbrellaStakeToken` that should be set for this reserve address umbrellaStake; /// @notice Percentage of funds slashed on top of the new deficit uint256 liquidationFee; /// @notice Oracle of `UmbrellaStakeToken`s underlying address umbrellaStakeUnderlyingOracle; } struct SlashingConfigRemoval { /// @notice Reserve which configuration is being removed address reserve; /// @notice Address of `UmbrellaStakeToken` that will be removed from this reserve address umbrellaStake; } struct SlashingConfig { /// @notice Address of `UmbrellaStakeToken` address umbrellaStake; /// @notice `UmbrellaStakeToken` underlying oracle address address umbrellaStakeUnderlyingOracle; /// @notice Percentage of funds slashed on top of the new deficit uint256 liquidationFee; } struct StakeTokenData { /// @notice Oracle for pricing an underlying assets of `UmbrellaStakeToken` /// @dev Remains after removal of `SlashingConfig` address underlyingOracle; /// @notice Reserve address for which this `UmbrellaStakeToken` is configured /// @dev Will be deleted after removal of `SlashingConfig` address reserve; } /** * @notice Event is emitted whenever a configuration is added or updated. * @param reserve Reserve which configuration is changed * @param umbrellaStake Address of `UmbrellaStakeToken` * @param liquidationFee Percentage of funds slashed on top of the deficit * @param umbrellaStakeUnderlyingOracle `UmbrellaStakeToken` underlying oracle address */ event SlashingConfigurationChanged( address indexed reserve, address indexed umbrellaStake, uint256 liquidationFee, address umbrellaStakeUnderlyingOracle ); /** * @notice Event is emitted whenever a configuration is removed. * @param reserve Reserve which configuration is removed * @param umbrellaStake Address of `UmbrellaStakeToken` */ event SlashingConfigurationRemoved(address indexed reserve, address indexed umbrellaStake); /** * @notice Event is emitted whenever the `deficitOffset` is changed. * @param reserve Reserve which `deficitOffset` is changed * @param newDeficitOffset New amount of `deficitOffset` */ event DeficitOffsetChanged(address indexed reserve, uint256 newDeficitOffset); /** * @notice Event is emitted whenever the `pendingDeficit` is changed. * @param reserve Reserve which `pendingDeficit` is changed * @param newPendingDeficit New amount of `pendingDeficit` */ event PendingDeficitChanged(address indexed reserve, uint256 newPendingDeficit); /** * @dev Attempted to set zero address. */ error ZeroAddress(); /** * @dev Attempted to interact with a `UmbrellaStakeToken` that should be deployed by this `Umbrella` instance, but is not. */ error InvalidStakeToken(); /** * @dev Attempted to set a `UmbrellaStakeToken` that has a different number of decimals than `reserve`. */ error InvalidNumberOfDecimals(); /** * @dev Attempted to set `liquidationFee` greater than 100%. */ error InvalidLiquidationFee(); /** * @dev Attempted to get `SlashingConfig` for this `reserve` and `StakeToken`, however config doesn't exist for this pair. */ error ConfigurationNotExist(); /** * @dev Attempted to get price of `StakeToken` underlying, however the oracle has never been set. */ error ConfigurationHasNotBeenSet(); /** * @dev Attempted to set `UmbrellaStakeToken`, which is already set for another reserve. */ error UmbrellaStakeAlreadySetForAnotherReserve(); /** * @dev Attempted to add `reserve` to configuration, which isn't exist in the `Pool`. */ error InvalidReserve(); /** * @dev Attempted to set `umbrellaStakeUnderlyingOracle` that returns invalid price. */ error InvalidOraclePrice(); // DEFAULT_ADMIN_ROLE ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Updates a set of slashing configurations. * @dev If the configs contain an already existing configuration, the configuration will be overwritten. * If install more than 1 configuration, then `slash` will not work in the current version. * @param slashingConfigs An array of configurations */ function updateSlashingConfigs(SlashingConfigUpdate[] calldata slashingConfigs) external; /** * @notice Removes a set of slashing configurations. * @dev If such a config did not exist, the function does not revert. * @param removalPairs An array of coverage pairs (reserve:stk) to remove */ function removeSlashingConfigs(SlashingConfigRemoval[] calldata removalPairs) external; ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Returns all the slashing configurations, configured for a given `reserve`. * @param reserve Address of the `reserve` * @return An array of `SlashingConfig` structs */ function getReserveSlashingConfigs(address reserve) external returns (SlashingConfig[] memory); /** * @notice Returns the slashing configuration for a given `UmbrellaStakeToken` in regards to a specific `reserve`. * @dev Reverts if `SlashingConfig` doesn't exist. * @param reserve Address of the `reserve` * @param umbrellaStake Address of the `UmbrellaStakeToken` * @return A `SlashingConfig` struct */ function getReserveSlashingConfig( address reserve, address umbrellaStake ) external returns (SlashingConfig memory); /** * @notice Returns if a reserve is currently slashable or not. * A reserve is slashable if: * - there's only one stk configured for slashing * - if there is a non zero new deficit * @param reserve Address of the `reserve` * @return flag If `Umbrella` could slash for a given `reserve` * @return amount Amount of the new deficit, by which `UmbrellaStakeToken` potentially could be slashed */ function isReserveSlashable(address reserve) external view returns (bool flag, uint256 amount); /** * @notice Returns the amount of deficit that can't be slashed using `UmbrellaStakeToken` funds. * @param reserve Address of the `reserve` * @return The amount of the `deficitOffset` */ function getDeficitOffset(address reserve) external returns (uint256); /** * @notice Returns the amount of already slashed funds that have not yet been used for the deficit elimination. * @param reserve Address of the `reserve` * @return The amount of funds pending for deficit elimination */ function getPendingDeficit(address reserve) external returns (uint256); /** * @notice Returns the `StakeTokenData` of the `umbrellaStake`. * @param umbrellaStake Address of the `UmbrellaStakeToken` * @return stakeTokenData A `StakeTokenData` struct */ function getStakeTokenData( address umbrellaStake ) external view returns (StakeTokenData memory stakeTokenData); /** * @notice Returns the price of the `UmbrellaStakeToken` underlying. * @dev This price is used for calculations inside `Umbrella` and should not be used outside of this system. * * The underlying price is determined based on the current oracle, if the oracle has never been set, the function will revert. * The system retains information about the last oracle installed for a given `StakeToken`. * * If the `SlashingConfig` associated with the `StakeToken` is removed, this function will still be operational. * However, the results of its work are not guaranteed. * * @param umbrellaStake Address of the `UmbrellaStakeToken` * @return latestAnswer Price of the underlying */ function latestUnderlyingAnswer( address umbrellaStake ) external view returns (int256 latestAnswer); /** * @notice Returns the Pool addresses provider. * @return Pool addresses provider address */ function POOL_ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Returns the address that is receiving the slashed funds. * @return Slashed funds recipient */ function SLASHED_FUNDS_RECIPIENT() external view returns (address); /** * @notice Returns the Aave Pool for which this `Umbrella` instance is configured. * @return Pool address */ function POOL() external view returns (IPool); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol'; import {IUmbrellaConfiguration} from './IUmbrellaConfiguration.sol'; interface IUmbrellaStkManager is IUmbrellaConfiguration { struct StakeTokenSetup { /// @notice Address of the underlying token for which the `UmbrellaStakeToken` will be created address underlying; /// @notice Cooldown duration of the `UmbrellaStakeToken` uint256 cooldown; /// @notice Time period during which funds can be withdrawn from the `UmbrellaStakeToken` uint256 unstakeWindow; /// @notice Suffix to be added in the end to name and symbol (optional, can be empty) string suffix; } struct CooldownConfig { /// @notice `UmbrellaStakeToken` address address umbrellaStake; /// @notice Amount of seconds users have to wait between triggering the `cooldown()` and being able to withdraw funds uint256 newCooldown; } struct UnstakeWindowConfig { /// @notice `UmbrellaStakeToken` address address umbrellaStake; /// @notice Amount of seconds users have to withdraw after `cooldown` uint256 newUnstakeWindow; } /** * @notice Event is emitted when a new `UmbrellaStakeToken` is created. * @param umbrellaStake Address of the new `UmbrellaStakeToken` * @param underlying Address of the underlying token it is created for * @param name Name of the new `UmbrellaStakeToken` * @param symbol Symbol of the new `UmbrellaStakeToken` */ event UmbrellaStakeTokenCreated( address indexed umbrellaStake, address indexed underlying, string name, string symbol ); // DEFAULT_ADMIN_ROLE ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Creates new `UmbrlleaStakeToken`s. * @param stakeTokenSetups Array of `UmbrellaStakeToken`s setup configs * @return stakeTokens Array of new `UmbrellaStakeToken`s addresses */ function createStakeTokens( StakeTokenSetup[] calldata stakeTokenSetups ) external returns (address[] memory stakeTokens); /** * @notice Sets a new `cooldown`s (in seconds) for the specified `UmbrellaStakeToken`s. * @param cooldownConfigs Array of new `cooldown` configs */ function setCooldownStk(CooldownConfig[] calldata cooldownConfigs) external; /** * @notice Sets a new `unstakeWindow`s (in seconds) for the specified `UmbrellaStakeToken`s. * @param unstakeWindowConfigs Array of new `unstakeWindow` configs */ function setUnstakeWindowStk(UnstakeWindowConfig[] calldata unstakeWindowConfigs) external; // RESCUE_GUARDIAN_ROLE ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Rescue tokens sent erroneously to the contract. * @param stk Address of the `UmbrellaStakeToken` to rescue from * @param erc20Token Address of the token to rescue * @param to Address of the tokens receiver * @param amount Amount of tokens to rescue */ function emergencyTokenTransferStk( address stk, address erc20Token, address to, uint256 amount ) external; /** * @notice Rescue native currency (e.g. Ethereum) sent erroneously to the contract. * @param stk Address of the `UmbrellaStakeToken` to rescue from * @param to Address of the tokens receiver * @param amount Amount of tokens to rescue */ function emergencyEtherTransferStk(address stk, address to, uint256 amount) external; // PAUSE_GUARDIAN_ROLE ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Pauses `UmbrellaStakeToken`. * @param stk Address of the `UmbrellaStakeToken` to turn pause on */ function pauseStk(address stk) external; /** * @notice Unpauses `UmbrellaStakeToken`. * @param stk Address of the `UmbrellaStakeToken` to turn pause off */ function unpauseStk(address stk) external; ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Predicts new `UmbrellaStakeToken`s addresses. * @dev Should be used only to predict new `UmbrellaStakeToken` addresses and not to calculate already deployed ones. * @param stakeSetups Array of `UmbrellaStakeToken`s setup configs * @return stakeTokens Array of new `UmbrellaStakeToken`s predicted addresses */ function predictStakeTokensAddresses( StakeTokenSetup[] calldata stakeSetups ) external view returns (address[] memory); /** * @notice Returns a list of all the `UmbrellaStakeToken`s created via this `Umbrella` instance. * @return Array of addresses containing all the `UmbrellaStakeToken`s */ function getStkTokens() external view returns (address[] memory); /** * @notice Returns true if the provided address is a `UmbrellaStakeToken` belonging to this `Umbrella` instance. * @return True if the token is part of this `Umbrella`, false otherwise */ function isUmbrellaStkToken(address stakeToken) external view returns (bool); /** * @notice Returns the `TransparentProxyFactory` contract used to create `UmbrellaStakeToken`s. * @return `TransparentProxyFactory` address */ function TRANSPARENT_PROXY_FACTORY() external view returns (ITransparentProxyFactory); /** * @notice Returns the `UmbrellaStakeToken` implementation used to instantiate new umbrella stake tokens. * @return `UmbrellaStakeToken` implementation address */ function UMBRELLA_STAKE_TOKEN_IMPL() external view returns (address); /** * @notice Returns the `SUPER_ADMIN` address, which has `DEFAULT_ADMIN_ROLE` and is used to manage `UmbrellaStakeToken`s upgreadability. * @return `SUPER_ADMIN` address */ function SUPER_ADMIN() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol'; import {IPool, IPoolAddressesProvider} from '../../../interfaces/IPool.sol'; interface IStataTokenFactory { error NotListedUnderlying(address underlying); /** * @notice The pool associated with the factory. * @return The pool address. */ function POOL() external view returns (IPool); /** * @notice The proxy admin used for all tokens created via the factory. * @return The proxy admin address. */ function PROXY_ADMIN() external view returns (address); /** * @notice The proxy factory used for all tokens created via the stata factory. * @return The proxy factory address. */ function TRANSPARENT_PROXY_FACTORY() external view returns (ITransparentProxyFactory); /** * @notice The stata implementation used for all tokens created via the factory. * @return The implementation address. */ function STATA_TOKEN_IMPL() external view returns (address); /** * @notice Creates new StataTokens * @param underlyings the addresses of the underlyings to create. * @return address[] addresses of the new StataTokens. */ function createStataTokens(address[] memory underlyings) external returns (address[] memory); /** * @notice Returns all StataTokens deployed via this registry. * @return address[] list of StataTokens */ function getStataTokens() external view returns (address[] memory); /** * @notice Returns the StataToken for a given underlying. * @param underlying the address of the underlying. * @return address the StataToken address. */ function getStataToken(address underlying) external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC4626StataToken} from './IERC4626StataToken.sol'; import {IERC20AaveLM} from './IERC20AaveLM.sol'; import {IERC4626} from '@openzeppelin/contracts/interfaces/IERC4626.sol'; import {IERC20Permit} from '@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol'; interface IStataTokenV2 is IERC4626, IERC20Permit, IERC4626StataToken, IERC20AaveLM { /** * @notice Checks if the passed actor is permissioned emergency admin. * @param actor The reward to claim * @return bool signaling if actor can pause the vault. */ function canPause(address actor) external view returns (bool); /** * @notice Pauses/unpauses all system's operations * @param paused boolean determining if the token should be paused or unpaused */ function setPaused(bool paused) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; import {IScaledBalanceToken} from './IScaledBalanceToken.sol'; import {IInitializableAToken} from './IInitializableAToken.sol'; /** * @title IAToken * @author Aave * @notice Defines the basic interface for an AToken. */ interface IAToken is IERC20, IScaledBalanceToken, IInitializableAToken { /** * @dev Emitted during the transfer action * @param from The user whose tokens are being transferred * @param to The recipient * @param value The scaled amount being transferred * @param index The next liquidity index of the reserve */ event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index); /** * @notice Mints `amount` aTokens to `user` * @param caller The address performing the mint * @param onBehalfOf The address of the user that will receive the minted aTokens * @param amount The amount of tokens getting minted * @param index The next liquidity index of the reserve * @return `true` if the the previous balance of the user was 0 */ function mint( address caller, address onBehalfOf, uint256 amount, uint256 index ) external returns (bool); /** * @notice Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying` * @dev In some instances, the mint event could be emitted from a burn transaction * if the amount to burn is less than the interest that the user accrued * @param from The address from which the aTokens will be burned * @param receiverOfUnderlying The address that will receive the underlying * @param amount The amount being burned * @param index The next liquidity index of the reserve */ function burn(address from, address receiverOfUnderlying, uint256 amount, uint256 index) external; /** * @notice Mints aTokens to the reserve treasury * @param amount The amount of tokens getting minted * @param index The next liquidity index of the reserve */ function mintToTreasury(uint256 amount, uint256 index) external; /** * @notice 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; /** * @notice Transfers the underlying asset to `target`. * @dev Used by the Pool to transfer assets in borrow(), withdraw() and flashLoan() * @param target The recipient of the underlying * @param amount The amount getting transferred */ function transferUnderlyingTo(address target, uint256 amount) external; /** * @notice Handles the underlying received by the aToken after the transfer has been completed. * @dev The default implementation is empty as with standard ERC20 tokens, nothing needs to be done after the * transfer is concluded. However in the future there may be aTokens that allow for example to stake the underlying * to receive LM rewards. In that case, `handleRepayment()` would perform the staking of the underlying asset. * @param user The user executing the repayment * @param onBehalfOf The address of the user who will get his debt reduced/removed * @param amount The amount getting repaid */ function handleRepayment(address user, address onBehalfOf, uint256 amount) external; /** * @notice Allow passing a signed message to approve spending * @dev implements the permit function as for * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md * @param owner The owner of the funds * @param spender The spender * @param value The amount * @param deadline The deadline timestamp, type(uint256).max for max deadline * @param v Signature param * @param s Signature param * @param r Signature param */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @notice Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH) * @return The address of the underlying asset */ function UNDERLYING_ASSET_ADDRESS() external view returns (address); /** * @notice Returns the address of the Aave treasury, receiving the fees on this aToken. * @return Address of the Aave treasury */ function RESERVE_TREASURY_ADDRESS() external view returns (address); /** * @notice Get the domain separator for the token * @dev Return cached value if chainId matches cache, otherwise recomputes separator * @return The domain separator of the token at current chain */ function DOMAIN_SEPARATOR() external view returns (bytes32); /** * @notice Returns the nonce for owner. * @param owner The address of the owner * @return The nonce of the owner */ function nonces(address owner) external view returns (uint256); /** * @notice Rescue and transfer tokens locked in this contract * @param token The address of the token * @param to The address of the recipient * @param amount The amount of token to transfer */ function rescueTokens(address token, address to, uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPriceOracleGetter} from './IPriceOracleGetter.sol'; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; /** * @title IAaveOracle * @author Aave * @notice Defines the basic interface for the Aave Oracle */ interface IAaveOracle is IPriceOracleGetter { /** * @dev Emitted after the base currency is set * @param baseCurrency The base currency of used for price quotes * @param baseCurrencyUnit The unit of the base currency */ event BaseCurrencySet(address indexed baseCurrency, uint256 baseCurrencyUnit); /** * @dev Emitted after the price source of an asset is updated * @param asset The address of the asset * @param source The price source of the asset */ event AssetSourceUpdated(address indexed asset, address indexed source); /** * @dev Emitted after the address of fallback oracle is updated * @param fallbackOracle The address of the fallback oracle */ event FallbackOracleUpdated(address indexed fallbackOracle); /** * @notice Returns the PoolAddressesProvider * @return The address of the PoolAddressesProvider contract */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Sets or replaces price sources of assets * @param assets The addresses of the assets * @param sources The addresses of the price sources */ function setAssetSources(address[] calldata assets, address[] calldata sources) external; /** * @notice Sets the fallback oracle * @param fallbackOracle The address of the fallback oracle */ function setFallbackOracle(address fallbackOracle) external; /** * @notice Returns a list of prices from a list of assets addresses * @param assets The list of assets addresses * @return The prices of the given assets */ function getAssetsPrices(address[] calldata assets) external view returns (uint256[] memory); /** * @notice Returns the address of the source for an asset address * @param asset The address of the asset * @return The address of the source */ function getSourceOfAsset(address asset) external view returns (address); /** * @notice Returns the address of the fallback oracle * @return The address of the fallback oracle */ function getFallbackOracle() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @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); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC-20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library ApyCalculator { uint256 internal constant SECONDS_PER_YEAR = 365 days; uint256 internal constant APY_PRECISION = 10_000; function calculateApy( uint256 currentEmissionsPerSecondScaled, // in 18 decimals uint256 stakedTokenTotalAssets, uint256 stakeTokenPrice, uint256 stakeTokenDecimals, uint256 rewardTokenPrice ) internal pure returns (uint256) { if (stakedTokenTotalAssets == 0 || stakeTokenPrice == 0 || rewardTokenPrice == 0) { return 0; } uint256 totalAssetsScaled = stakedTokenTotalAssets * (10 ** (18 - stakeTokenDecimals)); uint256 totalAssetsScaledUsd = totalAssetsScaled * stakeTokenPrice; uint256 yearlyRewards = currentEmissionsPerSecondScaled * SECONDS_PER_YEAR; uint256 yearlyRewardsUsd = yearlyRewards * rewardTokenPrice; return (yearlyRewardsUsd * APY_PRECISION) / totalAssetsScaledUsd; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {IERC20Permit} from 'openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol'; import {IERC4626StakeToken} from './IERC4626StakeToken.sol'; interface IStakeToken is IERC4626StakeToken, IERC20Permit {}
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; interface IOracleToken { /** * @notice Returns the current asset price of the `UmbrellaStakeToken`. * @dev The price is calculated as `underlyingPrice * exchangeRate`. * * This function is not functional immediately after the creation of an `UmbrellaStakeToken`, * but after the creation of a `SlashingConfig` for this token within `Umbrella`. * The function will remain operational even after the removal of `SlashingConfig`, * as the `Umbrella` contract retains information about the last installed oracle. * * The function may result in a revert if the asset to shares exchange rate leads to overflow. * * This function is intended solely for off-chain calculations and is not a critical component of `Umbrella`. * It should not be relied upon by other systems as a primary source of price information. * * @return Current asset price */ function latestAnswer() external view returns (int256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {IRewardsStructs} from './IRewardsStructs.sol'; interface IRewardsDistributor is IRewardsStructs { /** * @notice Event is emitted when a `user` or admin installs/disables `claimer` for claiming user rewards. * @param user Address of the `user` * @param claimer Address of the `claimer` to install/disable * @param caller Address of the `msg.sender` who changes claimer * @param flag Flag responsible for setting/disabling `claimer` */ event ClaimerSet( address indexed user, address indexed claimer, address indexed caller, bool flag ); /** * @dev Attempted to use signature with expired deadline. */ error ExpiredSignature(uint256 deadline); /** * @dev Mismatched signature. */ error InvalidSigner(address signer, address owner); /** * @dev Attempted to claim `reward` without authorization. */ error ClaimerNotAuthorized(address claimer, address user); /** * @dev Attempted to claim rewards for assets while arrays lengths don't match. */ error LengthsDontMatch(); /** * @dev Attempted to set zero address. */ error ZeroAddress(); // DEFAULT_ADMIN_ROLE ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Installs/disables `claimer` for claiming `user` rewards. * @param user Address of the `user` * @param claimer Address of the `claimer` to install/disable * @param flag Flag responsible for setting/disabling `claimer` */ function setClaimer(address user, address claimer, bool flag) external; ///////////////////////////////////////////////////////////////////////////////////////// /** * @notice Installs/disables `claimer` for claiming `msg.sender` rewards. * @param claimer Address of the `claimer` to install/disable * @param flag Flag responsible for setting/disabling `claimer` */ function setClaimer(address claimer, bool flag) external; /** * @notice Claims all existing `rewards` for a certain `asset` on behalf of `msg.sender`. * Makes an update and calculates new `index` and `accrued` `rewards` before claim. * @dev Always claims all `rewards`. * @param asset Address of the `asset` whose `rewards` should be claimed * @param receiver Address of the funds receiver * @return rewards Array containing the addresses of all `reward` tokens claimed * @return amounts Array containing the corresponding `amounts` of each `reward` claimed */ function claimAllRewards( address asset, address receiver ) external returns (address[] memory rewards, uint256[] memory amounts); /** * @notice Claims all existing `rewards` on behalf of `user` for a certain `asset` by `msg.sender`. * Makes an update and calculates new `index` and `accrued` `rewards` before claim. * @dev Always claims all `rewards`. * @param asset Address of the `asset` whose `rewards` should be claimed * @param user Address of user, which accrued `rewards` should be claimed * @param receiver Address of the funds receiver * @return rewards Array containing the addresses of all `reward` tokens claimed * @return amounts Array containing the corresponding `amounts` of each `reward` claimed */ function claimAllRewardsOnBehalf( address asset, address user, address receiver ) external returns (address[] memory rewards, uint256[] memory amounts); /** * @notice Claims all existing `rewards` on behalf of `user` for a certain `asset` using signature. * Makes an update and calculates new `index` and `accrued` `rewards` before claim. * @dev Always claims all `rewards`. * @param asset Address of the `asset` whose `rewards` should be claimed * @param user Address of user, which accrued `rewards` should be claimed * @param receiver Address of the funds receiver * @param deadline Signature deadline for claiming * @param sig Signature parameters * @return rewards Array containing the addresses of all `reward` tokens claimed * @return amounts Array containing the corresponding `amounts` of each `reward` claimed */ function claimAllRewardsPermit( address asset, address user, address receiver, uint256 deadline, SignatureParams calldata sig ) external returns (address[] memory rewards, uint256[] memory amounts); /** * @notice Claims selected `rewards` of `msg.sender` for a certain `asset`. * Makes an update and calculates new `index` and `accrued` `rewards` before claim. * @param asset Address of the `asset` whose `rewards` should be claimed * @param rewards Array of `reward` addresses, which should be claimed * @param receiver Address of the funds receiver * @return amounts Array containing the corresponding `amounts` of each `reward` claimed */ function claimSelectedRewards( address asset, address[] calldata rewards, address receiver ) external returns (uint256[] memory amounts); /** * @notice Claims selected `rewards` on behalf of `user` for a certain `asset` by `msg.sender`. * Makes an update and calculates new `index` and `accrued` `rewards` before claim. * @param asset Address of the `asset` whose `rewards` should be claimed * @param rewards Array of `reward` addresses, which should be claimed * @param user Address of user, which accrued `rewards` should be claimed * @param receiver Address of the funds receiver * @return amounts Array containing the corresponding `amounts` of each `reward` claimed */ function claimSelectedRewardsOnBehalf( address asset, address[] calldata rewards, address user, address receiver ) external returns (uint256[] memory amounts); /** * @notice Claims selected `rewards` on behalf of `user` for a certain `asset` using signature. * Makes an update and calculates new `index` and `accrued` `rewards` before claim. * @param asset Address of the `asset` whose `rewards` should be claimed * @param rewards Array of `reward` addresses, which should be claimed * @param user Address of user, which accrued `rewards` should be claimed * @param receiver Address of the funds receiver * @param deadline Signature deadline for claiming * @param sig Signature parameters * @return amounts Array containing the corresponding `amounts` of each `reward` claimed */ function claimSelectedRewardsPermit( address asset, address[] calldata rewards, address user, address receiver, uint256 deadline, SignatureParams calldata sig ) external returns (uint256[] memory amounts); /** * @notice Claims all existing `rewards` of `msg.sender` across multiple `assets`. * Makes an update and calculates new `index` and `accrued` `rewards` before claim. * @dev Always claims all `rewards`. * @param assets Array of addresses representing the `assets`, whose `rewards` should be claimed * @param receiver Address of the funds receiver * @return rewards Two-dimensional array where each inner array contains the addresses of `reward` tokens for a specific `asset` * @return amounts Two-dimensional array where each inner array contains the amounts of each `reward` claimed for a specific `asset` */ function claimAllRewards( address[] calldata assets, address receiver ) external returns (address[][] memory rewards, uint256[][] memory amounts); /** * @notice Claims all existing `rewards` on behalf of `user` across multiple `assets` by `msg.sender`. * Makes an update and calculates new `index` and `accrued` `rewards` before claim. * @dev Always claims all `rewards`. * @param assets Array of addresses representing the `assets`, whose `rewards` should be claimed * @param user Address of user, which accrued `rewards` should be claimed * @param receiver Address of the funds receiver * @return rewards Two-dimensional array where each inner array contains the addresses of `reward` tokens for a specific `asset` * @return amounts Two-dimensional array where each inner array contains the amounts of each `reward` claimed for a specific `asset` */ function claimAllRewardsOnBehalf( address[] calldata assets, address user, address receiver ) external returns (address[][] memory rewards, uint256[][] memory amounts); /** * @notice Claims selected `rewards` of `msg.sender` across multiple `assets`. * Makes an update and calculates new `index` and `accrued` `rewards` before claim. * @param assets Array of addresses representing the `assets`, whose `rewards` should be claimed * @param rewards Two-dimensional array where each inner array contains the addresses of `rewards` for a specific `asset` * @param receiver Address of the funds receiver * @return amounts Two-dimensional array where each inner array contains the amounts of each `reward` claimed for a specific `asset` */ function claimSelectedRewards( address[] calldata assets, address[][] calldata rewards, address receiver ) external returns (uint256[][] memory); /** * @notice Claims selected `rewards` on behalf of `user` across multiple `assets` by `msg.sender`. * Makes an update and calculates new `index` and `accrued` `rewards` before claim. * @param assets Array of addresses representing the `assets`, whose `rewards` should be claimed * @param rewards Two-dimensional array where each inner array contains the addresses of `rewards` for a specific `asset` * @param user Address of user, which accrued `rewards` should be claimed * @param receiver Address of the funds receiver * @return amounts Two-dimensional array where each inner array contains the amounts of each `reward` claimed for a specific `asset` */ function claimSelectedRewardsOnBehalf( address[] calldata assets, address[][] calldata rewards, address user, address receiver ) external returns (uint256[][] memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title IPool * @author Aave * @notice Defines the basic interface for an Aave Pool. */ interface IPool { /** * @dev Emitted on mintUnbacked() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens * @param amount The amount of supplied assets * @param referralCode The referral code used */ event MintUnbacked( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on backUnbacked() * @param reserve The address of the underlying asset of the reserve * @param backer The address paying for the backing * @param amount The amount added as backing * @param fee The amount paid in fees */ event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee); /** * @dev Emitted on supply() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supply, receiving the aTokens * @param amount The amount supplied * @param referralCode The referral code used */ event Supply( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on withdraw() * @param reserve The address of the underlying asset being withdrawn * @param user The address initiating the withdrawal, owner of aTokens * @param to The 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 interestRateMode The rate mode: 2 for Variable, 1 is deprecated (changed on v3.2.0) * @param borrowRate The numeric rate at which the user has borrowed, expressed in ray * @param referralCode The referral code used */ event Borrow( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 borrowRate, uint16 indexed referralCode ); /** * @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 * @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly */ event Repay( address indexed reserve, address indexed user, address indexed repayer, uint256 amount, bool useATokens ); /** * @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets * @param asset The address of the underlying asset of the reserve * @param totalDebt The total isolation mode debt for the reserve */ event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); /** * @dev Emitted when the user selects a certain asset category for eMode * @param user The address of the user * @param categoryId The category id */ event UserEModeSet(address indexed user, uint8 categoryId); /** * @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 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 interestRateMode The flashloan mode: 0 for regular flashloan, * 1 for Stable (Deprecated on v3.2.0), 2 for Variable * @param premium The fee flash borrowed * @param referralCode The referral code used */ event FlashLoan( address indexed target, address initiator, address indexed asset, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 premium, uint16 indexed referralCode ); /** * @dev Emitted when a borrower is liquidated. * @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 liquidator * @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. * @param reserve The address of the underlying asset of the reserve * @param liquidityRate The next liquidity rate * @param stableBorrowRate The next stable borrow rate @note deprecated on v3.2.0 * @param variableBorrowRate The next variable borrow rate * @param liquidityIndex The next liquidity index * @param variableBorrowIndex The next variable borrow index */ event ReserveDataUpdated( address indexed reserve, uint256 liquidityRate, uint256 stableBorrowRate, uint256 variableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex ); /** * @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest. * @param reserve The address of the reserve * @param amountMinted The amount minted to the treasury */ event MintedToTreasury(address indexed reserve, uint256 amountMinted); /** * @notice Mints an `amount` of aTokens to the `onBehalfOf` * @param asset The address of the underlying asset to mint * @param amount The amount to mint * @param onBehalfOf The address that will receive the aTokens * @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 mintUnbacked( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; /** * @notice Back the current unbacked underlying with `amount` and pay `fee`. * @param asset The address of the underlying asset to back * @param amount The amount to back * @param fee The amount paid in fees * @return The backed amount */ function backUnbacked(address asset, uint256 amount, uint256 fee) external returns (uint256); /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @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 supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; /** * @notice Supply with transfer approval of asset to be supplied done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @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 deadline The deadline timestamp that the permit is valid * @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 permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig */ function supplyWithPermit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external; /** * @notice 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 The 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); /** * @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower * already supplied enough collateral, or he was given enough allowance by a credit delegator on the VariableDebtToken * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet * and 100 variable debt tokens * @param asset The address of the underlying asset to borrow * @param amount The amount to be borrowed * @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0 * @param referralCode The 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 The 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 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 interestRateMode 2 for Variable, 1 is deprecated on v3.2.0 * @param onBehalfOf The 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 interestRateMode, address onBehalfOf ) external returns (uint256); /** * @notice Repay with transfer approval of asset to be repaid done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @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 interestRateMode 2 for Variable, 1 is deprecated on v3.2.0 * @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 * @param deadline The deadline timestamp that the permit is valid * @param permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig * @return The final amount repaid */ function repayWithPermit( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external returns (uint256); /** * @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the * equivalent debt tokens * - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable debt tokens * @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken * balance is not enough to cover the whole debt * @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 interestRateMode DEPRECATED in v3.2.0 * @return The final amount repaid */ function repayWithATokens( address asset, uint256 amount, uint256 interestRateMode ) external returns (uint256); /** * @notice Allows suppliers to enable/disable a specific supplied asset as collateral * @param asset The address of the underlying asset supplied * @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise */ function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; /** * @notice 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; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface * @param assets The addresses of the assets being flash-borrowed * @param amounts The amounts of the assets being flash-borrowed * @param interestRateModes 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 -> Deprecated on v3.2.0 * 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 2 on `modes` * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The 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 interestRateModes, address onBehalfOf, bytes calldata params, uint16 referralCode ) external; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface * @param asset The address of the asset being flash-borrowed * @param amount The amount of the asset being flash-borrowed * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The 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 flashLoanSimple( address receiverAddress, address asset, uint256 amount, bytes calldata params, uint16 referralCode ) external; /** * @notice Returns the user account data across all the reserves * @param user The address of the user * @return totalCollateralBase The total collateral of the user in the base currency used by the price feed * @return totalDebtBase The total debt of the user in the base currency used by the price feed * @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed * @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 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); /** * @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an * interest rate strategy * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param aTokenAddress The address of the aToken that will be assigned to the reserve * @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve * @param interestRateStrategyAddress The address of the interest rate strategy contract */ function initReserve( address asset, address aTokenAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; /** * @notice Drop a reserve * @dev Only callable by the PoolConfigurator contract * @dev Does not reset eMode flags, which must be considered when reusing the same reserve id for a different reserve. * @param asset The address of the underlying asset of the reserve */ function dropReserve(address asset) external; /** * @notice Updates the address of the interest rate strategy contract * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param rateStrategyAddress The address of the interest rate strategy contract */ function setReserveInterestRateStrategyAddress( address asset, address rateStrategyAddress ) external; /** * @notice Accumulates interest to all indexes of the reserve * @dev Only callable by the PoolConfigurator contract * @dev To be used when required by the configurator, for example when updating interest rates strategy data * @param asset The address of the underlying asset of the reserve */ function syncIndexesState(address asset) external; /** * @notice Updates interest rates on the reserve data * @dev Only callable by the PoolConfigurator contract * @dev To be used when required by the configurator, for example when updating interest rates strategy data * @param asset The address of the underlying asset of the reserve */ function syncRatesState(address asset) external; /** * @notice Sets the configuration bitmap of the reserve as a whole * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param configuration The new configuration bitmap */ function setConfiguration( address asset, DataTypes.ReserveConfigurationMap calldata configuration ) external; /** * @notice 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); /** * @notice 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); /** * @notice Returns the 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); /** * @notice Returns the normalized variable debt per unit of asset * @dev WARNING: This function is intended to be used primarily by the protocol itself to get a * "dynamic" variable index based on time, current stored index and virtual rate at the current * moment (approx. a borrower would get if opening a position). This means that is always used in * combination with variable debt supply/balances. * If using this function externally, consider that is possible to have an increasing normalized * variable debt that is not equivalent to how the variable debt index would be updated in storage * (e.g. only updates with non-zero variable debt supply) * @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); /** * @notice Returns the state and configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The state and configuration data of the reserve */ function getReserveData(address asset) external view returns (DataTypes.ReserveDataLegacy memory); /** * @notice Returns the state and configuration of the reserve, including extra data included with Aave v3.1 * @dev DEPRECATED use independent getters instead (getReserveData, getLiquidationGracePeriod) * @param asset The address of the underlying asset of the reserve * @return The state and configuration data of the reserve with virtual accounting */ function getReserveDataExtended( address asset ) external view returns (DataTypes.ReserveData memory); /** * @notice Returns the virtual underlying balance of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve virtual underlying balance */ function getVirtualUnderlyingBalance(address asset) external view returns (uint128); /** * @notice Validates and finalizes an aToken transfer * @dev Only callable by the overlying aToken of the `asset` * @param asset The address of the underlying asset of the aToken * @param from The user from which the aTokens are transferred * @param to The user receiving the aTokens * @param amount The amount being transferred/withdrawn * @param balanceFromBefore The aToken balance of the `from` user before the transfer * @param balanceToBefore The aToken balance of the `to` user before the transfer */ function finalizeTransfer( address asset, address from, address to, uint256 amount, uint256 balanceFromBefore, uint256 balanceToBefore ) external; /** * @notice Returns the list of the underlying assets of all the initialized reserves * @dev It does not include dropped reserves * @return The addresses of the underlying assets of the initialized reserves */ function getReservesList() external view returns (address[] memory); /** * @notice Returns the number of initialized reserves * @dev It includes dropped reserves * @return The count */ function getReservesCount() external view returns (uint256); /** * @notice Returns the address of the underlying asset of a reserve by the reserve id as stored in the DataTypes.ReserveData struct * @param id The id of the reserve as stored in the DataTypes.ReserveData struct * @return The address of the reserve associated with id */ function getReserveAddressById(uint16 id) external view returns (address); /** * @notice Returns the PoolAddressesProvider connected to this contract * @return The address of the PoolAddressesProvider */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Updates the protocol fee on the bridging * @param bridgeProtocolFee The part of the premium sent to the protocol treasury */ function updateBridgeProtocolFee(uint256 bridgeProtocolFee) external; /** * @notice Updates flash loan premiums. Flash loan premium consists of two parts: * - A part is sent to aToken holders as extra, one time accumulated interest * - A part is collected by the protocol treasury * @dev The total premium is calculated on the total borrowed amount * @dev The premium to protocol is calculated on the total premium, being a percentage of `flashLoanPremiumTotal` * @dev Only callable by the PoolConfigurator contract * @param flashLoanPremiumTotal The total premium, expressed in bps * @param flashLoanPremiumToProtocol The part of the premium sent to the protocol treasury, expressed in bps */ function updateFlashloanPremiums( uint128 flashLoanPremiumTotal, uint128 flashLoanPremiumToProtocol ) external; /** * @notice Configures a new or alters an existing collateral configuration of an eMode. * @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category. * The category 0 is reserved as it's the default for volatile assets * @param id The id of the category * @param config The configuration of the category */ function configureEModeCategory( uint8 id, DataTypes.EModeCategoryBaseConfiguration memory config ) external; /** * @notice Replaces the current eMode collateralBitmap. * @param id The id of the category * @param collateralBitmap The collateralBitmap of the category */ function configureEModeCategoryCollateralBitmap(uint8 id, uint128 collateralBitmap) external; /** * @notice Replaces the current eMode borrowableBitmap. * @param id The id of the category * @param borrowableBitmap The borrowableBitmap of the category */ function configureEModeCategoryBorrowableBitmap(uint8 id, uint128 borrowableBitmap) external; /** * @notice Returns the data of an eMode category * @dev DEPRECATED use independent getters instead * @param id The id of the category * @return The configuration data of the category */ function getEModeCategoryData( uint8 id ) external view returns (DataTypes.EModeCategoryLegacy memory); /** * @notice Returns the label of an eMode category * @param id The id of the category * @return The label of the category */ function getEModeCategoryLabel(uint8 id) external view returns (string memory); /** * @notice Returns the collateral config of an eMode category * @param id The id of the category * @return The ltv,lt,lb of the category */ function getEModeCategoryCollateralConfig( uint8 id ) external view returns (DataTypes.CollateralConfig memory); /** * @notice Returns the collateralBitmap of an eMode category * @param id The id of the category * @return The collateralBitmap of the category */ function getEModeCategoryCollateralBitmap(uint8 id) external view returns (uint128); /** * @notice Returns the borrowableBitmap of an eMode category * @param id The id of the category * @return The borrowableBitmap of the category */ function getEModeCategoryBorrowableBitmap(uint8 id) external view returns (uint128); /** * @notice Allows a user to use the protocol in eMode * @param categoryId The id of the category */ function setUserEMode(uint8 categoryId) external; /** * @notice Returns the eMode the user is using * @param user The address of the user * @return The eMode id */ function getUserEMode(address user) external view returns (uint256); /** * @notice Resets the isolation mode total debt of the given asset to zero * @dev It requires the given asset has zero debt ceiling * @param asset The address of the underlying asset to reset the isolationModeTotalDebt */ function resetIsolationModeTotalDebt(address asset) external; /** * @notice Sets the liquidation grace period of the given asset * @dev To enable a liquidation grace period, a timestamp in the future should be set, * To disable a liquidation grace period, any timestamp in the past works, like 0 * @param asset The address of the underlying asset to set the liquidationGracePeriod * @param until Timestamp when the liquidation grace period will end **/ function setLiquidationGracePeriod(address asset, uint40 until) external; /** * @notice Returns the liquidation grace period of the given asset * @param asset The address of the underlying asset * @return Timestamp when the liquidation grace period will end **/ function getLiquidationGracePeriod(address asset) external returns (uint40); /** * @notice Returns the total fee on flash loans * @return The total fee on flashloans */ function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128); /** * @notice Returns the part of the bridge fees sent to protocol * @return The bridge fee sent to the protocol treasury */ function BRIDGE_PROTOCOL_FEE() external view returns (uint256); /** * @notice Returns the part of the flashloan fees sent to protocol * @return The flashloan fee sent to the protocol treasury */ function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128); /** * @notice Returns the maximum number of reserves supported to be listed in this Pool * @return The maximum number of reserves supported */ function MAX_NUMBER_RESERVES() external view returns (uint16); /** * @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens * @param assets The list of reserves for which the minting needs to be executed */ function mintToTreasury(address[] calldata assets) external; /** * @notice Rescue and transfer tokens locked in this contract * @param token The address of the token * @param to The address of the recipient * @param amount The amount of token to transfer */ function rescueTokens(address token, address to, uint256 amount) external; /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @dev Deprecated: Use the `supply` function instead * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @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; /** * @notice Gets the address of the external FlashLoanLogic */ function getFlashLoanLogic() external view returns (address); /** * @notice Gets the address of the external BorrowLogic */ function getBorrowLogic() external view returns (address); /** * @notice Gets the address of the external BridgeLogic */ function getBridgeLogic() external view returns (address); /** * @notice Gets the address of the external EModeLogic */ function getEModeLogic() external view returns (address); /** * @notice Gets the address of the external LiquidationLogic */ function getLiquidationLogic() external view returns (address); /** * @notice Gets the address of the external PoolLogic */ function getPoolLogic() external view returns (address); /** * @notice Gets the address of the external SupplyLogic */ function getSupplyLogic() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IPoolAddressesProvider * @author Aave * @notice Defines the basic interface for a Pool Addresses Provider. */ interface IPoolAddressesProvider { /** * @dev Emitted when the market identifier is updated. * @param oldMarketId The old id of the market * @param newMarketId The new id of the market */ event MarketIdSet(string indexed oldMarketId, string indexed newMarketId); /** * @dev Emitted when the pool is updated. * @param oldAddress The old address of the Pool * @param newAddress The new address of the Pool */ event PoolUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the pool configurator is updated. * @param oldAddress The old address of the PoolConfigurator * @param newAddress The new address of the PoolConfigurator */ event PoolConfiguratorUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the price oracle is updated. * @param oldAddress The old address of the PriceOracle * @param newAddress The new address of the PriceOracle */ event PriceOracleUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the ACL manager is updated. * @param oldAddress The old address of the ACLManager * @param newAddress The new address of the ACLManager */ event ACLManagerUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the ACL admin is updated. * @param oldAddress The old address of the ACLAdmin * @param newAddress The new address of the ACLAdmin */ event ACLAdminUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the price oracle sentinel is updated. * @param oldAddress The old address of the PriceOracleSentinel * @param newAddress The new address of the PriceOracleSentinel */ event PriceOracleSentinelUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the pool data provider is updated. * @param oldAddress The old address of the PoolDataProvider * @param newAddress The new address of the PoolDataProvider */ event PoolDataProviderUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when a new proxy is created. * @param id The identifier of the proxy * @param proxyAddress The address of the created proxy contract * @param implementationAddress The address of the implementation contract */ event ProxyCreated( bytes32 indexed id, address indexed proxyAddress, address indexed implementationAddress ); /** * @dev Emitted when a new non-proxied contract address is registered. * @param id The identifier of the contract * @param oldAddress The address of the old contract * @param newAddress The address of the new contract */ event AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the implementation of the proxy registered with id is updated * @param id The identifier of the contract * @param proxyAddress The address of the proxy contract * @param oldImplementationAddress The address of the old implementation contract * @param newImplementationAddress The address of the new implementation contract */ event AddressSetAsProxy( bytes32 indexed id, address indexed proxyAddress, address oldImplementationAddress, address indexed newImplementationAddress ); /** * @notice Returns the id of the Aave market to which this contract points to. * @return The market id */ function getMarketId() external view returns (string memory); /** * @notice Associates an id with a specific PoolAddressesProvider. * @dev This can be used to create an onchain registry of PoolAddressesProviders to * identify and validate multiple Aave markets. * @param newMarketId The market id */ function setMarketId(string calldata newMarketId) external; /** * @notice Returns an address by its identifier. * @dev The returned address might be an EOA or a contract, potentially proxied * @dev It returns ZERO if there is no registered address with the given id * @param id The id * @return The address of the registered for the specified id */ function getAddress(bytes32 id) external view returns (address); /** * @notice General function to update the implementation of a proxy registered with * certain `id`. If there is no proxy registered, it will instantiate one and * set as implementation the `newImplementationAddress`. * @dev IMPORTANT Use this function carefully, only for ids that don't have an explicit * setter function, in order to avoid unexpected consequences * @param id The id * @param newImplementationAddress The address of the new implementation */ function setAddressAsProxy(bytes32 id, address newImplementationAddress) external; /** * @notice Sets an address for an id replacing the address saved in the addresses map. * @dev IMPORTANT Use this function carefully, as it will do a hard replacement * @param id The id * @param newAddress The address to set */ function setAddress(bytes32 id, address newAddress) external; /** * @notice Returns the address of the Pool proxy. * @return The Pool proxy address */ function getPool() external view returns (address); /** * @notice Updates the implementation of the Pool, or creates a proxy * setting the new `pool` implementation when the function is called for the first time. * @param newPoolImpl The new Pool implementation */ function setPoolImpl(address newPoolImpl) external; /** * @notice Returns the address of the PoolConfigurator proxy. * @return The PoolConfigurator proxy address */ function getPoolConfigurator() external view returns (address); /** * @notice Updates the implementation of the PoolConfigurator, or creates a proxy * setting the new `PoolConfigurator` implementation when the function is called for the first time. * @param newPoolConfiguratorImpl The new PoolConfigurator implementation */ function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external; /** * @notice Returns the address of the price oracle. * @return The address of the PriceOracle */ function getPriceOracle() external view returns (address); /** * @notice Updates the address of the price oracle. * @param newPriceOracle The address of the new PriceOracle */ function setPriceOracle(address newPriceOracle) external; /** * @notice Returns the address of the ACL manager. * @return The address of the ACLManager */ function getACLManager() external view returns (address); /** * @notice Updates the address of the ACL manager. * @param newAclManager The address of the new ACLManager */ function setACLManager(address newAclManager) external; /** * @notice Returns the address of the ACL admin. * @return The address of the ACL admin */ function getACLAdmin() external view returns (address); /** * @notice Updates the address of the ACL admin. * @param newAclAdmin The address of the new ACL admin */ function setACLAdmin(address newAclAdmin) external; /** * @notice Returns the address of the price oracle sentinel. * @return The address of the PriceOracleSentinel */ function getPriceOracleSentinel() external view returns (address); /** * @notice Updates the address of the price oracle sentinel. * @param newPriceOracleSentinel The address of the new PriceOracleSentinel */ function setPriceOracleSentinel(address newPriceOracleSentinel) external; /** * @notice Returns the address of the data provider. * @return The address of the DataProvider */ function getPoolDataProvider() external view returns (address); /** * @notice Updates the address of the data provider. * @param newDataProvider The address of the new DataProvider */ function setPoolDataProvider(address newDataProvider) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import {ProxyAdmin} from '../ProxyAdmin.sol'; interface ITransparentProxyFactory { event ProxyCreated(address proxy, address indexed logic, address indexed proxyAdmin); event ProxyAdminCreated(address proxyAdmin, address indexed adminOwner); event ProxyDeterministicCreated( address proxy, address indexed logic, address indexed admin, bytes32 indexed salt ); event ProxyAdminDeterministicCreated( address proxyAdmin, address indexed adminOwner, bytes32 indexed salt ); /** * @notice Creates a transparent proxy instance, doing the first initialization in construction * @dev Version using CREATE * @param logic The address of the implementation contract * @param admin The admin of the proxy. * @param data abi encoded call to the function with `initializer` (or `reinitializer`) modifier. * E.g. `abi.encodeWithSelector(mockImpl.initialize.selector, 2)` * for an `initialize` function being `function initialize(uint256 foo) external initializer;` * @return address The address of the proxy deployed **/ function create(address logic, ProxyAdmin admin, bytes memory data) external returns (address); /** * @notice Creates a proxyAdmin instance, and transfers ownership to provided owner * @dev Version using CREATE * @param adminOwner The owner of the proxyAdmin deployed. * @return address The address of the proxyAdmin deployed **/ function createProxyAdmin(address adminOwner) external returns (address); /** * @notice Creates a transparent proxy instance, doing the first initialization in construction * @dev Version using CREATE2, so deterministic * @param logic The address of the implementation contract * @param admin The admin of the proxy. * @param data abi encoded call to the function with `initializer` (or `reinitializer`) modifier. * E.g. `abi.encodeWithSelector(mockImpl.initialize.selector, 2)` * for an `initialize` function being `function initialize(uint256 foo) external initializer;` * @param salt Value to be used in the address calculation, to be chosen by the account calling this function * @return address The address of the proxy deployed **/ function createDeterministic( address logic, ProxyAdmin admin, bytes memory data, bytes32 salt ) external returns (address); /** * @notice Deterministically create a proxy admin instance and transfers ownership to provided owner. * @dev Version using CREATE2, so deterministic * @param adminOwner The owner of the ProxyAdmin deployed. * @param salt Value to be used in the address calculation, to be chosen by the account calling this function * @return address The address of the proxy admin deployed **/ function createDeterministicProxyAdmin( address adminOwner, bytes32 salt ) external returns (address); /** * @notice Pre-calculates and return the address on which `createDeterministic` will deploy a proxy * @param logic The address of the implementation contract * @param admin The admin of the proxy * @param data abi encoded call to the function with `initializer` (or `reinitializer`) modifier. * E.g. `abi.encodeWithSelector(mockImpl.initialize.selector, 2)` * for an `initialize` function being `function initialize(uint256 foo) external initializer;` * @param salt Value to be used in the address calculation, to be chosen by the account calling this function * @return address The pre-calculated address **/ function predictCreateDeterministic( address logic, ProxyAdmin admin, bytes calldata data, bytes32 salt ) external view returns (address); /** * @notice Pre-calculates and return the address on which `createDeterministic` will deploy the proxyAdmin * @param salt Value to be used in the address calculation, to be chosen by the account calling this function * @return address The pre-calculated address **/ function predictCreateDeterministicProxyAdmin( bytes32 salt, address initialOwner ) external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IPool, IPoolAddressesProvider} from '../../../interfaces/IPool.sol'; interface IERC4626StataToken { struct SignatureParams { uint8 v; bytes32 r; bytes32 s; } error PoolAddressMismatch(address pool); error StaticATokenInvalidZeroShares(); error OnlyPauseGuardian(address caller); /** * @notice The pool associated with the aToken. * @return The pool address. */ function POOL() external view returns (IPool); /** * @notice The poolAddressesProvider associated with the pool. * @return The poolAddressesProvider address. */ function POOL_ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Burns `shares` of static aToken, with receiver receiving the corresponding amount of aToken * @param shares The shares to withdraw, in static balance of StaticAToken * @param receiver The address that will receive the amount of `ASSET` withdrawn from the Aave protocol * @return amountToWithdraw: aToken send to `receiver`, dynamic balance **/ function redeemATokens( uint256 shares, address receiver, address owner ) external returns (uint256); /** * @notice Deposits aTokens and mints static aTokens to msg.sender * @param assets The amount of aTokens to deposit (e.g. deposit of 100 aUSDC) * @param receiver The address that will receive the static aTokens * @return uint256 The amount of StaticAToken minted, static balance **/ function depositATokens(uint256 assets, address receiver) external returns (uint256); /** * @notice Universal deposit method for proving aToken or underlying liquidity with permit * @param assets The amount of aTokens or underlying to deposit * @param receiver The address that will receive the static aTokens * @param deadline Must be a timestamp in the future * @param sig A `secp256k1` signature params from `msgSender()` * @return uint256 The amount of StaticAToken minted, static balance **/ function depositWithPermit( uint256 assets, address receiver, uint256 deadline, SignatureParams memory sig, bool depositToAave ) external returns (uint256); /** * @notice The aToken used inside the 4626 vault. * @return address The aToken address. */ function aToken() external view returns (address); /** * @notice Returns the current asset price of the stataToken. * The price is calculated as `underlying_price * exchangeRate`. * It is important to note that: * - `underlying_price` is the price obtained by the aave-oracle and is subject to it's internal pricing mechanisms. * - as the price is scaled over the exchangeRate, but maintains the same precision as the underlying the price might be underestimated by 1 unit. * - when pricing multiple `shares` as `shares * price` keep in mind that the error compounds. * @return price the current asset price. */ function latestAnswer() external view returns (int256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; interface IERC20AaveLM { struct UserRewardsData { uint128 rewardsIndexOnLastInteraction; uint128 unclaimedRewards; } struct RewardIndexCache { bool isRegistered; uint248 lastUpdatedIndex; } error ZeroIncentivesControllerIsForbidden(); error InvalidClaimer(address claimer); error RewardNotInitialized(address reward); event RewardTokenRegistered(address indexed reward, uint256 startIndex); /** * @notice Claims rewards from `INCENTIVES_CONTROLLER` and updates internal accounting of rewards. * @param reward The reward to claim * @return uint256 Amount collected */ function collectAndUpdateRewards(address reward) external returns (uint256); /** * @notice Claim rewards on behalf of a user and send them to a receiver * @dev Only callable by if sender is onBehalfOf or sender is approved claimer * @param onBehalfOf The address to claim on behalf of * @param receiver The address to receive the rewards * @param rewards The rewards to claim */ function claimRewardsOnBehalf( address onBehalfOf, address receiver, address[] memory rewards ) external; /** * @notice Claim rewards and send them to a receiver * @param receiver The address to receive the rewards * @param rewards The rewards to claim */ function claimRewards(address receiver, address[] memory rewards) external; /** * @notice Claim rewards * @param rewards The rewards to claim */ function claimRewardsToSelf(address[] memory rewards) external; /** * @notice Get the total claimable rewards of the contract. * @param reward The reward to claim * @return uint256 The current balance + pending rewards from the `_incentivesController` */ function getTotalClaimableRewards(address reward) external view returns (uint256); /** * @notice Get the total claimable rewards for a user in asset decimals * @param user The address of the user * @param reward The reward to claim * @return uint256 The claimable amount of rewards in asset decimals */ function getClaimableRewards(address user, address reward) external view returns (uint256); /** * @notice The unclaimed rewards for a user in asset decimals * @param user The address of the user * @param reward The reward to claim * @return uint256 The unclaimed amount of rewards in asset decimals */ function getUnclaimedRewards(address user, address reward) external view returns (uint256); /** * @notice The underlying asset reward index in RAY * @param reward The reward to claim * @return uint256 The underlying asset reward index in RAY */ function getCurrentRewardsIndex(address reward) external view returns (uint256); /** * @notice Returns reference a/v token address used on INCENTIVES_CONTROLLER for tracking * @return address of reference token */ function getReferenceAsset() external view returns (address); /** * @notice The IERC20s that are currently rewarded to addresses of the vault via LM on incentivescontroller. * @return IERC20 The IERC20s of the rewards. */ function rewardTokens() external view returns (address[] memory); /** * @notice Fetches all rewardTokens from the incentivecontroller and registers the missing ones. */ function refreshRewardTokens() external; /** * @notice Checks if the passed token is a registered reward. * @param reward The reward to claim * @return bool signaling if token is a registered reward. */ function isRegisteredRewardToken(address reward) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4626.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol"; import {IERC20Metadata} from "../token/ERC20/extensions/IERC20Metadata.sol"; /** * @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. */ interface IERC4626 is IERC20, IERC20Metadata { event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. * * - MUST be an ERC-20 token contract. * - MUST NOT revert. */ function asset() external view returns (address assetTokenAddress); /** * @dev Returns the total amount of the underlying asset that is “managed” by Vault. * * - SHOULD include any compounding that occurs from yield. * - MUST be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT revert. */ function totalAssets() external view returns (uint256 totalManagedAssets); /** * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToShares(uint256 assets) external view returns (uint256 shares); /** * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToAssets(uint256 shares) external view returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, * through a deposit call. * * - MUST return a limited value if receiver is subject to some deposit limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. * - MUST NOT revert. */ function maxDeposit(address receiver) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given * current on-chain conditions. * * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called * in the same transaction. * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the * deposit would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewDeposit(uint256 assets) external view returns (uint256 shares); /** * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * deposit execution, and are accounted for during deposit. * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function deposit(uint256 assets, address receiver) external returns (uint256 shares); /** * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. * - MUST return a limited value if receiver is subject to some mint limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. * - MUST NOT revert. */ function maxMint(address receiver) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given * current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the * same transaction. * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint * would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by minting. */ function previewMint(uint256 shares) external view returns (uint256 assets); /** * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint * execution, and are accounted for during mint. * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function mint(uint256 shares, address receiver) external returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the * Vault, through a withdraw call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST NOT revert. */ function maxWithdraw(address owner) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, * given current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if * called * in the same transaction. * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though * the withdrawal would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewWithdraw(uint256 assets) external view returns (uint256 shares); /** * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * withdraw execution, and are accounted for during withdraw. * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); /** * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, * through a redeem call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. * - MUST NOT revert. */ function maxRedeem(address owner) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, * given current on-chain conditions. * * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the * same transaction. * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the * redemption would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by redeeming. */ function previewRedeem(uint256 shares) external view returns (uint256 assets); /** * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * redeem execution, and are accounted for during redeem. * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IScaledBalanceToken * @author Aave * @notice Defines the basic interface for a scaled-balance token. */ interface IScaledBalanceToken { /** * @dev Emitted after the mint action * @param caller The address performing the mint * @param onBehalfOf The address of the user that will receive the minted tokens * @param value The scaled-up amount being minted (based on user entered amount and balance increase from interest) * @param balanceIncrease The increase in scaled-up balance since the last action of 'onBehalfOf' * @param index The next liquidity index of the reserve */ event Mint( address indexed caller, address indexed onBehalfOf, uint256 value, uint256 balanceIncrease, uint256 index ); /** * @dev Emitted after the burn action * @dev If the burn function does not involve a transfer of the underlying asset, the target defaults to zero address * @param from The address from which the tokens will be burned * @param target The address that will receive the underlying, if any * @param value The scaled-up amount being burned (user entered amount - balance increase from interest) * @param balanceIncrease The increase in scaled-up balance since the last action of 'from' * @param index The next liquidity index of the reserve */ event Burn( address indexed from, address indexed target, uint256 value, uint256 balanceIncrease, uint256 index ); /** * @notice Returns the scaled balance of the user. * @dev The scaled balance is the sum of all the updated stored balance divided by the reserve's liquidity index * at the moment of the update * @param user The user whose balance is calculated * @return The scaled balance of the user */ function scaledBalanceOf(address user) external view returns (uint256); /** * @notice Returns the scaled balance of the user and the scaled total supply. * @param user The address of the user * @return The scaled balance of the user * @return The scaled total supply */ function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); /** * @notice Returns the scaled total supply of the scaled balance token. Represents sum(debt/index) * @return The scaled total supply */ function scaledTotalSupply() external view returns (uint256); /** * @notice Returns last index interest was accrued to the user's balance * @param user The address of the user * @return The last index interest was accrued to the user's balance, expressed in ray */ function getPreviousIndex(address user) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; import {IPool} from './IPool.sol'; /** * @title IInitializableAToken * @author Aave * @notice Interface for the initialize function on AToken */ interface IInitializableAToken { /** * @dev Emitted when an aToken is initialized * @param underlyingAsset The address of the underlying asset * @param pool The address of the associated pool * @param treasury The address of the treasury * @param incentivesController The address of the incentives controller for this aToken * @param aTokenDecimals The decimals of the underlying * @param aTokenName The name of the aToken * @param aTokenSymbol The symbol of the aToken * @param params A set of encoded parameters for additional initialization */ event Initialized( address indexed underlyingAsset, address indexed pool, address treasury, address incentivesController, uint8 aTokenDecimals, string aTokenName, string aTokenSymbol, bytes params ); /** * @notice Initializes the aToken * @param pool The pool contract that is initializing this contract * @param treasury The address of the Aave treasury, receiving the fees on this aToken * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH) * @param incentivesController The smart contract managing potential incentives distribution * @param aTokenDecimals The decimals of the aToken, same as the underlying asset's * @param aTokenName The name of the aToken * @param aTokenSymbol The symbol of the aToken * @param params A set of encoded parameters for additional initialization */ function initialize( IPool pool, address treasury, address underlyingAsset, IAaveIncentivesController incentivesController, uint8 aTokenDecimals, string calldata aTokenName, string calldata aTokenSymbol, bytes calldata params ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IPriceOracleGetter * @author Aave * @notice Interface for the Aave price oracle. */ interface IPriceOracleGetter { /** * @notice Returns the base currency address * @dev Address 0x0 is reserved for USD as base currency. * @return Returns the base currency address. */ function BASE_CURRENCY() external view returns (address); /** * @notice Returns the base currency unit * @dev 1 ether for ETH, 1e8 for USD. * @return Returns the base currency unit. */ function BASE_CURRENCY_UNIT() external view returns (uint256); /** * @notice Returns the asset price in the base currency * @param asset The address of the asset * @return The price of the asset */ function getAssetPrice(address asset) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[ERC-2612]. * * Adds the {permit} method, which can be used to change an account's ERC-20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {IERC4626} from 'openzeppelin-contracts/contracts/interfaces/IERC4626.sol'; interface IERC4626StakeToken is IERC4626 { struct CooldownSnapshot { /// @notice Amount of shares available to redeem uint192 amount; /// @notice Timestamp after which funds will be unlocked for withdrawal uint32 endOfCooldown; /// @notice Period of time to withdraw funds after end of cooldown uint32 withdrawalWindow; } struct SignatureParams { uint8 v; bytes32 r; bytes32 s; } /** * @notice Event is emitted when a cooldown of staker is changed. * @param user Staker address * @param amount Amount of shares on the time cooldown is changed * @param endOfCooldown Future timestamp, from which funds can be withdrawn * @param unstakeWindow Duration of time to withdraw funds */ event StakerCooldownUpdated( address indexed user, uint256 amount, uint256 endOfCooldown, uint256 unstakeWindow ); /** * @notice Event is emitted when a user installs/disables the operator for cooldown. * @param user User address * @param operator Address of operator to install/disable * @param flag Flag responsible for setting/disabling operator */ event CooldownOperatorSet(address indexed user, address indexed operator, bool flag); /** * @notice Event is emitted when a successful slash occurs * @param destination Address, where funds transferred to * @param amount Amount of funds transferred */ event Slashed(address indexed destination, uint256 amount); /** * @notice Event is emitted when `cooldown` is changed to the new one * @param oldCooldown Old `cooldown` duration * @param newCooldown New `cooldown` duration */ event CooldownChanged(uint256 oldCooldown, uint256 newCooldown); /** * @notice Event is emitted when `unstakeWindow` is changed to the new one * @param oldUnstakeWindow Old `unstakeWindow` duration * @param newUnstakeWindow new `unstakeWindow` duration */ event UnstakeWindowChanged(uint256 oldUnstakeWindow, uint256 newUnstakeWindow); /** * @dev Attempted to set zero address as a variable. */ error ZeroAddress(); /** * @dev Attempted to call cooldown without locked liquidity. */ error ZeroBalanceInStaking(); /** * @dev Attempted to slash for zero amount of assets. */ error ZeroAmountSlashing(); /** * @dev Attempted to slash with insufficient funds in staking. */ error ZeroFundsAvailable(); /** * @dev Attempted to call cooldown without approval for `cooldownOnBehalf`. * @param owner Address of user, which cooldown wasn't triggered * @param spender Address of `msg.sender` */ error NotApprovedForCooldown(address owner, address spender); /** * @notice Deposits by issuing approval for the required number of tokens (if `asset` supports the `permit` function). * Emits a {Deposit} event. * @param assets Amount of assets to be deposited * @param receiver Receiver of shares * @param deadline Signature deadline for issuing approve * @param sig Signature parameters * @return Amount of shares received */ function depositWithPermit( uint256 assets, address receiver, uint256 deadline, SignatureParams calldata sig ) external returns (uint256); /** * @notice Triggers user's `cooldown` using signature. * Emits a {StakerCooldownUpdated} event. * @param user The address, which `cooldown` will be triggered * @param deadline Signature deadline for issuing approve * @param sig Signature parameters */ function cooldownWithPermit( address user, uint256 deadline, SignatureParams calldata sig ) external; /** * @notice Activates the cooldown period to unstake for `msg.sender`. * It can't be called if the user is not staking. * Emits a {StakerCooldownUpdated} event. */ function cooldown() external; /** * @notice Activates the cooldown period to unstake for a certain user. * It can't be called if the user is not staking. * `from` must set as `cooldownOperator` for `msg.sender` so that he can activate the cooldown on his behalf. * Emits a {StakerCooldownUpdated} event. * @param from Address at which the `cooldown` will be activated */ function cooldownOnBehalfOf(address from) external; /** * @notice Sets the ability to call `cooldownOnBehalf` for `msg.sender` by specified `operator` to `true` or `false`. * Doesn't revert if the new `flag` value is the same as the old one. * Emits a {CooldownOnBehalfChanged} event. * @param operator The address that the ability to call `cooldownOnBehalf` for `msg.sender` can be changed * @param flag True - to activate this ability, false - to deactivate */ function setCooldownOperator(address operator, bool flag) external; /** * @notice Executes a slashing of the asset of a certain amount, transferring the seized funds * to destination. Decreasing the amount of underlying will automatically adjust the exchange rate. * If the amount exceeds maxSlashableAmount then the second one is taken. * Can only be called by the `owner`. * Emits a {Slashed} event. * @param destination Address where seized funds will be transferred * @param amount Amount to be slashed * @return amount Amount slashed */ function slash(address destination, uint256 amount) external returns (uint256); /** * @notice Pauses the contract, can be called by `owner`. * Emits a {Paused} event. */ function pause() external; /** * @notice Unpauses the contract, can be called by `owner`. * Emits a {Unpaused} event. */ function unpause() external; /** * @notice Sets a new `cooldown` duration. * Can only be called by the `owner`. * Emits a {CooldownChanged} event. * @param cooldown Amount of seconds users have to wait between starting the `cooldown` and being able to withdraw funds */ function setCooldown(uint256 cooldown) external; /** * @notice Sets a new `unstakeWindow` duration. * Can only be called by the `owner`. * Emits a {UnstakeWindowChanged} event. * @param newUnstakeWindow Amount of seconds users have to withdraw after `cooldown` */ function setUnstakeWindow(uint256 newUnstakeWindow) external; /** * @notice Returns current `cooldown` duration. * @return _cooldown duration */ function getCooldown() external view returns (uint256); /** * @notice Returns current `unstakeWindow` duration. * @return _unstakeWindow duration */ function getUnstakeWindow() external view returns (uint256); /** * @notice Returns the last activated user `cooldown`. Contains the amount of tokens and timestamp. * May return zero values if all funds have been withdrawn or transferred. * @param user Address of user * @return User's cooldown snapshot */ function getStakerCooldown(address user) external view returns (CooldownSnapshot memory); /** * @notice Returns true if the user's cooldown can be triggered by an operator, false - otherwise. * @param user Address of the user. * @param operator Address of an operator. * @return Is operator set for `cooldownOnBehalf` */ function isCooldownOperator(address user, address operator) external view returns (bool); /** * @notice Returns the next unused nonce for an address, which could be used inside signature for `cooldownWithPermit()` function. * @param owner Address for which unused `cooldown` nonce will be returned * @return The next unused `cooldown` nonce */ function cooldownNonces(address owner) external view returns (uint256); /** * @notice Returns the maximum slashable assets available for now. * @return Maximum assets available for slash */ function getMaxSlashableAssets() external view returns (uint256); /** * @notice Returns the minimum amount of assets, which can't be slashed. * @return Minimum assets value that cannot be slashed */ function MIN_ASSETS_REMAINING() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library DataTypes { /** * This exists specifically to maintain the `getReserveData()` interface, since the new, internal * `ReserveData` struct includes the reserve's `virtualUnderlyingBalance`. */ struct ReserveDataLegacy { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; // DEPRECATED on v3.2.0 uint128 currentStableBorrowRate; //timestamp of last update uint40 lastUpdateTimestamp; //the id of the reserve. Represents the position in the list of the active reserves uint16 id; //aToken address address aTokenAddress; // DEPRECATED on v3.2.0 address stableDebtTokenAddress; //variableDebtToken address address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the current treasury balance, scaled uint128 accruedToTreasury; //the outstanding unbacked aTokens minted through the bridging feature uint128 unbacked; //the outstanding debt borrowed against this asset in isolation mode uint128 isolationModeTotalDebt; } struct ReserveData { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; // DEPRECATED on v3.2.0 uint128 __deprecatedStableBorrowRate; //timestamp of last update uint40 lastUpdateTimestamp; //the id of the reserve. Represents the position in the list of the active reserves uint16 id; //timestamp until when liquidations are not allowed on the reserve, if set to past liquidations will be allowed uint40 liquidationGracePeriodUntil; //aToken address address aTokenAddress; // DEPRECATED on v3.2.0 address __deprecatedStableDebtTokenAddress; //variableDebtToken address address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the current treasury balance, scaled uint128 accruedToTreasury; //the outstanding unbacked aTokens minted through the bridging feature uint128 unbacked; //the outstanding debt borrowed against this asset in isolation mode uint128 isolationModeTotalDebt; //the amount of underlying accounted for by the protocol uint128 virtualUnderlyingBalance; } 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: DEPRECATED: stable rate borrowing enabled //bit 60: asset is paused //bit 61: borrowing in isolation mode is enabled //bit 62: siloed borrowing enabled //bit 63: flashloaning enabled //bit 64-79: reserve factor //bit 80-115: borrow cap in whole tokens, borrowCap == 0 => no cap //bit 116-151: supply cap in whole tokens, supplyCap == 0 => no cap //bit 152-167: liquidation protocol fee //bit 168-175: DEPRECATED: eMode category //bit 176-211: unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled //bit 212-251: debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals //bit 252: virtual accounting is enabled for the reserve //bit 253-255 unused uint256 data; } struct UserConfigurationMap { /** * @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset. * The first bit indicates if an asset is used as collateral by the user, the second whether an * asset is borrowed by the user. */ uint256 data; } // DEPRECATED: kept for backwards compatibility, might be removed in a future version struct EModeCategoryLegacy { // each eMode category has a custom ltv and liquidation threshold uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; // DEPRECATED address priceSource; string label; } struct CollateralConfig { uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; } struct EModeCategoryBaseConfiguration { uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; string label; } struct EModeCategory { // each eMode category has a custom ltv and liquidation threshold uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; uint128 collateralBitmap; string label; uint128 borrowableBitmap; } enum InterestRateMode { NONE, __DEPRECATED, VARIABLE } struct ReserveCache { uint256 currScaledVariableDebt; uint256 nextScaledVariableDebt; uint256 currLiquidityIndex; uint256 nextLiquidityIndex; uint256 currVariableBorrowIndex; uint256 nextVariableBorrowIndex; uint256 currLiquidityRate; uint256 currVariableBorrowRate; uint256 reserveFactor; ReserveConfigurationMap reserveConfiguration; address aTokenAddress; address variableDebtTokenAddress; uint40 reserveLastUpdateTimestamp; } struct ExecuteLiquidationCallParams { uint256 reservesCount; uint256 debtToCover; address collateralAsset; address debtAsset; address user; bool receiveAToken; address priceOracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteSupplyParams { address asset; uint256 amount; address onBehalfOf; uint16 referralCode; } struct ExecuteBorrowParams { address asset; address user; address onBehalfOf; uint256 amount; InterestRateMode interestRateMode; uint16 referralCode; bool releaseUnderlying; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteRepayParams { address asset; uint256 amount; InterestRateMode interestRateMode; address onBehalfOf; bool useATokens; } struct ExecuteWithdrawParams { address asset; uint256 amount; address to; uint256 reservesCount; address oracle; uint8 userEModeCategory; } struct ExecuteSetUserEModeParams { uint256 reservesCount; address oracle; uint8 categoryId; } struct FinalizeTransferParams { address asset; address from; address to; uint256 amount; uint256 balanceFromBefore; uint256 balanceToBefore; uint256 reservesCount; address oracle; uint8 fromEModeCategory; } struct FlashloanParams { address receiverAddress; address[] assets; uint256[] amounts; uint256[] interestRateModes; address onBehalfOf; bytes params; uint16 referralCode; uint256 flashLoanPremiumToProtocol; uint256 flashLoanPremiumTotal; uint256 reservesCount; address addressesProvider; address pool; uint8 userEModeCategory; bool isAuthorizedFlashBorrower; } struct FlashloanSimpleParams { address receiverAddress; address asset; uint256 amount; bytes params; uint16 referralCode; uint256 flashLoanPremiumToProtocol; uint256 flashLoanPremiumTotal; } struct FlashLoanRepaymentParams { uint256 amount; uint256 totalPremium; uint256 flashLoanPremiumToProtocol; address asset; address receiverAddress; uint16 referralCode; } struct CalculateUserAccountDataParams { UserConfigurationMap userConfig; uint256 reservesCount; address user; address oracle; uint8 userEModeCategory; } struct ValidateBorrowParams { ReserveCache reserveCache; UserConfigurationMap userConfig; address asset; address userAddress; uint256 amount; InterestRateMode interestRateMode; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; bool isolationModeActive; address isolationModeCollateralAddress; uint256 isolationModeDebtCeiling; } struct ValidateLiquidationCallParams { ReserveCache debtReserveCache; uint256 totalDebt; uint256 healthFactor; address priceOracleSentinel; } struct CalculateInterestRatesParams { uint256 unbacked; uint256 liquidityAdded; uint256 liquidityTaken; uint256 totalDebt; uint256 reserveFactor; address reserve; bool usingVirtualBalance; uint256 virtualUnderlyingBalance; } struct InitReserveParams { address asset; address aTokenAddress; address variableDebtAddress; address interestRateStrategyAddress; uint16 reservesCount; uint16 maxNumberReserves; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/transparent/ProxyAdmin.sol) pragma solidity ^0.8.20; import {ITransparentUpgradeableProxy} from './TransparentUpgradeableProxy.sol'; import {Ownable} from 'openzeppelin-contracts/contracts/access/Ownable.sol'; /** * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}. */ contract ProxyAdmin is Ownable { /** * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgrade(address)` * and `upgradeAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called, * while `upgradeAndCall` will invoke the `receive` function if the second argument is the empty byte string. * If the getter returns `"5.0.0"`, only `upgradeAndCall(address,bytes)` is present, and the second argument must * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function * during an upgrade. */ string public constant UPGRADE_INTERFACE_VERSION = '5.0.0'; /** * @dev Sets the initial owner who can perform upgrades. */ constructor(address initialOwner) Ownable(initialOwner) {} /** * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. * See {TransparentUpgradeableProxy-_dispatchUpgradeToAndCall}. * * Requirements: * * - This contract must be the admin of `proxy`. * - If `data` is empty, `msg.value` must be zero. */ function upgradeAndCall( ITransparentUpgradeableProxy proxy, address implementation, bytes memory data ) public payable virtual onlyOwner { proxy.upgradeToAndCall{value: msg.value}(implementation, data); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IAaveIncentivesController * @author Aave * @notice Defines the basic interface for an Aave Incentives Controller. * @dev It only contains one single function, needed as a hook on aToken and debtToken transfers. */ interface IAaveIncentivesController { /** * @dev Called by the corresponding asset on transfer hook in order to update the rewards distribution. * @dev The units of `totalSupply` and `userBalance` should be the same. * @param user The address of the user whose asset balance has changed * @param totalSupply The total supply of the asset prior to user balance change * @param userBalance The previous user balance prior to balance change */ function handleAction(address user, uint256 totalSupply, uint256 userBalance) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC4626.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol"; import {IERC20Metadata} from "../token/ERC20/extensions/IERC20Metadata.sol"; /** * @dev Interface of the ERC-4626 "Tokenized Vault Standard", as defined in * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. */ interface IERC4626 is IERC20, IERC20Metadata { event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. * * - MUST be an ERC-20 token contract. * - MUST NOT revert. */ function asset() external view returns (address assetTokenAddress); /** * @dev Returns the total amount of the underlying asset that is “managed” by Vault. * * - SHOULD include any compounding that occurs from yield. * - MUST be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT revert. */ function totalAssets() external view returns (uint256 totalManagedAssets); /** * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToShares(uint256 assets) external view returns (uint256 shares); /** * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToAssets(uint256 shares) external view returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, * through a deposit call. * * - MUST return a limited value if receiver is subject to some deposit limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. * - MUST NOT revert. */ function maxDeposit(address receiver) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given * current on-chain conditions. * * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called * in the same transaction. * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the * deposit would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewDeposit(uint256 assets) external view returns (uint256 shares); /** * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * deposit execution, and are accounted for during deposit. * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function deposit(uint256 assets, address receiver) external returns (uint256 shares); /** * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. * - MUST return a limited value if receiver is subject to some mint limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. * - MUST NOT revert. */ function maxMint(address receiver) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given * current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the * same transaction. * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint * would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by minting. */ function previewMint(uint256 shares) external view returns (uint256 assets); /** * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint * execution, and are accounted for during mint. * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function mint(uint256 shares, address receiver) external returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the * Vault, through a withdraw call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST NOT revert. */ function maxWithdraw(address owner) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, * given current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if * called * in the same transaction. * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though * the withdrawal would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewWithdraw(uint256 assets) external view returns (uint256 shares); /** * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * withdraw execution, and are accounted for during withdraw. * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); /** * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, * through a redeem call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. * - MUST NOT revert. */ function maxRedeem(address owner) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, * given current on-chain conditions. * * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the * same transaction. * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the * redemption would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by redeeming. */ function previewRedeem(uint256 shares) external view returns (uint256 assets); /** * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * redeem execution, and are accounted for during redeem. * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/transparent/TransparentUpgradeableProxy.sol) /** * Adaptation of OpenZeppelin's TransparentUpgradeableProxy contract by BGD Labs. * The original contract creates a new proxy admin per contract. * In the context of AAVE this is suboptimal, as it is more efficient to have a single proxy admin for all proxies. * This way, if an executor is ever migrated to a new address only the ownership of that single proxy admin has to ever change. */ pragma solidity ^0.8.20; import {ERC1967Utils} from 'openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol'; import {ERC1967Proxy} from 'openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol'; import {IERC1967} from 'openzeppelin-contracts/contracts/interfaces/IERC1967.sol'; import {ProxyAdmin} from './ProxyAdmin.sol'; /** * @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy} * does not implement this interface directly, and its upgradeability mechanism is implemented by an internal dispatch * mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not * include them in the ABI so this interface must be used to interact with it. */ interface ITransparentUpgradeableProxy is IERC1967 { function upgradeToAndCall(address, bytes calldata) external payable; } /** * @dev This contract implements a proxy that is upgradeable through an associated {ProxyAdmin} instance. * * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector * clashing], which can potentially be used in an attack, this contract uses the * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two * things that go hand in hand: * * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if * that call matches the {ITransparentUpgradeableProxy-upgradeToAndCall} function exposed by the proxy itself. * 2. If the admin calls the proxy, it can call the `upgradeToAndCall` function but any other call won't be forwarded to * the implementation. If the admin tries to call a function on the implementation it will fail with an error indicating * the proxy admin cannot fallback to the target implementation. * * These properties mean that the admin account can only be used for upgrading the proxy, so it's best if it's a * dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to * call a function from the proxy implementation. You should think of the `ProxyAdmin` instance as the administrative * interface of the proxy, including the ability to change who can trigger upgrades by transferring ownership. * * NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not * inherit from that interface, and instead `upgradeToAndCall` is implicitly implemented using a custom dispatch * mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to * fully implement transparency without decoding reverts caused by selector clashes between the proxy and the * implementation. * * NOTE: This proxy does not inherit from {Context} deliberately. The {ProxyAdmin} of this contract won't send a * meta-transaction in any way, and any other meta-transaction setup should be made in the implementation contract. * * IMPORTANT: This contract avoids unnecessary storage reads by setting the admin only during construction as an * immutable variable, preventing any changes thereafter. However, the admin slot defined in ERC-1967 can still be * overwritten by the implementation logic pointed to by this proxy. In such cases, the contract may end up in an * undesirable state where the admin slot is different from the actual admin. * * WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the * compiler will not check that there are no selector conflicts, due to the note above. A selector clash between any new * function and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This * could render the `upgradeToAndCall` function inaccessible, preventing upgradeability and compromising transparency. */ contract TransparentUpgradeableProxy is ERC1967Proxy { // An immutable address for the admin to avoid unnecessary SLOADs before each call // at the expense of removing the ability to change the admin once it's set. // This is acceptable if the admin is always a ProxyAdmin instance or similar contract // with its own ability to transfer the permissions to another account. address private immutable _admin; /** * @dev The proxy caller is the current admin, and can't fallback to the proxy target. */ error ProxyDeniedAdminAccess(); /** * @dev Initializes an upgradeable proxy managed by an instance of a {ProxyAdmin} with an `initialOwner`, * backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in * {ERC1967Proxy-constructor}. */ constructor( address _logic, ProxyAdmin initialOwner, bytes memory _data ) payable ERC1967Proxy(_logic, _data) { _admin = address(initialOwner); // Set the storage value and emit an event for ERC-1967 compatibility ERC1967Utils.changeAdmin(_proxyAdmin()); } /** * @dev Returns the admin of this proxy. */ function _proxyAdmin() internal virtual returns (address) { return _admin; } /** * @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior. */ function _fallback() internal virtual override { if (msg.sender == _proxyAdmin()) { if (msg.sig != ITransparentUpgradeableProxy.upgradeToAndCall.selector) { revert ProxyDeniedAdminAccess(); } else { _dispatchUpgradeToAndCall(); } } else { super._fallback(); } } /** * @dev Upgrade the implementation of the proxy. See {ERC1967Utils-upgradeToAndCall}. * * Requirements: * * - If `data` is empty, `msg.value` must be zero. */ function _dispatchUpgradeToAndCall() private { (address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes)); ERC1967Utils.upgradeToAndCall(newImplementation, data); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../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. * * The initial owner is set to the address provided by the deployer. 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; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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 { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _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 (last updated v5.1.0) (proxy/ERC1967/ERC1967Utils.sol) pragma solidity ^0.8.21; import {IBeacon} from "../beacon/IBeacon.sol"; import {IERC1967} from "../../interfaces/IERC1967.sol"; import {Address} from "../../utils/Address.sol"; import {StorageSlot} from "../../utils/StorageSlot.sol"; /** * @dev This library provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] slots. */ library ERC1967Utils { /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1. */ // solhint-disable-next-line private-vars-leading-underscore bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev The `implementation` of the proxy is invalid. */ error ERC1967InvalidImplementation(address implementation); /** * @dev The `admin` of the proxy is invalid. */ error ERC1967InvalidAdmin(address admin); /** * @dev The `beacon` of the proxy is invalid. */ error ERC1967InvalidBeacon(address beacon); /** * @dev An upgrade function sees `msg.value > 0` that may be lost. */ error ERC1967NonPayable(); /** * @dev Returns the current implementation address. */ function getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the ERC-1967 implementation slot. */ function _setImplementation(address newImplementation) private { if (newImplementation.code.length == 0) { revert ERC1967InvalidImplementation(newImplementation); } StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Performs implementation upgrade with additional setup call if data is nonempty. * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected * to avoid stuck value in the contract. * * Emits an {IERC1967-Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) internal { _setImplementation(newImplementation); emit IERC1967.Upgraded(newImplementation); if (data.length > 0) { Address.functionDelegateCall(newImplementation, data); } else { _checkNonPayable(); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1. */ // solhint-disable-next-line private-vars-leading-underscore bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` */ function getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(ADMIN_SLOT).value; } /** * @dev Stores a new address in the ERC-1967 admin slot. */ function _setAdmin(address newAdmin) private { if (newAdmin == address(0)) { revert ERC1967InvalidAdmin(address(0)); } StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {IERC1967-AdminChanged} event. */ function changeAdmin(address newAdmin) internal { emit IERC1967.AdminChanged(getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1. */ // solhint-disable-next-line private-vars-leading-underscore bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(BEACON_SLOT).value; } /** * @dev Stores a new beacon in the ERC-1967 beacon slot. */ function _setBeacon(address newBeacon) private { if (newBeacon.code.length == 0) { revert ERC1967InvalidBeacon(newBeacon); } StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon; address beaconImplementation = IBeacon(newBeacon).implementation(); if (beaconImplementation.code.length == 0) { revert ERC1967InvalidImplementation(beaconImplementation); } } /** * @dev Change the beacon and trigger a setup call if data is nonempty. * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected * to avoid stuck value in the contract. * * Emits an {IERC1967-BeaconUpgraded} event. * * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for * efficiency. */ function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal { _setBeacon(newBeacon); emit IERC1967.BeaconUpgraded(newBeacon); if (data.length > 0) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } else { _checkNonPayable(); } } /** * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract * if an upgrade doesn't perform an initialization call. */ function _checkNonPayable() private { if (msg.value > 0) { revert ERC1967NonPayable(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (proxy/ERC1967/ERC1967Proxy.sol) pragma solidity ^0.8.20; import {Proxy} from "../Proxy.sol"; import {ERC1967Utils} from "./ERC1967Utils.sol"; /** * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an * implementation address that can be changed. This address is stored in storage in the location specified by * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967], so that it doesn't conflict with the storage layout of the * implementation behind the proxy. */ contract ERC1967Proxy is Proxy { /** * @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`. * * If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an * encoded function call, and allows initializing the storage of the proxy like a Solidity constructor. * * Requirements: * * - If `data` is empty, `msg.value` must be zero. */ constructor(address implementation, bytes memory _data) payable { ERC1967Utils.upgradeToAndCall(implementation, _data); } /** * @dev Returns the current implementation address. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` */ function _implementation() internal view virtual override returns (address) { return ERC1967Utils.getImplementation(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.20; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. */ interface IERC1967 { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.20; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {UpgradeableBeacon} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol) pragma solidity ^0.8.20; import {Errors} from "./Errors.sol"; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert Errors.InsufficientBalance(address(this).balance, amount); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert Errors.FailedCall(); } } /** * @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 or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {Errors.FailedCall} error. * * 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. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @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`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case * of an unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {Errors.FailedCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}. */ function _revert(bytes memory returndata) private pure { // 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 ("memory-safe") { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert Errors.FailedCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.20; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC-1967 implementation slot: * ```solidity * contract ERC1967 { * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot. * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(newImplementation.code.length > 0); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * TIP: Consider using this library along with {SlotDerivation}. */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct Int256Slot { int256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `Int256Slot` with member `value` located at `slot`. */ function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { assembly ("memory-safe") { r.slot := store.slot } } /** * @dev Returns a `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { assembly ("memory-safe") { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol) pragma solidity ^0.8.20; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overridden so it returns the address to which the fallback * function and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _fallback() internal virtual { _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol) pragma solidity ^0.8.20; /** * @dev Collection of common custom errors used in multiple contracts * * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library. * It is recommended to avoid relying on the error API for critical functionality. * * _Available since v5.1._ */ library Errors { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error InsufficientBalance(uint256 balance, uint256 needed); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedCall(); /** * @dev The deployment failed. */ error FailedDeployment(); /** * @dev A necessary precompile is missing. */ error MissingPrecompile(address); }
{ "remappings": [ "aave-v3-origin/=lib/aave-v3-origin/src/", "forge-std/=lib/aave-v3-origin/lib/forge-std/src/", "solidity-utils/=lib/aave-v3-origin/lib/solidity-utils/src/", "@openzeppelin/contracts-upgradeable/=lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/", "ds-test/=lib/aave-v3-origin/lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/", "aave-umbrella/=lib/aave-umbrella/src/contracts/", "aave-address-book/=lib/aave-umbrella/lib/aave-helpers/lib/aave-address-book/src/", "aave-helpers/=lib/aave-umbrella/lib/aave-helpers/src/", "aave-v3-origin-tests/=lib/aave-umbrella/lib/aave-v3-origin/tests/", "halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/", "openzeppelin-contracts-upgradeable/=lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "shanghai", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IUmbrellaStkManager","name":"_umbrella","type":"address"},{"internalType":"contract IRewardsController","name":"_rewardsController","type":"address"},{"internalType":"contract IStataTokenFactory","name":"_stataTokenFactory","type":"address"},{"internalType":"contract IAaveOracle","name":"_aaveOracle","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"aaveOracle","outputs":[{"internalType":"contract IAaveOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakeData","outputs":[{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"totalAssets","type":"uint256"},{"internalType":"uint256","name":"targetLiquidity","type":"uint256"},{"internalType":"address","name":"underlyingTokenAddress","type":"address"},{"internalType":"string","name":"underlyingTokenName","type":"string"},{"internalType":"string","name":"underlyingTokenSymbol","type":"string"},{"internalType":"uint8","name":"underlyingTokenDecimals","type":"uint8"},{"internalType":"uint256","name":"cooldownSeconds","type":"uint256"},{"internalType":"uint256","name":"unstakeWindowSeconds","type":"uint256"},{"internalType":"bool","name":"underlyingIsStataToken","type":"bool"},{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"string","name":"assetName","type":"string"},{"internalType":"string","name":"assetSymbol","type":"string"},{"internalType":"address","name":"aToken","type":"address"},{"internalType":"string","name":"aTokenName","type":"string"},{"internalType":"string","name":"aTokenSymbol","type":"string"}],"internalType":"struct StataTokenData","name":"stataTokenData","type":"tuple"},{"components":[{"internalType":"address","name":"rewardAddress","type":"address"},{"internalType":"string","name":"rewardName","type":"string"},{"internalType":"string","name":"rewardSymbol","type":"string"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"maxEmissionPerSecond","type":"uint256"},{"internalType":"uint256","name":"distributionEnd","type":"uint256"},{"internalType":"uint256","name":"currentEmissionPerSecond","type":"uint256"},{"internalType":"uint256","name":"apy","type":"uint256"}],"internalType":"struct Reward[]","name":"rewards","type":"tuple[]"}],"internalType":"struct StakeData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserStakeData","outputs":[{"components":[{"internalType":"address","name":"stakeToken","type":"address"},{"internalType":"string","name":"stakeTokenName","type":"string"},{"components":[{"internalType":"uint256","name":"stakeTokenBalance","type":"uint256"},{"internalType":"uint256","name":"stakeTokenRedeemableAmount","type":"uint256"},{"internalType":"uint256","name":"underlyingTokenBalance","type":"uint256"},{"internalType":"uint256","name":"stataTokenAssetBalance","type":"uint256"},{"internalType":"uint256","name":"stataTokenATokenBalance","type":"uint256"}],"internalType":"struct StakeUserBalances","name":"balances","type":"tuple"},{"components":[{"internalType":"uint192","name":"cooldownAmount","type":"uint192"},{"internalType":"uint32","name":"endOfCooldown","type":"uint32"},{"internalType":"uint32","name":"withdrawalWindow","type":"uint32"}],"internalType":"struct StakeUserCooldown","name":"cooldown","type":"tuple"},{"internalType":"address[]","name":"rewards","type":"address[]"},{"internalType":"uint256[]","name":"rewardsAccrued","type":"uint256[]"}],"internalType":"struct StakeUserData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsController","outputs":[{"internalType":"contract IRewardsController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stataTokenFactory","outputs":[{"internalType":"contract IStataTokenFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"umbrella","outputs":[{"internalType":"contract IUmbrellaStkManager","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
610100604052348015610010575f5ffd5b506040516128f73803806128f783398101604081905261002f91610068565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c4565b6001600160a01b0381168114610065575f5ffd5b50565b5f5f5f5f6080858703121561007b575f5ffd5b845161008681610051565b602086015190945061009781610051565b60408601519093506100a881610051565b60608601519092506100b981610051565b939692955090935050565b60805160a05160c05160e0516127be6101395f395f818160ad015261182901525f81816069015281816102320152610b1b01525f818160d40152818161060b01528181610c0f01528181610d7401528181610ede0152610f7301525f818160fb015281816101570152610a4001526127be5ff3fe608060405234801561000f575f5ffd5b5060043610610060575f3560e01c80631494088f146100645780636372b281146100a85780636bb65f53146100cf57806384914262146100f6578063a16a09af1461011d578063e9ce34a514610132575b5f5ffd5b61008b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61008b7f000000000000000000000000000000000000000000000000000000000000000081565b61008b7f000000000000000000000000000000000000000000000000000000000000000081565b61008b7f000000000000000000000000000000000000000000000000000000000000000081565b610125610152565b60405161009f9190611f1a565b6101456101403660046120bc565b610a3b565b60405161009f919061214a565b60605f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663de3767766040518163ffffffff1660e01b81526004015f60405180830381865afa1580156101b0573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526101d79190810190612344565b90505f81516001600160401b038111156101f3576101f361226b565b60405190808252806020026020018201604052801561022c57816020015b610219611c11565b8152602001906001900390816102115790505b5090505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663529080176040518163ffffffff1660e01b81526004015f60405180830381865afa15801561028b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526102b29190810190612344565b90505f5b8351811015610a32575f8482815181106102d2576102d261237d565b602002602001015190505f8190505f826001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561031d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103419190612391565b90505f826001600160a01b03166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610380573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103a491906123ac565b90505f6104718483876001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103e8573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061040c91906123c3565b886001600160a01b03166301e1d1146040518163ffffffff1660e01b8152600401602060405180830381865afa158015610448573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061046c91906123ac565b610d50565b90505f61047e84896111b1565b90505f5f6001600160a01b0316825f01516001600160a01b031614159050604051806101e001604052808c8a815181106104ba576104ba61237d565b60200260200101516001600160a01b03168152602001886001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa15801561050b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261053291908101906123e3565b8152602001886001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015610572573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261059991908101906123e3565b8152602001858152602001886001600160a01b03166301e1d1146040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105e0573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061060491906123ac565b81526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631652e7b78e8c8151811061064a5761064a61237d565b60200260200101516040518263ffffffff1660e01b815260040161067d91906001600160a01b0391909116815260200190565b6040805180830381865afa158015610697573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106bb9190612469565b5f01518152602001866001600160a01b03168152602001886001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561070e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107329190612391565b6001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa15801561076c573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261079391908101906123e3565b8152602001886001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107d4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107f89190612391565b6001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015610832573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261085991908101906123e3565b8152602001886001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561089a573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108be9190612391565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108f9573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061091d91906123c3565b60ff168152602001886001600160a01b031663218e4a156040518163ffffffff1660e01b8152600401602060405180830381865afa158015610961573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061098591906123ac565b8152602001886001600160a01b03166390b9f9e46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109ea91906123ac565b81526020018215158152602001838152602001848152508a8981518110610a1357610a1361237d565b60200260200101819052505050505050505080806001019150506102b6565b50909392505050565b60605f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663de3767766040518163ffffffff1660e01b81526004015f60405180830381865afa158015610a99573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ac09190810190612344565b90505f81516001600160401b03811115610adc57610adc61226b565b604051908082528060200260200182016040528015610b1557816020015b610b02611c9b565b815260200190600190039081610afa5790505b5090505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663529080176040518163ffffffff1660e01b81526004015f60405180830381865afa158015610b74573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610b9b9190810190612344565b90505f5b8351811015610d46575f848281518110610bbb57610bbb61237d565b602002602001015190505f610bd1888386611460565b90505f610bde89846116d5565b60405160016204621960e51b031981526001600160a01b0385811660048301528b811660248301529192505f9182917f00000000000000000000000000000000000000000000000000000000000000009091169063ff73bce0906044015f60405180830381865afa158015610c55573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610c7c91908101906124b7565b915091506040518060c00160405280866001600160a01b03168152602001866001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015610cd5573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610cfc91908101906123e3565b815260200185815260200184815260200183815260200182815250888781518110610d2957610d2961237d565b602002602001018190525050505050508080600101915050610b9f565b5090949350505050565b60405163362a3fad60e01b81526001600160a01b0385811660048301526060915f917f0000000000000000000000000000000000000000000000000000000000000000169063362a3fad906024015f60405180830381865afa158015610db8573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ddf9190810190612344565b90505f81516001600160401b03811115610dfb57610dfb61226b565b604051908082528060200260200182016040528015610e8657816020015b610e736040518061014001604052805f6001600160a01b0316815260200160608152602001606081526020015f81526020015f60ff1681526020015f81526020015f81526020015f81526020015f81526020015f81525090565b815260200190600190039081610e195790505b5090505f5b82518110156111a6575f838281518110610ea757610ea761237d565b60209081029190910101516040516334fb3ea160e11b81526001600160a01b038b8116600483015280831660248301529192505f917f000000000000000000000000000000000000000000000000000000000000000016906369f67d4290604401608060405180830381865afa158015610f23573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f479190612573565b604051630450881160e51b81526001600160a01b038c8116600483015284811660248301529192505f917f00000000000000000000000000000000000000000000000000000000000000001690638a11022090604401602060405180830381865afa158015610fb8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fdc91906123ac565b90505f610fe8846117a2565b9050604051806101400160405280856001600160a01b03168152602001856001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015611040573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261106791908101906123e3565b8152602001856001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa1580156110a7573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526110ce91908101906123e3565b8152602001828152602001856001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611115573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061113991906123c3565b60ff168152602001846020015181526020018460400151815260200184606001518152602001838152602001611175848c8f8f60ff1687611968565b81525086868151811061118a5761118a61237d565b6020026020010181905250505050508080600101915050610e8b565b509695505050505050565b6111b9611d1c565b6111c383836119fe565b1561145a575f8390505f816001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611209573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061122d9190612391565b90505f826001600160a01b031663a0c1f15e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112909190612391565b90506040518060c00160405280836001600160a01b03168152602001836001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa1580156112e7573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261130e91908101906123e3565b8152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa15801561134e573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261137591908101906123e3565b8152602001826001600160a01b03168152602001826001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa1580156113c4573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526113eb91908101906123e3565b8152602001826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa15801561142b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261145291908101906123e3565b905293505050505b92915050565b61148d6040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b5f836001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114ca573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114ee9190612391565b90505f5f6114fd878487611a57565b6040805160a08101918290526370a0823160e01b9091526001600160a01b038a811660a483015292945090925090819088166370a0823160c48301602060405180830381865afa158015611553573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157791906123ac565b81526040516370a0823160e01b81526001600160a01b038a81166004830152602090920191891690634cdad5069082906370a0823190602401602060405180830381865afa1580156115cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115ef91906123ac565b6040518263ffffffff1660e01b815260040161160d91815260200190565b602060405180830381865afa158015611628573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061164c91906123ac565b81526040516370a0823160e01b81526001600160a01b038a811660048301526020909201918616906370a0823190602401602060405180830381865afa158015611698573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116bc91906123ac565b8152602081019390935260409092015295945050505050565b604080516060810182525f80825260208201819052918101919091526040516317c547a160e11b81526001600160a01b0384811660048301525f9190841690632f8a8f4290602401606060405180830381865afa158015611738573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061175c91906125f6565b90506040518060600160405280825f01516001600160c01b03168152602001826020015163ffffffff168152602001826040015163ffffffff1681525091505092915050565b5f5f8290505f836001600160a01b031663b16a19de6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611802575060408051601f3d908101601f191682019092526117ff91810190612391565b60015b1561180a5791505b60405163b3596f0760e01b81526001600160a01b0383811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063b3596f0790602401602060405180830381865afa92505050801561188c575060408051601f3d908101601f19168201909252611889918101906123ac565b60015b61195e57836001600160a01b031663a0c1f15e6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156118ea575060408051601f3d908101601f191682019092526118e791810190612391565b60015b6118f657505f19611961565b50836001600160a01b03166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611933573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061195791906123ac565b9050611961565b90505b9392505050565b5f841580611974575083155b8061197d575081155b1561198957505f6119f5565b5f611995846012612682565b6119a090600a612770565b6119aa908761277b565b90505f6119b7868361277b565b90505f6119c86301e133808a61277b565b90505f6119d5868361277b565b9050826119e46127108361277b565b6119ee9190612792565b9450505050505b95945050505050565b5f805b8251811015611a4e57828181518110611a1c57611a1c61237d565b60200260200101516001600160a01b0316846001600160a01b031603611a4657600191505061145a565b600101611a01565b505f9392505050565b5f5f611a6384846119fe565b15611c09575f846001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611aa5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ac99190612391565b90505f856001600160a01b031663a0c1f15e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b08573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b2c9190612391565b6040516370a0823160e01b81526001600160a01b038981166004830152919250908316906370a0823190602401602060405180830381865afa158015611b74573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b9891906123ac565b6040516370a0823160e01b81526001600160a01b038981166004830152919550908216906370a0823190602401602060405180830381865afa158015611be0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c0491906123ac565b925050505b935093915050565b604051806101e001604052805f6001600160a01b0316815260200160608152602001606081526020015f81526020015f81526020015f81526020015f6001600160a01b0316815260200160608152602001606081526020015f60ff1681526020015f81526020015f81526020015f15158152602001611c8e611d1c565b8152602001606081525090565b6040518060c001604052805f6001600160a01b0316815260200160608152602001611ce96040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b8152604080516060810182525f808252602082810182905292820152910190815260200160608152602001606081525090565b6040518060c001604052805f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b0316815260200160608152602001606081525090565b5f5b83811015611d7c578181015183820152602001611d64565b50505f910152565b5f8151808452611d9b816020860160208601611d62565b601f01601f19169290920160200192915050565b60018060a01b0381511682525f602082015160c06020850152611dd560c0850182611d84565b905060408301518482036040860152611dee8282611d84565b91505060018060a01b03606084015116606085015260808301518482036080860152611e1a8282611d84565b91505060a083015184820360a08601526119f58282611d84565b5f82825180855260208501945060208160051b830101602085015f5b83811015611f0e57848303601f19018852815180516001600160a01b0316845260208101516101406020860152611e8b610140860182611d84565b905060408201518582036040870152611ea48282611d84565b915050606082015160608601526080820151611ec5608087018260ff169052565b5060a0828101519086015260c0808301519086015260e0808301519086015261010080830151908601526101209182015191909401526020978801979190910190600101611e50565b50909695505050505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561209957868503603f19018452815180516001600160a01b0316865260208101516101e06020880152611f7b6101e0880182611d84565b905060408201518782036040890152611f948282611d84565b915050606082015160608801526080820151608088015260a082015160a088015260c0820151611fcf60c08901826001600160a01b03169052565b5060e082015187820360e0890152611fe78282611d84565b9150506101008201518782036101008901526120038282611d84565b91505061012082015161201c61012089018260ff169052565b5061014082015161014088015261016082015161016088015261018082015161204a61018089018215159052565b506101a08201518782036101a08901526120648282611daf565b9150506101c082015191508681036101c08801526120828183611e34565b965050506020938401939190910190600101611f40565b50929695505050505050565b6001600160a01b03811681146120b9575f5ffd5b50565b5f602082840312156120cc575f5ffd5b8135611961816120a5565b5f8151808452602084019350602083015f5b828110156121105781516001600160a01b03168652602095860195909101906001016120e9565b5093949350505050565b5f8151808452602084019350602083015f5b8281101561211057815186526020958601959091019060010161212c565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561209957868503603f19018452815180516001600160a01b03168652602080820151610180918801829052906121ac90880182611d84565b90506040820151805160408901526020810151606089015260408101516080890152606081015160a0890152608081015160c089015250606082015161221e60e089018280516001600160c01b0316825260208082015163ffffffff9081169184019190915260409182015116910152565b50608082015187820361014089015261223782826120d7565b91505060a08201519150868103610160880152612254818361211a565b965050506020938401939190910190600101612170565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156122a7576122a761226b565b604052919050565b5f6001600160401b038211156122c7576122c761226b565b5060051b60200190565b5f82601f8301126122e0575f5ffd5b81516122f36122ee826122af565b61227f565b8082825260208201915060208360051b860101925085831115612314575f5ffd5b602085015b8381101561233a57805161232c816120a5565b835260209283019201612319565b5095945050505050565b5f60208284031215612354575f5ffd5b81516001600160401b03811115612369575f5ffd5b612375848285016122d1565b949350505050565b634e487b7160e01b5f52603260045260245ffd5b5f602082840312156123a1575f5ffd5b8151611961816120a5565b5f602082840312156123bc575f5ffd5b5051919050565b5f602082840312156123d3575f5ffd5b815160ff81168114611961575f5ffd5b5f602082840312156123f3575f5ffd5b81516001600160401b03811115612408575f5ffd5b8201601f81018413612418575f5ffd5b80516001600160401b038111156124315761243161226b565b612444601f8201601f191660200161227f565b818152856020838501011115612458575f5ffd5b6119f5826020830160208601611d62565b5f604082840312801561247a575f5ffd5b50604080519081016001600160401b038111828210171561249d5761249d61226b565b604052825181526020928301519281019290925250919050565b5f5f604083850312156124c8575f5ffd5b82516001600160401b038111156124dd575f5ffd5b6124e9858286016122d1565b92505060208301516001600160401b03811115612504575f5ffd5b8301601f81018513612514575f5ffd5b80516125226122ee826122af565b8082825260208201915060208360051b850101925087831115612543575f5ffd5b6020840193505b8284101561256557835182526020938401939091019061254a565b809450505050509250929050565b5f6080828403128015612584575f5ffd5b50604051608081016001600160401b03811182821017156125a7576125a761226b565b60405282516125b5816120a5565b815260208381015190820152604080840151908201526060928301519281019290925250919050565b805163ffffffff811681146125f1575f5ffd5b919050565b5f6060828403128015612607575f5ffd5b50604051606081016001600160401b038111828210171561262a5761262a61226b565b60405282516001600160c01b0381168114612643575f5ffd5b8152612651602084016125de565b6020820152612662604084016125de565b60408201529392505050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561145a5761145a61266e565b6001815b6001841115611c09578085048111156126b4576126b461266e565b60018416156126c257908102905b60019390931c928002612699565b5f826126de5750600161145a565b816126ea57505f61145a565b8160018114612700576002811461270a57612726565b600191505061145a565b60ff84111561271b5761271b61266e565b50506001821b61145a565b5060208310610133831016604e8410600b8410161715612749575081810a61145a565b6127555f198484612695565b805f19048211156127685761276861266e565b029392505050565b5f61196183836126d0565b808202811582820484141761145a5761145a61266e565b5f826127ac57634e487b7160e01b5f52601260045260245ffd5b50049056fea164736f6c634300081b000a000000000000000000000000d400fc38ed4732893174325693a63c30ee3881a80000000000000000000000004655ce3d625a63d30ba704087e52b4c31e38188b000000000000000000000000cb0b5ca20b6c5c02a9a3b2ce433650768ed2974f00000000000000000000000054586be62e3c3580375ae3723c145253060ca0c2
Deployed Bytecode
0x608060405234801561000f575f5ffd5b5060043610610060575f3560e01c80631494088f146100645780636372b281146100a85780636bb65f53146100cf57806384914262146100f6578063a16a09af1461011d578063e9ce34a514610132575b5f5ffd5b61008b7f000000000000000000000000cb0b5ca20b6c5c02a9a3b2ce433650768ed2974f81565b6040516001600160a01b0390911681526020015b60405180910390f35b61008b7f00000000000000000000000054586be62e3c3580375ae3723c145253060ca0c281565b61008b7f0000000000000000000000004655ce3d625a63d30ba704087e52b4c31e38188b81565b61008b7f000000000000000000000000d400fc38ed4732893174325693a63c30ee3881a881565b610125610152565b60405161009f9190611f1a565b6101456101403660046120bc565b610a3b565b60405161009f919061214a565b60605f7f000000000000000000000000d400fc38ed4732893174325693a63c30ee3881a86001600160a01b031663de3767766040518163ffffffff1660e01b81526004015f60405180830381865afa1580156101b0573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526101d79190810190612344565b90505f81516001600160401b038111156101f3576101f361226b565b60405190808252806020026020018201604052801561022c57816020015b610219611c11565b8152602001906001900390816102115790505b5090505f7f000000000000000000000000cb0b5ca20b6c5c02a9a3b2ce433650768ed2974f6001600160a01b031663529080176040518163ffffffff1660e01b81526004015f60405180830381865afa15801561028b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526102b29190810190612344565b90505f5b8351811015610a32575f8482815181106102d2576102d261237d565b602002602001015190505f8190505f826001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561031d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103419190612391565b90505f826001600160a01b03166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610380573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103a491906123ac565b90505f6104718483876001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103e8573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061040c91906123c3565b886001600160a01b03166301e1d1146040518163ffffffff1660e01b8152600401602060405180830381865afa158015610448573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061046c91906123ac565b610d50565b90505f61047e84896111b1565b90505f5f6001600160a01b0316825f01516001600160a01b031614159050604051806101e001604052808c8a815181106104ba576104ba61237d565b60200260200101516001600160a01b03168152602001886001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa15801561050b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261053291908101906123e3565b8152602001886001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015610572573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261059991908101906123e3565b8152602001858152602001886001600160a01b03166301e1d1146040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105e0573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061060491906123ac565b81526020017f0000000000000000000000004655ce3d625a63d30ba704087e52b4c31e38188b6001600160a01b0316631652e7b78e8c8151811061064a5761064a61237d565b60200260200101516040518263ffffffff1660e01b815260040161067d91906001600160a01b0391909116815260200190565b6040805180830381865afa158015610697573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106bb9190612469565b5f01518152602001866001600160a01b03168152602001886001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561070e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107329190612391565b6001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa15801561076c573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261079391908101906123e3565b8152602001886001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107d4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107f89190612391565b6001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015610832573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261085991908101906123e3565b8152602001886001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561089a573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108be9190612391565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108f9573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061091d91906123c3565b60ff168152602001886001600160a01b031663218e4a156040518163ffffffff1660e01b8152600401602060405180830381865afa158015610961573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061098591906123ac565b8152602001886001600160a01b03166390b9f9e46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109ea91906123ac565b81526020018215158152602001838152602001848152508a8981518110610a1357610a1361237d565b60200260200101819052505050505050505080806001019150506102b6565b50909392505050565b60605f7f000000000000000000000000d400fc38ed4732893174325693a63c30ee3881a86001600160a01b031663de3767766040518163ffffffff1660e01b81526004015f60405180830381865afa158015610a99573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ac09190810190612344565b90505f81516001600160401b03811115610adc57610adc61226b565b604051908082528060200260200182016040528015610b1557816020015b610b02611c9b565b815260200190600190039081610afa5790505b5090505f7f000000000000000000000000cb0b5ca20b6c5c02a9a3b2ce433650768ed2974f6001600160a01b031663529080176040518163ffffffff1660e01b81526004015f60405180830381865afa158015610b74573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610b9b9190810190612344565b90505f5b8351811015610d46575f848281518110610bbb57610bbb61237d565b602002602001015190505f610bd1888386611460565b90505f610bde89846116d5565b60405160016204621960e51b031981526001600160a01b0385811660048301528b811660248301529192505f9182917f0000000000000000000000004655ce3d625a63d30ba704087e52b4c31e38188b9091169063ff73bce0906044015f60405180830381865afa158015610c55573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610c7c91908101906124b7565b915091506040518060c00160405280866001600160a01b03168152602001866001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015610cd5573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610cfc91908101906123e3565b815260200185815260200184815260200183815260200182815250888781518110610d2957610d2961237d565b602002602001018190525050505050508080600101915050610b9f565b5090949350505050565b60405163362a3fad60e01b81526001600160a01b0385811660048301526060915f917f0000000000000000000000004655ce3d625a63d30ba704087e52b4c31e38188b169063362a3fad906024015f60405180830381865afa158015610db8573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ddf9190810190612344565b90505f81516001600160401b03811115610dfb57610dfb61226b565b604051908082528060200260200182016040528015610e8657816020015b610e736040518061014001604052805f6001600160a01b0316815260200160608152602001606081526020015f81526020015f60ff1681526020015f81526020015f81526020015f81526020015f81526020015f81525090565b815260200190600190039081610e195790505b5090505f5b82518110156111a6575f838281518110610ea757610ea761237d565b60209081029190910101516040516334fb3ea160e11b81526001600160a01b038b8116600483015280831660248301529192505f917f0000000000000000000000004655ce3d625a63d30ba704087e52b4c31e38188b16906369f67d4290604401608060405180830381865afa158015610f23573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f479190612573565b604051630450881160e51b81526001600160a01b038c8116600483015284811660248301529192505f917f0000000000000000000000004655ce3d625a63d30ba704087e52b4c31e38188b1690638a11022090604401602060405180830381865afa158015610fb8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fdc91906123ac565b90505f610fe8846117a2565b9050604051806101400160405280856001600160a01b03168152602001856001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015611040573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261106791908101906123e3565b8152602001856001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa1580156110a7573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526110ce91908101906123e3565b8152602001828152602001856001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611115573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061113991906123c3565b60ff168152602001846020015181526020018460400151815260200184606001518152602001838152602001611175848c8f8f60ff1687611968565b81525086868151811061118a5761118a61237d565b6020026020010181905250505050508080600101915050610e8b565b509695505050505050565b6111b9611d1c565b6111c383836119fe565b1561145a575f8390505f816001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611209573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061122d9190612391565b90505f826001600160a01b031663a0c1f15e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112909190612391565b90506040518060c00160405280836001600160a01b03168152602001836001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa1580156112e7573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261130e91908101906123e3565b8152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa15801561134e573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261137591908101906123e3565b8152602001826001600160a01b03168152602001826001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa1580156113c4573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526113eb91908101906123e3565b8152602001826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa15801561142b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261145291908101906123e3565b905293505050505b92915050565b61148d6040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b5f836001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114ca573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114ee9190612391565b90505f5f6114fd878487611a57565b6040805160a08101918290526370a0823160e01b9091526001600160a01b038a811660a483015292945090925090819088166370a0823160c48301602060405180830381865afa158015611553573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157791906123ac565b81526040516370a0823160e01b81526001600160a01b038a81166004830152602090920191891690634cdad5069082906370a0823190602401602060405180830381865afa1580156115cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115ef91906123ac565b6040518263ffffffff1660e01b815260040161160d91815260200190565b602060405180830381865afa158015611628573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061164c91906123ac565b81526040516370a0823160e01b81526001600160a01b038a811660048301526020909201918616906370a0823190602401602060405180830381865afa158015611698573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116bc91906123ac565b8152602081019390935260409092015295945050505050565b604080516060810182525f80825260208201819052918101919091526040516317c547a160e11b81526001600160a01b0384811660048301525f9190841690632f8a8f4290602401606060405180830381865afa158015611738573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061175c91906125f6565b90506040518060600160405280825f01516001600160c01b03168152602001826020015163ffffffff168152602001826040015163ffffffff1681525091505092915050565b5f5f8290505f836001600160a01b031663b16a19de6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611802575060408051601f3d908101601f191682019092526117ff91810190612391565b60015b1561180a5791505b60405163b3596f0760e01b81526001600160a01b0383811660048301527f00000000000000000000000054586be62e3c3580375ae3723c145253060ca0c2169063b3596f0790602401602060405180830381865afa92505050801561188c575060408051601f3d908101601f19168201909252611889918101906123ac565b60015b61195e57836001600160a01b031663a0c1f15e6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156118ea575060408051601f3d908101601f191682019092526118e791810190612391565b60015b6118f657505f19611961565b50836001600160a01b03166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611933573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061195791906123ac565b9050611961565b90505b9392505050565b5f841580611974575083155b8061197d575081155b1561198957505f6119f5565b5f611995846012612682565b6119a090600a612770565b6119aa908761277b565b90505f6119b7868361277b565b90505f6119c86301e133808a61277b565b90505f6119d5868361277b565b9050826119e46127108361277b565b6119ee9190612792565b9450505050505b95945050505050565b5f805b8251811015611a4e57828181518110611a1c57611a1c61237d565b60200260200101516001600160a01b0316846001600160a01b031603611a4657600191505061145a565b600101611a01565b505f9392505050565b5f5f611a6384846119fe565b15611c09575f846001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611aa5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ac99190612391565b90505f856001600160a01b031663a0c1f15e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b08573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b2c9190612391565b6040516370a0823160e01b81526001600160a01b038981166004830152919250908316906370a0823190602401602060405180830381865afa158015611b74573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b9891906123ac565b6040516370a0823160e01b81526001600160a01b038981166004830152919550908216906370a0823190602401602060405180830381865afa158015611be0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c0491906123ac565b925050505b935093915050565b604051806101e001604052805f6001600160a01b0316815260200160608152602001606081526020015f81526020015f81526020015f81526020015f6001600160a01b0316815260200160608152602001606081526020015f60ff1681526020015f81526020015f81526020015f15158152602001611c8e611d1c565b8152602001606081525090565b6040518060c001604052805f6001600160a01b0316815260200160608152602001611ce96040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b8152604080516060810182525f808252602082810182905292820152910190815260200160608152602001606081525090565b6040518060c001604052805f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b0316815260200160608152602001606081525090565b5f5b83811015611d7c578181015183820152602001611d64565b50505f910152565b5f8151808452611d9b816020860160208601611d62565b601f01601f19169290920160200192915050565b60018060a01b0381511682525f602082015160c06020850152611dd560c0850182611d84565b905060408301518482036040860152611dee8282611d84565b91505060018060a01b03606084015116606085015260808301518482036080860152611e1a8282611d84565b91505060a083015184820360a08601526119f58282611d84565b5f82825180855260208501945060208160051b830101602085015f5b83811015611f0e57848303601f19018852815180516001600160a01b0316845260208101516101406020860152611e8b610140860182611d84565b905060408201518582036040870152611ea48282611d84565b915050606082015160608601526080820151611ec5608087018260ff169052565b5060a0828101519086015260c0808301519086015260e0808301519086015261010080830151908601526101209182015191909401526020978801979190910190600101611e50565b50909695505050505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561209957868503603f19018452815180516001600160a01b0316865260208101516101e06020880152611f7b6101e0880182611d84565b905060408201518782036040890152611f948282611d84565b915050606082015160608801526080820151608088015260a082015160a088015260c0820151611fcf60c08901826001600160a01b03169052565b5060e082015187820360e0890152611fe78282611d84565b9150506101008201518782036101008901526120038282611d84565b91505061012082015161201c61012089018260ff169052565b5061014082015161014088015261016082015161016088015261018082015161204a61018089018215159052565b506101a08201518782036101a08901526120648282611daf565b9150506101c082015191508681036101c08801526120828183611e34565b965050506020938401939190910190600101611f40565b50929695505050505050565b6001600160a01b03811681146120b9575f5ffd5b50565b5f602082840312156120cc575f5ffd5b8135611961816120a5565b5f8151808452602084019350602083015f5b828110156121105781516001600160a01b03168652602095860195909101906001016120e9565b5093949350505050565b5f8151808452602084019350602083015f5b8281101561211057815186526020958601959091019060010161212c565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561209957868503603f19018452815180516001600160a01b03168652602080820151610180918801829052906121ac90880182611d84565b90506040820151805160408901526020810151606089015260408101516080890152606081015160a0890152608081015160c089015250606082015161221e60e089018280516001600160c01b0316825260208082015163ffffffff9081169184019190915260409182015116910152565b50608082015187820361014089015261223782826120d7565b91505060a08201519150868103610160880152612254818361211a565b965050506020938401939190910190600101612170565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156122a7576122a761226b565b604052919050565b5f6001600160401b038211156122c7576122c761226b565b5060051b60200190565b5f82601f8301126122e0575f5ffd5b81516122f36122ee826122af565b61227f565b8082825260208201915060208360051b860101925085831115612314575f5ffd5b602085015b8381101561233a57805161232c816120a5565b835260209283019201612319565b5095945050505050565b5f60208284031215612354575f5ffd5b81516001600160401b03811115612369575f5ffd5b612375848285016122d1565b949350505050565b634e487b7160e01b5f52603260045260245ffd5b5f602082840312156123a1575f5ffd5b8151611961816120a5565b5f602082840312156123bc575f5ffd5b5051919050565b5f602082840312156123d3575f5ffd5b815160ff81168114611961575f5ffd5b5f602082840312156123f3575f5ffd5b81516001600160401b03811115612408575f5ffd5b8201601f81018413612418575f5ffd5b80516001600160401b038111156124315761243161226b565b612444601f8201601f191660200161227f565b818152856020838501011115612458575f5ffd5b6119f5826020830160208601611d62565b5f604082840312801561247a575f5ffd5b50604080519081016001600160401b038111828210171561249d5761249d61226b565b604052825181526020928301519281019290925250919050565b5f5f604083850312156124c8575f5ffd5b82516001600160401b038111156124dd575f5ffd5b6124e9858286016122d1565b92505060208301516001600160401b03811115612504575f5ffd5b8301601f81018513612514575f5ffd5b80516125226122ee826122af565b8082825260208201915060208360051b850101925087831115612543575f5ffd5b6020840193505b8284101561256557835182526020938401939091019061254a565b809450505050509250929050565b5f6080828403128015612584575f5ffd5b50604051608081016001600160401b03811182821017156125a7576125a761226b565b60405282516125b5816120a5565b815260208381015190820152604080840151908201526060928301519281019290925250919050565b805163ffffffff811681146125f1575f5ffd5b919050565b5f6060828403128015612607575f5ffd5b50604051606081016001600160401b038111828210171561262a5761262a61226b565b60405282516001600160c01b0381168114612643575f5ffd5b8152612651602084016125de565b6020820152612662604084016125de565b60408201529392505050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561145a5761145a61266e565b6001815b6001841115611c09578085048111156126b4576126b461266e565b60018416156126c257908102905b60019390931c928002612699565b5f826126de5750600161145a565b816126ea57505f61145a565b8160018114612700576002811461270a57612726565b600191505061145a565b60ff84111561271b5761271b61266e565b50506001821b61145a565b5060208310610133831016604e8410600b8410161715612749575081810a61145a565b6127555f198484612695565b805f19048211156127685761276861266e565b029392505050565b5f61196183836126d0565b808202811582820484141761145a5761145a61266e565b5f826127ac57634e487b7160e01b5f52601260045260245ffd5b50049056fea164736f6c634300081b000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d400fc38ed4732893174325693a63c30ee3881a80000000000000000000000004655ce3d625a63d30ba704087e52b4c31e38188b000000000000000000000000cb0b5ca20b6c5c02a9a3b2ce433650768ed2974f00000000000000000000000054586be62e3c3580375ae3723c145253060ca0c2
-----Decoded View---------------
Arg [0] : _umbrella (address): 0xD400fc38ED4732893174325693a63C30ee3881a8
Arg [1] : _rewardsController (address): 0x4655Ce3D625a63d30bA704087E52B4C31E38188B
Arg [2] : _stataTokenFactory (address): 0xCb0b5cA20b6C5C02A9A3B2cE433650768eD2974F
Arg [3] : _aaveOracle (address): 0x54586bE62E3c3580375aE3723C145253060Ca0C2
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000d400fc38ed4732893174325693a63c30ee3881a8
Arg [1] : 0000000000000000000000004655ce3d625a63d30ba704087e52b4c31e38188b
Arg [2] : 000000000000000000000000cb0b5ca20b6c5c02a9a3b2ce433650768ed2974f
Arg [3] : 00000000000000000000000054586be62e3c3580375ae3723c145253060ca0c2
Loading...
Loading
Loading...
Loading

Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.