mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Use better types than address
Fixes ABDK CVF-6, CVF-7, CVF-16, CVF-17, CVF-31 and CVF-32.
This commit is contained in:
parent
bf7b19a181
commit
d8b8d50de8
|
@ -21,6 +21,8 @@ import {FlashLoanReceiverBase} from '../flashloan/base/FlashLoanReceiverBase.sol
|
||||||
abstract contract BaseParaSwapAdapter is FlashLoanReceiverBase, Ownable {
|
abstract contract BaseParaSwapAdapter is FlashLoanReceiverBase, Ownable {
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
using SafeERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
|
using SafeERC20 for IERC20Detailed;
|
||||||
|
using SafeERC20 for IERC20WithPermit;
|
||||||
|
|
||||||
struct PermitSignature {
|
struct PermitSignature {
|
||||||
uint256 amount;
|
uint256 amount;
|
||||||
|
@ -56,8 +58,8 @@ abstract contract BaseParaSwapAdapter is FlashLoanReceiverBase, Ownable {
|
||||||
* @dev Get the decimals of an asset
|
* @dev Get the decimals of an asset
|
||||||
* @return number of decimals of the asset
|
* @return number of decimals of the asset
|
||||||
*/
|
*/
|
||||||
function _getDecimals(address asset) internal view returns (uint8) {
|
function _getDecimals(IERC20Detailed asset) internal view returns (uint8) {
|
||||||
uint8 decimals = IERC20Detailed(asset).decimals();
|
uint8 decimals = asset.decimals();
|
||||||
// Ensure 10**decimals won't overflow a uint256
|
// Ensure 10**decimals won't overflow a uint256
|
||||||
require(decimals <= 77, 'TOO_MANY_DECIMALS_ON_TOKEN');
|
require(decimals <= 77, 'TOO_MANY_DECIMALS_ON_TOKEN');
|
||||||
return decimals;
|
return decimals;
|
||||||
|
@ -81,14 +83,14 @@ abstract contract BaseParaSwapAdapter is FlashLoanReceiverBase, Ownable {
|
||||||
*/
|
*/
|
||||||
function _pullATokenAndWithdraw(
|
function _pullATokenAndWithdraw(
|
||||||
address reserve,
|
address reserve,
|
||||||
address reserveAToken,
|
IERC20WithPermit reserveAToken,
|
||||||
address user,
|
address user,
|
||||||
uint256 amount,
|
uint256 amount,
|
||||||
PermitSignature memory permitSignature
|
PermitSignature memory permitSignature
|
||||||
) internal {
|
) internal {
|
||||||
// If deadline is set to zero, assume there is no signature for permit
|
// If deadline is set to zero, assume there is no signature for permit
|
||||||
if (permitSignature.deadline != 0) {
|
if (permitSignature.deadline != 0) {
|
||||||
IERC20WithPermit(reserveAToken).permit(
|
reserveAToken.permit(
|
||||||
user,
|
user,
|
||||||
address(this),
|
address(this),
|
||||||
permitSignature.amount,
|
permitSignature.amount,
|
||||||
|
@ -100,7 +102,7 @@ abstract contract BaseParaSwapAdapter is FlashLoanReceiverBase, Ownable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// transfer from user to adapter
|
// transfer from user to adapter
|
||||||
IERC20(reserveAToken).safeTransferFrom(user, address(this), amount);
|
reserveAToken.safeTransferFrom(user, address(this), amount);
|
||||||
|
|
||||||
// withdraw reserve
|
// withdraw reserve
|
||||||
require(
|
require(
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {BaseParaSwapAdapter} from './BaseParaSwapAdapter.sol';
|
||||||
import {PercentageMath} from '../protocol/libraries/math/PercentageMath.sol';
|
import {PercentageMath} from '../protocol/libraries/math/PercentageMath.sol';
|
||||||
import {IParaSwapAugustus} from '../interfaces/IParaSwapAugustus.sol';
|
import {IParaSwapAugustus} from '../interfaces/IParaSwapAugustus.sol';
|
||||||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||||
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @title BaseParaSwapSellAdapter
|
* @title BaseParaSwapSellAdapter
|
||||||
|
@ -36,9 +36,9 @@ abstract contract BaseParaSwapSellAdapter is BaseParaSwapAdapter {
|
||||||
function _sellOnParaSwap(
|
function _sellOnParaSwap(
|
||||||
uint256 fromAmountOffset,
|
uint256 fromAmountOffset,
|
||||||
bytes memory swapCalldata,
|
bytes memory swapCalldata,
|
||||||
address augustus,
|
IParaSwapAugustus augustus,
|
||||||
address assetToSwapFrom,
|
IERC20Detailed assetToSwapFrom,
|
||||||
address assetToSwapTo,
|
IERC20Detailed assetToSwapTo,
|
||||||
uint256 amountToSwap,
|
uint256 amountToSwap,
|
||||||
uint256 minAmountToReceive
|
uint256 minAmountToReceive
|
||||||
) internal returns (uint256 amountReceived) {
|
) internal returns (uint256 amountReceived) {
|
||||||
|
@ -46,8 +46,8 @@ abstract contract BaseParaSwapSellAdapter is BaseParaSwapAdapter {
|
||||||
uint256 fromAssetDecimals = _getDecimals(assetToSwapFrom);
|
uint256 fromAssetDecimals = _getDecimals(assetToSwapFrom);
|
||||||
uint256 toAssetDecimals = _getDecimals(assetToSwapTo);
|
uint256 toAssetDecimals = _getDecimals(assetToSwapTo);
|
||||||
|
|
||||||
uint256 fromAssetPrice = _getPrice(assetToSwapFrom);
|
uint256 fromAssetPrice = _getPrice(address(assetToSwapFrom));
|
||||||
uint256 toAssetPrice = _getPrice(assetToSwapTo);
|
uint256 toAssetPrice = _getPrice(address(assetToSwapTo));
|
||||||
|
|
||||||
uint256 expectedMinAmountOut =
|
uint256 expectedMinAmountOut =
|
||||||
amountToSwap
|
amountToSwap
|
||||||
|
@ -58,13 +58,13 @@ abstract contract BaseParaSwapSellAdapter is BaseParaSwapAdapter {
|
||||||
require(expectedMinAmountOut <= minAmountToReceive, 'MIN_AMOUNT_EXCEEDS_MAX_SLIPPAGE');
|
require(expectedMinAmountOut <= minAmountToReceive, 'MIN_AMOUNT_EXCEEDS_MAX_SLIPPAGE');
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 balanceBeforeAssetFrom = IERC20(assetToSwapFrom).balanceOf(address(this));
|
uint256 balanceBeforeAssetFrom = assetToSwapFrom.balanceOf(address(this));
|
||||||
require(balanceBeforeAssetFrom >= amountToSwap, 'INSUFFICIENT_BALANCE_BEFORE_SWAP');
|
require(balanceBeforeAssetFrom >= amountToSwap, 'INSUFFICIENT_BALANCE_BEFORE_SWAP');
|
||||||
uint256 balanceBeforeAssetTo = IERC20(assetToSwapTo).balanceOf(address(this));
|
uint256 balanceBeforeAssetTo = assetToSwapTo.balanceOf(address(this));
|
||||||
|
|
||||||
address tokenTransferProxy = IParaSwapAugustus(augustus).getTokenTransferProxy();
|
address tokenTransferProxy = augustus.getTokenTransferProxy();
|
||||||
IERC20(assetToSwapFrom).safeApprove(tokenTransferProxy, 0);
|
assetToSwapFrom.safeApprove(tokenTransferProxy, 0);
|
||||||
IERC20(assetToSwapFrom).safeApprove(tokenTransferProxy, amountToSwap);
|
assetToSwapFrom.safeApprove(tokenTransferProxy, amountToSwap);
|
||||||
|
|
||||||
if (fromAmountOffset != 0) {
|
if (fromAmountOffset != 0) {
|
||||||
// Ensure 256 bit (32 bytes) fromAmount value is within bounds of the
|
// Ensure 256 bit (32 bytes) fromAmount value is within bounds of the
|
||||||
|
@ -79,7 +79,7 @@ abstract contract BaseParaSwapSellAdapter is BaseParaSwapAdapter {
|
||||||
mstore(add(swapCalldata, add(fromAmountOffset, 32)), amountToSwap)
|
mstore(add(swapCalldata, add(fromAmountOffset, 32)), amountToSwap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(bool success,) = augustus.call(swapCalldata);
|
(bool success,) = address(augustus).call(swapCalldata);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
// Copy revert reason from call
|
// Copy revert reason from call
|
||||||
assembly {
|
assembly {
|
||||||
|
@ -87,10 +87,15 @@ abstract contract BaseParaSwapSellAdapter is BaseParaSwapAdapter {
|
||||||
revert(0, returndatasize())
|
revert(0, returndatasize())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
require(IERC20(assetToSwapFrom).balanceOf(address(this)) == balanceBeforeAssetFrom - amountToSwap, 'WRONG_BALANCE_AFTER_SWAP');
|
require(assetToSwapFrom.balanceOf(address(this)) == balanceBeforeAssetFrom - amountToSwap, 'WRONG_BALANCE_AFTER_SWAP');
|
||||||
amountReceived = IERC20(assetToSwapTo).balanceOf(address(this)).sub(balanceBeforeAssetTo);
|
amountReceived = assetToSwapTo.balanceOf(address(this)).sub(balanceBeforeAssetTo);
|
||||||
require(amountReceived >= minAmountToReceive, 'INSUFFICIENT_AMOUNT_RECEIVED');
|
require(amountReceived >= minAmountToReceive, 'INSUFFICIENT_AMOUNT_RECEIVED');
|
||||||
|
|
||||||
emit Swapped(assetToSwapFrom, assetToSwapTo, amountToSwap, amountReceived);
|
emit Swapped(
|
||||||
|
address(assetToSwapFrom),
|
||||||
|
address(assetToSwapTo),
|
||||||
|
amountToSwap,
|
||||||
|
amountReceived
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,9 @@ pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
import {BaseParaSwapSellAdapter} from './BaseParaSwapSellAdapter.sol';
|
import {BaseParaSwapSellAdapter} from './BaseParaSwapSellAdapter.sol';
|
||||||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||||
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
||||||
|
import {IERC20WithPermit} from '../interfaces/IERC20WithPermit.sol';
|
||||||
|
import {IParaSwapAugustus} from '../interfaces/IParaSwapAugustus.sol';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @title ParaSwapLiquiditySwapAdapter
|
* @title ParaSwapLiquiditySwapAdapter
|
||||||
|
@ -50,15 +52,22 @@ contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter {
|
||||||
uint256 flashLoanAmount = amounts[0];
|
uint256 flashLoanAmount = amounts[0];
|
||||||
uint256 premium = premiums[0];
|
uint256 premium = premiums[0];
|
||||||
address initiatorLocal = initiator;
|
address initiatorLocal = initiator;
|
||||||
address assetToSwapFrom = assets[0];
|
IERC20Detailed assetToSwapFrom = IERC20Detailed(assets[0]);
|
||||||
(
|
(
|
||||||
address assetToSwapTo,
|
IERC20Detailed assetToSwapTo,
|
||||||
uint256 minAmountToReceive,
|
uint256 minAmountToReceive,
|
||||||
uint256 swapAllBalanceOffset,
|
uint256 swapAllBalanceOffset,
|
||||||
bytes memory swapCalldata,
|
bytes memory swapCalldata,
|
||||||
address augustus,
|
IParaSwapAugustus augustus,
|
||||||
PermitSignature memory permitParams
|
PermitSignature memory permitParams
|
||||||
) = abi.decode(params, (address, uint256, uint256, bytes, address, PermitSignature));
|
) = abi.decode(params, (
|
||||||
|
IERC20Detailed,
|
||||||
|
uint256,
|
||||||
|
uint256,
|
||||||
|
bytes,
|
||||||
|
IParaSwapAugustus,
|
||||||
|
PermitSignature
|
||||||
|
));
|
||||||
|
|
||||||
_swapLiquidity(
|
_swapLiquidity(
|
||||||
swapAllBalanceOffset,
|
swapAllBalanceOffset,
|
||||||
|
@ -90,25 +99,26 @@ contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter {
|
||||||
* @param permitParams Struct containing the permit signatures, set to all zeroes if not used
|
* @param permitParams Struct containing the permit signatures, set to all zeroes if not used
|
||||||
*/
|
*/
|
||||||
function swapAndDeposit(
|
function swapAndDeposit(
|
||||||
address assetToSwapFrom,
|
IERC20Detailed assetToSwapFrom,
|
||||||
address assetToSwapTo,
|
IERC20Detailed assetToSwapTo,
|
||||||
uint256 amountToSwap,
|
uint256 amountToSwap,
|
||||||
uint256 minAmountToReceive,
|
uint256 minAmountToReceive,
|
||||||
uint256 swapAllBalanceOffset,
|
uint256 swapAllBalanceOffset,
|
||||||
bytes calldata swapCalldata,
|
bytes calldata swapCalldata,
|
||||||
address augustus,
|
IParaSwapAugustus augustus,
|
||||||
PermitSignature calldata permitParams
|
PermitSignature calldata permitParams
|
||||||
) external {
|
) external {
|
||||||
address aToken = _getReserveData(assetToSwapFrom).aTokenAddress;
|
IERC20WithPermit aToken =
|
||||||
|
IERC20WithPermit(_getReserveData(address(assetToSwapFrom)).aTokenAddress);
|
||||||
|
|
||||||
if (swapAllBalanceOffset != 0) {
|
if (swapAllBalanceOffset != 0) {
|
||||||
uint256 balance = IERC20(aToken).balanceOf(msg.sender);
|
uint256 balance = aToken.balanceOf(msg.sender);
|
||||||
require(balance <= amountToSwap, 'INSUFFICIENT_AMOUNT_TO_SWAP');
|
require(balance <= amountToSwap, 'INSUFFICIENT_AMOUNT_TO_SWAP');
|
||||||
amountToSwap = balance;
|
amountToSwap = balance;
|
||||||
}
|
}
|
||||||
|
|
||||||
_pullATokenAndWithdraw(
|
_pullATokenAndWithdraw(
|
||||||
assetToSwapFrom,
|
address(assetToSwapFrom),
|
||||||
aToken,
|
aToken,
|
||||||
msg.sender,
|
msg.sender,
|
||||||
amountToSwap,
|
amountToSwap,
|
||||||
|
@ -125,9 +135,9 @@ contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter {
|
||||||
minAmountToReceive
|
minAmountToReceive
|
||||||
);
|
);
|
||||||
|
|
||||||
IERC20(assetToSwapTo).safeApprove(address(LENDING_POOL), 0);
|
assetToSwapTo.safeApprove(address(LENDING_POOL), 0);
|
||||||
IERC20(assetToSwapTo).safeApprove(address(LENDING_POOL), amountReceived);
|
assetToSwapTo.safeApprove(address(LENDING_POOL), amountReceived);
|
||||||
LENDING_POOL.deposit(assetToSwapTo, amountReceived, msg.sender, 0);
|
LENDING_POOL.deposit(address(assetToSwapTo), amountReceived, msg.sender, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,19 +156,20 @@ contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter {
|
||||||
function _swapLiquidity (
|
function _swapLiquidity (
|
||||||
uint256 swapAllBalanceOffset,
|
uint256 swapAllBalanceOffset,
|
||||||
bytes memory swapCalldata,
|
bytes memory swapCalldata,
|
||||||
address augustus,
|
IParaSwapAugustus augustus,
|
||||||
PermitSignature memory permitParams,
|
PermitSignature memory permitParams,
|
||||||
uint256 flashLoanAmount,
|
uint256 flashLoanAmount,
|
||||||
uint256 premium,
|
uint256 premium,
|
||||||
address initiator,
|
address initiator,
|
||||||
address assetToSwapFrom,
|
IERC20Detailed assetToSwapFrom,
|
||||||
address assetToSwapTo,
|
IERC20Detailed assetToSwapTo,
|
||||||
uint256 minAmountToReceive
|
uint256 minAmountToReceive
|
||||||
) internal {
|
) internal {
|
||||||
address aToken = _getReserveData(assetToSwapFrom).aTokenAddress;
|
IERC20WithPermit aToken =
|
||||||
|
IERC20WithPermit(_getReserveData(address(assetToSwapFrom)).aTokenAddress);
|
||||||
uint256 amountToSwap = flashLoanAmount;
|
uint256 amountToSwap = flashLoanAmount;
|
||||||
|
|
||||||
uint256 balance = IERC20(aToken).balanceOf(initiator);
|
uint256 balance = aToken.balanceOf(initiator);
|
||||||
if (swapAllBalanceOffset != 0) {
|
if (swapAllBalanceOffset != 0) {
|
||||||
uint256 balanceToSwap = balance.sub(premium);
|
uint256 balanceToSwap = balance.sub(premium);
|
||||||
require(balanceToSwap <= amountToSwap, 'INSUFFICIENT_AMOUNT_TO_SWAP');
|
require(balanceToSwap <= amountToSwap, 'INSUFFICIENT_AMOUNT_TO_SWAP');
|
||||||
|
@ -177,12 +188,12 @@ contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter {
|
||||||
minAmountToReceive
|
minAmountToReceive
|
||||||
);
|
);
|
||||||
|
|
||||||
IERC20(assetToSwapTo).safeApprove(address(LENDING_POOL), 0);
|
assetToSwapTo.safeApprove(address(LENDING_POOL), 0);
|
||||||
IERC20(assetToSwapTo).safeApprove(address(LENDING_POOL), amountReceived);
|
assetToSwapTo.safeApprove(address(LENDING_POOL), amountReceived);
|
||||||
LENDING_POOL.deposit(assetToSwapTo, amountReceived, initiator, 0);
|
LENDING_POOL.deposit(address(assetToSwapTo), amountReceived, initiator, 0);
|
||||||
|
|
||||||
_pullATokenAndWithdraw(
|
_pullATokenAndWithdraw(
|
||||||
assetToSwapFrom,
|
address(assetToSwapFrom),
|
||||||
aToken,
|
aToken,
|
||||||
initiator,
|
initiator,
|
||||||
amountToSwap.add(premium),
|
amountToSwap.add(premium),
|
||||||
|
@ -190,7 +201,7 @@ contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Repay flash loan
|
// Repay flash loan
|
||||||
IERC20(assetToSwapFrom).safeApprove(address(LENDING_POOL), 0);
|
assetToSwapFrom.safeApprove(address(LENDING_POOL), 0);
|
||||||
IERC20(assetToSwapFrom).safeApprove(address(LENDING_POOL), flashLoanAmount.add(premium));
|
assetToSwapFrom.safeApprove(address(LENDING_POOL), flashLoanAmount.add(premium));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user