In AmirX.sol the defiToStablecoinSwap function the user might receive a lot less funds than expected
Summary
In AmirX.sol contract the function defiToStableCoinSwap performs a defiSwaphere which is followed by a stableCoinSwaphere in the end. After checking the validating the params in the structs. It checks initial balance of the ss.origin then it performs a _defiSwap. Then it checks the finalBalance of the ss.origin. The issue that'll arise here is that before performing the _stableSwap it takes difference between the fBalance and the iBalance as ss.origin and performs the _stableCoinSwap with this amount.
The flow of the function will be like - AAVE -> USDC -> eUSD this indicates that first the defiSwap then the stableSwap will take place. In the issue if the token is FoT then the target tokens that'll be received will more less and then too there will be fees also included in stableCoinSwap which will be taken out from the walet.
Note that even if there are slippage checks in the aggregator or router contracts, The transaction then will mostly revert.
Root Cause
Takes difference between the finalBalance and the initialBalance for the ending stableCoinSwap
Internal pre-conditions
The SWAPPER must have a preset value of lets say 1000 USDC.
External pre-conditions
the SWAPPER calls the function with preset balance of 1000 USDC as ss.origin in the wallet
Attack Path
Lets take a scenario where SWAPPER makes a swap of AAVE -> USDC -> eUSD.
SWAPPER calls the defiToStableCoinSwap function with 1000 USDC (ss.origin) in his wallet.
the iBalance will be = 1000
then the _defiSwap will be called with AAVE -> USDC. Lets say he gets 200 USDC for 100 AAVE
After this the fBalance will be = 1200 USDC
Then ss.oAmount = fBalance - iBalance; = 1200 - 1000 = 200 USDC
then the _stableCoinSwap will be called with swapping only 200 to the target token(eUSD)
This clearly shows that end target token received is indeed very less than the user would expect to get as the target token. Note that this amount will reduce more in case of Fee on Transfer Tokens and also including the fees which taken for the _stableCoinSwap
Impact
The user will receive less target than he expected
PoC
See Attack Path and;
//check balance to adjust second swap
uint256 iBalance = ERC20(ss.origin).balanceOf(wallet); //1000 USDC
_defiSwap(wallet, defi); // AAVE -> USDC = 100 AAVE-> 200 USDC
uint256 fBalance = ERC20(ss.origin).balanceOf(wallet); //1200 USDC
//AUDIT-> ss.oAmount = fBalance - iBalance; // 1200 - 1000 = 200
//change balance to reflect change
_stablecoinSwap(wallet, ss); //it'll swap 200 USDC -> 200 eUSD (Note: there will also be issues here if FoT are included)
}
Mitigation
Recommendation will be that instead of taking the difffernce b/w the fBalance and the iBalance_stableCoinSwap should be called directly after the defiSwap.
//check balance to adjust second swap
uint256 iBalance = ERC20(ss.origin).balanceOf(wallet);
_defiSwap(wallet, defi);
uint256 fBalance = ERC20(ss.origin).balanceOf(wallet);
-> ss.oAmount = fBalance - iBalance;
//change balance to reflect change
_stablecoinSwap(wallet, ss);
}
hard1k
Medium
In
AmirX.sol
thedefiToStablecoinSwap
function the user might receive a lot less funds than expectedSummary
In AmirX.sol contract the function defiToStableCoinSwap performs a
defiSwap
here which is followed by astableCoinSwap
here in the end. After checking the validating the params in the structs. It checks initial balance of the ss.origin then it performs a_defiSwap
. Then it checks the finalBalance of the ss.origin. The issue that'll arise here is that before performing the_stableSwap
it takes difference between the fBalance and the iBalance as ss.origin and performs the_stableCoinSwap
with this amount. The flow of the function will be like -AAVE -> USDC -> eUSD
this indicates that first the defiSwap then the stableSwap will take place. In the issue if the token is FoT then the target tokens that'll be received will more less and then too there will be fees also included instableCoinSwap
which will be taken out from the walet. Note that even if there are slippage checks in the aggregator or router contracts, The transaction then will mostly revert.Root Cause
Takes difference between the
finalBalance and the initialBalance
for the endingstableCoinSwap
Internal pre-conditions
The SWAPPER must have a preset value of lets say 1000 USDC.
External pre-conditions
the SWAPPER calls the function with preset balance of 1000 USDC as
ss.origin
in the walletAttack Path
Lets take a scenario where SWAPPER makes a swap of AAVE -> USDC -> eUSD. SWAPPER calls the
defiToStableCoinSwap
function with 1000 USDC (ss.origin) in his wallet. the iBalance will be = 1000 then the_defiSwap
will be called with AAVE -> USDC. Lets say he gets 200 USDC for 100 AAVE After this the fBalance will be = 1200 USDC Thenss.oAmount = fBalance - iBalance;
= 1200 - 1000 = 200 USDC then the_stableCoinSwap
will be called with swapping only 200 to the target token(eUSD)This clearly shows that end target token received is indeed very less than the user would expect to get as the target token. Note that this amount will reduce more in case of Fee on Transfer Tokens and also including the fees which taken for the
_stableCoinSwap
Impact
The user will receive less
target
than he expectedPoC
See Attack Path and;
Mitigation
Recommendation will be that instead of taking the difffernce b/w the
fBalance and the iBalance
_stableCoinSwap
should be called directly after the defiSwap.