Skip to content

Commit

Permalink
fix: use SafeERC20 safeApprove to work well with non standard ERC20 t…
Browse files Browse the repository at this point in the history
…okens (#176)

* fix: use SafeERC20

* fix: only use SafeERC20 for safeApprove
  • Loading branch information
grothem authored Jul 6, 2023
1 parent f526d94 commit f5d0af9
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 26 deletions.
6 changes: 4 additions & 2 deletions contracts/adapters/paraswap/BaseParaSwapBuyAdapter.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.10;

import {SafeERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol';
import {SafeMath} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeMath.sol';
import {PercentageMath} from '@aave/core-v3/contracts/protocol/libraries/math/PercentageMath.sol';
import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol';
Expand All @@ -16,6 +17,7 @@ import {BaseParaSwapAdapter} from './BaseParaSwapAdapter.sol';
abstract contract BaseParaSwapBuyAdapter is BaseParaSwapAdapter {
using PercentageMath for uint256;
using SafeMath for uint256;
using SafeERC20 for IERC20Detailed;

IParaSwapAugustusRegistry public immutable AUGUSTUS_REGISTRY;

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

address tokenTransferProxy = augustus.getTokenTransferProxy();
assetToSwapFrom.approve(tokenTransferProxy, 0);
assetToSwapFrom.approve(tokenTransferProxy, maxAmountToSwap);
assetToSwapFrom.safeApprove(tokenTransferProxy, 0);
assetToSwapFrom.safeApprove(tokenTransferProxy, maxAmountToSwap);

if (toAmountOffset != 0) {
// Ensure 256 bit (32 bytes) toAmountOffset value is within bounds of the
Expand Down
6 changes: 4 additions & 2 deletions contracts/adapters/paraswap/BaseParaSwapSellAdapter.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.10;

import {SafeERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol';
import {SafeMath} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeMath.sol';
import {PercentageMath} from '@aave/core-v3/contracts/protocol/libraries/math/PercentageMath.sol';
import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol';
Expand All @@ -17,6 +18,7 @@ import {BaseParaSwapAdapter} from './BaseParaSwapAdapter.sol';
abstract contract BaseParaSwapSellAdapter is BaseParaSwapAdapter {
using PercentageMath for uint256;
using SafeMath for uint256;
using SafeERC20 for IERC20Detailed;

IParaSwapAugustusRegistry public immutable AUGUSTUS_REGISTRY;

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

address tokenTransferProxy = augustus.getTokenTransferProxy();
assetToSwapFrom.approve(tokenTransferProxy, 0);
assetToSwapFrom.approve(tokenTransferProxy, amountToSwap);
assetToSwapFrom.safeApprove(tokenTransferProxy, 0);
assetToSwapFrom.safeApprove(tokenTransferProxy, amountToSwap);

if (fromAmountOffset != 0) {
// Ensure 256 bit (32 bytes) fromAmount value is within bounds of the
Expand Down
14 changes: 8 additions & 6 deletions contracts/adapters/paraswap/ParaSwapLiquiditySwapAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.10;
import {IERC20Detailed} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol';
import {IERC20WithPermit} from '@aave/core-v3/contracts/interfaces/IERC20WithPermit.sol';
import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol';
import {SafeERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol';
import {SafeMath} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeMath.sol';
import {BaseParaSwapSellAdapter} from './BaseParaSwapSellAdapter.sol';
import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol';
Expand All @@ -17,6 +18,7 @@ import {ReentrancyGuard} from '../../dependencies/openzeppelin/ReentrancyGuard.s
*/
contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter, ReentrancyGuard {
using SafeMath for uint256;
using SafeERC20 for IERC20Detailed;

constructor(
IPoolAddressesProvider addressesProvider,
Expand Down Expand Up @@ -135,8 +137,8 @@ contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter, ReentrancyGuar
minAmountToReceive
);

assetToSwapTo.approve(address(POOL), 0);
assetToSwapTo.approve(address(POOL), amountReceived);
assetToSwapTo.safeApprove(address(POOL), 0);
assetToSwapTo.safeApprove(address(POOL), amountReceived);
POOL.deposit(address(assetToSwapTo), amountReceived, msg.sender, 0);
}

Expand Down Expand Up @@ -189,8 +191,8 @@ contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter, ReentrancyGuar
minAmountToReceive
);

assetToSwapTo.approve(address(POOL), 0);
assetToSwapTo.approve(address(POOL), amountReceived);
assetToSwapTo.safeApprove(address(POOL), 0);
assetToSwapTo.safeApprove(address(POOL), amountReceived);
POOL.deposit(address(assetToSwapTo), amountReceived, initiator, 0);

_pullATokenAndWithdraw(
Expand All @@ -202,7 +204,7 @@ contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter, ReentrancyGuar
);

// Repay flash loan
assetToSwapFrom.approve(address(POOL), 0);
assetToSwapFrom.approve(address(POOL), flashLoanAmount.add(premium));
assetToSwapFrom.safeApprove(address(POOL), 0);
assetToSwapFrom.safeApprove(address(POOL), flashLoanAmount.add(premium));
}
}
18 changes: 10 additions & 8 deletions contracts/adapters/paraswap/ParaSwapRepayAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {IERC20Detailed} from '@aave/core-v3/contracts/dependencies/openzeppelin/
import {IERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20.sol';
import {IERC20WithPermit} from '@aave/core-v3/contracts/interfaces/IERC20WithPermit.sol';
import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol';
import {SafeERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol';
import {SafeMath} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeMath.sol';
import {BaseParaSwapBuyAdapter} from './BaseParaSwapBuyAdapter.sol';
import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol';
Expand All @@ -19,6 +20,7 @@ import {ReentrancyGuard} from '../../dependencies/openzeppelin/ReentrancyGuard.s
**/
contract ParaSwapRepayAdapter is BaseParaSwapBuyAdapter, ReentrancyGuard {
using SafeMath for uint256;
using SafeERC20 for IERC20;

struct RepayParams {
address collateralAsset;
Expand Down Expand Up @@ -125,14 +127,14 @@ contract ParaSwapRepayAdapter is BaseParaSwapBuyAdapter, ReentrancyGuard {

//deposit collateral back in the pool, if left after the swap(buy)
if (collateralBalanceLeft > 0) {
IERC20(collateralAsset).approve(address(POOL), 0);
IERC20(collateralAsset).approve(address(POOL), collateralBalanceLeft);
IERC20(collateralAsset).safeApprove(address(POOL), 0);
IERC20(collateralAsset).safeApprove(address(POOL), collateralBalanceLeft);
POOL.deposit(address(collateralAsset), collateralBalanceLeft, msg.sender, 0);
}

// Repay debt. Approves 0 first to comply with tokens that implement the anti frontrunning approval fix
IERC20(debtAsset).approve(address(POOL), 0);
IERC20(debtAsset).approve(address(POOL), debtRepayAmount);
IERC20(debtAsset).safeApprove(address(POOL), 0);
IERC20(debtAsset).safeApprove(address(POOL), debtRepayAmount);
POOL.repay(address(debtAsset), debtRepayAmount, debtRateMode, msg.sender);
}

Expand Down Expand Up @@ -178,8 +180,8 @@ contract ParaSwapRepayAdapter is BaseParaSwapBuyAdapter, ReentrancyGuard {
);

// Repay debt. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
IERC20(debtAsset).approve(address(POOL), 0);
IERC20(debtAsset).approve(address(POOL), debtRepayAmount);
IERC20(debtAsset).safeApprove(address(POOL), 0);
IERC20(debtAsset).safeApprove(address(POOL), debtRepayAmount);
POOL.repay(address(debtAsset), debtRepayAmount, rateMode, initiator);

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

// Repay flashloan. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
IERC20(collateralAsset).approve(address(POOL), 0);
IERC20(collateralAsset).approve(address(POOL), collateralAmount.add(premium));
IERC20(collateralAsset).safeApprove(address(POOL), 0);
IERC20(collateralAsset).safeApprove(address(POOL), collateralAmount.add(premium));
}

function getDebtRepayAmount(
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,6 @@
"url": "git://github.com/aave/aave-v3-periphery"
},
"dependencies": {
"@aave/core-v3": "1.17.0"
"@aave/core-v3": "1.19.0"
}
}

0 comments on commit f5d0af9

Please sign in to comment.