Open howlbot-integration[bot] opened 1 month ago
The Warden has identified a potential edge case in the pre-computed values yielded by the Stable2LUT1::getRatiosFromPriceSwap
function where the discrepancy between the upper and lower price bounds is significant and adversely affects reserve calculations.
I believe a medium-risk assessment is better suited for this particular vulnerability due to its low likelihood of manifesting in a production environment. Specifically, the PoC will directly interact with the Stable2
contract even though the ratios passed into it stem from different calculations in the MultiFlowPump
contract.
In order to properly accept the medium-risk assessment, I invite the wardens of the team to supplement a PoC that demonstrates the vulnerability manifesting in a production environment through a higher-level call to the Basin system. As the issue stands, it lacks sufficient impact although the actual flaw is adequately described.
For the above reason, I will consider this submission as QA (L) pending substantiation by the Warden team.
alex-ppg changed the severity to QA (Quality Assurance)
alex-ppg marked the issue as grade-c
Hey @alex-ppg
Thanks for your expertise about the following finding. Here are my arguments regarding why the issue should be a valid Medium:
1:4.6
, which is realistic in de-peg situations for stablecoins.We would tend to agree with classifying this issue as Medium severity. While the likelihood of it occurring in a real production environment is low, it effectively renders the well function unusable. According to the severity documentation, which states that "assets are not at direct risk, but the protocol's function or availability could be impacted," this issue clearly falls within that category. Instead of recalculating the data points for the lookup table, the issue was resolved by improving the step size, ensuring that the maxStep size can never exceed the j reserve. You can see the complete fix in this PR: https://github.com/BeanstalkFarms/Basin/pull/137.
Hey @NicolaMirchev and @nickkatsios, thank you for your PJQA contributions! After evaluating all relevant information as well as discussing it with the Sponsor, I believe that the submission should be accepted as a medium-risk vulnerability due to relying on hypotheticals yet demonstrating the flaw clearly.
Submission #22 was resolved using the same approach as this one and thus the root cause is the large gap that exists in the step size. As such, the issues will remain group rendering this submission to be treated as a "single" one.
This previously downgraded issue has been upgraded by alex-ppg
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-07-basin/blob/7d5aacbb144d0ba0bc358dfde6e0cc913d25310e/src/functions/StableLUT/Stable2LUT1.sol#L750-L758
Vulnerability details
Impact
Basin team has implemented look up table to fetch pre-calculated values, which are close to the
targetPrice
to decrease the complexity ofcalcReserveAtRatioSwap
andcalcReserveAtRatioLiquidity
functions. Stable2LUT1 has a functiongetRatiosFromPriceSwap
, which returnsPriceData
struct based on providedprice
. We can see that in case of super extreme price, the function will revert withLUT: Invalid price
, but there is also support for extreme prices, which we assume should work correctly, when such situation occurs.We will investigate an edge case, which is present, when we enter
if (price < 0.213318e6)
and price is above0.001083e6
. Is such situation, function will return the following struct:If you can notice we have a large gap between
highPrice
andlowPrice
and more precisely.The following results in large jump in reserves calculation when
updateReserve
which leads to skipping the target price sequentially, which moves awaypd.currentPrice
until we exit thefor
loop, which returns 0.Here is an estimation of the impact based on the PoC which is below.: For a ratio ~ 1:4.6 of the price of the tokens
targetPrice
of 212104 (0.21)44957
(0.04), which is ~ X5 less than the requested amount3623929482258792273
, instead of2421185918213441156
, which is a big differenceProof of Concept
Place the following test inside
/test/beanstalk/BeanstalkStable2.calcReserveAtRatioLiquidity.t.sol
and run it withforge test --mt "test_calcReserveAtRatioSwapSkipTarget" -vv
You can further add
console.log
inside the for loop ofcalcReserveAtRatioSwap
and logpd.currentPrice
on each update. You can notice that each time the current price is further away from the target. Here are logs:Tools Used
Recommended Mitigation Steps
Recalculate the
PriceData
for the given case and consider narrowing down the price diff.Assessed type
Invalid Validation