Skip to content
This repository was archived by the owner on Oct 21, 2025. It is now read-only.

Commit f5d0af9

Browse files
authored
fix: use SafeERC20 safeApprove to work well with non standard ERC20 tokens (#176)
* fix: use SafeERC20 * fix: only use SafeERC20 for safeApprove
1 parent f526d94 commit f5d0af9

File tree

6 files changed

+34
-26
lines changed

6 files changed

+34
-26
lines changed

contracts/adapters/paraswap/BaseParaSwapBuyAdapter.sol

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: AGPL-3.0
22
pragma solidity ^0.8.10;
33

4+
import {SafeERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol';
45
import {SafeMath} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeMath.sol';
56
import {PercentageMath} from '@aave/core-v3/contracts/protocol/libraries/math/PercentageMath.sol';
67
import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol';
@@ -16,6 +17,7 @@ import {BaseParaSwapAdapter} from './BaseParaSwapAdapter.sol';
1617
abstract contract BaseParaSwapBuyAdapter is BaseParaSwapAdapter {
1718
using PercentageMath for uint256;
1819
using SafeMath for uint256;
20+
using SafeERC20 for IERC20Detailed;
1921

2022
IParaSwapAugustusRegistry public immutable AUGUSTUS_REGISTRY;
2123

@@ -72,8 +74,8 @@ abstract contract BaseParaSwapBuyAdapter is BaseParaSwapAdapter {
7274
uint256 balanceBeforeAssetTo = assetToSwapTo.balanceOf(address(this));
7375

7476
address tokenTransferProxy = augustus.getTokenTransferProxy();
75-
assetToSwapFrom.approve(tokenTransferProxy, 0);
76-
assetToSwapFrom.approve(tokenTransferProxy, maxAmountToSwap);
77+
assetToSwapFrom.safeApprove(tokenTransferProxy, 0);
78+
assetToSwapFrom.safeApprove(tokenTransferProxy, maxAmountToSwap);
7779

7880
if (toAmountOffset != 0) {
7981
// Ensure 256 bit (32 bytes) toAmountOffset value is within bounds of the

contracts/adapters/paraswap/BaseParaSwapSellAdapter.sol

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: AGPL-3.0
22
pragma solidity ^0.8.10;
33

4+
import {SafeERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol';
45
import {SafeMath} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeMath.sol';
56
import {PercentageMath} from '@aave/core-v3/contracts/protocol/libraries/math/PercentageMath.sol';
67
import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol';
@@ -17,6 +18,7 @@ import {BaseParaSwapAdapter} from './BaseParaSwapAdapter.sol';
1718
abstract contract BaseParaSwapSellAdapter is BaseParaSwapAdapter {
1819
using PercentageMath for uint256;
1920
using SafeMath for uint256;
21+
using SafeERC20 for IERC20Detailed;
2022

2123
IParaSwapAugustusRegistry public immutable AUGUSTUS_REGISTRY;
2224

@@ -70,8 +72,8 @@ abstract contract BaseParaSwapSellAdapter is BaseParaSwapAdapter {
7072
uint256 balanceBeforeAssetTo = assetToSwapTo.balanceOf(address(this));
7173

7274
address tokenTransferProxy = augustus.getTokenTransferProxy();
73-
assetToSwapFrom.approve(tokenTransferProxy, 0);
74-
assetToSwapFrom.approve(tokenTransferProxy, amountToSwap);
75+
assetToSwapFrom.safeApprove(tokenTransferProxy, 0);
76+
assetToSwapFrom.safeApprove(tokenTransferProxy, amountToSwap);
7577

7678
if (fromAmountOffset != 0) {
7779
// Ensure 256 bit (32 bytes) fromAmount value is within bounds of the

contracts/adapters/paraswap/ParaSwapLiquiditySwapAdapter.sol

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pragma solidity ^0.8.10;
44
import {IERC20Detailed} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol';
55
import {IERC20WithPermit} from '@aave/core-v3/contracts/interfaces/IERC20WithPermit.sol';
66
import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol';
7+
import {SafeERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol';
78
import {SafeMath} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeMath.sol';
89
import {BaseParaSwapSellAdapter} from './BaseParaSwapSellAdapter.sol';
910
import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol';
@@ -17,6 +18,7 @@ import {ReentrancyGuard} from '../../dependencies/openzeppelin/ReentrancyGuard.s
1718
*/
1819
contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter, ReentrancyGuard {
1920
using SafeMath for uint256;
21+
using SafeERC20 for IERC20Detailed;
2022

2123
constructor(
2224
IPoolAddressesProvider addressesProvider,
@@ -135,8 +137,8 @@ contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter, ReentrancyGuar
135137
minAmountToReceive
136138
);
137139

138-
assetToSwapTo.approve(address(POOL), 0);
139-
assetToSwapTo.approve(address(POOL), amountReceived);
140+
assetToSwapTo.safeApprove(address(POOL), 0);
141+
assetToSwapTo.safeApprove(address(POOL), amountReceived);
140142
POOL.deposit(address(assetToSwapTo), amountReceived, msg.sender, 0);
141143
}
142144

@@ -189,8 +191,8 @@ contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter, ReentrancyGuar
189191
minAmountToReceive
190192
);
191193

192-
assetToSwapTo.approve(address(POOL), 0);
193-
assetToSwapTo.approve(address(POOL), amountReceived);
194+
assetToSwapTo.safeApprove(address(POOL), 0);
195+
assetToSwapTo.safeApprove(address(POOL), amountReceived);
194196
POOL.deposit(address(assetToSwapTo), amountReceived, initiator, 0);
195197

196198
_pullATokenAndWithdraw(
@@ -202,7 +204,7 @@ contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter, ReentrancyGuar
202204
);
203205

204206
// Repay flash loan
205-
assetToSwapFrom.approve(address(POOL), 0);
206-
assetToSwapFrom.approve(address(POOL), flashLoanAmount.add(premium));
207+
assetToSwapFrom.safeApprove(address(POOL), 0);
208+
assetToSwapFrom.safeApprove(address(POOL), flashLoanAmount.add(premium));
207209
}
208210
}

contracts/adapters/paraswap/ParaSwapRepayAdapter.sol

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {IERC20Detailed} from '@aave/core-v3/contracts/dependencies/openzeppelin/
66
import {IERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20.sol';
77
import {IERC20WithPermit} from '@aave/core-v3/contracts/interfaces/IERC20WithPermit.sol';
88
import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol';
9+
import {SafeERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol';
910
import {SafeMath} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeMath.sol';
1011
import {BaseParaSwapBuyAdapter} from './BaseParaSwapBuyAdapter.sol';
1112
import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol';
@@ -19,6 +20,7 @@ import {ReentrancyGuard} from '../../dependencies/openzeppelin/ReentrancyGuard.s
1920
**/
2021
contract ParaSwapRepayAdapter is BaseParaSwapBuyAdapter, ReentrancyGuard {
2122
using SafeMath for uint256;
23+
using SafeERC20 for IERC20;
2224

2325
struct RepayParams {
2426
address collateralAsset;
@@ -125,14 +127,14 @@ contract ParaSwapRepayAdapter is BaseParaSwapBuyAdapter, ReentrancyGuard {
125127

126128
//deposit collateral back in the pool, if left after the swap(buy)
127129
if (collateralBalanceLeft > 0) {
128-
IERC20(collateralAsset).approve(address(POOL), 0);
129-
IERC20(collateralAsset).approve(address(POOL), collateralBalanceLeft);
130+
IERC20(collateralAsset).safeApprove(address(POOL), 0);
131+
IERC20(collateralAsset).safeApprove(address(POOL), collateralBalanceLeft);
130132
POOL.deposit(address(collateralAsset), collateralBalanceLeft, msg.sender, 0);
131133
}
132134

133135
// Repay debt. Approves 0 first to comply with tokens that implement the anti frontrunning approval fix
134-
IERC20(debtAsset).approve(address(POOL), 0);
135-
IERC20(debtAsset).approve(address(POOL), debtRepayAmount);
136+
IERC20(debtAsset).safeApprove(address(POOL), 0);
137+
IERC20(debtAsset).safeApprove(address(POOL), debtRepayAmount);
136138
POOL.repay(address(debtAsset), debtRepayAmount, debtRateMode, msg.sender);
137139
}
138140

@@ -178,8 +180,8 @@ contract ParaSwapRepayAdapter is BaseParaSwapBuyAdapter, ReentrancyGuard {
178180
);
179181

180182
// Repay debt. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
181-
IERC20(debtAsset).approve(address(POOL), 0);
182-
IERC20(debtAsset).approve(address(POOL), debtRepayAmount);
183+
IERC20(debtAsset).safeApprove(address(POOL), 0);
184+
IERC20(debtAsset).safeApprove(address(POOL), debtRepayAmount);
183185
POOL.repay(address(debtAsset), debtRepayAmount, rateMode, initiator);
184186

185187
uint256 neededForFlashLoanRepay = amountSold.add(premium);
@@ -193,8 +195,8 @@ contract ParaSwapRepayAdapter is BaseParaSwapBuyAdapter, ReentrancyGuard {
193195
);
194196

195197
// Repay flashloan. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
196-
IERC20(collateralAsset).approve(address(POOL), 0);
197-
IERC20(collateralAsset).approve(address(POOL), collateralAmount.add(premium));
198+
IERC20(collateralAsset).safeApprove(address(POOL), 0);
199+
IERC20(collateralAsset).safeApprove(address(POOL), collateralAmount.add(premium));
198200
}
199201

200202
function getDebtRepayAmount(

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,6 @@
8585
"url": "git://github.com/aave/aave-v3-periphery"
8686
},
8787
"dependencies": {
88-
"@aave/core-v3": "1.17.0"
88+
"@aave/core-v3": "1.19.0"
8989
}
9090
}

0 commit comments

Comments
 (0)