When balanceOut is divided by tokenOutOffset, Solidity performs integer division. If balanceOut is not a perfect multiple of tokenOutOffset, the division will result in a truncated integer, losing the fractional part.
This happens also in other functions like removeLiquidityAndUnwrapToken and removeLiquidityETHAndUnwrap.
Impact
Users suffer from the precision loss, getting out less than they expect to.
giraffe
medium
Precision loss in multiple areas of MasterRouter
Summary
Precision loss due to performing division before multiplication
Vulnerability Detail
In JalaMasterRouter, several functions including _unwrapAndTransfer() calculates
tokenReturnAmount
:When balanceOut is divided by tokenOutOffset, Solidity performs integer division. If balanceOut is not a perfect multiple of tokenOutOffset, the division will result in a truncated integer, losing the fractional part.
This happens also in other functions like
removeLiquidityAndUnwrapToken
andremoveLiquidityETHAndUnwrap
.Impact
Users suffer from the precision loss, getting out less than they expect to.
Code Snippet
https://github.com/sherlock-audit/2024-02-jala-swap/blob/main/jalaswap-dex-contract/contracts/JalaMasterRouter.sol#L312
Tool used
Manual Review
Recommendation
Amend to
uint256 tokenOutReturnAmount = balanceOut * tokenOutOffset / tokenOutOffset;