diff --git a/contracts/arbitrum/connectors/aave/v3-import-permit/events.sol b/contracts/arbitrum/connectors/aave/v3-import-permit/events.sol index 10a93d70..75d3c8bb 100644 --- a/contracts/arbitrum/connectors/aave/v3-import-permit/events.sol +++ b/contracts/arbitrum/connectors/aave/v3-import-permit/events.sol @@ -12,4 +12,14 @@ contract Events { uint256[] supplyAmts, uint256[] borrowAmts ); + event LogAaveV3ImportWithPermitAndCollateral( + address indexed user, + address[] atokens, + string[] supplyIds, + string[] borrowIds, + uint256[] flashLoanFees, + uint256[] supplyAmts, + uint256[] borrowAmts, + bool[] enableCollateral + ); } diff --git a/contracts/arbitrum/connectors/aave/v3-import-permit/helpers.sol b/contracts/arbitrum/connectors/aave/v3-import-permit/helpers.sol index 61b1687d..3f1a1917 100644 --- a/contracts/arbitrum/connectors/aave/v3-import-permit/helpers.sol +++ b/contracts/arbitrum/connectors/aave/v3-import-permit/helpers.sol @@ -279,6 +279,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-permit/main.sol b/contracts/arbitrum/connectors/aave/v3-import-permit/main.sol index 2a3aafe8..0ea7abac 100644 --- a/contracts/arbitrum/connectors/aave/v3-import-permit/main.sol +++ b/contracts/arbitrum/connectors/aave/v3-import-permit/main.sol @@ -103,6 +103,102 @@ contract AaveV3ImportPermitResolver is AaveHelpers { ); } + function _importAaveWithCollateral( + address userAccount, + ImportInputData memory inputData, + SignedPermits memory permitData, + 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, "supplytokens-enableCol-len-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 + ); + + //permit this address to transfer aTokens + _PermitATokens( + userAccount, + data.aTokens, + data._supplyTokens, + permitData.v, + permitData.r, + permitData.s, + permitData.expiry + ); + + // 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 = "LogAaveV3ImportWithPermitAndCollateral(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 @@ -125,8 +221,34 @@ contract AaveV3ImportPermitResolver is AaveHelpers { permitData ); } + + /** + * @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 permitData The struct containing signed permit data like v,r,s,expiry + * @param enableCollateral The boolean array to enable selected collaterals in the imported position + */ + function importAaveWithCollateral( + address userAccount, + ImportInputData memory inputData, + SignedPermits memory permitData, + bool[] memory enableCollateral + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + (_eventName, _eventParam) = _importAaveWithCollateral( + userAccount, + inputData, + permitData, + enableCollateral + ); + } } contract ConnectV2AaveV3ImportPermitArbitrum is AaveV3ImportPermitResolver { - string public constant name = "Aave-v3-import-permit-v1"; + string public constant name = "Aave-v3-import-permit-v1.1"; } diff --git a/contracts/avalanche/connectors/aave/v3-import-permit/events.sol b/contracts/avalanche/connectors/aave/v3-import-permit/events.sol index 10a93d70..75d3c8bb 100644 --- a/contracts/avalanche/connectors/aave/v3-import-permit/events.sol +++ b/contracts/avalanche/connectors/aave/v3-import-permit/events.sol @@ -12,4 +12,14 @@ contract Events { uint256[] supplyAmts, uint256[] borrowAmts ); + event LogAaveV3ImportWithPermitAndCollateral( + 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-permit/helpers.sol b/contracts/avalanche/connectors/aave/v3-import-permit/helpers.sol index 2d77c4fb..ce6401a5 100644 --- a/contracts/avalanche/connectors/aave/v3-import-permit/helpers.sol +++ b/contracts/avalanche/connectors/aave/v3-import-permit/helpers.sol @@ -281,6 +281,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-permit/main.sol b/contracts/avalanche/connectors/aave/v3-import-permit/main.sol index 96f000ac..35865830 100644 --- a/contracts/avalanche/connectors/aave/v3-import-permit/main.sol +++ b/contracts/avalanche/connectors/aave/v3-import-permit/main.sol @@ -103,6 +103,102 @@ contract AaveV3ImportPermitResolver is AaveHelpers { ); } + function _importAaveWithCollateral( + address userAccount, + ImportInputData memory inputData, + SignedPermits memory permitData, + 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, "supplytokens-enableCol-len-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 + ); + + //permit this address to transfer aTokens + _PermitATokens( + userAccount, + data.aTokens, + data._supplyTokens, + permitData.v, + permitData.r, + permitData.s, + permitData.expiry + ); + + // 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 = "LogAaveV3ImportWithPermitAndCollateral(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 @@ -125,8 +221,34 @@ contract AaveV3ImportPermitResolver is AaveHelpers { permitData ); } + + /** + * @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 permitData The struct containing signed permit data like v,r,s,expiry + * @param enableCollateral The boolean array to enable selected collaterals in the imported position + */ + function importAaveWithCollateral( + address userAccount, + ImportInputData memory inputData, + SignedPermits memory permitData, + bool[] memory enableCollateral + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + (_eventName, _eventParam) = _importAaveWithCollateral( + userAccount, + inputData, + permitData, + enableCollateral + ); + } } contract ConnectV2AaveV3ImportPermitAvalanche is AaveV3ImportPermitResolver { - string public constant name = "Aave-v3-import-permit-v1"; + string public constant name = "Aave-v3-import-permit-v1.1"; } diff --git a/contracts/polygon/connectors/aave/v3-import-permit/events.sol b/contracts/polygon/connectors/aave/v3-import-permit/events.sol index 10a93d70..75d3c8bb 100644 --- a/contracts/polygon/connectors/aave/v3-import-permit/events.sol +++ b/contracts/polygon/connectors/aave/v3-import-permit/events.sol @@ -12,4 +12,14 @@ contract Events { uint256[] supplyAmts, uint256[] borrowAmts ); + event LogAaveV3ImportWithPermitAndCollateral( + address indexed user, + address[] atokens, + string[] supplyIds, + string[] borrowIds, + uint256[] flashLoanFees, + uint256[] supplyAmts, + uint256[] borrowAmts, + bool[] enableCollateral + ); } diff --git a/contracts/polygon/connectors/aave/v3-import-permit/helpers.sol b/contracts/polygon/connectors/aave/v3-import-permit/helpers.sol index dc514687..d338bd00 100644 --- a/contracts/polygon/connectors/aave/v3-import-permit/helpers.sol +++ b/contracts/polygon/connectors/aave/v3-import-permit/helpers.sol @@ -279,6 +279,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/polygon/connectors/aave/v3-import-permit/main.sol b/contracts/polygon/connectors/aave/v3-import-permit/main.sol index 8a6c61a5..250572e6 100644 --- a/contracts/polygon/connectors/aave/v3-import-permit/main.sol +++ b/contracts/polygon/connectors/aave/v3-import-permit/main.sol @@ -104,6 +104,102 @@ contract AaveV3ImportPermitResolver is AaveHelpers { ); } + function _importAaveWithCollateral( + address userAccount, + ImportInputData memory inputData, + SignedPermits memory permitData, + 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, "supplytokens-enableCol-len-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 + ); + + //permit this address to transfer aTokens + _PermitATokens( + userAccount, + data.aTokens, + data._supplyTokens, + permitData.v, + permitData.r, + permitData.s, + permitData.expiry + ); + + // 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 = "LogAaveV3ImportWithPermitAndCollateral(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 @@ -126,8 +222,34 @@ contract AaveV3ImportPermitResolver is AaveHelpers { permitData ); } + + /** + * @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 permitData The struct containing signed permit data like v,r,s,expiry + * @param enableCollateral The boolean array to enable selected collaterals in the imported position + */ + function importAaveWithCollateral( + address userAccount, + ImportInputData memory inputData, + SignedPermits memory permitData, + bool[] memory enableCollateral + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + (_eventName, _eventParam) = _importAaveWithCollateral( + userAccount, + inputData, + permitData, + enableCollateral + ); + } } contract ConnectV2AaveV3ImportPermitPolygon is AaveV3ImportPermitResolver { - string public constant name = "Aave-v3-import-permit-v1"; + string public constant name = "Aave-v3-import-permit-v1.1"; }