From 420ada2036465b2ad7d671734655a79ea573eda3 Mon Sep 17 00:00:00 2001 From: bhavik-m Date: Sat, 19 Feb 2022 19:17:39 +0530 Subject: [PATCH] added paybackWithAToken func + minor fix --- .../mainnet/connectors/aave/v3/helpers.sol | 91 +++-- .../mainnet/connectors/aave/v3/interface.sol | 110 +++-- contracts/mainnet/connectors/aave/v3/main.sol | 382 ++++++++++-------- 3 files changed, 354 insertions(+), 229 deletions(-) diff --git a/contracts/mainnet/connectors/aave/v3/helpers.sol b/contracts/mainnet/connectors/aave/v3/helpers.sol index 7d5b9836..13431d11 100644 --- a/contracts/mainnet/connectors/aave/v3/helpers.sol +++ b/contracts/mainnet/connectors/aave/v3/helpers.sol @@ -2,48 +2,65 @@ pragma solidity ^0.7.0; import { DSMath } from "../../../common/math.sol"; import { Basic } from "../../../common/basic.sol"; -import { AaveLendingPoolProviderInterface, AaveDataProviderInterface } from "./interface.sol"; +import { AavePoolProviderInterface, AaveDataProviderInterface } from "./interface.sol"; abstract contract Helpers is DSMath, Basic { - - /** - * @dev Aave Lending Pool Provider - */ - AaveLendingPoolProviderInterface constant internal aaveProvider = AaveLendingPoolProviderInterface(0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5); + /** + * @dev Aave Pool Provider + */ + AavePoolProviderInterface internal constant aaveProvider = + AavePoolProviderInterface(0xA55125A90d75a95EC00130E8E8C197dB5641Eb19); // rinkeby address - /** - * @dev Aave Protocol Data Provider - */ - AaveDataProviderInterface constant internal aaveData = AaveDataProviderInterface(0x057835Ad21a177dbdd3090bB1CAE03EaCF78Fc6d); + /** + * @dev Aave Pool Data Provider + */ + AaveDataProviderInterface internal constant aaveData = + AaveDataProviderInterface(0x256bBbeDbA70a1240a1EB64210abB1b063267408); // rinkeby address - /** - * @dev Aave Referral Code - */ - uint16 constant internal referralCode = 3228; + /** + * @dev Aave Referral Code + */ + uint16 internal constant referralCode = 3228; - /** - * @dev Checks if collateral is enabled for an asset - * @param token token address of the asset.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - */ - function getIsColl(address token) internal view returns (bool isCol) { - (, , , , , , , , isCol) = aaveData.getUserReserveData(token, address(this)); - } + /** + * @dev Checks if collateral is enabled for an asset + * @param token token address of the asset.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + */ - /** - * @dev Get total debt balance & fee for an asset - * @param token token address of the debt.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param rateMode Borrow rate mode (Stable = 1, Variable = 2) - */ - function getPaybackBalance(address token, uint rateMode) internal view returns (uint) { - (, uint stableDebt, uint variableDebt, , , , , , ) = aaveData.getUserReserveData(token, address(this)); - return rateMode == 1 ? stableDebt : variableDebt; - } + function getIsColl(address token) internal view returns (bool isCol) { + (, , , , , , , , isCol) = aaveData.getUserReserveData( + token, + address(this) + ); + } - /** - * @dev Get total collateral balance for an asset - * @param token token address of the collateral.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - */ - function getCollateralBalance(address token) internal view returns (uint bal) { - (bal, , , , , , , ,) = aaveData.getUserReserveData(token, address(this)); - } + /** + * @dev Get total debt balance & fee for an asset + * @param token token address of the debt.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param rateMode Borrow rate mode (Stable = 1, Variable = 2) + */ + function getPaybackBalance(address token, uint256 rateMode) + internal + view + returns (uint256) + { + (, uint256 stableDebt, uint256 variableDebt, , , , , , ) = aaveData + .getUserReserveData(token, address(this)); + return rateMode == 1 ? stableDebt : variableDebt; + } + + /** + * @dev Get total collateral balance for an asset + * @param token token address of the collateral.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + */ + function getCollateralBalance(address token) + internal + view + returns (uint256 bal) + { + (bal, , , , , , , , ) = aaveData.getUserReserveData( + token, + address(this) + ); + } } diff --git a/contracts/mainnet/connectors/aave/v3/interface.sol b/contracts/mainnet/connectors/aave/v3/interface.sol index ab17fd22..8ae14716 100644 --- a/contracts/mainnet/connectors/aave/v3/interface.sol +++ b/contracts/mainnet/connectors/aave/v3/interface.sol @@ -1,47 +1,91 @@ pragma solidity ^0.7.0; interface AaveInterface { - function deposit(address _asset, uint256 _amount, address _onBehalfOf, uint16 _referralCode) external; - function withdraw(address _asset, uint256 _amount, address _to) external; - function borrow( - address _asset, - uint256 _amount, - uint256 _interestRateMode, - uint16 _referralCode, - address _onBehalfOf - ) external; - function repay(address _asset, uint256 _amount, uint256 _rateMode, address _onBehalfOf) external; - function setUserUseReserveAsCollateral(address _asset, bool _useAsCollateral) external; - function swapBorrowRateMode(address _asset, uint256 _rateMode) external; + function supply( + address asset, + uint256 amount, + address onBehalfOf, + uint16 referralCode + ) external; + + function withdraw( + address asset, + uint256 amount, + address to + ) external returns (uint256); + + function borrow( + address asset, + uint256 amount, + uint256 interestRateMode, + uint16 referralCode, + address onBehalfOf + ) external; + + function repay( + address asset, + uint256 amount, + uint256 interestRateMode, + address onBehalfOf + ) external returns (uint256); + + function repayWithATokens( + address asset, + uint256 amount, + uint256 interestRateMode + ) external returns (uint256); + + function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) + external; + + function swapBorrowRateMode(address asset, uint256 interestRateMode) + external; + + function setUserEMode(uint8 categoryId) external; } -interface AaveLendingPoolProviderInterface { - function getLendingPool() external view returns (address); +interface AavePoolProviderInterface { + function getPool() external view returns (address); } interface AaveDataProviderInterface { - function getReserveTokensAddresses(address _asset) external view returns ( - address aTokenAddress, - address stableDebtTokenAddress, - address variableDebtTokenAddress - ); - function getUserReserveData(address _asset, address _user) external view returns ( - uint256 currentATokenBalance, - uint256 currentStableDebt, - uint256 currentVariableDebt, - uint256 principalStableDebt, - uint256 scaledVariableDebt, - uint256 stableBorrowRate, - uint256 liquidityRate, - uint40 stableRateLastUpdated, - bool usageAsCollateralEnabled - ); + function getReserveTokensAddresses(address _asset) + external + view + returns ( + address aTokenAddress, + address stableDebtTokenAddress, + address variableDebtTokenAddress + ); + + function getUserReserveData(address _asset, address _user) + external + view + returns ( + uint256 currentATokenBalance, + uint256 currentStableDebt, + uint256 currentVariableDebt, + uint256 principalStableDebt, + uint256 scaledVariableDebt, + uint256 stableBorrowRate, + uint256 liquidityRate, + uint40 stableRateLastUpdated, + bool usageAsCollateralEnabled + ); + + function getReserveEModeCategory(address asset) + external + view + returns (uint256); } interface AaveAddressProviderRegistryInterface { - function getAddressesProvidersList() external view returns (address[] memory); + function getAddressesProvidersList() + external + view + returns (address[] memory); } interface ATokenInterface { - function balanceOf(address _user) external view returns(uint256); -} \ No newline at end of file + function balanceOf(address _user) external view returns (uint256); +} diff --git a/contracts/mainnet/connectors/aave/v3/main.sol b/contracts/mainnet/connectors/aave/v3/main.sol index d3f7d01a..d55e0339 100644 --- a/contracts/mainnet/connectors/aave/v3/main.sol +++ b/contracts/mainnet/connectors/aave/v3/main.sol @@ -1,7 +1,7 @@ pragma solidity ^0.7.0; /** - * @title Aave v2. + * @title Aave v3. * @dev Lending & Borrowing. */ @@ -12,204 +12,268 @@ import { Events } from "./events.sol"; import { AaveInterface } from "./interface.sol"; abstract contract AaveResolver is Events, Helpers { - /** - * @dev Deposit ETH/ERC20_Token. - * @notice Deposit a token to Aave v2 for lending / collaterization. - * @param token The address of the token to deposit.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param amt The amount of the token to deposit. (For max: `uint256(-1)`) - * @param getId ID to retrieve amt. - * @param setId ID stores the amount of tokens deposited. - */ - function deposit( - address token, - uint256 amt, - uint256 getId, - uint256 setId - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint _amt = getUint(getId, amt); + /** + * @dev Deposit ETH/ERC20_Token. + * @notice Deposit a token to Aave v2 for lending / collaterization. + * @param token The address of the token to deposit.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param amt The amount of the token to deposit. (For max: `uint256(-1)`) + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens deposited. + */ + function deposit( + address token, + uint256 amt, + uint256 getId, + uint256 setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(getId, amt); - AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); + AaveInterface aave = AaveInterface(aaveProvider.getPool()); - bool isEth = token == ethAddr; - address _token = isEth ? wethAddr : token; + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; - TokenInterface tokenContract = TokenInterface(_token); + TokenInterface tokenContract = TokenInterface(_token); - if (isEth) { - _amt = _amt == uint(-1) ? address(this).balance : _amt; - convertEthToWeth(isEth, tokenContract, _amt); - } else { - _amt = _amt == uint(-1) ? tokenContract.balanceOf(address(this)) : _amt; - } + if (isEth) { + _amt = _amt == uint256(-1) ? address(this).balance : _amt; + convertEthToWeth(isEth, tokenContract, _amt); + } else { + _amt = _amt == uint256(-1) + ? tokenContract.balanceOf(address(this)) + : _amt; + } - approve(tokenContract, address(aave), _amt); + approve(tokenContract, address(aave), _amt); - aave.deposit(_token, _amt, address(this), referralCode); + aave.supply(_token, _amt, address(this), referralCode); - if (!getIsColl(_token)) { - aave.setUserUseReserveAsCollateral(_token, true); - } + if (!getIsColl(_token)) { + aave.setUserUseReserveAsCollateral(_token, true); + } - setUint(setId, _amt); + setUint(setId, _amt); - _eventName = "LogDeposit(address,uint256,uint256,uint256)"; - _eventParam = abi.encode(token, _amt, getId, setId); - } + _eventName = "LogDeposit(address,uint256,uint256,uint256)"; + _eventParam = abi.encode(token, _amt, getId, setId); + } - /** - * @dev Withdraw ETH/ERC20_Token. - * @notice Withdraw deposited token from Aave v2 - * @param token The address of the token to withdraw.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param amt The amount of the token to withdraw. (For max: `uint256(-1)`) - * @param getId ID to retrieve amt. - * @param setId ID stores the amount of tokens withdrawn. - */ - function withdraw( - address token, - uint256 amt, - uint256 getId, - uint256 setId - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint _amt = getUint(getId, amt); + /** + * @dev Withdraw ETH/ERC20_Token. + * @notice Withdraw deposited token from Aave v2 + * @param token The address of the token to withdraw.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param amt The amount of the token to withdraw. (For max: `uint256(-1)`) + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens withdrawn. + */ + function withdraw( + address token, + uint256 amt, + uint256 getId, + uint256 setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(getId, amt); - AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); - bool isEth = token == ethAddr; - address _token = isEth ? wethAddr : token; + AaveInterface aave = AaveInterface(aaveProvider.getPool()); + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; - TokenInterface tokenContract = TokenInterface(_token); + TokenInterface tokenContract = TokenInterface(_token); - uint initialBal = tokenContract.balanceOf(address(this)); - aave.withdraw(_token, _amt, address(this)); - uint finalBal = tokenContract.balanceOf(address(this)); + uint256 initialBal = tokenContract.balanceOf(address(this)); + aave.withdraw(_token, _amt, address(this)); + uint256 finalBal = tokenContract.balanceOf(address(this)); - _amt = sub(finalBal, initialBal); + _amt = sub(finalBal, initialBal); - convertWethToEth(isEth, tokenContract, _amt); - - setUint(setId, _amt); + convertWethToEth(isEth, tokenContract, _amt); - _eventName = "LogWithdraw(address,uint256,uint256,uint256)"; - _eventParam = abi.encode(token, _amt, getId, setId); - } + setUint(setId, _amt); - /** - * @dev Borrow ETH/ERC20_Token. - * @notice Borrow a token using Aave v2 - * @param token The address of the token to borrow.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param amt The amount of the token to borrow. - * @param rateMode The type of borrow debt. (For Stable: 1, Variable: 2) - * @param getId ID to retrieve amt. - * @param setId ID stores the amount of tokens borrowed. - */ - function borrow( - address token, - uint256 amt, - uint256 rateMode, - uint256 getId, - uint256 setId - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint _amt = getUint(getId, amt); + _eventName = "LogWithdraw(address,uint256,uint256,uint256)"; + _eventParam = abi.encode(token, _amt, getId, setId); + } - AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); + /** + * @dev Borrow ETH/ERC20_Token. + * @notice Borrow a token using Aave v2 + * @param token The address of the token to borrow.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param amt The amount of the token to borrow. + * @param rateMode The type of borrow debt. (For Stable: 1, Variable: 2) + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens borrowed. + */ + function borrow( + address token, + uint256 amt, + uint256 rateMode, + uint256 getId, + uint256 setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(getId, amt); - bool isEth = token == ethAddr; - address _token = isEth ? wethAddr : token; + AaveInterface aave = AaveInterface(aaveProvider.getPool()); - aave.borrow(_token, _amt, rateMode, referralCode, address(this)); - convertWethToEth(isEth, TokenInterface(_token), _amt); + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; - setUint(setId, _amt); + aave.borrow(_token, _amt, rateMode, referralCode, address(this)); + convertWethToEth(isEth, TokenInterface(_token), _amt); - _eventName = "LogBorrow(address,uint256,uint256,uint256,uint256)"; - _eventParam = abi.encode(token, _amt, rateMode, getId, setId); - } + setUint(setId, _amt); - /** - * @dev Payback borrowed ETH/ERC20_Token. - * @notice Payback debt owed. - * @param token The address of the token to payback.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param amt The amount of the token to payback. (For max: `uint256(-1)`) - * @param rateMode The type of debt paying back. (For Stable: 1, Variable: 2) - * @param getId ID to retrieve amt. - * @param setId ID stores the amount of tokens paid back. - */ - function payback( - address token, - uint256 amt, - uint256 rateMode, - uint256 getId, - uint256 setId - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint _amt = getUint(getId, amt); + _eventName = "LogBorrow(address,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(token, _amt, rateMode, getId, setId); + } - AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); + /** + * @dev Payback borrowed ETH/ERC20_Token. + * @notice Payback debt owed. + * @param token The address of the token to payback.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param amt The amount of the token to payback. (For max: `uint256(-1)`) + * @param rateMode The type of debt paying back. (For Stable: 1, Variable: 2) + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens paid back. + */ + function payback( + address token, + uint256 amt, + uint256 rateMode, + uint256 getId, + uint256 setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(getId, amt); - bool isEth = token == ethAddr; - address _token = isEth ? wethAddr : token; + AaveInterface aave = AaveInterface(aaveProvider.getPool()); - TokenInterface tokenContract = TokenInterface(_token); + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; - _amt = _amt == uint(-1) ? getPaybackBalance(_token, rateMode) : _amt; + TokenInterface tokenContract = TokenInterface(_token); - if (isEth) convertEthToWeth(isEth, tokenContract, _amt); + _amt = _amt == uint256(-1) ? getPaybackBalance(_token, rateMode) : _amt; - approve(tokenContract, address(aave), _amt); + if (isEth) convertEthToWeth(isEth, tokenContract, _amt); - aave.repay(_token, _amt, rateMode, address(this)); + approve(tokenContract, address(aave), _amt); - setUint(setId, _amt); + aave.repay(_token, _amt, rateMode, address(this)); - _eventName = "LogPayback(address,uint256,uint256,uint256,uint256)"; - _eventParam = abi.encode(token, _amt, rateMode, getId, setId); - } + setUint(setId, _amt); - /** - * @dev Enable collateral - * @notice Enable an array of tokens as collateral - * @param tokens Array of tokens to enable collateral - */ - function enableCollateral( - address[] calldata tokens - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint _length = tokens.length; - require(_length > 0, "0-tokens-not-allowed"); + _eventName = "LogPayback(address,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(token, _amt, rateMode, getId, setId); + } - AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); + /** + * @dev Payback borrowed ETH/ERC20_Token . + * @notice Payback debt owed. + * @param token The address of the token to payback.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param amt The amount of the token to payback. (For max: `uint256(-1)`) + * @param rateMode The type of debt paying back. (For Stable: 1, Variable: 2) + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens paid back. + */ + function paybackWithATokens( + address token, + uint256 amt, + uint256 rateMode, + uint256 getId, + uint256 setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(getId, amt); - for (uint i = 0; i < _length; i++) { - address token = tokens[i]; - if (getCollateralBalance(token) > 0 && !getIsColl(token)) { - aave.setUserUseReserveAsCollateral(token, true); - } - } + AaveInterface aave = AaveInterface(aaveProvider.getPool()); - _eventName = "LogEnableCollateral(address[])"; - _eventParam = abi.encode(tokens); - } + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; - /** - * @dev Swap borrow rate mode - * @notice Swaps user borrow rate mode between variable and stable - * @param token The address of the token to swap borrow rate.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param rateMode Desired borrow rate mode. (Stable = 1, Variable = 2) - */ - function swapBorrowRateMode( - address token, - uint rateMode - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); + TokenInterface tokenContract = TokenInterface(_token); - uint currentRateMode = rateMode == 1 ? 2 : 1; + _amt = _amt == uint256(-1) ? getPaybackBalance(_token, rateMode) : _amt; - if (getPaybackBalance(token, currentRateMode) > 0) { - aave.swapBorrowRateMode(token, rateMode); - } + if (isEth) convertEthToWeth(isEth, tokenContract, _amt); - _eventName = "LogSwapRateMode(address,uint256)"; - _eventParam = abi.encode(token, rateMode); - } + approve(tokenContract, address(aave), _amt); + + aave.repayWithATokens(_token, _amt, rateMode); + + setUint(setId, _amt); + + _eventName = "LogPayback(address,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(token, _amt, rateMode, getId, setId); + } + + /** + * @dev Enable collateral + * @notice Enable an array of tokens as collateral + * @param tokens Array of tokens to enable collateral + */ + function enableCollateral(address[] calldata tokens) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _length = tokens.length; + require(_length > 0, "0-tokens-not-allowed"); + + AaveInterface aave = AaveInterface(aaveProvider.getPool()); + + for (uint256 i = 0; i < _length; i++) { + address token = tokens[i]; + if (getCollateralBalance(token) > 0 && !getIsColl(token)) { + aave.setUserUseReserveAsCollateral(token, true); + } + } + + _eventName = "LogEnableCollateral(address[])"; + _eventParam = abi.encode(tokens); + } + + /** + * @dev Swap borrow rate mode + * @notice Swaps user borrow rate mode between variable and stable + * @param token The address of the token to swap borrow rate.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param rateMode Desired borrow rate mode. (Stable = 1, Variable = 2) + */ + function swapBorrowRateMode(address token, uint256 rateMode) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + AaveInterface aave = AaveInterface(aaveProvider.getPool()); + + uint256 currentRateMode = rateMode == 1 ? 2 : 1; + + if (getPaybackBalance(token, currentRateMode) > 0) { + aave.swapBorrowRateMode(token, rateMode); + } + + _eventName = "LogSwapRateMode(address,uint256)"; + _eventParam = abi.encode(token, rateMode); + } } -contract ConnectV2AaveV2 is AaveResolver { - string constant public name = "AaveV2-v1.1"; +contract ConnectV2AaveV3 is AaveResolver { + string public constant name = "AaveV3-v1.1"; }