-
Notifications
You must be signed in to change notification settings - Fork 3
Feat/aave and morpho vaults #185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
43707c9
d05d40d
462e01e
e76018c
db24ac1
74b10e9
64618d2
d78beb8
cf6ae91
714194d
c50988f
675402c
8fc4cf5
23a59c1
8dbcbcd
8dfa398
e54995e
cb1033e
67c35b9
62d441b
840a2a0
4703429
478497f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,201 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity 0.8.9; | ||
|
|
||
| import {IERC20Upgradeable as IERC20} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; | ||
| import {SafeERC20Upgradeable as SafeERC20} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; | ||
|
|
||
| import "./DepositVault.sol"; | ||
| import "./interfaces/aave/IAaveV3Pool.sol"; | ||
|
|
||
| /** | ||
| * @title DepositVaultWithAave | ||
| * @notice Smart contract that handles mToken minting and invests | ||
| * proceeds into Aave V3 Pool | ||
| * @dev If `aaveDepositsEnabled` is false, regular deposit flow is used | ||
| * @author RedDuck Software | ||
| */ | ||
| contract DepositVaultWithAave is DepositVault { | ||
| using DecimalsCorrectionLibrary for uint256; | ||
| using SafeERC20 for IERC20; | ||
|
|
||
| /** | ||
| * @notice mapping payment token to Aave V3 Pool | ||
| */ | ||
| mapping(address => IAaveV3Pool) public aavePools; | ||
|
|
||
| /** | ||
| * @notice Whether Aave auto-invest deposits are enabled | ||
| * @dev if false, regular deposit flow will be used | ||
| */ | ||
| bool public aaveDepositsEnabled; | ||
|
|
||
| /** | ||
| * @notice Whether to fall back to raw token transfer on auto-invest failure | ||
| * @dev if false, the transaction will revert when auto-invest fails | ||
| */ | ||
| bool public autoInvestFallbackEnabled; | ||
|
|
||
| /** | ||
| * @dev leaving a storage gap for futures updates | ||
| */ | ||
| uint256[50] private __gap; | ||
|
|
||
| /** | ||
| * @notice Emitted when an Aave V3 Pool is configured for a payment token | ||
| * @param caller address of the caller | ||
| * @param token payment token address | ||
| * @param pool Aave V3 Pool address | ||
| */ | ||
| event SetAavePool( | ||
| address indexed caller, | ||
| address indexed token, | ||
| address indexed pool | ||
| ); | ||
|
|
||
| /** | ||
| * @notice Emitted when an Aave V3 Pool is removed for a payment token | ||
| * @param caller address of the caller | ||
| * @param token payment token address | ||
| */ | ||
| event RemoveAavePool(address indexed caller, address indexed token); | ||
|
|
||
| /** | ||
| * @notice Emitted when `aaveDepositsEnabled` flag is updated | ||
| * @param enabled Whether Aave deposits are enabled | ||
| */ | ||
| event SetAaveDepositsEnabled(bool indexed enabled); | ||
|
|
||
| /** | ||
| * @notice Emitted when `autoInvestFallbackEnabled` flag is updated | ||
| * @param enabled Whether fallback to raw transfer is enabled | ||
| */ | ||
| event SetAutoInvestFallbackEnabled(bool indexed enabled); | ||
|
|
||
| /** | ||
| * @notice Sets the Aave V3 Pool for a specific payment token | ||
| * @param _token payment token address | ||
| * @param _aavePool Aave V3 Pool address for this token | ||
| */ | ||
| function setAavePool(address _token, address _aavePool) | ||
| external | ||
| onlyVaultAdmin | ||
| { | ||
| _validateAddress(_token, true); | ||
| _validateAddress(_aavePool, true); | ||
| require( | ||
| IAaveV3Pool(_aavePool).getReserveAToken(_token) != address(0), | ||
| "DVA: token not in pool" | ||
| ); | ||
| aavePools[_token] = IAaveV3Pool(_aavePool); | ||
| emit SetAavePool(msg.sender, _token, _aavePool); | ||
| } | ||
|
|
||
| /** | ||
| * @notice Removes the Aave V3 Pool for a specific payment token | ||
| * @param _token payment token address | ||
| */ | ||
| function removeAavePool(address _token) external onlyVaultAdmin { | ||
| require(address(aavePools[_token]) != address(0), "DVA: pool not set"); | ||
| delete aavePools[_token]; | ||
| emit RemoveAavePool(msg.sender, _token); | ||
| } | ||
|
|
||
| /** | ||
| * @notice Updates `aaveDepositsEnabled` value | ||
| * @param enabled whether Aave auto-invest deposits are enabled | ||
| */ | ||
| function setAaveDepositsEnabled(bool enabled) external onlyVaultAdmin { | ||
| aaveDepositsEnabled = enabled; | ||
| emit SetAaveDepositsEnabled(enabled); | ||
| } | ||
|
|
||
| /** | ||
| * @notice Updates `autoInvestFallbackEnabled` value | ||
| * @param enabled whether fallback to raw transfer is enabled on auto-invest failure | ||
| */ | ||
| function setAutoInvestFallbackEnabled(bool enabled) | ||
| external | ||
| onlyVaultAdmin | ||
| { | ||
| autoInvestFallbackEnabled = enabled; | ||
| emit SetAutoInvestFallbackEnabled(enabled); | ||
| } | ||
|
|
||
| /** | ||
| * @dev overrides instant deposit transfer hook to auto-invest into Aave | ||
| */ | ||
| function _instantTransferTokensToTokensReceiver( | ||
| address tokenIn, | ||
| uint256 amountToken, | ||
| uint256 tokensDecimals | ||
| ) internal override { | ||
| IAaveV3Pool pool = aavePools[tokenIn]; | ||
| if (!aaveDepositsEnabled || address(pool) == address(0)) { | ||
| return | ||
| super._instantTransferTokensToTokensReceiver( | ||
| tokenIn, | ||
| amountToken, | ||
| tokensDecimals | ||
| ); | ||
| } | ||
|
|
||
| _autoInvest(tokenIn, amountToken, tokensDecimals, pool); | ||
| } | ||
|
|
||
| /** | ||
| * @dev overrides request deposit transfer hook to auto-invest into Aave | ||
| */ | ||
| function _requestTransferTokensToTokensReceiver( | ||
| address tokenIn, | ||
| uint256 amountToken, | ||
| uint256 tokensDecimals | ||
| ) internal override { | ||
| IAaveV3Pool pool = aavePools[tokenIn]; | ||
| if (!aaveDepositsEnabled || address(pool) == address(0)) { | ||
| return | ||
| super._requestTransferTokensToTokensReceiver( | ||
| tokenIn, | ||
| amountToken, | ||
| tokensDecimals | ||
| ); | ||
| } | ||
|
|
||
| _autoInvest(tokenIn, amountToken, tokensDecimals, pool); | ||
| } | ||
|
|
||
| /** | ||
| * @dev Transfers tokens from user to this contract and supplies them | ||
| * to the Aave V3 Pool. On failure, either falls back to raw transfer | ||
| * or reverts based on `autoInvestFallbackEnabled`. | ||
| * @param tokenIn token address | ||
| * @param amountToken amount of tokens to transfer in base18 | ||
| * @param tokensDecimals decimals of tokens | ||
| * @param pool Aave V3 Pool | ||
| */ | ||
| function _autoInvest( | ||
| address tokenIn, | ||
| uint256 amountToken, | ||
| uint256 tokensDecimals, | ||
| IAaveV3Pool pool | ||
| ) private { | ||
| uint256 transferredAmount = _tokenTransferFromUser( | ||
| tokenIn, | ||
| address(this), | ||
| amountToken, | ||
| tokensDecimals | ||
| ); | ||
|
|
||
| IERC20(tokenIn).safeIncreaseAllowance(address(pool), transferredAmount); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| try | ||
| pool.supply(tokenIn, transferredAmount, tokensReceiver, 0) | ||
| {} catch { | ||
| if (autoInvestFallbackEnabled) { | ||
| IERC20(tokenIn).safeApprove(address(pool), 0); | ||
| IERC20(tokenIn).safeTransfer(tokensReceiver, transferredAmount); | ||
| } else { | ||
| revert("DVA: auto-invest failed"); | ||
| } | ||
| } | ||
| } | ||
dmytro-horbatenko marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.