Submitted by Egis_Security
calcLpTokenSupply is used in both calcReserveAtRatioLiquidity and calcReserveAtRatioSwap, well focus on calcReserveAtRatioLiquidity.
calcLpTokenSupply is called inside calcRate 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 to calcReserveAtRatioLiquidity revert. Well investigate this further inside the PoC section.
Paste the following inside BeanstalkStable2LiquidityTest and run forge test --mt test_calcReserveAtRatioLiquidity_equal_equalPositive -vv. This is a rough test to loop through some of the cases in Stable2LUT1.
Youll 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 the lowPrice.
PriceData(0.27702e6, 0, 9.646293093274934449e18, 0.001083e6, 0, 2000e18, 1e18);
Its unclear what causes this looping to occur, so its hard to say what the root cause is.
Something interesting is that this started happening once the revert was introduced, the last audit didnt have it, but the code still worked. Then it didnt revert it just returned the last lpTokenSupply.
Also note that the underlying issue is in calcLpTokenSupply, so if the function is used on its own it can still revert, but it happens much more often when calcReserveAtRatioLiquidity is used.
Foundry
Its very hard to recommend a fix here, as many tweaks can fix the issue. We recommend:
DoS
Brean0 (Basin) confirmed
0xsomeone (judge) commented:
For this audit, 2 reports were submitted by wardens detailing low risk and non-critical issues. The report highlighted below by Egis_Security received the top score from the judge.
The following wardens also submitted reports: ZanyBonzy.
