From 7d117a52c3bf21b905f6fc74fd44c72ed22e6017 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Thu, 5 May 2022 22:34:38 +0530 Subject: [PATCH 1/6] added function for imprtWithCollateral --- .../connectors/aave/v3-import/events.sol | 10 ++ .../connectors/aave/v3-import/helpers.sol | 3 +- .../connectors/aave/v3-import/main.sol | 96 +++++++++++++++++++ 3 files changed, 108 insertions(+), 1 deletion(-) diff --git a/contracts/polygon/connectors/aave/v3-import/events.sol b/contracts/polygon/connectors/aave/v3-import/events.sol index 03aafca4..2a1c4e23 100644 --- a/contracts/polygon/connectors/aave/v3-import/events.sol +++ b/contracts/polygon/connectors/aave/v3-import/events.sol @@ -12,4 +12,14 @@ contract Events { uint256[] supplyAmts, uint256[] borrowAmts ); + event LogAaveV3ImportWithCollateral( + address indexed user, + address[] ctokens, + string[] supplyIds, + string[] borrowIds, + uint256[] flashLoanFees, + uint256[] supplyAmts, + uint256[] borrowAmts, + bool[] enableCollateral + ); } diff --git a/contracts/polygon/connectors/aave/v3-import/helpers.sol b/contracts/polygon/connectors/aave/v3-import/helpers.sol index ebad1560..7e1ffbc2 100644 --- a/contracts/polygon/connectors/aave/v3-import/helpers.sol +++ b/contracts/polygon/connectors/aave/v3-import/helpers.sol @@ -229,10 +229,11 @@ contract AaveHelpers is Helper { ATokenInterface[] memory atokenContracts, uint256[] memory amts, address[] memory tokens, + bool[] memory colEnable, address userAccount ) internal { for (uint256 i = 0; i < _length; i++) { - if (amts[i] > 0) { + if (amts[i] > 0 && colEnable[i]) { uint256 _amt = amts[i]; require( atokenContracts[i].transferFrom( diff --git a/contracts/polygon/connectors/aave/v3-import/main.sol b/contracts/polygon/connectors/aave/v3-import/main.sol index 4a3b38e7..5356818a 100644 --- a/contracts/polygon/connectors/aave/v3-import/main.sol +++ b/contracts/polygon/connectors/aave/v3-import/main.sol @@ -92,6 +92,87 @@ contract AaveV3ImportResolver is AaveHelpers { ); } + function _importAaveWithCollateral(address userAccount, ImportInputData memory inputData, bool[] memory enableCollateral) + internal + returns (string memory _eventName, bytes memory _eventParam) + { + require( + AccountInterface(address(this)).isAuth(userAccount), + "user-account-not-auth" + ); + + require(inputData.supplyTokens.length > 0, "0-length-not-allowed"); + + ImportData memory data; + + AaveInterface aave = AaveInterface(aaveProvider.getPool()); + + data = getBorrowAmounts(userAccount, aave, inputData, data); + data = getSupplyAmounts(userAccount, inputData, data); + + // payback borrowed amount; + _PaybackStable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.stableBorrowAmts, + userAccount + ); + _PaybackVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.variableBorrowAmts, + userAccount + ); + + // transfer atokens to this address; + _TransferAtokens( + data._supplyTokens.length, + aave, + data.aTokens, + data.supplyAmts, + data._supplyTokens, + userAccount + ); + + // borrow assets after migrating position + if (data.convertStable) { + _BorrowVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.totalBorrowAmtsWithFee + ); + } else { + _BorrowStable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.stableBorrowAmtsWithFee + ); + _BorrowVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.variableBorrowAmtsWithFee + ); + } + + _eventName = "LogAaveV3ImportWithCollateral(address,bool,address[],address[],uint256[],uint256[],uint256[],uint256[])"; + _eventParam = abi.encode( + userAccount, + inputData.convertStable, + inputData.supplyTokens, + inputData.borrowTokens, + inputData.flashLoanFees, + data.supplyAmts, + data.stableBorrowAmts, + data.variableBorrowAmts, + enableCollateral + ); + } + /** * @dev Import aave V3 position . * @notice Import EOA's aave V3 position to DSA's aave v3 position @@ -105,6 +186,21 @@ contract AaveV3ImportResolver is AaveHelpers { { (_eventName, _eventParam) = _importAave(userAccount, inputData); } + + /** + * @dev Import aave V3 position (with collateral). + * @notice Import EOA's aave V3 position to DSA's aave v3 position + * @param userAccount The address of the EOA from which aave position will be imported + * @param inputData The struct containing all the neccessary input data + * @param enableCollateral The boolean array to enable selected collaterals in the imported position + */ + function importAaveWithCollateral(address userAccount, ImportInputData memory inputData, bool[] memory enableCollateral) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + (_eventName, _eventParam) = _importAaveWithCollateral(userAccount, inputData, enableCollateral); + } } contract ConnectV2AaveV3ImportPolygon is AaveV3ImportResolver { From 94490ef9393667cc1943f222a24685240ec5ede6 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Thu, 5 May 2022 22:49:52 +0530 Subject: [PATCH 2/6] added function for imprtWithCollateral-polygon --- .../connectors/aave/v3-import/helpers.sol | 27 +++++++++++++++++++ .../connectors/aave/v3-import/main.sol | 3 ++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/contracts/polygon/connectors/aave/v3-import/helpers.sol b/contracts/polygon/connectors/aave/v3-import/helpers.sol index 7e1ffbc2..aa436556 100644 --- a/contracts/polygon/connectors/aave/v3-import/helpers.sol +++ b/contracts/polygon/connectors/aave/v3-import/helpers.sol @@ -224,6 +224,33 @@ contract AaveHelpers is Helper { } function _TransferAtokens( + uint256 _length, + AaveInterface aave, + ATokenInterface[] memory atokenContracts, + uint256[] memory amts, + address[] memory tokens, + address userAccount + ) internal { + for (uint256 i = 0; i < _length; i++) { + if (amts[i] > 0) { + uint256 _amt = amts[i]; + require( + atokenContracts[i].transferFrom( + userAccount, + address(this), + _amt + ), + "allowance?" + ); + + if (!getIsColl(tokens[i], address(this))) { + aave.setUserUseReserveAsCollateral(tokens[i], true); + } + } + } + } + + function _TransferAtokensWithCollateral( uint256 _length, AaveInterface aave, ATokenInterface[] memory atokenContracts, diff --git a/contracts/polygon/connectors/aave/v3-import/main.sol b/contracts/polygon/connectors/aave/v3-import/main.sol index 5356818a..14cf4a28 100644 --- a/contracts/polygon/connectors/aave/v3-import/main.sol +++ b/contracts/polygon/connectors/aave/v3-import/main.sol @@ -127,12 +127,13 @@ contract AaveV3ImportResolver is AaveHelpers { ); // transfer atokens to this address; - _TransferAtokens( + _TransferAtokensWithCollateral( data._supplyTokens.length, aave, data.aTokens, data.supplyAmts, data._supplyTokens, + enableCollateral, userAccount ); From dc3f042eb6bef669a6ba34e4aa65eee7681ad910 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Thu, 5 May 2022 23:16:19 +0530 Subject: [PATCH 3/6] updated event --- contracts/polygon/connectors/aave/v3-import/main.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/polygon/connectors/aave/v3-import/main.sol b/contracts/polygon/connectors/aave/v3-import/main.sol index 14cf4a28..3a5394f8 100644 --- a/contracts/polygon/connectors/aave/v3-import/main.sol +++ b/contracts/polygon/connectors/aave/v3-import/main.sol @@ -160,7 +160,7 @@ contract AaveV3ImportResolver is AaveHelpers { ); } - _eventName = "LogAaveV3ImportWithCollateral(address,bool,address[],address[],uint256[],uint256[],uint256[],uint256[])"; + _eventName = "LogAaveV3ImportWithCollateral(address,bool,address[],address[],uint256[],uint256[],uint256[],uint256[],bool[])"; _eventParam = abi.encode( userAccount, inputData.convertStable, From 8be787aa88bcc9a1a7b8457be5091839ca201c23 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Thu, 5 May 2022 23:30:21 +0530 Subject: [PATCH 4/6] updated logic, name string --- contracts/polygon/connectors/aave/v3-import/helpers.sol | 4 ++-- contracts/polygon/connectors/aave/v3-import/main.sol | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/contracts/polygon/connectors/aave/v3-import/helpers.sol b/contracts/polygon/connectors/aave/v3-import/helpers.sol index aa436556..c581b8cf 100644 --- a/contracts/polygon/connectors/aave/v3-import/helpers.sol +++ b/contracts/polygon/connectors/aave/v3-import/helpers.sol @@ -260,7 +260,7 @@ contract AaveHelpers is Helper { address userAccount ) internal { for (uint256 i = 0; i < _length; i++) { - if (amts[i] > 0 && colEnable[i]) { + if (amts[i] > 0) { uint256 _amt = amts[i]; require( atokenContracts[i].transferFrom( @@ -272,7 +272,7 @@ contract AaveHelpers is Helper { ); if (!getIsColl(tokens[i], address(this))) { - aave.setUserUseReserveAsCollateral(tokens[i], true); + aave.setUserUseReserveAsCollateral(tokens[i], colEnable[i]); } } } diff --git a/contracts/polygon/connectors/aave/v3-import/main.sol b/contracts/polygon/connectors/aave/v3-import/main.sol index 3a5394f8..a6e1836b 100644 --- a/contracts/polygon/connectors/aave/v3-import/main.sol +++ b/contracts/polygon/connectors/aave/v3-import/main.sol @@ -102,6 +102,7 @@ contract AaveV3ImportResolver is AaveHelpers { ); require(inputData.supplyTokens.length > 0, "0-length-not-allowed"); + require(enableCollateral.length == inputData.supplyTokens.length, "lengths-not-same"); ImportData memory data; @@ -205,5 +206,5 @@ contract AaveV3ImportResolver is AaveHelpers { } contract ConnectV2AaveV3ImportPolygon is AaveV3ImportResolver { - string public constant name = "Aave-v3-import-v1"; + string public constant name = "Aave-v3-import-v1.1"; } From 878f82c63dcc909e833d2500da90a01f50025d43 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Thu, 5 May 2022 23:36:51 +0530 Subject: [PATCH 5/6] importWithCollateral-arbitrum --- .../connectors/aave/v3-import/events.sol | 10 ++ .../connectors/aave/v3-import/helpers.sol | 28 +++++ .../connectors/aave/v3-import/main.sol | 100 +++++++++++++++++- 3 files changed, 137 insertions(+), 1 deletion(-) diff --git a/contracts/arbitrum/connectors/aave/v3-import/events.sol b/contracts/arbitrum/connectors/aave/v3-import/events.sol index 03aafca4..2a1c4e23 100644 --- a/contracts/arbitrum/connectors/aave/v3-import/events.sol +++ b/contracts/arbitrum/connectors/aave/v3-import/events.sol @@ -12,4 +12,14 @@ contract Events { uint256[] supplyAmts, uint256[] borrowAmts ); + event LogAaveV3ImportWithCollateral( + address indexed user, + address[] ctokens, + string[] supplyIds, + string[] borrowIds, + uint256[] flashLoanFees, + uint256[] supplyAmts, + uint256[] borrowAmts, + bool[] enableCollateral + ); } diff --git a/contracts/arbitrum/connectors/aave/v3-import/helpers.sol b/contracts/arbitrum/connectors/aave/v3-import/helpers.sol index 4b609f94..09620366 100644 --- a/contracts/arbitrum/connectors/aave/v3-import/helpers.sol +++ b/contracts/arbitrum/connectors/aave/v3-import/helpers.sol @@ -250,6 +250,34 @@ contract AaveHelpers is Helper { } } + function _TransferAtokensWithCollateral( + uint256 _length, + AaveInterface aave, + ATokenInterface[] memory atokenContracts, + uint256[] memory amts, + address[] memory tokens, + bool[] memory colEnable, + address userAccount + ) internal { + for (uint256 i = 0; i < _length; i++) { + if (amts[i] > 0) { + uint256 _amt = amts[i]; + require( + atokenContracts[i].transferFrom( + userAccount, + address(this), + _amt + ), + "allowance?" + ); + + if (!getIsColl(tokens[i], address(this))) { + aave.setUserUseReserveAsCollateral(tokens[i], colEnable[i]); + } + } + } + } + function _BorrowVariable( uint256 _length, AaveInterface aave, diff --git a/contracts/arbitrum/connectors/aave/v3-import/main.sol b/contracts/arbitrum/connectors/aave/v3-import/main.sol index c9298a2c..fc3dce92 100644 --- a/contracts/arbitrum/connectors/aave/v3-import/main.sol +++ b/contracts/arbitrum/connectors/aave/v3-import/main.sol @@ -91,6 +91,89 @@ contract AaveV3ImportResolver is AaveHelpers { ); } + function _importAaveWithCollateral(address userAccount, ImportInputData memory inputData, bool[] memory enableCollateral) + internal + returns (string memory _eventName, bytes memory _eventParam) + { + require( + AccountInterface(address(this)).isAuth(userAccount), + "user-account-not-auth" + ); + + require(inputData.supplyTokens.length > 0, "0-length-not-allowed"); + require(enableCollateral.length == inputData.supplyTokens.length, "lengths-not-same"); + + ImportData memory data; + + AaveInterface aave = AaveInterface(aaveProvider.getPool()); + + data = getBorrowAmounts(userAccount, aave, inputData, data); + data = getSupplyAmounts(userAccount, inputData, data); + + // payback borrowed amount; + _PaybackStable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.stableBorrowAmts, + userAccount + ); + _PaybackVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.variableBorrowAmts, + userAccount + ); + + // transfer atokens to this address; + _TransferAtokensWithCollateral( + data._supplyTokens.length, + aave, + data.aTokens, + data.supplyAmts, + data._supplyTokens, + enableCollateral, + userAccount + ); + + // borrow assets after migrating position + if (data.convertStable) { + _BorrowVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.totalBorrowAmtsWithFee + ); + } else { + _BorrowStable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.stableBorrowAmtsWithFee + ); + _BorrowVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.variableBorrowAmtsWithFee + ); + } + + _eventName = "LogAaveV3ImportWithCollateral(address,bool,address[],address[],uint256[],uint256[],uint256[],uint256[],bool[])"; + _eventParam = abi.encode( + userAccount, + inputData.convertStable, + inputData.supplyTokens, + inputData.borrowTokens, + inputData.flashLoanFees, + data.supplyAmts, + data.stableBorrowAmts, + data.variableBorrowAmts, + enableCollateral + ); + } + /** * @dev Import aave V3 position . * @notice Import EOA's aave V3 position to DSA's aave v3 position @@ -104,8 +187,23 @@ contract AaveV3ImportResolver is AaveHelpers { { (_eventName, _eventParam) = _importAave(userAccount, inputData); } + + /** + * @dev Import aave V3 position (with collateral). + * @notice Import EOA's aave V3 position to DSA's aave v3 position + * @param userAccount The address of the EOA from which aave position will be imported + * @param inputData The struct containing all the neccessary input data + * @param enableCollateral The boolean array to enable selected collaterals in the imported position + */ + function importAaveWithCollateral(address userAccount, ImportInputData memory inputData, bool[] memory enableCollateral) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + (_eventName, _eventParam) = _importAaveWithCollateral(userAccount, inputData, enableCollateral); + } } contract ConnectV2AaveV3ImportArbitrum is AaveV3ImportResolver { - string public constant name = "Aave-v3-import-v1"; + string public constant name = "Aave-v3-import-v1.1"; } From 856bf2eb8dbb1882f787f8350817dcd4efda8b11 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Thu, 5 May 2022 23:57:38 +0530 Subject: [PATCH 6/6] importWithCollateral-avalanche,fantom,mainnet,optimism --- .../connectors/aave/v3-import/events.sol | 12 ++- .../connectors/aave/v3-import/helpers.sol | 28 +++++ .../connectors/aave/v3-import/main.sol | 100 +++++++++++++++++- .../connectors/aave/v3-import/events.sol | 10 ++ .../connectors/aave/v3-import/helpers.sol | 28 +++++ .../fantom/connectors/aave/v3-import/main.sol | 100 +++++++++++++++++- .../connectors/aave/v3-import/events.sol | 10 ++ .../connectors/aave/v3-import/helpers.sol | 28 +++++ .../connectors/aave/v3-import/main.sol | 100 +++++++++++++++++- .../connectors/aave/v3-import/events.sol | 10 ++ .../connectors/aave/v3-import/helpers.sol | 28 +++++ .../connectors/aave/v3-import/main.sol | 100 +++++++++++++++++- 12 files changed, 549 insertions(+), 5 deletions(-) diff --git a/contracts/avalanche/connectors/aave/v3-import/events.sol b/contracts/avalanche/connectors/aave/v3-import/events.sol index 03aafca4..6317bdba 100644 --- a/contracts/avalanche/connectors/aave/v3-import/events.sol +++ b/contracts/avalanche/connectors/aave/v3-import/events.sol @@ -5,11 +5,21 @@ pragma experimental ABIEncoderV2; contract Events { event LogAaveV3Import( address indexed user, - address[] ctokens, + address[] atokens, string[] supplyIds, string[] borrowIds, uint256[] flashLoanFees, uint256[] supplyAmts, uint256[] borrowAmts ); + event LogAaveV3ImportWithCollateral( + address indexed user, + address[] atokens, + string[] supplyIds, + string[] borrowIds, + uint256[] flashLoanFees, + uint256[] supplyAmts, + uint256[] borrowAmts, + bool[] enableCollateral + ); } diff --git a/contracts/avalanche/connectors/aave/v3-import/helpers.sol b/contracts/avalanche/connectors/aave/v3-import/helpers.sol index c0844f37..42c0684c 100644 --- a/contracts/avalanche/connectors/aave/v3-import/helpers.sol +++ b/contracts/avalanche/connectors/aave/v3-import/helpers.sol @@ -252,6 +252,34 @@ contract AaveHelpers is Helper { } } + function _TransferAtokensWithCollateral( + uint256 _length, + AaveInterface aave, + ATokenInterface[] memory atokenContracts, + uint256[] memory amts, + address[] memory tokens, + bool[] memory colEnable, + address userAccount + ) internal { + for (uint256 i = 0; i < _length; i++) { + if (amts[i] > 0) { + uint256 _amt = amts[i]; + require( + atokenContracts[i].transferFrom( + userAccount, + address(this), + _amt + ), + "allowance?" + ); + + if (!getIsColl(tokens[i], address(this))) { + aave.setUserUseReserveAsCollateral(tokens[i], colEnable[i]); + } + } + } + } + function _BorrowVariable( uint256 _length, AaveInterface aave, diff --git a/contracts/avalanche/connectors/aave/v3-import/main.sol b/contracts/avalanche/connectors/aave/v3-import/main.sol index e242bdc8..925bb25b 100644 --- a/contracts/avalanche/connectors/aave/v3-import/main.sol +++ b/contracts/avalanche/connectors/aave/v3-import/main.sol @@ -91,6 +91,89 @@ contract AaveV3ImportResolver is AaveHelpers { ); } + function _importAaveWithCollateral(address userAccount, ImportInputData memory inputData, bool[] memory enableCollateral) + internal + returns (string memory _eventName, bytes memory _eventParam) + { + require( + AccountInterface(address(this)).isAuth(userAccount), + "user-account-not-auth" + ); + + require(inputData.supplyTokens.length > 0, "0-length-not-allowed"); + require(enableCollateral.length == inputData.supplyTokens.length, "lengths-not-same"); + + ImportData memory data; + + AaveInterface aave = AaveInterface(aaveProvider.getPool()); + + data = getBorrowAmounts(userAccount, aave, inputData, data); + data = getSupplyAmounts(userAccount, inputData, data); + + // payback borrowed amount; + _PaybackStable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.stableBorrowAmts, + userAccount + ); + _PaybackVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.variableBorrowAmts, + userAccount + ); + + // transfer atokens to this address; + _TransferAtokensWithCollateral( + data._supplyTokens.length, + aave, + data.aTokens, + data.supplyAmts, + data._supplyTokens, + enableCollateral, + userAccount + ); + + // borrow assets after migrating position + if (data.convertStable) { + _BorrowVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.totalBorrowAmtsWithFee + ); + } else { + _BorrowStable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.stableBorrowAmtsWithFee + ); + _BorrowVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.variableBorrowAmtsWithFee + ); + } + + _eventName = "LogAaveV3ImportWithCollateral(address,bool,address[],address[],uint256[],uint256[],uint256[],uint256[],bool[])"; + _eventParam = abi.encode( + userAccount, + inputData.convertStable, + inputData.supplyTokens, + inputData.borrowTokens, + inputData.flashLoanFees, + data.supplyAmts, + data.stableBorrowAmts, + data.variableBorrowAmts, + enableCollateral + ); + } + /** * @dev Import aave V3 position . * @notice Import EOA's aave V3 position to DSA's aave v3 position @@ -104,8 +187,23 @@ contract AaveV3ImportResolver is AaveHelpers { { (_eventName, _eventParam) = _importAave(userAccount, inputData); } + + /** + * @dev Import aave V3 position (with collateral). + * @notice Import EOA's aave V3 position to DSA's aave v3 position + * @param userAccount The address of the EOA from which aave position will be imported + * @param inputData The struct containing all the neccessary input data + * @param enableCollateral The boolean array to enable selected collaterals in the imported position + */ + function importAaveWithCollateral(address userAccount, ImportInputData memory inputData, bool[] memory enableCollateral) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + (_eventName, _eventParam) = _importAaveWithCollateral(userAccount, inputData, enableCollateral); + } } contract ConnectV2AaveV3ImportAvalanche is AaveV3ImportResolver { - string public constant name = "Aave-v3-import-v1"; + string public constant name = "Aave-v3-import-v1.1"; } diff --git a/contracts/fantom/connectors/aave/v3-import/events.sol b/contracts/fantom/connectors/aave/v3-import/events.sol index 03aafca4..2a1c4e23 100644 --- a/contracts/fantom/connectors/aave/v3-import/events.sol +++ b/contracts/fantom/connectors/aave/v3-import/events.sol @@ -12,4 +12,14 @@ contract Events { uint256[] supplyAmts, uint256[] borrowAmts ); + event LogAaveV3ImportWithCollateral( + address indexed user, + address[] ctokens, + string[] supplyIds, + string[] borrowIds, + uint256[] flashLoanFees, + uint256[] supplyAmts, + uint256[] borrowAmts, + bool[] enableCollateral + ); } diff --git a/contracts/fantom/connectors/aave/v3-import/helpers.sol b/contracts/fantom/connectors/aave/v3-import/helpers.sol index ee59c40b..ca016df4 100644 --- a/contracts/fantom/connectors/aave/v3-import/helpers.sol +++ b/contracts/fantom/connectors/aave/v3-import/helpers.sol @@ -250,6 +250,34 @@ contract AaveHelpers is Helper { } } + function _TransferAtokensWithCollateral( + uint256 _length, + AaveInterface aave, + ATokenInterface[] memory atokenContracts, + uint256[] memory amts, + address[] memory tokens, + bool[] memory colEnable, + address userAccount + ) internal { + for (uint256 i = 0; i < _length; i++) { + if (amts[i] > 0) { + uint256 _amt = amts[i]; + require( + atokenContracts[i].transferFrom( + userAccount, + address(this), + _amt + ), + "allowance?" + ); + + if (!getIsColl(tokens[i], address(this))) { + aave.setUserUseReserveAsCollateral(tokens[i], colEnable[i]); + } + } + } + } + function _BorrowVariable( uint256 _length, AaveInterface aave, diff --git a/contracts/fantom/connectors/aave/v3-import/main.sol b/contracts/fantom/connectors/aave/v3-import/main.sol index 19e4030b..37bf360c 100644 --- a/contracts/fantom/connectors/aave/v3-import/main.sol +++ b/contracts/fantom/connectors/aave/v3-import/main.sol @@ -92,6 +92,89 @@ contract AaveV3ImportResolver is AaveHelpers { ); } + function _importAaveWithCollateral(address userAccount, ImportInputData memory inputData, bool[] memory enableCollateral) + internal + returns (string memory _eventName, bytes memory _eventParam) + { + require( + AccountInterface(address(this)).isAuth(userAccount), + "user-account-not-auth" + ); + + require(inputData.supplyTokens.length > 0, "0-length-not-allowed"); + require(enableCollateral.length == inputData.supplyTokens.length, "lengths-not-same"); + + ImportData memory data; + + AaveInterface aave = AaveInterface(aaveProvider.getPool()); + + data = getBorrowAmounts(userAccount, aave, inputData, data); + data = getSupplyAmounts(userAccount, inputData, data); + + // payback borrowed amount; + _PaybackStable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.stableBorrowAmts, + userAccount + ); + _PaybackVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.variableBorrowAmts, + userAccount + ); + + // transfer atokens to this address; + _TransferAtokensWithCollateral( + data._supplyTokens.length, + aave, + data.aTokens, + data.supplyAmts, + data._supplyTokens, + enableCollateral, + userAccount + ); + + // borrow assets after migrating position + if (data.convertStable) { + _BorrowVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.totalBorrowAmtsWithFee + ); + } else { + _BorrowStable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.stableBorrowAmtsWithFee + ); + _BorrowVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.variableBorrowAmtsWithFee + ); + } + + _eventName = "LogAaveV3ImportWithCollateral(address,bool,address[],address[],uint256[],uint256[],uint256[],uint256[],bool[])"; + _eventParam = abi.encode( + userAccount, + inputData.convertStable, + inputData.supplyTokens, + inputData.borrowTokens, + inputData.flashLoanFees, + data.supplyAmts, + data.stableBorrowAmts, + data.variableBorrowAmts, + enableCollateral + ); + } + /** * @dev Import aave V3 position . * @notice Import EOA's aave V3 position to DSA's aave v3 position @@ -105,8 +188,23 @@ contract AaveV3ImportResolver is AaveHelpers { { (_eventName, _eventParam) = _importAave(userAccount, inputData); } + + /** + * @dev Import aave V3 position (with collateral). + * @notice Import EOA's aave V3 position to DSA's aave v3 position + * @param userAccount The address of the EOA from which aave position will be imported + * @param inputData The struct containing all the neccessary input data + * @param enableCollateral The boolean array to enable selected collaterals in the imported position + */ + function importAaveWithCollateral(address userAccount, ImportInputData memory inputData, bool[] memory enableCollateral) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + (_eventName, _eventParam) = _importAaveWithCollateral(userAccount, inputData, enableCollateral); + } } contract ConnectV2AaveV3ImportFantom is AaveV3ImportResolver { - string public constant name = "Aave-v3-import-v1"; + string public constant name = "Aave-v3-import-v1.1"; } diff --git a/contracts/mainnet/connectors/aave/v3-import/events.sol b/contracts/mainnet/connectors/aave/v3-import/events.sol index 03aafca4..c9aaeebb 100644 --- a/contracts/mainnet/connectors/aave/v3-import/events.sol +++ b/contracts/mainnet/connectors/aave/v3-import/events.sol @@ -12,4 +12,14 @@ contract Events { uint256[] supplyAmts, uint256[] borrowAmts ); + event LogAaveV3ImportWithCollateral( + address indexed user, + address[] atokens, + string[] supplyIds, + string[] borrowIds, + uint256[] flashLoanFees, + uint256[] supplyAmts, + uint256[] borrowAmts, + bool[] enableCollateral + ); } diff --git a/contracts/mainnet/connectors/aave/v3-import/helpers.sol b/contracts/mainnet/connectors/aave/v3-import/helpers.sol index 2fb34c13..7da027d4 100644 --- a/contracts/mainnet/connectors/aave/v3-import/helpers.sol +++ b/contracts/mainnet/connectors/aave/v3-import/helpers.sol @@ -250,6 +250,34 @@ contract AaveHelpers is Helper { } } + function _TransferAtokensWithCollateral( + uint256 _length, + AaveInterface aave, + ATokenInterface[] memory atokenContracts, + uint256[] memory amts, + address[] memory tokens, + bool[] memory colEnable, + address userAccount + ) internal { + for (uint256 i = 0; i < _length; i++) { + if (amts[i] > 0) { + uint256 _amt = amts[i]; + require( + atokenContracts[i].transferFrom( + userAccount, + address(this), + _amt + ), + "allowance?" + ); + + if (!getIsColl(tokens[i], address(this))) { + aave.setUserUseReserveAsCollateral(tokens[i], colEnable[i]); + } + } + } + } + function _BorrowVariable( uint256 _length, AaveInterface aave, diff --git a/contracts/mainnet/connectors/aave/v3-import/main.sol b/contracts/mainnet/connectors/aave/v3-import/main.sol index 6693b8ce..397c903b 100644 --- a/contracts/mainnet/connectors/aave/v3-import/main.sol +++ b/contracts/mainnet/connectors/aave/v3-import/main.sol @@ -91,6 +91,89 @@ contract AaveV3ImportResolver is AaveHelpers { ); } + function _importAaveWithCollateral(address userAccount, ImportInputData memory inputData, bool[] memory enableCollateral) + internal + returns (string memory _eventName, bytes memory _eventParam) + { + require( + AccountInterface(address(this)).isAuth(userAccount), + "user-account-not-auth" + ); + + require(inputData.supplyTokens.length > 0, "0-length-not-allowed"); + require(enableCollateral.length == inputData.supplyTokens.length, "lengths-not-same"); + + ImportData memory data; + + AaveInterface aave = AaveInterface(aaveProvider.getPool()); + + data = getBorrowAmounts(userAccount, aave, inputData, data); + data = getSupplyAmounts(userAccount, inputData, data); + + // payback borrowed amount; + _PaybackStable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.stableBorrowAmts, + userAccount + ); + _PaybackVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.variableBorrowAmts, + userAccount + ); + + // transfer atokens to this address; + _TransferAtokensWithCollateral( + data._supplyTokens.length, + aave, + data.aTokens, + data.supplyAmts, + data._supplyTokens, + enableCollateral, + userAccount + ); + + // borrow assets after migrating position + if (data.convertStable) { + _BorrowVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.totalBorrowAmtsWithFee + ); + } else { + _BorrowStable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.stableBorrowAmtsWithFee + ); + _BorrowVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.variableBorrowAmtsWithFee + ); + } + + _eventName = "LogAaveV3ImportWithCollateral(address,bool,address[],address[],uint256[],uint256[],uint256[],uint256[],bool[])"; + _eventParam = abi.encode( + userAccount, + inputData.convertStable, + inputData.supplyTokens, + inputData.borrowTokens, + inputData.flashLoanFees, + data.supplyAmts, + data.stableBorrowAmts, + data.variableBorrowAmts, + enableCollateral + ); + } + /** * @dev Import aave V3 position . * @notice Import EOA's aave V3 position to DSA's aave v3 position @@ -104,8 +187,23 @@ contract AaveV3ImportResolver is AaveHelpers { { (_eventName, _eventParam) = _importAave(userAccount, inputData); } + + /** + * @dev Import aave V3 position (with collateral). + * @notice Import EOA's aave V3 position to DSA's aave v3 position + * @param userAccount The address of the EOA from which aave position will be imported + * @param inputData The struct containing all the neccessary input data + * @param enableCollateral The boolean array to enable selected collaterals in the imported position + */ + function importAaveWithCollateral(address userAccount, ImportInputData memory inputData, bool[] memory enableCollateral) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + (_eventName, _eventParam) = _importAaveWithCollateral(userAccount, inputData, enableCollateral); + } } contract ConnectV2AaveV3Import is AaveV3ImportResolver { - string public constant name = "Aave-v3-import-v1"; + string public constant name = "Aave-v3-import-v1.1"; } diff --git a/contracts/optimism/connectors/aave/v3-import/events.sol b/contracts/optimism/connectors/aave/v3-import/events.sol index 03aafca4..2a1c4e23 100644 --- a/contracts/optimism/connectors/aave/v3-import/events.sol +++ b/contracts/optimism/connectors/aave/v3-import/events.sol @@ -12,4 +12,14 @@ contract Events { uint256[] supplyAmts, uint256[] borrowAmts ); + event LogAaveV3ImportWithCollateral( + address indexed user, + address[] ctokens, + string[] supplyIds, + string[] borrowIds, + uint256[] flashLoanFees, + uint256[] supplyAmts, + uint256[] borrowAmts, + bool[] enableCollateral + ); } diff --git a/contracts/optimism/connectors/aave/v3-import/helpers.sol b/contracts/optimism/connectors/aave/v3-import/helpers.sol index 4b609f94..09620366 100644 --- a/contracts/optimism/connectors/aave/v3-import/helpers.sol +++ b/contracts/optimism/connectors/aave/v3-import/helpers.sol @@ -250,6 +250,34 @@ contract AaveHelpers is Helper { } } + function _TransferAtokensWithCollateral( + uint256 _length, + AaveInterface aave, + ATokenInterface[] memory atokenContracts, + uint256[] memory amts, + address[] memory tokens, + bool[] memory colEnable, + address userAccount + ) internal { + for (uint256 i = 0; i < _length; i++) { + if (amts[i] > 0) { + uint256 _amt = amts[i]; + require( + atokenContracts[i].transferFrom( + userAccount, + address(this), + _amt + ), + "allowance?" + ); + + if (!getIsColl(tokens[i], address(this))) { + aave.setUserUseReserveAsCollateral(tokens[i], colEnable[i]); + } + } + } + } + function _BorrowVariable( uint256 _length, AaveInterface aave, diff --git a/contracts/optimism/connectors/aave/v3-import/main.sol b/contracts/optimism/connectors/aave/v3-import/main.sol index 599dc703..6b9acfb1 100644 --- a/contracts/optimism/connectors/aave/v3-import/main.sol +++ b/contracts/optimism/connectors/aave/v3-import/main.sol @@ -91,6 +91,89 @@ contract AaveV3ImportResolver is AaveHelpers { ); } + function _importAaveWithCollateral(address userAccount, ImportInputData memory inputData, bool[] memory enableCollateral) + internal + returns (string memory _eventName, bytes memory _eventParam) + { + require( + AccountInterface(address(this)).isAuth(userAccount), + "user-account-not-auth" + ); + + require(inputData.supplyTokens.length > 0, "0-length-not-allowed"); + require(enableCollateral.length == inputData.supplyTokens.length, "lengths-not-same"); + + ImportData memory data; + + AaveInterface aave = AaveInterface(aaveProvider.getPool()); + + data = getBorrowAmounts(userAccount, aave, inputData, data); + data = getSupplyAmounts(userAccount, inputData, data); + + // payback borrowed amount; + _PaybackStable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.stableBorrowAmts, + userAccount + ); + _PaybackVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.variableBorrowAmts, + userAccount + ); + + // transfer atokens to this address; + _TransferAtokensWithCollateral( + data._supplyTokens.length, + aave, + data.aTokens, + data.supplyAmts, + data._supplyTokens, + enableCollateral, + userAccount + ); + + // borrow assets after migrating position + if (data.convertStable) { + _BorrowVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.totalBorrowAmtsWithFee + ); + } else { + _BorrowStable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.stableBorrowAmtsWithFee + ); + _BorrowVariable( + data._borrowTokens.length, + aave, + data._borrowTokens, + data.variableBorrowAmtsWithFee + ); + } + + _eventName = "LogAaveV3ImportWithCollateral(address,bool,address[],address[],uint256[],uint256[],uint256[],uint256[],bool[])"; + _eventParam = abi.encode( + userAccount, + inputData.convertStable, + inputData.supplyTokens, + inputData.borrowTokens, + inputData.flashLoanFees, + data.supplyAmts, + data.stableBorrowAmts, + data.variableBorrowAmts, + enableCollateral + ); + } + /** * @dev Import aave V3 position . * @notice Import EOA's aave V3 position to DSA's aave v3 position @@ -104,8 +187,23 @@ contract AaveV3ImportResolver is AaveHelpers { { (_eventName, _eventParam) = _importAave(userAccount, inputData); } + + /** + * @dev Import aave V3 position (with collateral). + * @notice Import EOA's aave V3 position to DSA's aave v3 position + * @param userAccount The address of the EOA from which aave position will be imported + * @param inputData The struct containing all the neccessary input data + * @param enableCollateral The boolean array to enable selected collaterals in the imported position + */ + function importAaveWithCollateral(address userAccount, ImportInputData memory inputData, bool[] memory enableCollateral) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + (_eventName, _eventParam) = _importAaveWithCollateral(userAccount, inputData, enableCollateral); + } } contract ConnectV2AaveV3ImportOptimism is AaveV3ImportResolver { - string public constant name = "Aave-v3-import-v1"; + string public constant name = "Aave-v3-import-v1.1"; }