Open c4-bot-10 opened 3 months ago
The Warden has outlined how the system might fail to converge under normal PriceData
configurations due to looping between the threshold by a deviancy of ±2
. I believe the vulnerability is valid as it causes normal operation of the system to result in a revert due to remediations carried out for a submission in the previous contest of Basin.
To note, a percentage-based deviation threshold might be better appropriate than a fixed unit (i.e. a permitted deviancy of 1
) to avoid instances whereby the permitted deviation itself is missed by a negligible amount.
alex-ppg marked the issue as selected for report
alex-ppg marked the issue as satisfactory
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