sellCollateral() when sell collateral, the quantity parameter passed may too large
Summary
In the sellCollateral()
due to rounding down, after executing yieldBox.withdraw(shares), subsequently calling yieldBox.toAmount(shares) returns the quantity that is 1 unit larger than the previous yieldBox.withdraw().
This difference leads to insufficient balance in subsequent exchanges.
Vulnerability Detail
The current implementation of sellCollateral() is as follows:
bin2chen
medium
sellCollateral() when sell collateral, the quantity parameter passed may too large
Summary
In the
sellCollateral()
due to rounding down, after executingyieldBox.withdraw(shares)
, subsequently callingyieldBox.toAmount(shares)
returns the quantity that is 1 unit larger than the previousyieldBox.withdraw()
. This difference leads to insufficient balance in subsequent exchanges.Vulnerability Detail
The current implementation of
sellCollateral()
is as follows:leverageAmount
recalculates usingyieldBox.toAmount()
. This value may be greater by 1 than the actual amount retrieved throughyieldBox.withdraw()
.Example:
totalShare = 4171824492 totalAsset = 4171824494 withdrawShares = 2931277435
yieldBox.toAmount(withdrawShares)
->round downreturn_amount - get_assets = 2931277437 - 2931277436 = 1
Calling
leverageExecutor.getAsset(leverageAmount)
will result in insufficient collateral, becauseleverageAmount
> 1.You can use the following fuzz to obtain other test values.
Impact
The withdraw collateral quantity small then the collateral quantity parameter used for exchange, which leads to revert.
Code Snippet
https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/contracts/markets/singularity/SGLLeverage.sol#L128
Tool used
Manual Review
Recommendation
Don't recalculate, just take the return value of yieldBox.withdraw.
Duplicate of #61