Axis-Fi / axis-core

Axis Protocol
https://axis.finance
Other
3 stars 0 forks source link

Gradual Dutch Auction Module #1

Open Oighty opened 6 months ago

Oighty commented 6 months ago

Implement a standard Continuous Gradual Dutch Auction with options for Linear and Exponential Price Decay. The concept is based on this article by Paradigm, which covers the Exponential case.

An initial version (where the equations are not updated to these versions) is implemented in src/modules/auctions/GDA.sol.

Auction Pricing Math

Exponential GDA

price in quote tokens for single (infinitesimal) auction at a time t:

$$ q(t) = k e^{- \lambda t} $$

priceFor: number of quote tokens required to purchase $P$ payout tokens

$$ Q(P) = \frac{k (e^{\frac{\lambda P}{r}} - 1)}{\lambda e^{\lambda T}} $$

We cannot add a minimum price directly into the equation in the exponential case because we run into issues with a special function case. However, we can truncate the equation with a minimum price.

$$ Q = max(Q(P), k_{min} P) $$

payoutFor: number of payout tokens to receive for providing $Q$ quote tokens We derive this by inverting the priceFor equation.

$$ P(Q) = \frac{r}{\lambda} ln \left(\frac{Q \lambda e^{\lambda T}}{k} + 1 \right) $$

We again take a minimum to truncate the equation to enforce a minimum value.

$$ P = min(P(Q), \frac{Q}{k_{min}}) $$

where:

Linear GDA

price in quote tokens for single (infinitesimal) auction at a time t:

$$ q(t) = (k - k{min}) (1 - \lambda t) + k{min} $$

In the linear case, we can introduce a minimum term into the individual auction equation.

priceFor: number of quote tokens required to purchase $P$ payout tokens

$$ Q(P) = \frac{\lambda (k - k_{min})}{2} \left(\frac{P^2}{r^2} - \frac{2TP}{r} \right) + \frac{k P}{r} $$

payoutFor: number of payout tokens to receive for providing $Q$ quote tokens We derive this by inverting the priceFor equation.

$$ P(Q) = \frac{2r \left(\sqrt{2 \lambda (k - k{min}) Q + (k - \lambda T (k - k{min}))^2} - (k - \lambda T (k - k{min})) \right)}{\sqrt{2 \lambda (k - k{min})}} $$

where:

Oighty commented 6 months ago

Implementation Considerations

In the previous auction system, a complicated price scaling system was used to cover a broad range of token prices and decimal values while avoiding under/overflows of the math. This was required due to the multiplication of two variables to calculate a price in the original SDA algorithm. This is no longer required. Instead, I believe it makes the most sense to have quote token quantities and auction prices stored in quote token decimals (i.e. quote scale). Base/payout token quantities can be represented in base token decimals (i.e. base scale).

The auction price equations detailed above require various math operations not available in standard Solidity. Additionally, there are some negative values used in the equations so it is not strictly unsigned math. Therefore, a FixedPoint Math library is required. The most robust that I have seen is PRBMath. For this case, we will need the SD59x18 variable type and associated operations, which the stored value as a signed fixed point number with 18 decimal places. Our input and output values will not be in this format since they are token quantities. Therefore, care should be taken to understand the various conversions between token scale and the fixed point math scale.

Oighty commented 2 months ago

After further review and discussion with tex, plan to only implement the exponential decay GDA and include a minimum price term in the equation. The updated math can be found here: https://oighty.eth.limo/gda-w-min-price/