Submitted by Bauchibred
The Mantra DEX stableswap implementation lacks the ability to modify the amplification coefficient (A) after pool creation, which is a critical feature present even in the original Curve implementation. While the focus was on reducing Newton-Raphson iterations from 256 to 32, the absence of amplifier ramping breaks the logic.
In Mantras implementation, the amplification factor is static:
/packages/amm/src/pool_manager.rs#L85-L94
Once set during pool creation, there is no mechanism to modify this value. In contrast, Curves implementation includes comprehensive amplifier management, this can be seen here:
Note that the Amplification Coefficient is a crucial feature for managing the pools behavior and adapting to changing market conditions.
Before going further we understand that the stableswap invariant is enforced by the equation: Anxi + D = AD + (D^(n+1))/(n^nxi), this can be seen in compute_y_raw(), that gets called from compute_y().
Then, this directly translates to how we mint the amount of liquidity say when a user is making a stable swap deposit when providing liquidity:
/contracts/pool-manager/src/liquidity/commands.rs#L256-L267
/contracts/pool-manager/src/helpers.rs#L790-L812
Thats to say essentially when we are trying to calculate the swap amount, see here:
To explain the bug case more, lets examine how different A (Amplifier) values affect a 2-token stableswap pool with DAI and USDC (n=2):
Initial Balanced State:
With Optimal A = 85:, concluding this as optimal considering this was also hinted in the original Curve implementation:
With Too High A = 1000:
With Too Low A = 10:
This demonstrates how:
As already slightly hinted under Proof of Concept, we can see how having a static amplification value causes lack of flexibility in managing the pools behavior, and would immensely affect the minting lps logic when we are providing liquidity to a stableswap pool, building up on the swap details already hinted:
Note that market conditions are not constant and deviate quite, which means we cant have a constant amp for all condition of the pool for its lifetime, just like we cant have say a constant slippage for all market conditions. Even at that, assume we end up with an amp value that works 80% of the time, the implementation is still broken for 20% of the time. And blackswan events unfortunately occur from time to time which would even cause the breach to be way higher.
To build up on the scenario already hinted at, we can see that in the case we have a very high amplifier (A) The curve is flatter, meaning the price wrongly remains relatively stable even with significant imbalances. Whereas this is desirable for stablecoins or pegged assets where maintaining a tight peg is paramount, we still have to take into account that a blackswan event could be occurring. As such, the price of one of the assets in the pool is heavily dropping due to some sort of freefall. We cant just keep the price stable or enforce the equilibrium; otherwise, we then allow for anyone with the now fall dropping asset to come steal the other assets since the the prices are ~same; i.e., assume when Terras UST was on a free fall, with a very high Amp value, holders of Terras UST can come steal the other stablecoined assets in the pool, assume USDC for this report.
For example, during USTs depeg:
Now with a low amplifier, the case is even exacerbated, considering the curve is even more curved, leading to even greater price fluctuations with even small imbalances. In this case, we just open up the window for malicious actors to front/back run trades and scoop up the asset thats cheaper in price at the time.
Implement amplifier ramping functionality similar to Curve:
And add safety constraints:
3docSec (judge) commented:
jvr0x (MANTRA) confirmed and commented:
3docSec (judge) decreased severity to Medium and commented:
