From 4daba04266e6a91739f9e081fcba40373d48f955 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sat, 18 Jun 2022 19:00:36 +0530 Subject: [PATCH 1/7] fixed aave swapMode bug --- .../avalanche/connectors/aave/v2/main.sol | 39 ++++++++++--------- contracts/mainnet/connectors/aave/v2/main.sol | 13 ++++--- contracts/polygon/connectors/aave/v2/main.sol | 38 +++++++++--------- 3 files changed, 46 insertions(+), 44 deletions(-) diff --git a/contracts/avalanche/connectors/aave/v2/main.sol b/contracts/avalanche/connectors/aave/v2/main.sol index 52fa67cc..98d48a48 100644 --- a/contracts/avalanche/connectors/aave/v2/main.sol +++ b/contracts/avalanche/connectors/aave/v2/main.sol @@ -276,28 +276,29 @@ abstract contract AaveResolver is Events, Helpers { _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 AVAX: 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.getLendingPool()); - uint256 currentRateMode = rateMode == 1 ? 2 : 1; + /** + * @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 AVAX: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param currentRateMode Current Rate mode. (Stable = 1, Variable = 2) + */ + function swapBorrowRateMode( + address token, + uint currentRateMode + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); - if (getPaybackBalance(token, currentRateMode) > 0) { - aave.swapBorrowRateMode(token, rateMode); - } + bool isAVAX = token == avaxAddr; + address _token = isAVAX ? wavaxAddr : token; - _eventName = "LogSwapRateMode(address,uint256)"; - _eventParam = abi.encode(token, rateMode); - } + if (getPaybackBalance(_token, currentRateMode) > 0) { + aave.swapBorrowRateMode(_token, currentRateMode); + } + + _eventName = "LogSwapRateMode(address,uint256)"; + _eventParam = abi.encode(token, currentRateMode); + } } contract ConnectV2AaveV2Avalanche is AaveResolver { diff --git a/contracts/mainnet/connectors/aave/v2/main.sol b/contracts/mainnet/connectors/aave/v2/main.sol index ec7b557b..4a4cf1bf 100644 --- a/contracts/mainnet/connectors/aave/v2/main.sol +++ b/contracts/mainnet/connectors/aave/v2/main.sol @@ -245,22 +245,23 @@ abstract contract AaveResolver is Events, Helpers { * @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) + * @param currentRateMode Current Rate mode. (Stable = 1, Variable = 2) */ function swapBorrowRateMode( address token, - uint rateMode + uint currentRateMode ) external payable returns (string memory _eventName, bytes memory _eventParam) { AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); - uint currentRateMode = rateMode == 1 ? 2 : 1; + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; - if (getPaybackBalance(token, currentRateMode) > 0) { - aave.swapBorrowRateMode(token, rateMode); + if (getPaybackBalance(_token, currentRateMode) > 0) { + aave.swapBorrowRateMode(_token, currentRateMode); } _eventName = "LogSwapRateMode(address,uint256)"; - _eventParam = abi.encode(token, rateMode); + _eventParam = abi.encode(token, currentRateMode); } } diff --git a/contracts/polygon/connectors/aave/v2/main.sol b/contracts/polygon/connectors/aave/v2/main.sol index 59911d9b..b8c11d96 100644 --- a/contracts/polygon/connectors/aave/v2/main.sol +++ b/contracts/polygon/connectors/aave/v2/main.sol @@ -276,28 +276,28 @@ abstract contract AaveResolver is Events, Helpers { _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 MATIC: 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.getLendingPool()); + /** + * @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 MATIC: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param currentRateMode Current Rate mode. (Stable = 1, Variable = 2) + */ + function swapBorrowRateMode( + address token, + uint currentRateMode + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); - uint256 currentRateMode = rateMode == 1 ? 2 : 1; + bool isMatic = token == maticAddr; + address _token = isMatic ? wmaticAddr : token; - if (getPaybackBalance(token, currentRateMode) > 0) { - aave.swapBorrowRateMode(token, rateMode); - } + if (getPaybackBalance(_token, currentRateMode) > 0) { + aave.swapBorrowRateMode(_token, currentRateMode); + } - _eventName = "LogSwapRateMode(address,uint256)"; - _eventParam = abi.encode(token, rateMode); - } + _eventName = "LogSwapRateMode(address,uint256)"; + _eventParam = abi.encode(token, currentRateMode); + } } contract ConnectV2AaveV2Polygon is AaveResolver { From 231b8fe34ac23b2c76f73d2488efcb3762f051d5 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sat, 18 Jun 2022 19:04:48 +0530 Subject: [PATCH 2/7] fixed native token bug aave v2 --- contracts/avalanche/connectors/aave/v2/main.sol | 9 +++++---- contracts/mainnet/connectors/aave/v2/main.sol | 8 +++++--- contracts/polygon/connectors/aave/v2/main.sol | 8 +++++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/contracts/avalanche/connectors/aave/v2/main.sol b/contracts/avalanche/connectors/aave/v2/main.sol index 98d48a48..85a82feb 100644 --- a/contracts/avalanche/connectors/aave/v2/main.sol +++ b/contracts/avalanche/connectors/aave/v2/main.sol @@ -266,9 +266,11 @@ abstract contract AaveResolver is Events, Helpers { AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); for (uint256 i = 0; i < _length; i++) { - address token = tokens[i]; - if (getCollateralBalance(token) > 0 && !getIsColl(token)) { - aave.setUserUseReserveAsCollateral(token, true); + bool isAvax = tokens[i] == avaxAddr; + address _token = isAvax ? wavaxAddr : tokens[i]; + + if (getCollateralBalance(_token) > 0 && !getIsColl(_token)) { + aave.setUserUseReserveAsCollateral(_token, true); } } @@ -276,7 +278,6 @@ abstract contract AaveResolver is Events, Helpers { _eventParam = abi.encode(tokens); } - /** * @dev Swap borrow rate mode * @notice Swaps user borrow rate mode between variable and stable diff --git a/contracts/mainnet/connectors/aave/v2/main.sol b/contracts/mainnet/connectors/aave/v2/main.sol index 4a4cf1bf..dcfa0f1f 100644 --- a/contracts/mainnet/connectors/aave/v2/main.sol +++ b/contracts/mainnet/connectors/aave/v2/main.sol @@ -231,9 +231,11 @@ abstract contract AaveResolver is Events, Helpers { AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); for (uint i = 0; i < _length; i++) { - address token = tokens[i]; - if (getCollateralBalance(token) > 0 && !getIsColl(token)) { - aave.setUserUseReserveAsCollateral(token, true); + bool isEth = tokens[i] == ethAddr; + address _token = isEth ? wethAddr : tokens[i]; + + if (getCollateralBalance(_token) > 0 && !getIsColl(_token)) { + aave.setUserUseReserveAsCollateral(_token, true); } } diff --git a/contracts/polygon/connectors/aave/v2/main.sol b/contracts/polygon/connectors/aave/v2/main.sol index b8c11d96..eaeacb13 100644 --- a/contracts/polygon/connectors/aave/v2/main.sol +++ b/contracts/polygon/connectors/aave/v2/main.sol @@ -266,9 +266,11 @@ abstract contract AaveResolver is Events, Helpers { AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); for (uint256 i = 0; i < _length; i++) { - address token = tokens[i]; - if (getCollateralBalance(token) > 0 && !getIsColl(token)) { - aave.setUserUseReserveAsCollateral(token, true); + bool isMatic = tokens[i] == maticAddr; + address _token = isMatic ? wmaticAddr : tokens[i]; + + if (getCollateralBalance(_token) > 0 && !getIsColl(_token)) { + aave.setUserUseReserveAsCollateral(_token, true); } } From 3b6d0be4c4d27af5e1125ca3820939823615887d Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sat, 18 Jun 2022 19:10:45 +0530 Subject: [PATCH 3/7] fixed mainnet aave v3 bugs --- contracts/mainnet/connectors/aave/v3/main.sol | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/contracts/mainnet/connectors/aave/v3/main.sol b/contracts/mainnet/connectors/aave/v3/main.sol index dd78cd6e..48751aa4 100644 --- a/contracts/mainnet/connectors/aave/v3/main.sol +++ b/contracts/mainnet/connectors/aave/v3/main.sol @@ -103,7 +103,7 @@ abstract contract AaveResolver is Events, Helpers { aave.supply(_token, _amt, address(this), referralCode); - if (getCollateralBalance(_token) > 0 && getIsColl(token)) { + if (getCollateralBalance(_token) > 0 && getIsColl(_token)) { aave.setUserUseReserveAsCollateral(_token, false); } @@ -375,9 +375,11 @@ abstract contract AaveResolver is Events, Helpers { 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); + bool isEth = tokens[i] == ethAddr; + address _token = isEth ? wethAddr : tokens[i]; + + if (getCollateralBalance(_token) > 0 && !getIsColl(_token)) { + aave.setUserUseReserveAsCollateral(_token, true); } } @@ -389,7 +391,7 @@ abstract contract AaveResolver is Events, Helpers { * @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) + * @param rateMode Current rate mode. (Stable = 1, Variable = 2) */ function swapBorrowRateMode(address token, uint256 rateMode) external @@ -398,10 +400,11 @@ abstract contract AaveResolver is Events, Helpers { { AaveInterface aave = AaveInterface(aaveProvider.getPool()); - uint256 currentRateMode = rateMode == 1 ? 2 : 1; + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; - if (getPaybackBalance(token, currentRateMode) > 0) { - aave.swapBorrowRateMode(token, rateMode); + if (getPaybackBalance(_token, rateMode) > 0) { + aave.swapBorrowRateMode(_token, rateMode); } _eventName = "LogSwapRateMode(address,uint256)"; From 51f4b1b9f4f14e057ec77f6410f14a2d7040e61f Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sat, 18 Jun 2022 19:12:19 +0530 Subject: [PATCH 4/7] aave v3: fixed swapBorrowRate bug --- contracts/arbitrum/connectors/aave/v3/main.sol | 6 ++---- contracts/avalanche/connectors/aave/v3/main.sol | 6 ++---- contracts/fantom/connectors/aave/v3/main.sol | 5 ++--- contracts/optimism/connectors/aave/v3/main.sol | 6 ++---- contracts/polygon/connectors/aave/v3/main.sol | 6 ++---- 5 files changed, 10 insertions(+), 19 deletions(-) diff --git a/contracts/arbitrum/connectors/aave/v3/main.sol b/contracts/arbitrum/connectors/aave/v3/main.sol index d5ed5c1c..8cf3db0b 100644 --- a/contracts/arbitrum/connectors/aave/v3/main.sol +++ b/contracts/arbitrum/connectors/aave/v3/main.sol @@ -433,7 +433,7 @@ abstract contract AaveResolver is Events, Helpers { * @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) + * @param rateMode current rate mode. (Stable = 1, Variable = 2) */ function swapBorrowRateMode(address token, uint256 rateMode) external @@ -442,12 +442,10 @@ abstract contract AaveResolver is Events, Helpers { { AaveInterface aave = AaveInterface(aaveProvider.getPool()); - uint256 currentRateMode = rateMode == 1 ? 2 : 1; - bool isEth = token == ethAddr; address _token = isEth ? wethAddr : token; - if (getPaybackBalance(_token, currentRateMode) > 0) { + if (getPaybackBalance(_token, rateMode) > 0) { aave.swapBorrowRateMode(_token, rateMode); } diff --git a/contracts/avalanche/connectors/aave/v3/main.sol b/contracts/avalanche/connectors/aave/v3/main.sol index f92cb0b6..c84887b7 100644 --- a/contracts/avalanche/connectors/aave/v3/main.sol +++ b/contracts/avalanche/connectors/aave/v3/main.sol @@ -434,7 +434,7 @@ abstract contract AaveResolver is Events, Helpers { * @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 avax: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param rateMode Desired borrow rate mode. (Stable = 1, Variable = 2) + * @param rateMode Current rate mode (Stable = 1, Variable = 2) */ function swapBorrowRateMode(address token, uint256 rateMode) external @@ -443,12 +443,10 @@ abstract contract AaveResolver is Events, Helpers { { AaveInterface aave = AaveInterface(aaveProvider.getPool()); - uint256 currentRateMode = rateMode == 1 ? 2 : 1; - bool isAVAX = token == avaxAddr; address _token = isAVAX ? wavaxAddr : token; - if (getPaybackBalance(_token, currentRateMode) > 0) { + if (getPaybackBalance(_token, rateMode) > 0) { aave.swapBorrowRateMode(_token, rateMode); } diff --git a/contracts/fantom/connectors/aave/v3/main.sol b/contracts/fantom/connectors/aave/v3/main.sol index bc4038bd..cb999a53 100644 --- a/contracts/fantom/connectors/aave/v3/main.sol +++ b/contracts/fantom/connectors/aave/v3/main.sol @@ -432,7 +432,7 @@ abstract contract AaveResolver is Events, Helpers { * @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 ftm: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param rateMode Desired borrow rate mode. (Stable = 1, Variable = 2) + * @param rateMode Current rate mode. (Stable = 1, Variable = 2) */ function swapBorrowRateMode(address token, uint256 rateMode) external @@ -441,11 +441,10 @@ abstract contract AaveResolver is Events, Helpers { { AaveInterface aave = AaveInterface(aaveProvider.getPool()); - uint256 currentRateMode = rateMode == 1 ? 2 : 1; bool isFTM = token == ftmAddr; address _token = isFTM ? wftmAddr : token; - if (getPaybackBalance(_token, currentRateMode) > 0) { + if (getPaybackBalance(_token, rateMode) > 0) { aave.swapBorrowRateMode(_token, rateMode); } diff --git a/contracts/optimism/connectors/aave/v3/main.sol b/contracts/optimism/connectors/aave/v3/main.sol index 639f9deb..59a26ef8 100644 --- a/contracts/optimism/connectors/aave/v3/main.sol +++ b/contracts/optimism/connectors/aave/v3/main.sol @@ -434,7 +434,7 @@ abstract contract AaveResolver is Events, Helpers { * @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) + * @param rateMode Current borrow rate (Stable = 1, Variable = 2) */ function swapBorrowRateMode(address token, uint256 rateMode) external @@ -443,12 +443,10 @@ abstract contract AaveResolver is Events, Helpers { { AaveInterface aave = AaveInterface(aaveProvider.getPool()); - uint256 currentRateMode = rateMode == 1 ? 2 : 1; - bool isEth = token == ethAddr; address _token = isEth ? wethAddr : token; - if (getPaybackBalance(_token, currentRateMode) > 0) { + if (getPaybackBalance(_token, rateMode) > 0) { aave.swapBorrowRateMode(_token, rateMode); } diff --git a/contracts/polygon/connectors/aave/v3/main.sol b/contracts/polygon/connectors/aave/v3/main.sol index 535269a0..84092977 100644 --- a/contracts/polygon/connectors/aave/v3/main.sol +++ b/contracts/polygon/connectors/aave/v3/main.sol @@ -434,7 +434,7 @@ abstract contract AaveResolver is Events, Helpers { * @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 matic: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param rateMode Desired borrow rate mode. (Stable = 1, Variable = 2) + * @param rateMode Current borrow rate s(Stable = 1, Variable = 2) */ function swapBorrowRateMode(address token, uint256 rateMode) external @@ -443,12 +443,10 @@ abstract contract AaveResolver is Events, Helpers { { AaveInterface aave = AaveInterface(aaveProvider.getPool()); - uint256 currentRateMode = rateMode == 1 ? 2 : 1; - bool isMatic = token == maticAddr; address _token = isMatic ? wmaticAddr : token; - if (getPaybackBalance(_token, currentRateMode) > 0) { + if (getPaybackBalance(_token, rateMode) > 0) { aave.swapBorrowRateMode(_token, rateMode); } From 09bcc1b8f755f107598e03d49b260dc994292b9c Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sat, 18 Jun 2022 19:26:50 +0530 Subject: [PATCH 5/7] lint fix --- .../avalanche/connectors/aave/v2/main.sol | 37 +- contracts/mainnet/connectors/aave/v2/main.sol | 370 ++++++++++-------- contracts/mainnet/connectors/aave/v3/main.sol | 33 +- contracts/polygon/connectors/aave/v2/main.sol | 37 +- 4 files changed, 268 insertions(+), 209 deletions(-) diff --git a/contracts/avalanche/connectors/aave/v2/main.sol b/contracts/avalanche/connectors/aave/v2/main.sol index 85a82feb..05a4808d 100644 --- a/contracts/avalanche/connectors/aave/v2/main.sol +++ b/contracts/avalanche/connectors/aave/v2/main.sol @@ -267,7 +267,7 @@ abstract contract AaveResolver is Events, Helpers { for (uint256 i = 0; i < _length; i++) { bool isAvax = tokens[i] == avaxAddr; - address _token = isAvax ? wavaxAddr : tokens[i]; + address _token = isAvax ? wavaxAddr : tokens[i]; if (getCollateralBalance(_token) > 0 && !getIsColl(_token)) { aave.setUserUseReserveAsCollateral(_token, true); @@ -278,28 +278,29 @@ abstract contract AaveResolver is Events, Helpers { _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 AVAX: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param currentRateMode Current Rate mode. (Stable = 1, Variable = 2) - */ - function swapBorrowRateMode( - address token, - uint currentRateMode - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); + /** + * @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 AVAX: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param currentRateMode Current Rate mode. (Stable = 1, Variable = 2) + */ + function swapBorrowRateMode(address token, uint256 currentRateMode) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); bool isAVAX = token == avaxAddr; address _token = isAVAX ? wavaxAddr : token; - if (getPaybackBalance(_token, currentRateMode) > 0) { - aave.swapBorrowRateMode(_token, currentRateMode); - } + if (getPaybackBalance(_token, currentRateMode) > 0) { + aave.swapBorrowRateMode(_token, currentRateMode); + } - _eventName = "LogSwapRateMode(address,uint256)"; - _eventParam = abi.encode(token, currentRateMode); - } + _eventName = "LogSwapRateMode(address,uint256)"; + _eventParam = abi.encode(token, currentRateMode); + } } contract ConnectV2AaveV2Avalanche is AaveResolver { diff --git a/contracts/mainnet/connectors/aave/v2/main.sol b/contracts/mainnet/connectors/aave/v2/main.sol index dcfa0f1f..5cf08931 100644 --- a/contracts/mainnet/connectors/aave/v2/main.sol +++ b/contracts/mainnet/connectors/aave/v2/main.sol @@ -13,162 +13,182 @@ 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.getLendingPool()); - 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.deposit(_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.getLendingPool()); + 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.getLendingPool()); - 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.getLendingPool()); - TokenInterface tokenContract = TokenInterface(_token); - - if (_amt == uint(-1)) { - uint _amtDSA = isEth ? address(this).balance : tokenContract.balanceOf(address(this)); - uint _amtDebt = getPaybackBalance(_token, rateMode); - _amt = _amtDSA <= _amtDebt ? _amtDSA : _amtDebt; - } + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; - if (isEth) convertEthToWeth(isEth, tokenContract, _amt); + TokenInterface tokenContract = TokenInterface(_token); - approve(tokenContract, address(aave), _amt); + if (_amt == uint256(-1)) { + uint256 _amtDSA = isEth + ? address(this).balance + : tokenContract.balanceOf(address(this)); + uint256 _amtDebt = getPaybackBalance(_token, rateMode); + _amt = _amtDSA <= _amtDebt ? _amtDSA : _amtDebt; + } - aave.repay(_token, _amt, rateMode, address(this)); + if (isEth) convertEthToWeth(isEth, tokenContract, _amt); - setUint(setId, _amt); + approve(tokenContract, address(aave), _amt); - _eventName = "LogPayback(address,uint256,uint256,uint256,uint256)"; - _eventParam = abi.encode(token, _amt, rateMode, getId, setId); - } + aave.repay(_token, _amt, rateMode, address(this)); - /** + setUint(setId, _amt); + + _eventName = "LogPayback(address,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(token, _amt, rateMode, getId, setId); + } + + /** * @dev Payback borrowed ETH/ERC20_Token on behalf of a user. * @notice Payback debt owed on behalf os a user. * @param token The address of the token to payback.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) @@ -199,9 +219,15 @@ abstract contract AaveResolver is Events, Helpers { TokenInterface tokenContract = TokenInterface(_token); - if (_amt == uint(-1)) { - uint _amtDSA = isEth ? address(this).balance : tokenContract.balanceOf(address(this)); - uint _amtDebt = getOnBehalfOfPaybackBalance(_token, rateMode, onBehalfOf); + if (_amt == uint256(-1)) { + uint256 _amtDSA = isEth + ? address(this).balance + : tokenContract.balanceOf(address(this)); + uint256 _amtDebt = getOnBehalfOfPaybackBalance( + _token, + rateMode, + onBehalfOf + ); _amt = _amtDSA <= _amtDebt ? _amtDSA : _amtDebt; } @@ -214,59 +240,69 @@ abstract contract AaveResolver is Events, Helpers { setUint(setId, _amt); _eventName = "LogPaybackOnBehalfOf(address,uint256,uint256,address,uint256,uint256)"; - _eventParam = abi.encode(token, _amt, rateMode, onBehalfOf, getId, setId); + _eventParam = abi.encode( + token, + _amt, + rateMode, + onBehalfOf, + 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) { - uint _length = tokens.length; - require(_length > 0, "0-tokens-not-allowed"); + /** + * @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.getLendingPool()); + AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); - for (uint i = 0; i < _length; i++) { - bool isEth = tokens[i] == ethAddr; - address _token = isEth ? wethAddr : tokens[i]; + for (uint256 i = 0; i < _length; i++) { + bool isEth = tokens[i] == ethAddr; + address _token = isEth ? wethAddr : tokens[i]; - if (getCollateralBalance(_token) > 0 && !getIsColl(_token)) { - aave.setUserUseReserveAsCollateral(_token, true); - } - } + if (getCollateralBalance(_token) > 0 && !getIsColl(_token)) { + aave.setUserUseReserveAsCollateral(_token, true); + } + } - _eventName = "LogEnableCollateral(address[])"; - _eventParam = abi.encode(tokens); - } + _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 currentRateMode Current Rate mode. (Stable = 1, Variable = 2) - */ - function swapBorrowRateMode( - address token, - uint currentRateMode - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); + /** + * @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 currentRateMode Current Rate mode. (Stable = 1, Variable = 2) + */ + function swapBorrowRateMode(address token, uint256 currentRateMode) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); bool isEth = token == ethAddr; address _token = isEth ? wethAddr : token; - if (getPaybackBalance(_token, currentRateMode) > 0) { - aave.swapBorrowRateMode(_token, currentRateMode); - } + if (getPaybackBalance(_token, currentRateMode) > 0) { + aave.swapBorrowRateMode(_token, currentRateMode); + } - _eventName = "LogSwapRateMode(address,uint256)"; - _eventParam = abi.encode(token, currentRateMode); - } + _eventName = "LogSwapRateMode(address,uint256)"; + _eventParam = abi.encode(token, currentRateMode); + } } contract ConnectV2AaveV2 is AaveResolver { - string constant public name = "AaveV2-v1.2"; + string public constant name = "AaveV2-v1.2"; } diff --git a/contracts/mainnet/connectors/aave/v3/main.sol b/contracts/mainnet/connectors/aave/v3/main.sol index 48751aa4..d49a869f 100644 --- a/contracts/mainnet/connectors/aave/v3/main.sol +++ b/contracts/mainnet/connectors/aave/v3/main.sol @@ -224,7 +224,14 @@ abstract contract AaveResolver is Events, Helpers { setUint(setId, _amt); _eventName = "LogBorrowOnBehalfOf(address,uint256,uint256,address,uint256,uint256)"; - _eventParam = abi.encode(token, _amt, rateMode, onBehalfOf, getId, setId); + _eventParam = abi.encode( + token, + _amt, + rateMode, + onBehalfOf, + getId, + setId + ); } /** @@ -344,7 +351,9 @@ abstract contract AaveResolver is Events, Helpers { TokenInterface tokenContract = TokenInterface(_token); - _amt = _amt == uint256(-1) ? getOnBehalfOfPaybackBalance(_token, rateMode, onBehalfOf) : _amt; + _amt = _amt == uint256(-1) + ? getOnBehalfOfPaybackBalance(_token, rateMode, onBehalfOf) + : _amt; if (isEth) convertEthToWeth(isEth, tokenContract, _amt); @@ -355,10 +364,16 @@ abstract contract AaveResolver is Events, Helpers { setUint(setId, _amt); _eventName = "LogPaybackOnBehalfOf(address,uint256,uint256,address,uint256,uint256)"; - _eventParam = abi.encode(token, _amt, rateMode, onBehalfOf, getId, setId); + _eventParam = abi.encode( + token, + _amt, + rateMode, + onBehalfOf, + getId, + setId + ); } - /** * @dev Enable collateral * @notice Enable an array of tokens as collateral @@ -463,8 +478,14 @@ abstract contract AaveResolver is Events, Helpers { setUint(setId, _amt); _eventName = "LogDelegateBorrow(address,uint256,uint256,address,uint256,uint256)"; - _eventParam = abi.encode(token, _amt, rateMode, delegateTo, getId, setId); - + _eventParam = abi.encode( + token, + _amt, + rateMode, + delegateTo, + getId, + setId + ); } } diff --git a/contracts/polygon/connectors/aave/v2/main.sol b/contracts/polygon/connectors/aave/v2/main.sol index eaeacb13..f597a487 100644 --- a/contracts/polygon/connectors/aave/v2/main.sol +++ b/contracts/polygon/connectors/aave/v2/main.sol @@ -267,7 +267,7 @@ abstract contract AaveResolver is Events, Helpers { for (uint256 i = 0; i < _length; i++) { bool isMatic = tokens[i] == maticAddr; - address _token = isMatic ? wmaticAddr : tokens[i]; + address _token = isMatic ? wmaticAddr : tokens[i]; if (getCollateralBalance(_token) > 0 && !getIsColl(_token)) { aave.setUserUseReserveAsCollateral(_token, true); @@ -278,28 +278,29 @@ abstract contract AaveResolver is Events, Helpers { _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 MATIC: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param currentRateMode Current Rate mode. (Stable = 1, Variable = 2) - */ - function swapBorrowRateMode( - address token, - uint currentRateMode - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); + /** + * @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 MATIC: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param currentRateMode Current Rate mode. (Stable = 1, Variable = 2) + */ + function swapBorrowRateMode(address token, uint256 currentRateMode) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + AaveInterface aave = AaveInterface(aaveProvider.getLendingPool()); bool isMatic = token == maticAddr; address _token = isMatic ? wmaticAddr : token; - if (getPaybackBalance(_token, currentRateMode) > 0) { - aave.swapBorrowRateMode(_token, currentRateMode); - } + if (getPaybackBalance(_token, currentRateMode) > 0) { + aave.swapBorrowRateMode(_token, currentRateMode); + } - _eventName = "LogSwapRateMode(address,uint256)"; - _eventParam = abi.encode(token, currentRateMode); - } + _eventName = "LogSwapRateMode(address,uint256)"; + _eventParam = abi.encode(token, currentRateMode); + } } contract ConnectV2AaveV2Polygon is AaveResolver { From 9b99b207a836173045d507c05713159c19dfc545 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Sat, 18 Jun 2022 23:06:47 +0530 Subject: [PATCH 6/7] added tests --- test/arbitrum/aave/v3-test.ts | 292 +++++++++++++++++++++++++++++++++ test/avalanche/aave/v3-test.ts | 273 ++++++++++++++++++++++++++++++ test/fantom/aave/v3-test.ts | 264 +++++++++++++++++++++++++++++ test/optimism/aave/v3-test.ts | 268 ++++++++++++++++++++++++++++++ test/polygon/aave/v3-test.ts | 264 +++++++++++++++++++++++++++++ 5 files changed, 1361 insertions(+) create mode 100644 test/arbitrum/aave/v3-test.ts create mode 100644 test/avalanche/aave/v3-test.ts create mode 100644 test/fantom/aave/v3-test.ts create mode 100644 test/optimism/aave/v3-test.ts create mode 100644 test/polygon/aave/v3-test.ts diff --git a/test/arbitrum/aave/v3-test.ts b/test/arbitrum/aave/v3-test.ts new file mode 100644 index 00000000..85e7065c --- /dev/null +++ b/test/arbitrum/aave/v3-test.ts @@ -0,0 +1,292 @@ +import { expect, should } from "chai"; +import hre, { ethers, waffle } from "hardhat"; +import type { Signer, Contract } from "ethers"; +import { ecsign, ecrecover, pubToAddress } from "ethereumjs-util"; +import { keccak256 } from "@ethersproject/keccak256"; +import { defaultAbiCoder } from "@ethersproject/abi"; +import { BigNumber } from "bignumber.js"; +import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2"; +import { addresses } from "../../../scripts/tests/arbitrum/addresses"; +import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector"; +import { abis } from "../../../scripts/constant/abis"; +import { getMasterSigner } from "../../../scripts/tests/getMasterSigner"; +import { parseEther, parseUnits } from "ethers/lib/utils"; +import { encodeSpells } from "../../../scripts/tests/encodeSpells"; +import encodeFlashcastData from "../../../scripts/tests/encodeFlashcastData"; +import { ConnectV2AaveV3Arbitrum__factory, IERC20__factory } from "../../../typechain"; + +const ABI = ["function balanceOf(address account) public view returns (uint256)"]; + +const aDaiAddress = "0x82E64f49Ed5EC1bC6e43DAD4FC8Af9bb3A2312EE"; +const aaveAddress = "0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654"; +let account = "0xc5ed2333f8a2c351fca35e5ebadb2a82f5d254c3"; +const DAI = "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1"; +const USDC = "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8"; +const mnemonic = "test test test test test test test test test test test junk"; +const connectorName = "AAVE-V3-X"; +let signer: any, wallet0: any; + +const aaveAbi = [ + { + inputs: [ + { internalType: "address", name: "asset", type: "address" }, + { internalType: "address", name: "user", type: "address" } + ], + name: "getUserReserveData", + outputs: [ + { internalType: "uint256", name: "currentATokenBalance", type: "uint256" }, + { internalType: "uint256", name: "currentStableDebt", type: "uint256" }, + { internalType: "uint256", name: "currentVariableDebt", type: "uint256" }, + { internalType: "uint256", name: "principalStableDebt", type: "uint256" }, + { internalType: "uint256", name: "scaledVariableDebt", type: "uint256" }, + { internalType: "uint256", name: "stableBorrowRate", type: "uint256" }, + { internalType: "uint256", name: "liquidityRate", type: "uint256" }, + { internalType: "uint40", name: "stableRateLastUpdated", type: "uint40" }, + { internalType: "bool", name: "usageAsCollateralEnabled", type: "bool" } + ], + stateMutability: "view", + type: "function" + } +]; + +const erc20Abi = [ + { + constant: false, + inputs: [ + { + name: "_spender", + type: "address" + }, + { + name: "_value", + type: "uint256" + } + ], + name: "approve", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "totalSupply", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "_owner", + type: "address" + } + ], + name: "balanceOf", + outputs: [ + { + name: "balance", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_to", + type: "address" + }, + { + name: "_value", + type: "uint256" + } + ], + name: "transfer", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + } +]; + +const token = new ethers.Contract(DAI, erc20Abi); +const aDai = new ethers.Contract(aDaiAddress, ABI); +const usdcToken = new ethers.Contract(USDC, erc20Abi); +const aave = new ethers.Contract(aaveAddress, aaveAbi); + +describe("Aave v3 Position for Arbitrum", function () { + let dsaWallet0: any; + let masterSigner: Signer; + let instaConnectorsV2: Contract; + let connector: any; + + const wallet = ethers.Wallet.fromMnemonic(mnemonic); + + before(async () => { + await hre.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + //@ts-ignore + jsonRpcUrl: hre.config.networks.hardhat.forking.url, + blockNumber: 9333600 + } + } + ] + }); + masterSigner = await getMasterSigner(); + [wallet0] = await ethers.getSigners(); + await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]); + + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [account] + }); + + signer = await ethers.getSigner(account); + + await token.connect(signer).transfer(wallet0.address, ethers.utils.parseEther("10")); + + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + connector = await deployAndEnableConnector({ + connectorName, + contractArtifact: ConnectV2AaveV3Arbitrum__factory, + signer: masterSigner, + connectors: instaConnectorsV2 + }); + }); + + describe("Deployment", async () => { + it("Should set correct name", async () => { + expect(await connector.name()).to.eq("AaveV3-v1.2"); + }); + }); + + describe("DSA wallet setup", async () => { + it("Should build DSA v2", async () => { + dsaWallet0 = await buildDSAv2(wallet0.address); + expect(!!dsaWallet0.address).to.be.true; + }); + + it("Deposit ETH into DSA wallet", async function () { + await wallet0.sendTransaction({ + to: dsaWallet0.address, + value: ethers.utils.parseEther("5") + }); + + expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("5")); + }); + }); + + describe("check user AAVE position", async () => { + it("Should create DSA Aave v3 position of DAI(collateral) and USDC(debt)", async () => { + await token.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseEther("10")); + + const spells = [ + //deposit DAI in aave + { + connector: connectorName, + method: "deposit", + args: [DAI, parseEther("10"), 0, 0] + }, + //borrow USDC from aave + { + connector: connectorName, + method: "borrow", + args: [USDC, parseUnits("3", 6), 2, 0, 0] + } + ]; + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address); + const receipt = await tx.wait(); + }); + + it("Should check position of dsa", async () => { + expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(10).multipliedBy(1e18).toString() + ); + + expect(await usdcToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt).to.be.equal( + 0 + ); + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + console.log( + `\tstable borrow before: ${ + (await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt + }` + ); + console.log( + `\tvariable borrow before: ${ + (await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt + }` + ); + }); + + it("Should swap borrowRateMode", async () => { + const spells = [ + //deposit DAI in aave + { + connector: connectorName, + method: "swapBorrowRateMode", + args: [USDC, 2] + } + ]; + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address); + const receipt = await tx.wait(); + }); + + it("Should check position of dsa", async () => { + expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(10).multipliedBy(1e18).toString() + ); + + expect(await usdcToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + expect( + (await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt + ).to.be.equal(0); + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + console.log( + `\tstable borrow after: ${ + (await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt + }` + ); + console.log( + `\tvariable borrow after: ${ + (await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt + }` + ); + }); + }); +}); diff --git a/test/avalanche/aave/v3-test.ts b/test/avalanche/aave/v3-test.ts new file mode 100644 index 00000000..3e9e23ae --- /dev/null +++ b/test/avalanche/aave/v3-test.ts @@ -0,0 +1,273 @@ +import { expect, should } from "chai"; +import hre, { ethers, waffle } from "hardhat"; +import type { Signer, Contract } from "ethers"; +import { BigNumber } from "bignumber.js"; +import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2"; +import { addresses } from "../../../scripts/tests/avalanche/addresses"; +import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector"; +import { abis } from "../../../scripts/constant/abis"; +import { getMasterSigner } from "../../../scripts/tests/getMasterSigner"; +import { parseEther, parseUnits } from "ethers/lib/utils"; +import { encodeSpells } from "../../../scripts/tests/encodeSpells"; +import { ConnectV2AaveV3Avalanche__factory, IERC20__factory } from "../../../typechain"; + +const ABI = ["function balanceOf(address account) public view returns (uint256)"]; + +const aDaiAddress = "0x82E64f49Ed5EC1bC6e43DAD4FC8Af9bb3A2312EE"; +const aaveAddress = "0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654"; +const ETH = "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"; +let account = "0xC4Aa5b4d4049324C09376D586482c7F8fB57542a"; +const DAI = "0xd586E7F844cEa2F87f50152665BCbc2C279D8d70"; +const mnemonic = "test test test test test test test test test test test junk"; +const connectorName = "AAVE-V3-X"; +let signer: any, wallet0: any; + +const aaveAbi = [ + { + inputs: [ + { internalType: "address", name: "asset", type: "address" }, + { internalType: "address", name: "user", type: "address" } + ], + name: "getUserReserveData", + outputs: [ + { internalType: "uint256", name: "currentATokenBalance", type: "uint256" }, + { internalType: "uint256", name: "currentStableDebt", type: "uint256" }, + { internalType: "uint256", name: "currentVariableDebt", type: "uint256" }, + { internalType: "uint256", name: "principalStableDebt", type: "uint256" }, + { internalType: "uint256", name: "scaledVariableDebt", type: "uint256" }, + { internalType: "uint256", name: "stableBorrowRate", type: "uint256" }, + { internalType: "uint256", name: "liquidityRate", type: "uint256" }, + { internalType: "uint40", name: "stableRateLastUpdated", type: "uint40" }, + { internalType: "bool", name: "usageAsCollateralEnabled", type: "bool" } + ], + stateMutability: "view", + type: "function" + } +]; + +const erc20Abi = [ + { + constant: false, + inputs: [ + { + name: "_spender", + type: "address" + }, + { + name: "_value", + type: "uint256" + } + ], + name: "approve", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "totalSupply", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "_owner", + type: "address" + } + ], + name: "balanceOf", + outputs: [ + { + name: "balance", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_to", + type: "address" + }, + { + name: "_value", + type: "uint256" + } + ], + name: "transfer", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + } +]; + +const token = new ethers.Contract(DAI, erc20Abi); +const aDai = new ethers.Contract(aDaiAddress, ABI); +const ethToken = new ethers.Contract(ETH, erc20Abi); +const aave = new ethers.Contract(aaveAddress, aaveAbi); + +describe("Aave v3 Position for Avalanche", function () { + let dsaWallet0: any; + let masterSigner: Signer; + let instaConnectorsV2: Contract; + let connector: any; + + const wallet = ethers.Wallet.fromMnemonic(mnemonic); + + before(async () => { + await hre.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + //@ts-ignore + jsonRpcUrl: hre.config.networks.hardhat.forking.url, + blockNumber: 16201000 + } + } + ] + }); + masterSigner = await getMasterSigner(); + [wallet0] = await ethers.getSigners(); + await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]); + + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [account] + }); + + signer = await ethers.getSigner(account); + + await token.connect(signer).transfer(wallet0.address, ethers.utils.parseEther("8")); + + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + connector = await deployAndEnableConnector({ + connectorName, + contractArtifact: ConnectV2AaveV3Avalanche__factory, + signer: masterSigner, + connectors: instaConnectorsV2 + }); + }); + + describe("Deployment", async () => { + it("Should set correct name", async () => { + expect(await connector.name()).to.eq("AaveV3-v1.2"); + }); + }); + + describe("DSA wallet setup", async () => { + it("Should build DSA v2", async () => { + dsaWallet0 = await buildDSAv2(wallet0.address); + expect(!!dsaWallet0.address).to.be.true; + }); + + it("Deposit ETH into DSA wallet", async function () { + await wallet0.sendTransaction({ + to: dsaWallet0.address, + value: ethers.utils.parseEther("5") + }); + + expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("5")); + }); + }); + + describe("check user AAVE position", async () => { + it("Should create DSA Aave v3 position of DAI(collateral) and USDC(debt)", async () => { + await token.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseEther("8")); + + const spells = [ + //deposit DAI in aave + { + connector: connectorName, + method: "deposit", + args: [DAI, parseEther("8"), 0, 0] + }, + //borrow USDC from aave + { + connector: connectorName, + method: "borrow", + args: [ETH, parseUnits("1", 6), 2, 0, 0] + } + ]; + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address); + const receipt = await tx.wait(); + }); + + it("Should check position of dsa", async () => { + expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(8).multipliedBy(1e18).toString() + ); + + expect(await ethToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(1).multipliedBy(1e6).toString() + ); + + expect((await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentStableDebt).to.be.equal( + 0 + ); + expect((await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentVariableDebt).to.be.gte( + new BigNumber(1).multipliedBy(1e6).toString() + ); + console.log(`\tstable borrow before: ${(await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentStableDebt}`); + console.log(`\tvariable borrow before: ${(await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentVariableDebt}`); + }); + + it("Should swap borrowRateMode", async () => { + const spells = [ + //deposit DAI in aave + { + connector: connectorName, + method: "swapBorrowRateMode", + args: [ETH, 2] + } + ]; + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address); + const receipt = await tx.wait(); + }); + + it("Should check position of dsa", async () => { + expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(8).multipliedBy(1e18).toString() + ); + + expect(await ethToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(1).multipliedBy(1e6).toString() + ); + expect( + (await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentVariableDebt + ).to.be.equal(0); + expect((await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentStableDebt).to.be.gte( + new BigNumber(1).multipliedBy(1e6).toString() + ); + + console.log(`\tstable borrow after: ${(await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentStableDebt}`); + console.log(`\tvariable borrow after: ${(await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentVariableDebt}`) + }); + }); +}); diff --git a/test/fantom/aave/v3-test.ts b/test/fantom/aave/v3-test.ts new file mode 100644 index 00000000..292d36b6 --- /dev/null +++ b/test/fantom/aave/v3-test.ts @@ -0,0 +1,264 @@ +import { expect, should } from "chai"; +import hre, { ethers, waffle } from "hardhat"; +import type { Signer, Contract } from "ethers"; +import { BigNumber } from "bignumber.js"; +import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2"; +import { addresses } from "../../../scripts/tests/fantom/addresses"; +import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector"; +import { abis } from "../../../scripts/constant/abis"; +import { getMasterSigner } from "../../../scripts/tests/getMasterSigner"; +import { parseEther, parseUnits } from "ethers/lib/utils"; +import { encodeSpells } from "../../../scripts/tests/encodeSpells"; +import { ConnectV2AaveV3Fantom__factory, IERC20__factory } from "../../../typechain"; + +const ABI = ["function balanceOf(address account) public view returns (uint256)"]; + +const aDaiAddress = "0x82E64f49Ed5EC1bC6e43DAD4FC8Af9bb3A2312EE"; +const aaveAddress = "0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654"; +let account = "0x1c664Bafc646510684Ba1588798c67fe22a8c7cf"; +const DAI = "0x8D11eC38a3EB5E956B052f67Da8Bdc9bef8Abf3E"; +const USDC = "0x04068DA6C83AFCFA0e13ba15A6696662335D5B75"; +const mnemonic = "test test test test test test test test test test test junk"; +const connectorName = "AAVE-V3-X"; +let signer: any, wallet0: any; + +const aaveAbi = [ + { + inputs: [ + { internalType: "address", name: "asset", type: "address" }, + { internalType: "address", name: "user", type: "address" } + ], + name: "getUserReserveData", + outputs: [ + { internalType: "uint256", name: "currentATokenBalance", type: "uint256" }, + { internalType: "uint256", name: "currentStableDebt", type: "uint256" }, + { internalType: "uint256", name: "currentVariableDebt", type: "uint256" }, + { internalType: "uint256", name: "principalStableDebt", type: "uint256" }, + { internalType: "uint256", name: "scaledVariableDebt", type: "uint256" }, + { internalType: "uint256", name: "stableBorrowRate", type: "uint256" }, + { internalType: "uint256", name: "liquidityRate", type: "uint256" }, + { internalType: "uint40", name: "stableRateLastUpdated", type: "uint40" }, + { internalType: "bool", name: "usageAsCollateralEnabled", type: "bool" } + ], + stateMutability: "view", + type: "function" + } +]; + +const erc20Abi = [ + { + constant: false, + inputs: [ + { + name: "_spender", + type: "address" + }, + { + name: "_value", + type: "uint256" + } + ], + name: "approve", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "totalSupply", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "_owner", + type: "address" + } + ], + name: "balanceOf", + outputs: [ + { + name: "balance", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_to", + type: "address" + }, + { + name: "_value", + type: "uint256" + } + ], + name: "transfer", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + } +]; + +const token = new ethers.Contract(DAI, erc20Abi); +const aDai = new ethers.Contract(aDaiAddress, ABI); +const usdcToken = new ethers.Contract(USDC, erc20Abi); +const aave = new ethers.Contract(aaveAddress, aaveAbi); + +describe("Aave v3 Position for Fantom", function () { + let dsaWallet0: any; + let masterSigner: Signer; + let instaConnectorsV2: Contract; + let connector: any; + + const wallet = ethers.Wallet.fromMnemonic(mnemonic); + + before(async () => { + await hre.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + //@ts-ignore + jsonRpcUrl: hre.config.networks.hardhat.forking.url, + blockNumber: 40790000 + } + } + ] + }); + masterSigner = await getMasterSigner(); + [wallet0] = await ethers.getSigners(); + await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]); + + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [account] + }); + + signer = await ethers.getSigner(account); + + await token.connect(signer).transfer(wallet0.address, ethers.utils.parseEther("10")); + + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + connector = await deployAndEnableConnector({ + connectorName, + contractArtifact: ConnectV2AaveV3Fantom__factory, + signer: masterSigner, + connectors: instaConnectorsV2 + }); + }); + + describe("Deployment", async () => { + it("Should set correct name", async () => { + expect(await connector.name()).to.eq("AaveV3-v1.2"); + }); + }); + + describe("DSA wallet setup", async () => { + it("Should build DSA v2", async () => { + dsaWallet0 = await buildDSAv2(wallet0.address); + expect(!!dsaWallet0.address).to.be.true; + }); + + it("Deposit ETH into DSA wallet", async function () { + await wallet0.sendTransaction({ + to: dsaWallet0.address, + value: ethers.utils.parseEther("5") + }); + + expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("5")); + }); + }); + + describe("check user AAVE position", async () => { + it("Should create DSA Aave v3 position of DAI(collateral) and USDC(debt)", async () => { + await token.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseEther("10")); + + const spells = [ + //deposit DAI in aave + { + connector: connectorName, + method: "deposit", + args: [DAI, parseEther("10"), 0, 0] + }, + //borrow USDC from aave + { + connector: connectorName, + method: "borrow", + args: [USDC, parseUnits("3", 6), 2, 0, 0] + } + ]; + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address); + const receipt = await tx.wait(); + }); + + it("Should check position of dsa", async () => { + expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(10).multipliedBy(1e18).toString() + ); + + expect(await usdcToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt).to.be.equal(0); + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + }); + + it("Should swap borrowRateMode", async () => { + const spells = [ + //deposit DAI in aave + { + connector: connectorName, + method: "swapBorrowRateMode", + args: [USDC, 2] + } + ]; + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address); + const receipt = await tx.wait(); + }); + + it("Should check position of dsa", async () => { + expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(10).multipliedBy(1e18).toString() + ); + + expect(await usdcToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt).to.be.equal(0); + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + }); + }); +}); diff --git a/test/optimism/aave/v3-test.ts b/test/optimism/aave/v3-test.ts new file mode 100644 index 00000000..5f6817f5 --- /dev/null +++ b/test/optimism/aave/v3-test.ts @@ -0,0 +1,268 @@ +import { expect, should } from "chai"; +import hre, { ethers, waffle } from "hardhat"; +import type { Signer, Contract } from "ethers"; +import { ecsign, ecrecover, pubToAddress } from "ethereumjs-util"; +import { keccak256 } from "@ethersproject/keccak256"; +import { defaultAbiCoder } from "@ethersproject/abi"; +import { BigNumber } from "bignumber.js"; +import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2"; +import { addresses } from "../../../scripts/tests/optimism/addresses"; +import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector"; +import { abis } from "../../../scripts/constant/abis"; +import { getMasterSigner } from "../../../scripts/tests/getMasterSigner"; +import { parseEther, parseUnits } from "ethers/lib/utils"; +import { encodeSpells } from "../../../scripts/tests/encodeSpells"; +import encodeFlashcastData from "../../../scripts/tests/encodeFlashcastData"; +import { ConnectV2AaveV3Optimism__factory, IERC20__factory } from "../../../typechain"; + +const ABI = ["function balanceOf(address account) public view returns (uint256)"]; + +const aDaiAddress = "0x82E64f49Ed5EC1bC6e43DAD4FC8Af9bb3A2312EE"; +const aaveAddress = "0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654"; +let account = "0xa06067164E76285cef0ac6C42B3AD3Ce9BE5039A"; +const DAI = "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1"; +const USDC = "0x7F5c764cBc14f9669B88837ca1490cCa17c31607"; +const mnemonic = "test test test test test test test test test test test junk"; +const connectorName = "AAVE-V3-X"; +let signer: any, wallet0: any; + +const aaveAbi = [ + { + inputs: [ + { internalType: "address", name: "asset", type: "address" }, + { internalType: "address", name: "user", type: "address" } + ], + name: "getUserReserveData", + outputs: [ + { internalType: "uint256", name: "currentATokenBalance", type: "uint256" }, + { internalType: "uint256", name: "currentStableDebt", type: "uint256" }, + { internalType: "uint256", name: "currentVariableDebt", type: "uint256" }, + { internalType: "uint256", name: "principalStableDebt", type: "uint256" }, + { internalType: "uint256", name: "scaledVariableDebt", type: "uint256" }, + { internalType: "uint256", name: "stableBorrowRate", type: "uint256" }, + { internalType: "uint256", name: "liquidityRate", type: "uint256" }, + { internalType: "uint40", name: "stableRateLastUpdated", type: "uint40" }, + { internalType: "bool", name: "usageAsCollateralEnabled", type: "bool" } + ], + stateMutability: "view", + type: "function" + } +]; + +const erc20Abi = [ + { + constant: false, + inputs: [ + { + name: "_spender", + type: "address" + }, + { + name: "_value", + type: "uint256" + } + ], + name: "approve", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "totalSupply", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "_owner", + type: "address" + } + ], + name: "balanceOf", + outputs: [ + { + name: "balance", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_to", + type: "address" + }, + { + name: "_value", + type: "uint256" + } + ], + name: "transfer", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + } +]; + +const token = new ethers.Contract(DAI, erc20Abi); +const aDai = new ethers.Contract(aDaiAddress, ABI); +const usdcToken = new ethers.Contract(USDC, erc20Abi); +const aave = new ethers.Contract(aaveAddress, aaveAbi); + +describe("Aave v3 Position for Optimism", function () { + let dsaWallet0: any; + let masterSigner: Signer; + let instaConnectorsV2: Contract; + let connector: any; + + const wallet = ethers.Wallet.fromMnemonic(mnemonic); + + before(async () => { + await hre.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + //@ts-ignore + jsonRpcUrl: hre.config.networks.hardhat.forking.url, + blockNumber: 12230000 + } + } + ] + }); + masterSigner = await getMasterSigner(); + [wallet0] = await ethers.getSigners(); + await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]); + + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [account] + }); + + signer = await ethers.getSigner(account); + + await token.connect(signer).transfer(wallet0.address, ethers.utils.parseEther("10")); + + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + connector = await deployAndEnableConnector({ + connectorName, + contractArtifact: ConnectV2AaveV3Optimism__factory, + signer: masterSigner, + connectors: instaConnectorsV2 + }); + }); + + describe("Deployment", async () => { + it("Should set correct name", async () => { + expect(await connector.name()).to.eq("AaveV3-v1.2"); + }); + }); + + describe("DSA wallet setup", async () => { + it("Should build DSA v2", async () => { + dsaWallet0 = await buildDSAv2(wallet0.address); + expect(!!dsaWallet0.address).to.be.true; + }); + + it("Deposit ETH into DSA wallet", async function () { + await wallet0.sendTransaction({ + to: dsaWallet0.address, + value: ethers.utils.parseEther("5") + }); + + expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("5")); + }); + }); + + describe("check user AAVE position", async () => { + it("Should create DSA Aave v3 position of DAI(collateral) and USDC(debt)", async () => { + await token.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseEther("10")); + + const spells = [ + //deposit DAI in aave + { + connector: connectorName, + method: "deposit", + args: [DAI, parseEther("10"), 0, 0] + }, + //borrow USDC from aave + { + connector: connectorName, + method: "borrow", + args: [USDC, parseUnits("3", 6), 2, 0, 0] + } + ]; + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address); + const receipt = await tx.wait(); + }); + + it("Should check position of dsa", async () => { + expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(10).multipliedBy(1e18).toString() + ); + + expect(await usdcToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt).to.be.equal(0); + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + }); + + it("Should swap borrowRateMode", async () => { + const spells = [ + //deposit DAI in aave + { + connector: connectorName, + method: "swapBorrowRateMode", + args: [USDC, 2] + } + ]; + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address); + const receipt = await tx.wait(); + }); + + it("Should check position of dsa", async () => { + expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(10).multipliedBy(1e18).toString() + ); + + expect(await usdcToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt).to.be.equal(0); + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + }); + }); +}); diff --git a/test/polygon/aave/v3-test.ts b/test/polygon/aave/v3-test.ts new file mode 100644 index 00000000..e76c77bc --- /dev/null +++ b/test/polygon/aave/v3-test.ts @@ -0,0 +1,264 @@ +import { expect, should } from "chai"; +import hre, { ethers, waffle } from "hardhat"; +import type { Signer, Contract } from "ethers"; +import { BigNumber } from "bignumber.js"; +import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2"; +import { addresses } from "../../../scripts/tests/polygon/addresses"; +import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector"; +import { abis } from "../../../scripts/constant/abis"; +import { getMasterSigner } from "../../../scripts/tests/getMasterSigner"; +import { parseEther, parseUnits } from "ethers/lib/utils"; +import { encodeSpells } from "../../../scripts/tests/encodeSpells"; +import { ConnectV2AaveV3Polygon__factory, IERC20__factory } from "../../../typechain"; + +const ABI = ["function balanceOf(address account) public view returns (uint256)"]; + +const aDaiAddress = "0x82E64f49Ed5EC1bC6e43DAD4FC8Af9bb3A2312EE"; +const aaveAddress = "0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654"; +const account = "0xf04adbf75cdfc5ed26eea4bbbb991db002036bdd"; +const DAI = "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063"; +const USDC = "0x2791bca1f2de4661ed88a30c99a7a9449aa84174"; +const mnemonic = "test test test test test test test test test test test junk"; +const connectorName = "AAVE-V3-X"; +let signer: any, wallet0: any; + +const aaveAbi = [ + { + inputs: [ + { internalType: "address", name: "asset", type: "address" }, + { internalType: "address", name: "user", type: "address" } + ], + name: "getUserReserveData", + outputs: [ + { internalType: "uint256", name: "currentATokenBalance", type: "uint256" }, + { internalType: "uint256", name: "currentStableDebt", type: "uint256" }, + { internalType: "uint256", name: "currentVariableDebt", type: "uint256" }, + { internalType: "uint256", name: "principalStableDebt", type: "uint256" }, + { internalType: "uint256", name: "scaledVariableDebt", type: "uint256" }, + { internalType: "uint256", name: "stableBorrowRate", type: "uint256" }, + { internalType: "uint256", name: "liquidityRate", type: "uint256" }, + { internalType: "uint40", name: "stableRateLastUpdated", type: "uint40" }, + { internalType: "bool", name: "usageAsCollateralEnabled", type: "bool" } + ], + stateMutability: "view", + type: "function" + } +]; + +const erc20Abi = [ + { + constant: false, + inputs: [ + { + name: "_spender", + type: "address" + }, + { + name: "_value", + type: "uint256" + } + ], + name: "approve", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "totalSupply", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "_owner", + type: "address" + } + ], + name: "balanceOf", + outputs: [ + { + name: "balance", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_to", + type: "address" + }, + { + name: "_value", + type: "uint256" + } + ], + name: "transfer", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + } +]; + +const token = new ethers.Contract(DAI, erc20Abi); +const aDai = new ethers.Contract(aDaiAddress, ABI); +const usdcToken = new ethers.Contract(USDC, erc20Abi); +const aave = new ethers.Contract(aaveAddress, aaveAbi); + +describe("Aave v3 Position for Polygon", function () { + let dsaWallet0: any; + let masterSigner: Signer; + let instaConnectorsV2: Contract; + let connector: any; + + const wallet = ethers.Wallet.fromMnemonic(mnemonic); + + before(async () => { + await hre.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + //@ts-ignore + jsonRpcUrl: hre.config.networks.hardhat.forking.url, + blockNumber: 26652016 + } + } + ] + }); + masterSigner = await getMasterSigner(); + [wallet0] = await ethers.getSigners(); + await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]); + + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [account] + }); + + signer = await ethers.getSigner(account); + + await token.connect(signer).transfer(wallet0.address, ethers.utils.parseEther("10")); + + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + connector = await deployAndEnableConnector({ + connectorName, + contractArtifact: ConnectV2AaveV3Polygon__factory, + signer: masterSigner, + connectors: instaConnectorsV2 + }); + }); + + describe("Deployment", async () => { + it("Should set correct name", async () => { + expect(await connector.name()).to.eq("AaveV3-v1.2"); + }); + }); + + describe("DSA wallet setup", async () => { + it("Should build DSA v2", async () => { + dsaWallet0 = await buildDSAv2(wallet0.address); + expect(!!dsaWallet0.address).to.be.true; + }); + + it("Deposit ETH into DSA wallet", async function () { + await wallet0.sendTransaction({ + to: dsaWallet0.address, + value: ethers.utils.parseEther("5") + }); + + expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("5")); + }); + }); + + describe("check user AAVE position", async () => { + it("Should create DSA Aave v3 position of DAI(collateral) and USDC(debt)", async () => { + await token.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseEther("10")); + + const spells = [ + //deposit DAI in aave + { + connector: connectorName, + method: "deposit", + args: [DAI, parseEther("10"), 0, 0] + }, + //borrow USDC from aave + { + connector: connectorName, + method: "borrow", + args: [USDC, parseUnits("3", 6), 2, 0, 0] + } + ]; + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address); + const receipt = await tx.wait(); + }); + + it("Should check position of dsa", async () => { + expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(10).multipliedBy(1e18).toString() + ); + + expect(await usdcToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt).to.be.equal(0); + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + }); + + it("Should swap borrowRateMode", async () => { + const spells = [ + //deposit DAI in aave + { + connector: connectorName, + method: "swapBorrowRateMode", + args: [USDC, 2] + } + ]; + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address); + const receipt = await tx.wait(); + }); + + it("Should check position of dsa", async () => { + expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(10).multipliedBy(1e18).toString() + ); + + expect(await usdcToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt).to.be.equal(0); + expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt).to.be.gte( + new BigNumber(3).multipliedBy(1e6).toString() + ); + }); + }); +}); From f66cfc6533ad2c84170f3d31f85d9361725072e6 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Sat, 18 Jun 2022 23:45:35 +0530 Subject: [PATCH 7/7] minor changes --- contracts/avalanche/connectors/aave/v2/main.sol | 10 +++++----- contracts/mainnet/connectors/aave/v2/main.sol | 10 +++++----- contracts/polygon/connectors/aave/v2/main.sol | 10 +++++----- hardhat.config.ts | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/contracts/avalanche/connectors/aave/v2/main.sol b/contracts/avalanche/connectors/aave/v2/main.sol index 05a4808d..44540022 100644 --- a/contracts/avalanche/connectors/aave/v2/main.sol +++ b/contracts/avalanche/connectors/aave/v2/main.sol @@ -282,9 +282,9 @@ abstract contract AaveResolver is Events, Helpers { * @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 AVAX: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param currentRateMode Current Rate mode. (Stable = 1, Variable = 2) + * @param rateMode Current Rate mode. (Stable = 1, Variable = 2) */ - function swapBorrowRateMode(address token, uint256 currentRateMode) + function swapBorrowRateMode(address token, uint256 rateMode) external payable returns (string memory _eventName, bytes memory _eventParam) @@ -294,12 +294,12 @@ abstract contract AaveResolver is Events, Helpers { bool isAVAX = token == avaxAddr; address _token = isAVAX ? wavaxAddr : token; - if (getPaybackBalance(_token, currentRateMode) > 0) { - aave.swapBorrowRateMode(_token, currentRateMode); + if (getPaybackBalance(_token, rateMode) > 0) { + aave.swapBorrowRateMode(_token, rateMode); } _eventName = "LogSwapRateMode(address,uint256)"; - _eventParam = abi.encode(token, currentRateMode); + _eventParam = abi.encode(token, rateMode); } } diff --git a/contracts/mainnet/connectors/aave/v2/main.sol b/contracts/mainnet/connectors/aave/v2/main.sol index 5cf08931..f7edda1d 100644 --- a/contracts/mainnet/connectors/aave/v2/main.sol +++ b/contracts/mainnet/connectors/aave/v2/main.sol @@ -282,9 +282,9 @@ abstract contract AaveResolver is Events, Helpers { * @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 currentRateMode Current Rate mode. (Stable = 1, Variable = 2) + * @param rateMode Current Rate mode. (Stable = 1, Variable = 2) */ - function swapBorrowRateMode(address token, uint256 currentRateMode) + function swapBorrowRateMode(address token, uint256 rateMode) external payable returns (string memory _eventName, bytes memory _eventParam) @@ -294,12 +294,12 @@ abstract contract AaveResolver is Events, Helpers { bool isEth = token == ethAddr; address _token = isEth ? wethAddr : token; - if (getPaybackBalance(_token, currentRateMode) > 0) { - aave.swapBorrowRateMode(_token, currentRateMode); + if (getPaybackBalance(_token, rateMode) > 0) { + aave.swapBorrowRateMode(_token, rateMode); } _eventName = "LogSwapRateMode(address,uint256)"; - _eventParam = abi.encode(token, currentRateMode); + _eventParam = abi.encode(token, rateMode); } } diff --git a/contracts/polygon/connectors/aave/v2/main.sol b/contracts/polygon/connectors/aave/v2/main.sol index f597a487..20677010 100644 --- a/contracts/polygon/connectors/aave/v2/main.sol +++ b/contracts/polygon/connectors/aave/v2/main.sol @@ -282,9 +282,9 @@ abstract contract AaveResolver is Events, Helpers { * @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 MATIC: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param currentRateMode Current Rate mode. (Stable = 1, Variable = 2) + * @param rateMode Current Rate mode. (Stable = 1, Variable = 2) */ - function swapBorrowRateMode(address token, uint256 currentRateMode) + function swapBorrowRateMode(address token, uint256 rateMode) external payable returns (string memory _eventName, bytes memory _eventParam) @@ -294,12 +294,12 @@ abstract contract AaveResolver is Events, Helpers { bool isMatic = token == maticAddr; address _token = isMatic ? wmaticAddr : token; - if (getPaybackBalance(_token, currentRateMode) > 0) { - aave.swapBorrowRateMode(_token, currentRateMode); + if (getPaybackBalance(_token, rateMode) > 0) { + aave.swapBorrowRateMode(_token, rateMode); } _eventName = "LogSwapRateMode(address,uint256)"; - _eventParam = abi.encode(token, currentRateMode); + _eventParam = abi.encode(token, rateMode); } } diff --git a/hardhat.config.ts b/hardhat.config.ts index 12280e70..0508b8e5 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -43,7 +43,7 @@ const networkGasPriceConfig: Record = { avalanche: 40, arbitrum: 1, optimism: 0.001, - fantom: 300 + fantom: 210 }; function createConfig(network: string) {