SappwerImpl: Malicious trader can drain out tokens because of difference in token decimals
Summary
there is no minimum amount for tokens to swap.
swapping the minimum amount of base token can result in zero amount of quote token, especially when the decimals of quote token is less.
So a malicious trader can call flash() and get some of the base tokens without sending any quote tokens
Vulnerability Detail
Suppose:
token in swapperImpl (B) is 18 decimals
tokenToBeneficiary (Q) is 2 decimals
The oracle price of swapping tokens is 0.001
Attacker calls flas() to get and swap 1 of token B and send token Q to the beneficiary
transferToTrader, transfers 1 token B to the attacker
amountToTrader = baseAmount = 1 token B = 1e18 (in decimals)
attacker does not need to return any tokens, since amountToBeneficiary is 0
_transferToBeneficiary(_tokenToBeneficiary, amountToBeneficiary)tokenToBeneficiary_.safeTransferFrom(msg.sender, _beneficiary, amountToBeneficiary_);
Attacker repeats the cycle to drain out all of token B in swapperImpl without paying any token
Note that since the tokenToBeneficiary (token Q) is 2 decimals, the amountToBeneficiary should be 2 decimals and can't be 18 decimals.
Impact
A malicious trader can drain out tokens without sending anything to the beneficiary
Ace-30
high
SappwerImpl: Malicious trader can drain out tokens because of difference in token decimals
Summary
there is no minimum amount for tokens to swap. swapping the minimum amount of base token can result in zero amount of quote token, especially when the decimals of quote token is less. So a malicious trader can call
flash()
and get some of the base tokens without sending any quote tokensVulnerability Detail
Suppose:
flas()
to get and swap 1 of token B and send token Q to the beneficiarytransferToTrader
, transfers 1 token B to the attacker_transferToBeneficiary(_tokenToBeneficiary, amountToBeneficiary)
tokenToBeneficiary_.safeTransferFrom(msg.sender, _beneficiary, amountToBeneficiary_);
swapperImpl
without paying any tokenNote that since the tokenToBeneficiary (token Q) is 2 decimals, the amountToBeneficiary should be 2 decimals and can't be 18 decimals.
Impact
A malicious trader can drain out tokens without sending anything to the beneficiary
Code Snippet
https://github.com/0xSplits/splits-swapper/blob/83ce1124767a097aac37d1cd162a9b27bbc48701/src/SwapperImpl.sol#L203-L221
Tool used
Manual Review
Recommendation
revet or skip (continue) when the quoteAmount = 0