Stable2::calcLpTokenSupply() - The function cannot convert under certain circumstances, DoSing calcReserveAtRatioLiquidity
#5
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
M-01
🤖_primary
AI based primary recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
selected for report
This submission will be included/highlighted in the audit report
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/2024-08-basin/blob/7e08ff591df0a2ade7d5618113dda2621cd899bc/src/functions/Stable2.sol#L103
Vulnerability details
Impact
calcLpTokenSupply
is used in bothcalcReserveAtRatioLiquidity
andcalcReserveAtRatioSwap
, we'll focus oncalcReserveAtRatioLiquidity
.calcLpTokenSupply
is called insidecalcRate
here:Inside we call the function:
Note that the only change to
calcLpTokenSupply
is the added revert on the last line of the function.The issue here lies that
calcLpTokenSupply
reverts under certain circumstances since it cannot converge, which makes the whole call tocalcReserveAtRatioLiquidity
revert.We'll investigate this further inside the PoC section.
Proof of Concept
Paste the following inside
BeanstalkStable2LiquidityTest
and runforge test --mt test_calcReserveAtRatioLiquidity_equal_equalPositive -vv
This is a rough test to loop through some of the cases in
Stable2LUT1
.You'll notice that the test reverts with:
[FAIL. Reason: revert: Non convergence: calcLpTokenSupply]
The values that it reverts with are:
This is when we hit this case in
Stable2LUT1
:Here are the last few iterations of
calcLpTokenSupply
:As you can see the values "loop" +-2, which makes it impossible to converge, since the difference has to be <= 1 so it converges.
Something to note is that even if we change the
reserves
in the test, the test continues failing with the same error, but every test fails when we hit this specific case in the lookup table and the price is closer to thelowPrice
.PriceData(0.27702e6, 0, 9.646293093274934449e18, 0.001083e6, 0, 2000e18, 1e18);
It's unclear what causes this "looping" to occur, so it's hard to say what the root cause is.
Something interesting is that this started happening once the revert was introduced, the last audit didn't have it, but the code still worked. Then it didn't revert it just returned the last
lpTokenSupply
.Also note that the underlying issue is in
calcLpTokenSupply
, so if the function is used on it's own it can still revert, but it happens much more often whencalcReserveAtRatioLiquidity
is used.Tools Used
Manual Review
Foundry
Recommended Mitigation Steps
It's very hard to recommend a fix here, as many tweaks can fix the issue. We can recommend:
calcLpTokenSupply
, if true then if the function doesn't converge it won't revert.PriceData
values for the specific case in the lookup table, narrowing down the range seems to fix the issue.Assessed type
DoS
The text was updated successfully, but these errors were encountered: