Description:
Multi-signature wallet contract requiring multiple confirmations for transaction execution.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"@itb/aave/contracts/aaveV3/DataTypesV3.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.10;
library DataTypesV3 {
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;
//the current stable borrow rate. Expressed in ray
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;
//stableDebtToken address
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 ReserveConfigurationMap {
//bit 0-15: LTV
//bit 16-31: Liq. threshold
//bit 32-47: Liq. bonus
//bit 48-55: Decimals
//bit 56: reserve is active
//bit 57: reserve is frozen
//bit 58: borrowing is enabled
//bit 59: stable rate borrowing enabled
//bit 60: asset is paused
//bit 61: borrowing in isolation mode is enabled
//bit 62-63: reserved
//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 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-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;
}
struct EModeCategory {
// each eMode category has a custom ltv and liquidation threshold
uint16 ltv;
uint16 liquidationThreshold;
uint16 liquidationBonus;
// each eMode category may or may not have a custom oracle to override the individual assets price oracles
address priceSource;
string label;
}
enum InterestRateMode {
NONE,
STABLE,
VARIABLE
}
struct ReserveCache {
uint256 currScaledVariableDebt;
uint256 nextScaledVariableDebt;
uint256 currPrincipalStableDebt;
uint256 currAvgStableBorrowRate;
uint256 currTotalStableDebt;
uint256 nextAvgStableBorrowRate;
uint256 nextTotalStableDebt;
uint256 currLiquidityIndex;
uint256 nextLiquidityIndex;
uint256 currVariableBorrowIndex;
uint256 nextVariableBorrowIndex;
uint256 currLiquidityRate;
uint256 currVariableBorrowRate;
uint256 reserveFactor;
ReserveConfigurationMap reserveConfiguration;
address aTokenAddress;
address stableDebtTokenAddress;
address variableDebtTokenAddress;
uint40 reserveLastUpdateTimestamp;
uint40 stableDebtLastUpdateTimestamp;
}
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 maxStableRateBorrowSizePercent;
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 maxStableRateBorrowSizePercent;
uint256 reservesCount;
address addressesProvider;
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 maxStableLoanPercent;
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 totalStableDebt;
uint256 totalVariableDebt;
uint256 averageStableBorrowRate;
uint256 reserveFactor;
address reserve;
address aToken;
}
struct InitReserveParams {
address asset;
address aTokenAddress;
address stableDebtAddress;
address variableDebtAddress;
address interestRateStrategyAddress;
uint16 reservesCount;
uint16 maxNumberReserves;
}
}"
},
"@itb/aave/contracts/aaveV3/IPool.sol": {
"content": "/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.0;
import {DataTypesV3} from './DataTypesV3.sol';
struct EModeCategory {
// each eMode category has a custom ltv and liquidation threshold
uint16 ltv;
uint16 liquidationThreshold;
uint16 liquidationBonus;
// each eMode category may or may not have a custom oracle to override the individual assets price oracles
address priceSource;
string label;
}
interface IPool {
/**
* @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 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
);
/**
* @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/stable 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 The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
* @return The final amount repaid
**/
function repayWithATokens(
address asset,
uint256 amount,
uint256 interestRateMode
) external returns (uint256);
/**
* @notice Returns the data of an eMode category
* @param id The id of the category
* @return The configuration data of the category
*/
function getEModeCategoryData(uint8 id) external view returns (EModeCategory memory);
/**
* @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 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 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
* corresponding debt token (StableDebtToken or VariableDebtToken)
* - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
* and 100 stable/variable debt tokens, depending on the `interestRateMode`
* @param asset The address of the underlying asset to borrow
* @param amount The amount to be borrowed
* @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable
* @param referralCode 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/stable debt tokens of the `onBehalfOf` address
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
* @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 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 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 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 (DataTypesV3.ReserveData memory);
/**
* @dev Returns the configuration of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The configuration of the reserve
**/
function getConfiguration(address asset) external view returns (uint);
}"
},
"@itb/aave/contracts/aaveV3/IProtocolDataProviderV3.sol": {
"content": "// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.0;
interface IProtocolDataProviderV3 {
function getReserveTokensAddresses(address asset) external view returns (address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress);
function getReserveConfigurationData(address asset) external view returns (uint256 decimals, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, uint256 reserveFactor, bool collateralEnabled, bool borrowingEnabled, bool stableRateBorrowingEnabled, bool isActive, bool isFrozen);
function getReserveData(address asset) external view returns (uint256 unbacked, uint256 accruedToTreasuryScaled, uint256 totalAToken, uint256 totalStableDebt, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, uint256 averageStableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp);
function getReserveCaps(address asset) external view returns (uint256 borrowCap, uint256 supplyCap);
function getUserReserveData(address asset, address user) external view returns (uint256 aTokenBalance, uint256 stableDebt, uint256 variableDebt, uint256 principalStableDebt, uint256 scaledVariableDebt, uint256 stableBorrowRate, uint256 reserveLiquidityRate, uint40 stableRateLastUpdate, bool usedAsCollateral);
}"
},
"@itb/aave/contracts/aaveV3/IRewardsControllerV3.sol": {
"content": "// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.0;
import {IRewardsDistributorV3} from './IRewardsDistributorV3.sol';
/**
* @title IRewardsController
* @author Aave
* @notice Defines the basic interface for a Rewards Controller.
*/
interface IRewardsControllerV3 is IRewardsDistributorV3 {
/**
* @dev Emitted when a new address is whitelisted as claimer of rewards on behalf of a user
* @param user The address of the user
* @param claimer The address of the claimer
*/
event ClaimerSet(address indexed user, address indexed claimer);
/**
* @dev Emitted when rewards are claimed
* @param user The address of the user rewards has been claimed on behalf of
* @param reward The address of the token reward is claimed
* @param to The address of the receiver of the rewards
* @param claimer The address of the claimer
* @param amount The amount of rewards claimed
*/
event RewardsClaimed(
address indexed user,
address indexed reward,
address indexed to,
address claimer,
uint256 amount
);
/**
* @dev Emitted when a transfer strategy is installed for the reward distribution
* @param reward The address of the token reward
* @param transferStrategy The address of TransferStrategy contract
*/
event TransferStrategyInstalled(address indexed reward, address indexed transferStrategy);
/**
* @dev Emitted when the reward oracle is updated
* @param reward The address of the token reward
* @param rewardOracle The address of oracle
*/
event RewardOracleUpdated(address indexed reward, address indexed rewardOracle);
/**
* @dev Whitelists an address to claim the rewards on behalf of another address
* @param user The address of the user
* @param claimer The address of the claimer
*/
function setClaimer(address user, address claimer) external;
/**
* @dev Get the price aggregator oracle address
* @param reward The address of the reward
* @return The price oracle of the reward
*/
function getRewardOracle(address reward) external view returns (address);
/**
* @dev Returns the whitelisted claimer for a certain address (0x0 if not set)
* @param user The address of the user
* @return The claimer address
*/
function getClaimer(address user) external view returns (address);
/**
* @dev Returns the Transfer Strategy implementation contract address being used for a reward address
* @param reward The address of the reward
* @return The address of the TransferStrategy contract
*/
function getTransferStrategy(address reward) external view returns (address);
/**
* @dev Called by the corresponding asset on any update that affects the rewards distribution
* @param user The address of the user
* @param userBalance The user balance of the asset
* @param totalSupply The total supply of the asset
**/
function handleAction(
address user,
uint256 userBalance,
uint256 totalSupply
) external;
/**
* @dev Claims reward for a user to the desired address, on all the assets of the pool, accumulating the pending rewards
* @param assets List of assets to check eligible distributions before claiming rewards
* @param amount The amount of rewards to claim
* @param to The address that will be receiving the rewards
* @param reward The address of the reward token
* @return The amount of rewards claimed
**/
function claimRewards(
address[] calldata assets,
uint256 amount,
address to,
address reward
) external returns (uint256);
/**
* @dev Claims reward for a user on behalf, on all the assets of the pool, accumulating the pending rewards. The
* caller must be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager
* @param assets The list of assets to check eligible distributions before claiming rewards
* @param amount The amount of rewards to claim
* @param user The address to check and claim rewards
* @param to The address that will be receiving the rewards
* @param reward The address of the reward token
* @return The amount of rewards claimed
**/
function claimRewardsOnBehalf(
address[] calldata assets,
uint256 amount,
address user,
address to,
address reward
) external returns (uint256);
/**
* @dev Claims reward for msg.sender, on all the assets of the pool, accumulating the pending rewards
* @param assets The list of assets to check eligible distributions before claiming rewards
* @param amount The amount of rewards to claim
* @param reward The address of the reward token
* @return The amount of rewards claimed
**/
function claimRewardsToSelf(
address[] calldata assets,
uint256 amount,
address reward
) external returns (uint256);
/**
* @dev Claims all rewards for a user to the desired address, on all the assets of the pool, accumulating the pending rewards
* @param assets The list of assets to check eligible distributions before claiming rewards
* @param to The address that will be receiving the rewards
* @return rewardsList List of addresses of the reward tokens
* @return claimedAmounts List that contains the claimed amount per reward, following same order as "rewardList"
**/
function claimAllRewards(address[] calldata assets, address to)
external
returns (address[] memory rewardsList, uint256[] memory claimedAmounts);
/**
* @dev Claims all rewards for a user on behalf, on all the assets of the pool, accumulating the pending rewards. The caller must
* be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager
* @param assets The list of assets to check eligible distributions before claiming rewards
* @param user The address to check and claim rewards
* @param to The address that will be receiving the rewards
* @return rewardsList List of addresses of the reward tokens
* @return claimedAmounts List that contains the claimed amount per reward, following same order as "rewardsList"
**/
function claimAllRewardsOnBehalf(
address[] calldata assets,
address user,
address to
) external returns (address[] memory rewardsList, uint256[] memory claimedAmounts);
/**
* @dev Claims all reward for msg.sender, on all the assets of the pool, accumulating the pending rewards
* @param assets The list of assets to check eligible distributions before claiming rewards
* @return rewardsList List of addresses of the reward tokens
* @return claimedAmounts List that contains the claimed amount per reward, following same order as "rewardsList"
**/
function claimAllRewardsToSelf(address[] calldata assets)
external
returns (address[] memory rewardsList, uint256[] memory claimedAmounts);
}
"
},
"@itb/aave/contracts/aaveV3/IRewardsDistributorV3.sol": {
"content": "// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.0;
/**
* @title IRewardsDistributor
* @author Aave
* @notice Defines the basic interface for a Rewards Distributor.
*/
interface IRewardsDistributorV3 {
/**
* @dev Emitted when the configuration of the rewards of an asset is updated.
* @param asset The address of the incentivized asset
* @param reward The address of the reward token
* @param oldEmission The old emissions per second value of the reward distribution
* @param newEmission The new emissions per second value of the reward distribution
* @param oldDistributionEnd The old end timestamp of the reward distribution
* @param newDistributionEnd The new end timestamp of the reward distribution
* @param assetIndex The index of the asset distribution
*/
event AssetConfigUpdated(
address indexed asset,
address indexed reward,
uint256 oldEmission,
uint256 newEmission,
uint256 oldDistributionEnd,
uint256 newDistributionEnd,
uint256 assetIndex
);
/**
* @dev Emitted when rewards of an asset are accrued on behalf of a user.
* @param asset The address of the incentivized asset
* @param reward The address of the reward token
* @param user The address of the user that rewards are accrued on behalf of
* @param assetIndex The index of the asset distribution
* @param userIndex The index of the asset distribution on behalf of the user
* @param rewardsAccrued The amount of rewards accrued
*/
event Accrued(
address indexed asset,
address indexed reward,
address indexed user,
uint256 assetIndex,
uint256 userIndex,
uint256 rewardsAccrued
);
/**
* @dev Emitted when the emission manager address is updated.
* @param oldEmissionManager The address of the old emission manager
* @param newEmissionManager The address of the new emission manager
*/
event EmissionManagerUpdated(
address indexed oldEmissionManager,
address indexed newEmissionManager
);
/**
* @dev Sets the end date for the distribution
* @param asset The asset to incentivize
* @param reward The reward token that incentives the asset
* @param newDistributionEnd The end date of the incentivization, in unix time format
**/
function setDistributionEnd(
address asset,
address reward,
uint32 newDistributionEnd
) external;
/**
* @dev Sets the emission per second of a set of reward distributions
* @param asset The asset is being incentivized
* @param rewards List of reward addresses are being distributed
* @param newEmissionsPerSecond List of new reward emissions per second
*/
function setEmissionPerSecond(
address asset,
address[] calldata rewards,
uint88[] calldata newEmissionsPerSecond
) external;
/**
* @dev Gets the end date for the distribution
* @param asset The incentivized asset
* @param reward The reward token of the incentivized asset
* @return The timestamp with the end of the distribution, in unix time format
**/
function getDistributionEnd(address asset, address reward) external view returns (uint256);
/**
* @dev Returns the index of a user on a reward distribution
* @param user Address of the user
* @param asset The incentivized asset
* @param reward The reward token of the incentivized asset
* @return The current user asset index, not including new distributions
**/
function getUserAssetIndex(
address user,
address asset,
address reward
) external view returns (uint256);
/**
* @dev Returns the configuration of the distribution reward for a certain asset
* @param asset The incentivized asset
* @param reward The reward token of the incentivized asset
* @return The index of the asset distribution
* @return The emission per second of the reward distribution
* @return The timestamp of the last update of the index
* @return The timestamp of the distribution end
**/
function getRewardsData(address asset, address reward)
external
view
returns (
uint256,
uint256,
uint256,
uint256
);
/**
* @dev Returns the list of available reward token addresses of an incentivized asset
* @param asset The incentivized asset
* @return List of rewards addresses of the input asset
**/
function getRewardsByAsset(address asset) external view returns (address[] memory);
/**
* @dev Returns the list of available reward addresses
* @return List of rewards supported in this contract
**/
function getRewardsList() external view returns (address[] memory);
/**
* @dev Returns the accrued rewards balance of a user, not including virtually accrued rewards since last distribution.
* @param user The address of the user
* @param reward The address of the reward token
* @return Unclaimed rewards, not including new distributions
**/
function getUserAccruedRewards(address user, address reward) external view returns (uint256);
/**
* @dev Returns a single rewards balance of a user, including virtually accrued and unrealized claimable rewards.
* @param assets List of incentivized assets to check eligible distributions
* @param user The address of the user
* @param reward The address of the reward token
* @return The rewards amount
**/
function getUserRewards(
address[] calldata assets,
address user,
address reward
) external view returns (uint256);
/**
* @dev Returns a list all rewards of a user, including already accrued and unrealized claimable rewards
* @param assets List of incentivized assets to check eligible distributions
* @param user The address of the user
* @return The list of reward addresses
* @return The list of unclaimed amount of rewards
**/
function getAllUserRewards(address[] calldata assets, address user)
external
view
returns (address[] memory, uint256[] memory);
/**
* @dev Returns the decimals of an asset to calculate the distribution delta
* @param asset The address to retrieve decimals
* @return The decimals of an underlying asset
*/
function getAssetDecimals(address asset) external view returns (uint8);
/**
* @dev Returns the address of the emission manager
* @return The address of the EmissionManager
*/
function getEmissionManager() external view returns (address);
/**
* @dev Updates the address of the emission manager
* @param emissionManager The address of the new EmissionManager
*/
function setEmissionManager(address emissionManager) external;
}
"
},
"@itb/aave/contracts/BasePositionManager.sol": {
"content": "/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/utils/math/Math.sol';
import '@itb/quant-common/contracts/solidity8/ITBContract.sol';
import './aaveV3/IRewardsControllerV3.sol';
import './aaveV3/IPool.sol';
import './aaveV3/IProtocolDataProviderV3.sol';
/// @title BasePositionManager that implements common functions accross different Aave markets and defaults to Aave V2
/// @author IntoTheBlock Corp
/// @dev Abstract
contract BasePositionManager is ITBContract {
IRewardsControllerV3 public rewards_controller;
IPool public lending_pool;
IProtocolDataProviderV3 public protocol_data_provider;
event Deposit(address indexed token, uint amount);
event Withdraw(address indexed token, uint amount);
event Borrow(address indexed token, uint amount);
event Repay(address indexed token, uint amount);
event UpdateLendingPool(IPool old_pool, IPool new_pool);
event UpdateRewardsController(IRewardsControllerV3 old_controller, IRewardsControllerV3 new_controller);
event UpdateProtocolDataProvider(IProtocolDataProviderV3 old_provider, IProtocolDataProviderV3 new_provider);
event ClaimRewards(address reward, uint amount);
/// @param _executors Executor addresses
/// @param _wnative Wrapped native token address
/// @param _lending_pool Aave V3 Pool address
/// @param _rewards_controller Aave V3 RewardsController address
/// @param _protocol_data_provider Aave V3 ProtocolDataProvider address
constructor(address[] memory _executors, address payable _wnative, IPool _lending_pool, IRewardsControllerV3 _rewards_controller, IProtocolDataProviderV3 _protocol_data_provider) ITBContract(_executors, _wnative) {
updateLendingPool(_lending_pool);
updateRewardsController(_rewards_controller);
updateProtocolDataProvider(_protocol_data_provider);
}
modifier hasRewardsController() {
require(address(rewards_controller) != address(0), 'C1'); // RewardsController not set
_;
}
/* Helpers */
/// @notice Atoken addresses for a given market
/// @param _token Underlying market
/// @return Atoken address
/// @return Stable debt address
/// @return Variable debt address
function _getAaveTokens(address _token) internal view returns (address, address, address) {
return protocol_data_provider.getReserveTokensAddresses(_token); /* aToken, stableDebtToken, variableDebtToken */
}
/// @notice Get the LTV of a given market taking into account current EMode category
/// @return LTV scaled to 1e18
function _getLTV(address _token) internal view returns (uint) {
uint current_emode_category = lending_pool.getUserEMode(address(this));
uint ltv_1e4;
if (current_emode_category == 0) {
uint mask = lending_pool.getConfiguration(_token);
ltv_1e4 = mask % 2**16;
}
else
ltv_1e4 = lending_pool.getEModeCategoryData(uint8(current_emode_category)).ltv;
return ltv_1e4 * 1e18 / 1e4;
}
/// @notice Supply tokens to a given market
/// @param _token Underlying market
/// @param _amount Amount to supply
function _deposit(address _token, uint _amount) internal {
_checkAllowanceAndApprove(_token, address(lending_pool), _amount);
lending_pool.supply(_token, _amount, address(this), 0);
emit Deposit(_token, _amount);
}
/// @notice Withdraw supplied tokens from a given market
/// @param _token Underlying market
/// @param _amount Amount to withdraw
function _withdrawSupply(address _token, uint256 _amount) internal {
lending_pool.withdraw(_token, _amount, address(this));
emit Withdraw(_token, _amount);
}
/// @notice Borrow tokens from a given market
/// @param _token Underlying market
/// @param _amount Amount to borrow
function _borrow(address _token, uint _amount) internal {
lending_pool.borrow(_token, _amount, 2, 0, address(this));
emit Borrow(_token, _amount);
}
/// @notice Repay debt for a given market
/// @param _token Underlying market
/// @param _amount Amount to repay
function _repay(address _token, uint _amount) internal {
_checkAllowanceAndApprove(_token, address(lending_pool), _amount);
lending_pool.repay(_token, _amount, 2, address(this));
emit Repay(_token, _amount);
}
/// @notice Repay all debt for a given market
/// @param _token Underlying market
function _repayAll(address _token) internal {
_repay(_token, type(uint).max);
}
/* Infra */
/// @notice Only owner. Update LendingPool address
/// @param _address New address
function updateLendingPool(IPool _address) public onlyOwner {
emit UpdateLendingPool(lending_pool, _address);
lending_pool = _address;
}
/// @notice Only owner. Update RewardsController address
/// @param _address New address
function updateRewardsController(IRewardsControllerV3 _address) public onlyOwner {
emit UpdateRewardsController(rewards_controller, _address);
rewards_controller = _address;
}
/// @notice Only owner. Update ProtocolDataProvider address
/// @param _address New address
function updateProtocolDataProvider(IProtocolDataProviderV3 _address) public onlyOwner {
emit UpdateProtocolDataProvider(protocol_data_provider, _address);
protocol_data_provider = _address;
}
/* Primitives */
}"
},
"@itb/aave/contracts/merkl/IMerkleDistributor.sol": {
"content": "/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.0;
interface IMerkleDistributor {
event Claimed(address indexed user, address indexed token, uint256 amount);
function claim(address[] calldata users, address[] calldata tokens, uint256[] calldata amounts, bytes32[][] calldata proofs) external;
function claimed(address user, address token) external view returns (uint208 amount, uint48 timestamp, bytes32 merkleRoot);
function toggleOperator(address user, address operator) external;
function operators(address user, address operator) external view returns (uint);
}"
},
"@itb/aave/contracts/single/PositionManager.sol": {
"content": "/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.0;
import '../BasePositionManager.sol';
/// @title PositionManager that targets Aave V2 markets
/// @author IntoTheBlock Corp
/// @notice Assembles a leveraged position using the same market for supply and borrow in Aave V2
/// @dev Deprecated, Aave now uses V3 markets
contract PositionManager is BasePositionManager {
/// @notice Mapping of underlying market to maximum leverage factor set by owner scaled by 1e18 (2x leverage: 2e18)
mapping (address => uint) public maxLFByMarket;
event Assemble(address token, uint amount, uint leverage_factor);
event Disassemble(address token, uint amount, uint leverage_factor);
event IncreaseLeverage(address token, uint amount, uint leverage_factor);
event DecreaseLeverage(address token, uint amount, uint leverage_factor);
event UpdatePositionConfig(PositionConfig old_config, PositionConfig new_config);
event UpdateMaxLF(address token, uint max_lf);
event SetEMode(uint8 category);
event RepayWithATokens(address indexed token, uint amount);
struct PositionConfig {
address underlying_token;
uint min_withdraw_step;
uint min_borrow_step;
uint leverage_factor_mantissa;
}
PositionConfig public parameters_config;
/// @param _executors Executor addresses
/// @param _wnative Wrapped native token address
/// @param _tokens Array of supported underlying markets
/// @param _max_lfs For each supported market in _tokens, maximum leverage factor set by owner scaled by 1e18
/// @param _lending_pool Aave V3 Pool address
/// @param _rewards_controller Aave V3 RewardsController address
/// @param _protocol_data_provider Aave V3 ProtocolDataProvider address
/// @param _parameters_config Configuration for assemble/disassemble without parameters
constructor(
address[] memory _executors,
address payable _wnative,
address[] memory _tokens,
uint[] memory _max_lfs,
IPool _lending_pool,
IRewardsControllerV3 _rewards_controller,
IProtocolDataProviderV3 _protocol_data_provider,
PositionConfig memory _parameters_config
) BasePositionManager(_executors, _wnative, _lending_pool, _rewards_controller, _protocol_data_provider) {
for (uint i = 0; i < _tokens.length; i++)
updateMaxLF(_tokens[i], _max_lfs[i]);
updatePositionConfig(_parameters_config);
}
function VERSION() external pure returns (string memory) {
return "2.0.0";
}
/// @notice Only executor. Update parameters configuration.
function updatePositionConfig(PositionConfig memory _parameters_config) public onlyExecutor {
emit UpdatePositionConfig(parameters_config, _parameters_config);
parameters_config = _parameters_config;
}
/* Helpers */
/// @notice Get underlyings addresses
/// @return assets all underlying assets
function getPositionAssets() public view returns (address[] memory assets) {
assets = new address[](1);
assets[0] = parameters_config.underlying_token;
}
/// @notice Get underlyings address and amounts
/// @return assets all underlying assets
/// @return amounts amounts of all underlying assets
function getUnderlyings() public view returns (address[] memory assets, uint256[] memory amounts) {
assets = getPositionAssets();
amounts = new uint[](1);
(uint supplied, uint borrowed) = accountMarketSnapshot(parameters_config.underlying_token);
amounts[0] = supplied - borrowed;
}
/// @notice Calculate liquidity and shortfall based on borrowing power (credit) and borrowed amount (debt)
/// @param _borrowing_power Borrowing power
/// @param _borrowed Borrowed amount
/// @return Liquidity (0 if undercollateralized)
/// @return Shortfall (0 if overcollateralized)
function _calculateLiquidity(uint _borrowing_power, uint _borrowed) internal pure returns (uint, uint) {
uint liquidity = _borrowing_power > _borrowed ? _borrowing_power - _borrowed : 0;
uint shortfall = _borrowing_power < _borrowed ? _borrowed - _borrowing_power : 0;
return (liquidity, shortfall);
}
/// @notice Use supply side aTokens to repay debt incurred in the same market
/// @param _token Underlying market
/// @param _amount Amount to repay
function _repayWithATokens(address _token, uint _amount) internal {
(, uint borrow_amount) = accountMarketSnapshot(_token);
if (borrow_amount != 0)
lending_pool.repayWithATokens(_token, _amount, 2);
emit RepayWithATokens(_token, _amount);
}
/// @notice Claim rewards in a given token for a given market and amount
/// @dev Will claim both supply and variable debt rewards
/// @param _token Underlying market
/// @param _amount Amount of _reward_address to claim
/// @param _reward_address Reward token to claim
/// @return claimed_amount claimed
function _claim_rewards(address _token, uint _amount, address _reward_address) internal returns (uint claimed_amount) {
address[] memory tokens = new address[](2);
(address atoken, , address variable_debt_token) = _getAaveTokens(_token);
tokens[0] = atoken;
tokens[1] = variable_debt_token;
uint bal_before = _erc20Balance(_reward_address);
rewards_controller.claimRewards(tokens, _amount, address(this), _reward_address);
uint bal_after = _erc20Balance(_reward_address);
claimed_amount = bal_after - bal_before;
emit ClaimRewards(_reward_address, claimed_amount);
}
/// @notice Compares after execution leverage vs max leverage factor and reverts if above max leverage factor
modifier leverageCheck(address _token) virtual {
_;
(uint supplied, uint borrowed) = accountMarketSnapshot(_token);
if (borrowed == 0)
return;
require(supplied >= borrowed, 'Dangerous LF');
uint net = supplied - borrowed;
uint max_lf_mantissa = maxLFByMarket[_token];
require(net * max_lf_mantissa / 1e18 >= supplied, 'Dangerous LF');
}
/* Infra */
/// @notice Only owner. Set maximum leverage for a given market
/// @param _token Underlying market
/// @param _max_lf Maximum leverage factor scaled by 1e18
function updateMaxLF(address _token, uint _max_lf) public onlyOwner {
maxLFByMarket[_token] = _max_lf;
emit UpdateMaxLF(_token, _max_lf);
}
/// @notice Only owner. Set EMode category and update maxLFs accordingly
/// @param _category Emode category
/// @param _tokens Array of supported underlying markets to update
/// @param _max_lfs For each supported market in _tokens, maximum leverage factor scaled by 1e18 (2x leverage: 2e18)
function setEMode(uint8 _category, address[] memory _tokens, uint[] memory _max_lfs) external onlyOwner {
lending_pool.setUserEMode(_category);
for (uint i = 0; i < _tokens.length; i++)
updateMaxLF(_tokens[i], _max_lfs[i]);
emit SetEMode(_category);
}
/* View */
/// @notice Atoken addresses for a given market
/// @param _token Underlying market
/// @return Atoken address
/// @return Stable debt address
/// @return Variable debt address
function getAaveTokens(address _token) external view returns(address, address, address) {
return _getAaveTokens(_token);
}
/// @notice Liquidity of the position accross all markets
/// @return Liquidity (or 0 if undercollateralized)
/// @return Shortfall (or 0 if overcollateralized)
function accountLiquidity() external view returns(uint, uint) {
(, uint borrow_oracle, uint borrowing_power_oracle, , ,) = lending_pool.getUserAccountData(address(this));
return _calculateLiquidity(borrowing_power_oracle, borrow_oracle);
}
/// @notice Liquidity of the position for a given market
/// @param _token Underlying market
/// @return Liquidity (or 0 if undercollateralized)
/// @return Shortfall (or 0 if overcollateralized)
function accountMarketLiquidity(address _token) external view returns (uint, uint) {
(uint supply_amount, uint borrow_amount) = accountMarketSnapshot(_token);
uint borrowing_power = supply_amount * _getLTV(_token) / 1e18;
return _calculateLiquidity(borrowing_power, borrow_amount);
}
/// @notice Snapshot of the position accross all markets
/// @return Total supplied measured in ETH
/// @return Total borrowed measured in ETH
function accountSnapshot() external virtual view returns(uint, uint) {
(uint supply_oracle, uint borrow_oracle, , , ,) = lending_pool.getUserAccountData(address(this));
return (supply_oracle, borrow_oracle);
}
/// @notice Snapshot of the position for a given market
/// @param _token Underlying market
/// @return Total supplied measured in _token
/// @return Total borrowed measured in _token
function accountMarketSnapshot(address _token) public view returns(uint, uint) {
(address _atoken, , address _variable_token) = _getAaveTokens(_token);
uint supply_amount = _erc20Balance(_atoken);
uint borrow_amount = _erc20Balance(_variable_token);
return (supply_amount, borrow_amount);
}
/* Primitives */
/// @notice Only executor. Supply tokens to a given market
/// @param _token Underlying market
/// @param _amount Amount to supply
function deposit(address _token, uint _amount) external virtual onlyExecutor {
_deposit(_token, _amount);
}
/// @notice Only executor. Withdraw supplied tokens from a given market
/// @param _token Underlying market
/// @param _amount Amount to withdraw
function withdrawSupply(address _token, uint _amount) external virtual onlyExecutor leverageCheck(_token) {
_withdrawSupply(_token, _amount);
}
/// @notice Only executor. Withdraw all supplied tokens from a given market
/// @param _token Underlying market
function withdrawSupplyAll(address _token) public virtual onlyExecutor leverageCheck(_token) {
_withdrawSupply(_token, type(uint).max);
}
/// @notice Only executor. Borrow tokens from a given market
/// @param _token Underlying market
/// @param _amount Amount to borrow
function borrow(address _token, uint _amount) external virtual onlyExecutor leverageCheck(_token) {
_borrow(_token, _amount);
}
/// @notice Only executor. Repay debt for a given market
/// @param _token Underlying market
/// @param _amount Amount to repay
function repay(address _token, uint _amount) external virtual onlyExecutor {
_repay(_token, _amount);
}
/// @notice Only executor. Repay all debt for a given market
/// @param _token Underlying market
function repayAll(address _token) external virtual onlyExecutor {
_repayAll(_token);
}
/// @notice Only executor. Use supply side aTokens to repay debt incurred in the same market
/// @param _amount Amount to repay
function repayWithATokens(address _token, uint _amount) external onlyExecutor {
_repayWithATokens(_token, _amount);
}
/// @notice Only executor. Use supply side aTokens to repay all debt incurred in the same market
/// @param _token Underlying market
function repayAllWithATokens(address _token) external onlyExecutor {
_repayWithATokens(_token, type(uint).max);
}
/* Assembling */
/// @notice Only executor. Supply tokens to the market and assemble a leveraged position. Resulting leverage cant go above maxLF set by owner
/// @dev Recursively supply-borrow-supply until desired leverage is reached or supplied amount is too small to make a difference
/// @param _token Underlying market
/// @param _amount Initial amount to supply to the market. Can be 0 to increase leverage without adding external collateral
/// @param _max_leverage_factor_mantissa Desired leverage scaled to 1e18
/// @param _min_borrow_step Minimum amount of tokens to borrow/supply on each step to avoid looping with small amounts
function increaseLeverage(address _token, uint _amount, uint _max_leverage_factor_mantissa, uint _min_borrow_step) public onlyExecutor leverageCheck(_token) {
if (_amount > 0)
_deposit(_token, _amount);
(uint supply_amount, uint borrow_amount) = accountMarketSnapshot(_token);
uint net_amount = supply_amount - borrow_amount;
uint collateral_factor_mantissa = _getLTV(_token);
/*
desired borrow based on desired leverage factor and net
S = LF * net
B = S - net
nB = nS - net
nB = nLF * net - net
*/
uint desired_borrow = net_amount * _max_leverage_factor_mantissa / 1e18 - net_amount;
while (desired_borrow > borrow_amount) {
uint max_to_borrow = desired_borrow - borrow_amount;
uint approx_borrow_limit = supply_amount * collateral_factor_mantissa / 1e18;
uint approx_current_liquidity = approx_borrow_limit - borrow_amount - 10;
uint to_borrow = Math.min(max_to_borrow, approx_current_liquidity);
if (to_borrow < _min_borrow_step)
break;
_borrow(_token, to_borrow);
_deposit(_token, to_borrow);
supply_amount = supply_amount + to_borrow;
borrow_amount = borrow_amount + to_borrow;
}
(supply_amount, borrow_amount) = accountMarketSnapshot(_token);
emit IncreaseLeverage(_token, _amount, _max_leverage_factor_mantissa);
}
/// @notice Only executor. Withdraw tokens to the market and disassemble a leveraged position. Resulting leverage cant go above maxLF set by owner
/// @dev Repay debt using supply to reach the desired leverage
/// @param _token Underlying market
/// @param _amount Initial amount to withdraw from the market
/// @param _min_leverage_factor_mantissa Desired leverage scaled to 1e18
function decreaseLeverage(address _token, uint _amount, uint _min_leverage_factor_mantissa, uint ) public onlyExecutor leverageCheck(_token) {
if (_amount > 0)
_deposit(_token, _amount);
if (_min_leverage_factor_mantissa == 1e18) {
_repayWithATokens(_token, type(uint).max);
return;
}
(uint supply_amount, uint borrow_amount) = accountMarketSnapshot(_token);
uint net_amount = supply_amount - borrow_amount;
/*
desired borrow based on desired leverage factor and net
S = LF * net
B = S - net
nB = nS - net
nB = nLF * net - net
*/
uint desired_borrow = net_amount * _min_leverage_factor_mantissa / 1e18 - net_amount;
uint to_repay = borrow_amount - desired_borrow;
_repayWithATokens(_token, to_repay);
emit DecreaseLeverage(_token, _amount, _min_leverage_factor_mantissa);
}
function _fullDisassemble(address _token) internal {
decreaseLeverage(_token, 0, 1e18, 0);
withdrawSupplyAll(_token);
}
/// @notice Only executor. Disassemble all leverage and withdraw everything from supply
/// @param _token Underlying market
function fullDisassemble(address _token) external onlyExecutor {
_fullDisassemble(_token);
}
/* Rewards */
/// @notice Only executor. Claim rewards in the first reward token for a given market and amount
/// @dev Will claim both supply and variable debt rewards. Assumes only 1 reward token and atoken reward token = variable debt reward token
/// @param _token Underlying market
/// @param _amount Amount of _reward_address to claim
/// @return Amount claimed
function claimRewards(address _token, uint _amount) external onlyExecutor hasRewardsController returns (uint) {
(address atoken, , ) = _getAaveTokens(_token);
address[] memory rewards = rewards_controller.getRewardsByAsset(atoken);
return _claim_rewards(_token, _amount, rewards[0]);
}
/// @notice Only executor. Claim rewards in a given token for a given market and amount
/// @dev Will claim both supply and variable debt rewards
/// @param _token Underlying market
/// @param _amount Amount of _reward_address to claim
/// @param _reward_address Reward token to claim
/// @return Amount claimed
function claimRewards(address _token, uint _amount, address _reward_address) external onlyExecutor hasRewardsController returns (uint) {
return _claim_rewards(_token, _amount, _reward_address);
}
/// @notice Only executor. Claim rewards in all reward tokens for a given market and amount
/// @dev Will claim both supply and variable debt rewards. TODO: develop Harvester with multiple reward tokens support
/// @param _token Underlying market
function claimAllRewards(address _token) public onlyExecutor hasRewardsController returns (address[] memory reward_addresses, uint[] memory claimed_amounts) {
address[] memory tokens = new address[](2);
(address atoken, , address variable_debt_token) = _getAaveTokens(_token);
tokens[0] = atoken;
tokens[1] = variable_debt_token;
return rewards_controller.claimAllRewards(tokens, address(this));
}
/// @notice Only executor. Claim all rewards using underlying_token from parameters_config
/// @return rewards_addresses all rewards address
/// @return claimed_amounts all amounts claimed
function claimRewards() public onlyExecutor hasRewardsController returns (address[] memory rewards_addresses, uint[] memory claimed_amounts) {
return claimAllRewards(parameters_config.underlying_token);
}
/* Assemble via parameters config */
/// @notice Checks if all parameters_config used in the assembly have the correct value
modifier hasConfig() {
require(parameters_config.underlying_token != address(0));
require(parameters_config.leverage_factor_mantissa >= 1e18);
_;
}
function _assemble() internal returns (uint) {
PositionConfig memory pc = parameters_config;
uint amount = _erc20Balance(pc.underlying_token);
increaseLeverage(pc.underlying_token, amount, pc.leverage_factor_mantissa, pc.min_borrow_step);
emit Assemble(pc.underlying_token, amount, pc.leverage_factor_mantissa);
return amount;
}
function _disassemble(uint _percent) internal returns (uint) {
(uint supply_amount, uint borrow_amount) = accountMarketSnapshot(parameters_config.underlying_token);
uint initial_net = supply_amount - borrow_amount;
uint final_net = initial_net * (1e18 - _percent) / 1e18;
uint final_lf = parameters_config.leverage_factor_mantissa;
uint final_supply = final_net * final_lf / 1e18;
uint to_withdraw = initial_net - final_net;
uint temp_supply = to_withdraw + final_supply;
uint temp_leverage_factor = 1e18 * temp_supply / initial_net;
decreaseLeverage(parameters_config.underlying_token, 0, temp_leverage_factor, parameters_config.min_withdraw_step);
if (to_withdraw != 0)
_withdrawSupply(parameters_config.underlying_token, to_withdraw);
(supply_amount, borrow_amount) = accountMarketSnapshot(parameters_config.underlying_token);
uint net = supply_amount - borrow_amount;
uint lf_mantissa = net != 0 ? supply_amount * 1e18 / net : 0;
emit Disassemble(parameters_config.underlying_token, initial_net - net /* should be same as to_withdraw */, lf_mantissa);
return to_withdraw;
}
/// @notice Only executor. assemble by configuration, use all amount available
function assemble() external onlyExecutor hasConfig {
_assemble();
}
/// @notice Only executor. Disassemble by configuration
/// @param _percent Amount to disassemble and withdrawSupply expressed as a percentage. 1e18 is equivalent to 100%.
function disassemble(uint _percent) external onlyExecutor hasConfig {
_disassemble(_percent);
}
/// @notice Only executor. fullDisassemble by configuration
function fullDisassemble() external onlyExecutor hasConfig {
_fullDisassemble(parameters_config.underlying_token);
}
/* YieldPositionMinOuts interface */
function assemble(uint) external onlyExecutor hasConfig returns (uint) {
return _assemble();
}
function disassemble(uint _percentage, uint[] memory) external onlyExecutor hasConfig returns (uint[] memory) {
uint[] memory amounts_out = new uint[](1);
amounts_out[0] = _disassemble(_percentage);
return amounts_out;
}
}"
},
"@itb/aave/contracts/single/PositionManagerMerkl.sol": {
"content": "/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.0;
import './PositionManager.sol';
import '../UseMerkl.sol';
/// @title PositionManager that allows to set claimer operator for Merkl rewards
/// @author IntoTheBlock Corp
contract PositionManagerMerkl is PositionManager, UseMerkl {
/// @param _executors Executor addresses
/// @param _wnative Wrapped native token address
/// @param _tokens Array of supported underlying markets
/// @param _max_lfs For each supported market in _tokens, maximum leverage factor set by owner scaled by 1e18 (2x leverage: 2e18)
/// @param _lending_pool Aave V3 LendingPool address
/// @param _rewards_controller Aave V3 RewardsController address
/// @param _protocol_data_provider Aave V3 ProtocolDataProvider address
/// @param _position_config Configuration for assemble/disassemble without parameters
/// @param _merkl_distributor Merkl distributor address
/// @param _merkl_operator Merkl operator address for claiming rewards
constructor(address[] memory _executors, address payable _wnative, address[] memory _tokens, uint[] memory _max_lfs, IPool _lending_pool, IRewardsControllerV3 _rewards_controller, IProtocolDataProviderV3 _protocol_data_provider, PositionConfig memory _position_config, IMerkleDistributor _merkl_distributor, address _merkl_operator) PositionManager(_executors, _wnative, _tokens, _max_lfs, _lending_pool, _rewards_controller, _protocol_data_provider, _position_config) UseMerkl(_merkl_distributor, _merkl_operator) {}
}"
},
"@itb/aave/contracts/single/PositionManagerMerklOwnable2StepWithShortcut.sol": {
"content": "/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.0;
import './PositionManagerMerkl.sol';
import '@itb/quant-common/contracts/solidity8/utils/Ownable2StepWithShortcut.sol';
contract PositionManagerMerklOwnable2StepWithShortcut is PositionManagerMerkl, Ownable2StepWithShortcut {
constructor(address[] memory _executors, address payable _wnative, address[] memory _tokens, uint[] memory _max_lfs, IPool _lending_pool, IRewardsControllerV3 _rewards_controller, IProtocolDataProviderV3 _protocol_data_provider, PositionConfig memory _position_config, IMerkleDistributor _merkl_distributor, address _merkl_operator) PositionManagerMerkl(_executors, _wnative, _tokens, _max_lfs, _lending_pool, _rewards_controller, _protocol_data_provider, _position_config, _merkl_distributor, _merkl_operator) {}
}"
},
"@itb/aave/contracts/UseMerkl.sol": {
"content": "/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.0;
import './merkl/IMerkleDistributor.sol';
import '@openzeppelin/contracts/access/Ownable2Step.sol';
/// @title Allows to set claimer operator for Merkl rewards
/// @author IntoTheBlock Corp
abstract contract UseMerkl is Ownable2Step {
IMerkleDistributor public merkl_distributor;
event UpdateMerklDistributor(address merkl_distributor);
event AddMerklOperator(address indexed operator);
event RemoveMerklOperator(address indexed operator);
/// @param _merkl_distributor Merkl distributor address
/// @param _merkl_operator Merkl operator address for claiming rewards
constructor(IMerkleDistributor _merkl_distributor, address _merkl_operator) {
updateMerklDistributor(_merkl_distributor);
if (_merkl_operator != address(0))
addMerklOperator(_merkl_operator);
}
function updateMerklDistributor(IMerkleDistributor _merkl_distributor) public onlyOwner {
merkl_distributor = _merkl_distributor;
emit UpdateMerklDistributor(address(_merkl_distributor));
}
function addMerklOperator(address _operator) public onlyOwner {
require(merkl_distributor.operators(address(this), _operator) == 0, 'O1'); // It's already an operator
merkl_distributor.toggleOperator(address(this), _operator);
emit AddMerklOperator(_operator);
}
function removeMerklOperator(address _operator) external onlyOwner {
require(merkl_distributor.operators(address(this), _operator) > 0, 'O2'); // It's not an operator
merkl_distributor.toggleOperator(address(this), _operator);
emit RemoveMerklOperator(_operator);
}
}"
},
"@itb/quant-common/contracts/solidity8/ITBContract.sol": {
"content": "/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.20;
import './utils/Withdrawable.sol';
import './utils/IWETH.sol';
/// @title ITBContract contract that implements common owner only functions accros all strategies
/// @author IntoTheBlock Corp
/// @dev Abstract
abstract contract ITBContract is Withdrawable {
using SafeERC20 for IERC20;
event ApproveToken(address indexed token, address guy, uint256 wad);
address payable immutable public WNATIVE;
uint constant ONE = 1e18;
/// @param _executors Executor addresses
constructor(address[] memory _executors, address payable _wnative) Executable(_executors) {
WNATIVE = _wnative;
}
function _percentageAmount(uint _amount, uint _percentage) internal pure returns (uint) {
return _amount * _percentage / ONE;
}
///
Submitted on: 2025-10-10 09:55:05
Comments
Log in to comment.
No comments yet.