Tempus
Search
⌃K

TempusAMM

The TempusAMM smart contract is an essential component of the Tempus Protocol. It allows users to swap Yields and Capitals for each other, or to provide liquidity to the platform to earn liquidity provider fees. Each TempusAMM is paired with a corresponding TempusPool (which are initialized concurrently).
We know much less about the value of Yields at the initialization of a pool, but as time goes on we can check the exact value of yield that is accruing in a pool, and by the time we reach maturity, we will know the full value.
When designing the TempusAMM, we wanted to optimize for two key properties:
  • If we are far from maturity, we want the market to drive the price between Capitals and Yields, which means it will be traded more like a "x * y = k" type of AMM
  • When approaching maturity, we want trades to be less sensitive of balances in the pool and closer to the actual yield that is being accrued
TempusAMM is implemented as Curve’s Stableswap type of AMM, with some small tweaks that were needed for our case. Stable pools are designed for swaps between stablecoins, or coins whose value is equal.
Liquidity provision formula for stable swap invariant:
Annxi+D=ADnn+Dn+1nnxiAn^n \sum x_i + D = ADn^n + \frac {D^{n+1}} {n^n \prod x_i}
Where
  • D is invariant
  • A is amplification coefficient
  • n is the number of tokens (in our case, it is 2)
  • xi is the balance of i-th token in the pool
By adjusting amplification over time, we change the price curve. If it has a small value, the AMM will trade like a constant product market maker (x * y = k), but if it has a bigger value, closer to or at 100, the AMM will trade more like a constant sum market maker (x + y = k).
You can check and play around with different amplification settings here to see the effect it makes.
Since Capitals and Yields are not traded as 1:1, we needed to change this formula a little bit. We did it by scaling the balances by actual values returned by Capitals and Yields. Both of them have implemented getPricePerFullShare that returns the value of one full share. So, we calculate balances as:
xi=pricePerFullShareibalanceix_i = pricePerFullShare_i * balance_i
You can check how we calculate the price per full share for both Capitals and Yields here.
Since the AMM is dealing with scaled balances in our invariant formula, it performs all actions (swaps, joins, and exits) using scaled balances. Conversely, the calculated "amounts out" figures in case of "exits" are reverted back to the previously scaled numbers.
We implemented our AMM using Balancer v2 Stable Pools with tweaks that are explained here.

Fees

Liquidity providers are providing liquidity in exchange for the receipt of additional yield. This yield comes from collecting fees on swaps.
TempusAMM has implemented a flat fee model that will initially be set by the pool deployer. All fees will accrue to those who provide liquidity to the TempusAMM.