Skip to content

Commit 105baaf

Browse files
authored
fix: Transfer excess back and reset allowance (#49)
1 parent 13caab8 commit 105baaf

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed

src/periphery/contracts/adapters/paraswap/BaseParaSwapBuyAdapter.sol

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ abstract contract BaseParaSwapBuyAdapter is BaseParaSwapAdapter {
3939
* @param maxAmountToSwap Max amount to be swapped
4040
* @param amountToReceive Amount to be received from the swap
4141
* @return amountSold The amount sold during the swap
42+
* @return amountBought The amount bought during the swap
4243
*/
4344
function _buyOnParaSwap(
4445
uint256 toAmountOffset,
@@ -47,7 +48,7 @@ abstract contract BaseParaSwapBuyAdapter is BaseParaSwapAdapter {
4748
IERC20Detailed assetToSwapTo,
4849
uint256 maxAmountToSwap,
4950
uint256 amountToReceive
50-
) internal returns (uint256 amountSold) {
51+
) internal returns (uint256 amountSold, uint256 amountBought) {
5152
(bytes memory buyCalldata, IParaSwapAugustus augustus) = abi.decode(
5253
paraswapData,
5354
(bytes, IParaSwapAugustus)
@@ -75,7 +76,6 @@ abstract contract BaseParaSwapBuyAdapter is BaseParaSwapAdapter {
7576
uint256 balanceBeforeAssetTo = assetToSwapTo.balanceOf(address(this));
7677

7778
address tokenTransferProxy = augustus.getTokenTransferProxy();
78-
assetToSwapFrom.safeApprove(tokenTransferProxy, 0);
7979
assetToSwapFrom.safeApprove(tokenTransferProxy, maxAmountToSwap);
8080

8181
if (toAmountOffset != 0) {
@@ -101,12 +101,15 @@ abstract contract BaseParaSwapBuyAdapter is BaseParaSwapAdapter {
101101
}
102102
}
103103

104+
// Reset allowance
105+
assetToSwapFrom.safeApprove(tokenTransferProxy, 0);
106+
104107
uint256 balanceAfterAssetFrom = assetToSwapFrom.balanceOf(address(this));
105108
amountSold = balanceBeforeAssetFrom - balanceAfterAssetFrom;
106109
require(amountSold <= maxAmountToSwap, 'WRONG_BALANCE_AFTER_SWAP');
107-
uint256 amountReceived = assetToSwapTo.balanceOf(address(this)).sub(balanceBeforeAssetTo);
108-
require(amountReceived >= amountToReceive, 'INSUFFICIENT_AMOUNT_RECEIVED');
110+
amountBought = assetToSwapTo.balanceOf(address(this)).sub(balanceBeforeAssetTo);
111+
require(amountBought >= amountToReceive, 'INSUFFICIENT_AMOUNT_RECEIVED');
109112

110-
emit Bought(address(assetToSwapFrom), address(assetToSwapTo), amountSold, amountReceived);
113+
emit Bought(address(assetToSwapFrom), address(assetToSwapTo), amountSold, amountBought);
111114
}
112115
}

src/periphery/contracts/adapters/paraswap/BaseParaSwapSellAdapter.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ abstract contract BaseParaSwapSellAdapter is BaseParaSwapAdapter {
9898
revert(0, returndatasize())
9999
}
100100
}
101+
101102
require(
102103
assetToSwapFrom.balanceOf(address(this)) == balanceBeforeAssetFrom - amountToSwap,
103104
'WRONG_BALANCE_AFTER_SWAP'

src/periphery/contracts/adapters/paraswap/ParaSwapRepayAdapter.sol

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ contract ParaSwapRepayAdapter is BaseParaSwapBuyAdapter, ReentrancyGuard {
114114
// Pull aTokens from user
115115
_pullATokenAndWithdraw(address(collateralAsset), msg.sender, collateralAmount, permitSignature);
116116
//buy debt asset using collateral asset
117-
uint256 amountSold = _buyOnParaSwap(
117+
(uint256 amountSold, uint256 amountBought) = _buyOnParaSwap(
118118
buyAllBalanceOffset,
119119
paraswapData,
120120
collateralAsset,
@@ -127,15 +127,23 @@ contract ParaSwapRepayAdapter is BaseParaSwapBuyAdapter, ReentrancyGuard {
127127

128128
//deposit collateral back in the pool, if left after the swap(buy)
129129
if (collateralBalanceLeft > 0) {
130-
IERC20(collateralAsset).safeApprove(address(POOL), 0);
131130
IERC20(collateralAsset).safeApprove(address(POOL), collateralBalanceLeft);
132131
POOL.deposit(address(collateralAsset), collateralBalanceLeft, msg.sender, 0);
132+
IERC20(collateralAsset).safeApprove(address(POOL), 0);
133133
}
134134

135135
// Repay debt. Approves 0 first to comply with tokens that implement the anti frontrunning approval fix
136-
IERC20(debtAsset).safeApprove(address(POOL), 0);
137136
IERC20(debtAsset).safeApprove(address(POOL), debtRepayAmount);
138137
POOL.repay(address(debtAsset), debtRepayAmount, debtRateMode, msg.sender);
138+
IERC20(debtAsset).safeApprove(address(POOL), 0);
139+
140+
{
141+
//transfer excess of debtAsset back to the user, if any
142+
uint256 debtAssetExcess = amountBought - debtRepayAmount;
143+
if (debtAssetExcess > 0) {
144+
IERC20(debtAsset).safeTransfer(msg.sender, debtAssetExcess);
145+
}
146+
}
139147
}
140148

141149
/**
@@ -170,7 +178,7 @@ contract ParaSwapRepayAdapter is BaseParaSwapBuyAdapter, ReentrancyGuard {
170178
initiator
171179
);
172180

173-
uint256 amountSold = _buyOnParaSwap(
181+
(uint256 amountSold, uint256 amountBought) = _buyOnParaSwap(
174182
buyAllBalanceOffset,
175183
paraswapData,
176184
collateralAsset,
@@ -180,9 +188,9 @@ contract ParaSwapRepayAdapter is BaseParaSwapBuyAdapter, ReentrancyGuard {
180188
);
181189

182190
// Repay debt. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
183-
IERC20(debtAsset).safeApprove(address(POOL), 0);
184191
IERC20(debtAsset).safeApprove(address(POOL), debtRepayAmount);
185192
POOL.repay(address(debtAsset), debtRepayAmount, rateMode, initiator);
193+
IERC20(debtAsset).safeApprove(address(POOL), 0);
186194

187195
uint256 neededForFlashLoanRepay = amountSold.add(premium);
188196

@@ -194,6 +202,14 @@ contract ParaSwapRepayAdapter is BaseParaSwapBuyAdapter, ReentrancyGuard {
194202
permitSignature
195203
);
196204

205+
{
206+
//transfer excess of debtAsset back to the user, if any
207+
uint256 debtAssetExcess = amountBought - debtRepayAmount;
208+
if (debtAssetExcess > 0) {
209+
IERC20(debtAsset).safeTransfer(initiator, debtAssetExcess);
210+
}
211+
}
212+
197213
// Repay flashloan. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
198214
IERC20(collateralAsset).safeApprove(address(POOL), 0);
199215
IERC20(collateralAsset).safeApprove(address(POOL), collateralAmount.add(premium));

0 commit comments

Comments
 (0)