1+ // SPDX-License-Identifier: AGPL-3.0
2+ pragma solidity ^ 0.8.10 ;
3+
4+ import {IERC20Detailed } from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol ' ;
5+ import {IERC20WithPermit } from '@aave/core-v3/contracts/interfaces/IERC20WithPermit.sol ' ;
6+ import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol ' ;
7+ import {BaseParaSwapSellAdapter} from './BaseParaSwapSellAdapter.sol ' ;
8+ import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol ' ;
9+ import {SafeERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol ' ;
10+ import {IParaSwapAugustus} from './interfaces/IParaSwapAugustus.sol ' ;
11+ import {ReentrancyGuard} from '../../dependencies/openzeppelin/ReentrancyGuard.sol ' ;
12+
13+ contract ParaSwapWithdrawSwapAdapter is BaseParaSwapSellAdapter , ReentrancyGuard {
14+ using SafeERC20 for IERC20Detailed ;
15+
16+ constructor (
17+ IPoolAddressesProvider addressesProvider ,
18+ IParaSwapAugustusRegistry augustusRegistry ,
19+ address owner
20+ ) BaseParaSwapSellAdapter (addressesProvider, augustusRegistry) {
21+ transferOwnership (owner);
22+ }
23+
24+ function executeOperation (
25+ address ,
26+ uint256 ,
27+ uint256 ,
28+ address ,
29+ bytes calldata
30+ ) external override nonReentrant returns (bool ) {
31+ revert ('NOT_SUPPORTED ' );
32+ }
33+
34+ /**
35+ * @dev Swaps an amount of an asset to another after a withdraw and transfers the new asset to the user.
36+ * The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset and perform the swap.
37+ * @param assetToSwapFrom Address of the underlying asset to be swapped from
38+ * @param assetToSwapTo Address of the underlying asset to be swapped to
39+ * @param amountToSwap Amount to be swapped, or maximum amount when swapping all balance
40+ * @param minAmountToReceive Minimum amount to be received from the swap
41+ * @param swapAllBalanceOffset Set to offset of fromAmount in Augustus calldata if wanting to swap all balance, otherwise 0
42+ * @param swapCalldata Calldata for ParaSwap's AugustusSwapper contract
43+ * @param augustus Address of ParaSwap's AugustusSwapper contract
44+ * @param permitParams Struct containing the permit signatures, set to all zeroes if not used
45+ */
46+ function withdrawAndSwap (
47+ IERC20Detailed assetToSwapFrom ,
48+ IERC20Detailed assetToSwapTo ,
49+ uint256 amountToSwap ,
50+ uint256 minAmountToReceive ,
51+ uint256 swapAllBalanceOffset ,
52+ bytes calldata swapCalldata ,
53+ IParaSwapAugustus augustus ,
54+ PermitSignature calldata permitParams
55+ ) external nonReentrant {
56+ IERC20WithPermit aToken = IERC20WithPermit (
57+ _getReserveData (address (assetToSwapFrom)).aTokenAddress
58+ );
59+
60+ if (swapAllBalanceOffset != 0 ) {
61+ uint256 balance = aToken.balanceOf (msg .sender );
62+ require (balance <= amountToSwap, 'INSUFFICIENT_AMOUNT_TO_SWAP ' );
63+ amountToSwap = balance;
64+ }
65+
66+ _pullATokenAndWithdraw (
67+ address (assetToSwapFrom),
68+ aToken,
69+ msg .sender ,
70+ amountToSwap,
71+ permitParams
72+ );
73+
74+ uint256 amountReceived = _sellOnParaSwap (
75+ swapAllBalanceOffset,
76+ swapCalldata,
77+ augustus,
78+ assetToSwapFrom,
79+ assetToSwapTo,
80+ amountToSwap,
81+ minAmountToReceive
82+ );
83+
84+ assetToSwapTo.safeTransfer (msg .sender , amountReceived);
85+ }
86+ }
0 commit comments