A Deep Dive into the Economics of Sanctum Infinity
This is a more technical look at how Sanctum Infinity works. How can Infinity support all LSTs at once? How does Infinity charge fees? How does Infinity rebalance the LP? And so on.
What is Infinity?
Infinity is a multi-LST liquidity pool (LP). Most LPs only have two assets (e.g. USDC-SOL). Some LPs, like a Curve stableswap pool, support three or four assets (e.g. USDC-USDT-DAI). Infinity supports all whitelisted LSTs (e.g. SOL-bSOL-bonkSOL-cgntSOL-compassSOL-driftSOL-…)
There is no limit to the number of LSTs that Infinity can support — hence the name. But how do we do that? Every LST has a different price and different staking returns. How can Infinity make sure to price all these assets fairly, especially given the fact that with N assets, there are N*N (N squared) pairwise swaps?
Why do we need Infinity?
For the introductory post, see introducing Infinity: enabling the infinite-LST future. But here’s the “why” in brief:
We’re going to have lots of new LSTs and all of these LSTs will need liquidity. Existing LPs can only support two assets, which becomes very capital-inefficient as the number of LSTs grows. Infinity is the only LP that can support an infinite-LST future: any LST, to any other LST, in a maximally capital-efficient way.
How can Infinity support so many LSTs at once?
All LSTs today provide a ‘delayed unstake’ instruction which consumes the LST token and returns you either SOL or a stake account. We can think of LSTs as a “convenience layer” over stake accounts.
The key insight is that there is an infallible on-chain oracle that tells us the floor price of every LST. The price of every LST can simply be read off the account itself — the ratio of totalLamports
to poolTokenSupply
.
Here’s an example from BlazeStake:
In this case, dividing totallamports
by poolTokenSupply
gives us 1.1084.
This ratio can be thought of as a floor price of the LST. The token accrues staking rewards over the epoch, so totalLamports
will go up at the start of the new epoch.
There’s one hiccup though — we need to account for the LST’s withdraw fees (if any). We can again read it off the account; In the case of bSOL there is a 0.10% fee. The “adjusted” ratio is therefore 1.1084∗(1−0.001)=1.1073.1.1084∗(1−0.001)=1.1073.
To price a swap fairly, we simply divide the adjusted ratios by one another. For example, if 1 bSOL = 1.1073 SOL and 1 scnSOL = 1.1758 SOL, 1 bSOL = 0.9417 scnSOL. This makes sense, as 1 scnSOL is worth more than 1 bSOL in SOL terms.
Because every LST can be priced relative to the SOL numeraire, the ratio method will work for every pairwise swap. This allows us to fairly price every asset pair. And that is how we can support all LSTs at once.
How does Infinity charge fees?
The above method gives us a fair price for every pairwise swap within the pool. But in order to make money Infinity needs to charge fees.
Every asset in the pool has an inputFee
and outputFee
. The total fee for swap is the sum of the input and output fee.
Let’s examine a hypothetical bSOL->scnSOL
swap. What price will Infinity charge?
Assuming the following fees:
asset | inputFee | outputFee |
bSOL | 2 | 5 |
scnSOL | 3 | 4 |
The inputFee
for bSOL is 2 basis points (bps) and the outputFee
for scnSOL is 4 bps. The total fee is therefore 6 bps.
To charge the fee, we look at the adjusted ratio of bSOL and adjust it again by the total fee. 1 bSOL = 1.1073 SOL, but to get the adjusted rate after fees we get 1.1073∗(1−0.0006)=1.1067.1.1073∗(1−0.0006)=1.1067. We take this new ratio and divide it by the scnSOL ratio to get 1 bSOL = 0.9412 scnSOL.
In this version of the program, the fee is flat: it does not increase as you swap more bSOL. Future versions of the program will be able to support ramping fees if we deem it desirable. We have abstracted out the pricing module into a separate program so it can be easily upgraded without touching the rest of the codebase.
Why do we charge fees in this way? And how do we determine inputFee
and outputFee
for each asset? These fees are set dynamically by the Infinity pool manager. Let’s see how this fee structure allows us to provide economic incentives to rebalance the pool.
What happens when Infinity becomes imbalanced?
Let’s consider an Infinity pool with 100 bSOL,100 scnSOL, and no other assets. Now imagine there is a big swap of e.g. 90 bSOL —> scnSOL that almost wipes out the bSOL balance in the pool.
Assuming that the pool manager wants to maintain a 50-50 ratio of bSOL to scnSOL, we now have a “surplus” of scnSOL and a “deficit” of bSOL. We can provide an economic incentive to rebalance the pool by changing the input and output fees to something like the following:
asset | inputFee | outputFee |
bSOL | 10 | 0 |
scnSOL | 0 | 10 |
Let’s see how the fees affect the swaps. We have the following fair prices:
1 bSOL = 1.1073 SOL
1 scnSOL = 1.1758 SOL
Consider a 1 scnSOL —> bSOL swap. What is the fee? Well, the inputFee
for scnSOL is 0, and the outputFee
for bSOL is also 0. Therefore, there is no fee, and the user will be given the fair rate of 1 scnSOL = 1.0619 bSOL (1 bSOL = 0.9417 scnSOL).
But now consider the reverse, a 1 bSOL —> scnSOL swap. In this case, the inputFee
for bSOL is 10, and the outputFee
for scnSOL is also 10. The total fee is therefore 20 bps. The adjusted rate after fees is 1.1073∗(1−0.002)=1.1050854,1.1073∗(1−0.002)=1.1050854, which gives us a ratio of 1 bSOL = 0.9399 scnSOL.
Summarising the results:
1 bSOL = x scnSOL | |
No fees | 0.9417 |
Regular fees | 0.9412 |
High fees | 0.9399 |
What does this mean? With this fee structure the swap from scnSOL → bSOL is cheap, while the swap from bSOL —> scnSOL is expensive. This of course makes perfect sense. Since the pool has a “deficit” of bSOL and a “surplus” of scnSOL, it offers cheaper rates for people willing to give scnSOL and take bSOL and higher rates for the reverse. In this way, Infinity’s dynamic fees encourage swaps that rebalance it.
This is not the only lever that the pool manager can pull. We have the option of a “manual rebalance”, where the manager unstakes from an LST and moves the stake manually to another LST. The manager can also rebalance via the Sanctum Reserve pool, instant unstaking to SOL and then staking to another LST. A detailed breakdown of these alternative methods will have to wait for a future post.
What about performance drift?
Some LSTs have better staking returns than others and will drift in value over time. If Infinity is overweighted with poor-performing LSTs, this will affect the APY of INF holders.
The yield accrued in INF is a combination of staking yields from the LST basket plus trading fees. A poorly-performing LST (in APY terms) could be a strong contributor to INF’s total returns if it sees strong trading volume. So it’s not the case that INF should only hold high-APY LSTs. Nonetheless, the pool manager can adjust fees (or manually rebalance) to reduce the pool’s holdings of poor-performing LSTs.
In the previous section we assumed that the pool manager wanted to maintain a 50-50 bSOL-scnSOL ratio. But that is of course arbitrary. The pool manager should target an allocation that maximises yields for INF holders (while maintaining a minimum amount for each LST), but what that allocation looks like exactly is impossible to answer at this time.
What kind of yields can we expect from Infinity?
No idea!
It will depend a lot on the number of LSTs, trading volume of those LSTs, TVL in the pool, TVL in other LPs, etc. We should expect a base staking return (a weighted average of the LSTs in the pool) of ~7.5% plus variable returns from trading fees on top of that.
I have another question about Infinity!
Please join us on Telegram to ask any questions! We look forward to seeing you there.
Last updated