Swap fees are undercollected #339
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
downgraded by judge
Judge downgraded the risk level of this issue
duplicate-470
satisfactory
satisfies C4 submission criteria; eligible for awards
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Lines of code
https://github.com/code-423n4/2022-10-traderjoe/blob/main/src/libraries/SwapHelper.sol#L59-L63
https://github.com/code-423n4/2022-10-traderjoe/blob/main/src/libraries/SwapHelper.sol#L65-L66
Vulnerability details
Impact
Trades pay less swap fees than expected, thus liquidity providers earn less than expected.
Proof of Concept
LBPair is a liquidity pool contract that allows liquidity providers to deposit tokens and earn swap fees accrued on liquidity that's used during tokens swapping. Traders can use the liquidity provided by liquidity providers to make token swaps. Each
LBPair
is a pool of liquidity of two tokens, which can be swapped with each other.Swap fees are accrued when traders swap tokens. SwapHelper.getAmounts is the function that:
Swap fees are collected from the input token:
When
_swapForY
is true (when selling token X to buy token Y), fees are added to_pair.feesX
(which stores fees accrued in token X); when_swapForY
is false, fees are added to_pair.feesY
(which stores fees in token Y):Thus, when we're selling token X and buying token Y, fees are collected from token X and added to
_pair.feesX
; when selling token Y and buying token X, fees are collected from token Y and added to_pair.feesY
.In Trader Joe V2, swap fees are made of two components: base fee and variable fee:
And both values are set as percentages with 18 decimals. Thus, to calculate fee amount we multiply input amount by a swap fee:
Then, we subtract the fee amount from the input amount and use the result to calculate the output amount:
However, there are two flaws in how this is implemented:
_maxAmountInToBin <= amountIn
, fees are collected from the reserve of the input token, not from the input amount;amountIn < _maxAmountInToBin
, wrong function is used to calculate fees: getFeeAmountFrom is used instead of getFeeAmount.In both of these situations, trader pays less fees than defined by the
getTotalFee
function.Tools Used
Manual review.
Recommended Mitigation Steps
Ensure that swap fees are calculated correctly:
FeeHelper.getFeeAmount
function.The text was updated successfully, but these errors were encountered: