"Adjusted" AMM

To protect LPs from front-run when oracle price is delayed and to simulate market makers’ behavior when a large order is traded, Symmetry implements an "Adjusted AMM mechanism".

Liquidity is uniformly distributed between λ-\lambda and. Outside this range, LP provides extra linear liquidity, which has the same liquidity distribution between and λ\lambda.

Parameters:

Symbol
Meaning

poraclep_{oracle}

oracle price before the trade

pmidp_{mid}

mid price before the trade

pbuyp_{buy}

taker’s buy price before the trade

psellp_{sell}

taker’s sell price before the trade. psellpbuyp_{sell}\leq p_{buy}

poraclep'_{oracle}

oracle price after the trade

pmidp'_{mid}

mid price after the trade

pbuyp'_{buy}

taker’s buy price after the trade

psellp'_{sell}

taker’s sell price after the trade. psellpbuyp'_{sell}\leq p'_{buy}

Calculation

AMM formula is as below:

Before trade is executed, prem=λsprLPprem = \frac { \lambda \cdot s} {pr \cdot LP},

After trade is executed, prem=λsprLPprem' =\frac {\lambda \cdot s'} {pr \cdot LP},

where s=s+Ts' = s + T, TT is trade quantity.

Therefore,

pmid=poracle(1+prem)=poracle(1+λsprLP)p_{mid} = p_{oracle}(1+prem) = p_{oracle} \left(1 + \frac { \lambda \cdot s} {pr \cdot LP}\right)
pmid=poracle(1+prem)=poracle(1+λ(s+T)prLP)p'_{mid} = p'_{oracle}(1+prem') = p'_{oracle} \left(1 + \frac { \lambda \cdot (s+T)} {pr \cdot LP}\right)

Besides poraclep_{oracle} and pmidp_{mid}, smart contract also keeps track of the taker's buy price pbuyp_{buy} and sell price psellp_{sell}.

【User’s Buy Price & Sell Price】

After the trade, when pmidp_{mid} is between pbuyp_{buy} and psellp_{sell}., both prices gradually move towards pmidp'_{mid}at a fixed speed, reaching pmidp'_{mid} after 60 seconds.

When pmidp'_{mid} exceeds either of these two prices, the crossed price moves immediately to pmidp'_{mid}. And the other one will gradually move towards pmidp'_{mid} at a fixed speed, reaching pmidp'_{mid} after 60 seconds.

Formally speaking, after tt seconds following a trade, these two prices change as follows.

pbuy={max(tpmid+(60t)pbuy60,pmid)t<60pmidt60psell={min(tpmid+(60t)psell60,pmid)t<60pmidt60\begin{align*} p'_{buy} &= \begin{dcases} max\left(\frac{t \cdot p'_{mid} + (60 - t) \cdot p_{buy}}{60}, p'_{mid} \right) && t < 60 \\ p'_{mid} && t \ge 60\\ \end{dcases} \\ p'_{sell} &= \begin{dcases} min \left(\frac{t \cdot p'_{mid} + (60 - t) \cdot p_{sell}}{60},p'_{mid} \right) && t < 60 \\ p'_{mid} && t \ge 60\\ \end{dcases} \end{align*}

【Execution Price】

A trade is executed as if it is divided into infinite tiny pieces, which are executed one by one. For example, assume that a buy trade of volume TT changes the mid price from pmidp_{mid} to pmidp'_{mid} and the user’s buy price is pbuyp_{buy} before the trade. Its turnover is

pexecT=0Tmax(vpmid+(Tv)pmidT,pbuy)dvp_{exec} \cdot T = \int_0^T \max\left( \frac{v \cdot p_{mid} + (T - v) \cdot p'_{mid}}{T}, p_{buy} \right) \mathrm{d}v

Therefore, the execution price for user’s buy order is

pexec={pbuypmidpbuy(pbuypmid)pbuy+(pmidpbuy)pmid+pbuy2pmidpmidpmid>pbuyp_{exec} = \begin{dcases} p_{buy} & p'_{mid} \le p_{buy} \\ \frac{(p_{buy} - p_{mid}) \cdot p_{buy} + (p'_{mid} - p_{buy}) \cdot \frac{p'_{mid} + p_{buy}}{2}}{p'_{mid} - p_{mid}} & p'_{mid} > p_{buy} \end{dcases}

Same as above, the execution notional for user’s sell order is

pexecT=0Tmin(vpmid+(Tv)pmidT,psell)dvp_{exec} \cdot T = \int_0^T \min\left( \frac{v \cdot p_{mid} + (T - v) \cdot p'_{mid}}{T}, p_{sell} \right) \mathrm{d}v

Example

Initial State

LPLP = 100,000,000 (assume it does not change in this example)

α\alpha = 1

λ\lambda = 0.05

prpr = 0.5

poraclep_{oracle} = 20000

s = 0

pmidp_{mid} = pbuyp_{buy} = psellp_{sell} = 20000

Trade #1 at time t = 0s

State before the trade

s=0s = 0

pmid=pbuy=psell=20000p_{mid} = p_{buy} = p_{sell} = 20000

User sells $40,000,000

s=40,000,000s' = -40,000,000

pmid=20000×(1+1×0.05×40,000,0000.5×100,000,000)=19200p'_{mid} = 20000 \times \left( 1 + \frac{1 \times 0.05 \times -40,000,000}{0.5 \times 100,000,000} \right) = 19200

psell=min(psell,pmid)=19200p'{sell} = \min(p_{sell}, p'_{mid}) = 19200

The trade volume is evenly distributed between psellp_{sell} and psellp'_{sell}.

pexec=psell+psell2=19600p_{exec} = \frac{p_{sell} + p'_{sell}}{2} = 19600

pbuy=pbuy=20000p'_{buy} = p_{buy} = 20000

Summary

Before this trade
After this trade

Buy Price

0%

0%

Mid Price

0%

-4%

Sell Price

0%

-4%

Trade #2 at time t = 15s

State before the trade

s=40,000,000s = -40,000,000

pmid=psell=19200p_{mid} = p_{sell} = 19200

pbuy=pmid×15+20000×(6015)60=19800p_{buy} = \frac{p_{mid} \times 15 + 20000 \times (60 - 15)}{60} = 19800

User sells $20,000,000

s=60,000,000s' = -60,000,000

pmid=18800p'_{mid} = 18800

psell=min(psell,pmid)=18800p'_{sell} = \min(p_{sell}, p'_{mid}) = 18800

The trade volume is evenly distributed between psellp_{sell} and psellp'_{sell}.

pexec=psell+psell2=19000p_{exec} = \frac{p_{sell} + p'_{sell}}{2} = 19000

pbuy=pbuy=19800p'_{buy} = p_{buy} = 19800

Summary

After the last trade
Before this trade
After this trade

Buy Price

0%

-1%

-1%

Mid

-4%

-4%

-6%

Sell Price

-4%

-4%

-6%

Trade #3 at time t = 39s (24 seconds later)

State before the trade

s=60,000,000s = -60,000,000

pmid=psell=18800p_{mid} = p_{sell} = 18800

pbuy=pmid×24+19800×(6024)60=19400p_{buy} = \frac{p_{mid} \times 24 + 19800 \times (60 - 24)}{60} = 19400

User buys $10,000,000

s=50,000,000s'=-50,000,000

pmid=19000p'_{mid} = 19000

pbuy=max(pbuy,pmid)=19400p'_{buy} = \max(p_{buy}, p'_{mid}) = 19400

The trade is completely executed at pbuyp_{buy}, which does not move in this trade

pexec=pbuy=19400p_{exec} = p_{buy} = 19400

psell=psell=18800p'_{sell} = p_{sell} = 18800

Summary

After the last trade
Before this trade
After this trade

Buy Price

-1%

-3%

-3%

Mid

-6%

-6%

-5%

Sell Price

-6%

-6%

-6%

Trade #4 at time t = 54s (15 seconds later)

State before the trade

s=50,000,000s = -50,000,000

pmid=19000p_{mid} = 19000

pbuy=pmid×15+19400×(6015)60=19300p_{buy} = \frac{p_{mid} \times 15 + 19400 \times (60 - 15)}{60} = 19300

psell=pmid×15+18800×(6015)60=18850p_{sell} = \frac{p_{mid} \times 15 + 18800 \times (60 - 15)}{60} = 18850

User buys $50,000,000

s=0s' = 0

pmid=20000p'_{mid} = 20000

pbuy=max(pbuy,pmid)=20000p'_{buy} = \max(p_{buy}, p'_{mid}) = 20000

A fraction of the trade volume is executed at pbuyp_{buy} and the rest is evenly distributed between pbuyp_{buy} and pbuyp'_{buy}.

pexec=((pbuypmid)×pbuy+(pbuypbuy)×pbuy+pbuy2)÷(pbuypmid)=19545p_{exec} = \left((p_{buy} - p_{mid}) \times p_{buy} + (p'_{buy} - p_{buy}) \times \frac{p_{buy} + p'_{buy}}{2} \right) \div (p'_{buy} - p_{mid}) = 19545

psell=psell=18850p'_{sell} = p_{sell} = 18850

Summary

After the last trade
Before this trade
After this trade

Buy Price

-3%

-3.5%

0%

Mid

-5%

-5%

0%

Sell Price

-6%

-5.75%

-5.75%

Last updated