TenderSwap

Homogenous Liquidity for LSTs

Introduction

TenderSwap is a cost-effective, application-specific DEX that offers instant liquidity for holders of Tenderize’s liquid staked tokens (tTokens). It is designed specifically to be a capital-efficient liquidity pool for homogenous liquid staked assets, like tToken LSTs. TenderSwap uses a novel shared liquidity design to enable low slippage with low capital requirements.
Upon exchange of a tToken LST, the user will receive an equivalent amount of the underlying assets, minus a fee based on both the current utilisation of total liquidity, as well as the amount of outstanding liquidity usage for a specific tToken.
TenderSwap is designed to efficiently share liquidity in a fair, efficient way for an underlying asset between various tTokens representing it. Charging an increasingly higher fee when utilisation increases and/or one specific tToken sees a lot of volume in a short period of time.

Instant Liquidity

Since liquidity is shared between similar-asset tTokens, newly created tTokens don’t require separate liquidity provision. New tTokens use already existing liquidity in Tenderswap, allowing for Tenderize users to enjoy liquidity without capital requirements for new tTokens.
  • Staking Service Providers: Offer liquid staking to your clients without worrying about in-house liquidity management or on-chain liquidity financing.
  • Solo Stakers: Continue validating the network from home while enjoying exit liquidity or lending of your stake.
  • Index/ETF Products: Deep liquidity for selling individual tTokens in an index, for rebalancing.
  • Borrowing/Lending Protocols: Deep on-chain liquidity for tToken routing/liquidations.
While Uniswap and Curve have both revolutionized the world of finance, neither are optimized specifically for LSTs. Tenderize’s shared liquidity approach works thanks to the homogenous nature of liquid staked derivatives. Each tToken can be unstaked, each of the tTokens can then be treated as a the same asset, sharing one liquidity pool.
When using Uniswap, each LSD requires its own liquidity pool, which is comprised of 50% LSD and 50% liquid, unstaked counterpart. This introduces three problems:
  • Inefficient Capital Allocation: By having to incentivize both staked assets and unstaked assets in a pool, capital is stuck in the pool which could be utilized elsewhere.
  • Liquidity Fragmentation: Without the ability to share one liquidity pool, traders end up paying more money for swaps due to the inability to access idle capital in like-asset pools.
  • Centralization: As DeFi builders adopt the most liquid product, this funnels stake to the preferred validator cartel of that liquid staked product’s team/community.
TenderSwaps’s shared-liquidity approach can be the most liquid solution on the market while eliminating capital requirements for new tTokens. Ultimately this approach isn’t confined to Tenderize’s tTokens and could also be used by protocol enshrined LSTs to have liquidity.

Glossary

  • LST: Liquid Staked Token
  • Underlying asset: tokens used in staking protocols (e.g. ETH, LPT, GRT, MATIC, …), representing the original asset
  • tTokens: tenderize’s validator specific LSTs. One underlying asset can have multiple tTokens representing assets staked towards different validators
  • Unlock NFT: a receipt as ERC-721 token, representing an amount tTokens that have been unlocked and are being unstaked
  • Maturity: time at which an unlock NFT can be withdrawn

Participants

  • tTokens holders looking to exchange their LSTs for the underlying asset instantly, at the cost of a dynamic fee based on the amount of available liquidity
  • Liquidity providers (LPs) looking to provide liquidity in the form of the underlying asset in exchange for a portion of the fees charged by the protocol
  • Sophisticated traders looking to purchase unlock NFTs for a discount based on the fee paid and the time to maturity of the unlock
  • Relayers processing unlocks that have reached maturity in return for a redemption reward, in order to replenish the assets in the pool with available unlocks

Overview

When exchanging tTokens, users receive an equivalent amount of the underlying asset minus a fee based on the available liquidity versus the total liquidity, expressed as assets (cash on hand) and liabilities (what is owed to LPs).
Upon receiving the tTokens, the protocol will unlock them, starting a timer until they become available for withdrawal. This timer is based upon the thawing period in the underlying’s token own staking system. The unlock receipt, represented as an NFT, is held in the TenderSwap’s inventory until maturity.
Time-Risk Arbitrage
Up until maturity is reached, market actors can purchase these unlock NFTs at a discount based on the slippage fee charged. The discount decays linearly to 0 as time to maturity approaches. By doing this these actors instantly replenish the capital in the pool for an additional bonus, but take on the effective time-risk remaining for the unlock. Unlock NFTs available for purchase are arranged according to the First In, Last Out (FIFO) principle. Since these should normally have the highest relative payout. Under normal utilisation of the liquidity, it’s unlikely the rates offered would be sufficient for a market maker to take on the risk. However should utilisation, and thus fees, rapidly increase the rates offered to instantly replenish capital would be attractive enough to prevent liquidity crunches.
Relayer Redemptions
Once time to maturity has been reached a redemption reward is given to any actor redeeming the unlock NFT on behalf of the protocol, withdrawing the unlocked tokens and replenishing the pool. Unlocks at maturity are ordered according to the First in, First out principle. This ensures that each unlock is withdrawn and not only unlocks that are most profitable, though in practice every redemption should be profitable.

Unlock Queue

The list of unlocks is implemented as an expandable data structure, called a double-ended queue or deque in short. This data type combines methods from a conventional queue and stack.
Stacks and queues are similar types of data structures used to temporarily hold data items (elements) until needed. When elements are needed, they are removed from the top of the data structure. The basic difference between a stack and a queue is where elements are added, elements are added to the top of a stack and to the bottom of a queue.
Using a deque elements can be removed from either the front or back, and it can easily be appended to. The queue will be ordered by time to maturity, where the front of the list are older items, and thus closer to maturity.
  • Relayers can only take Unlocks from the front of the deque, if they have reached maturity
  • Market makers can only take Unlocks from the back of the dequeue, if they haven’t reached maturity
Using multiple unlocks in batches is allowed for both user types, but only when sequentially traversing the list of unlocks starting from their respective starting point (front or back).

TenderSwap Model

TenderSwap is not a traditional AMM where token exchange and pricing occurs based on an invariant curve mapping the relation between two assets. Instead, TenderSwap acts more like a fractional reserve. Where exchange of homogenous assets occurs at a 1:1 price, but a fee is charged depending on the amount of utilised one-sided liquidity.
Utilisation of liquidity can be seen as a stochastic process where two types of events can occur:
  • Exchange event: a user exchanges tTokens for the underlying asset
  • Redemption event: An Unlock NFT is either bought by a market maker, or redeemed by a relayer after maturity
An exchange event at time
tt
, will increase the utilisation of the liquidity compared to the last event at
t1t-1
, increase the fee charged. A redemption event at time
tt
, will decrease the utilisation of the liquidity compared to the last event at
t1t-1
, decreasing the fee for future exchange events.

Utilisation Rate

The utilisation rate measures the current general amount of liquidity used, i.e. pending withdrawal, versus the total amount of liquidity available. In the system this is represented as total unlocks
UU
, divided by liabilities (what is owed to LPs)
LL
, giving us the general utilisation rate
rr
as a number between 0 and 1.
r[0,1]=ULULr \in [0,1] = \frac{U}{L} \rightarrow U \leq L

Utilisation Spread

Each tToken has its own utilisation spread based on the amount of withdrawals it has outstanding versus its supply, the resulting value is then normalised against the pool average to acquire a relative weight. This spread acts as an amplifier to the utilisation fee when one particular tToken sees a lot of sale volume in a short period of time.
We must first calculate the denormalised weight for a token
ii
by dividing the amount of unlocks it is using
uiu_i
by its supply
sis_i
. We can then normalise the resulting values by dividing it by the average of all tokens with outstanding unlocks.
wi=uisi+ui×j=1nsj+ujj=1nuj w_i = \frac{u_i}{s_i + u_i} \times \frac{\sum_{j=1}^{n} s_j + u_j }{\sum_{j=1}^{n} u_j}
The final result is a relative weight that takes into account both the number of withdrawals pending for a specific tToken and the supply of the specific tToken. This relative weight can be used to determine how much of a fee a specific tToken should be charged when it is redeemed.

Fee Model

The utilisation fee for a particular tToken is based upon its utilisation spread and the current general utilisation.
Base Fee
A base fee of 5 basis points (0.05%) is charged on every exchange to ensure that there is a minimum incentive for redemptions of unlocks to take place.
Utilisation Fee
We want the utilisation fee to be low when utilisation is low, and rapidly increase when utilisation is very high and might result in a liquidity crunch. To achieve this we express the fee
f(r)f(r)
as a polynomial in function of the utilisation rate
rr
, resulting in a ratio. between 0 and 1.
f(r)=rkrk[0,1]f(r) = {r^k} \rightarrow r^k \in [0,1]
Spread
A
ii
has a spread
wiw_i
, which is a relative weight based on its liquidity usage versus the average liquidity usage for all tTokens. This weight acts as a multiplier on the base fee. tTokens with a high impact on liquidity will pay significantly more than the base fee, while tTokens with a small impact compared to their relative size will pay less.
Marginal Fee
To calculate the marginal fee, we look at the amount, the weight after the hypothetical trade and the ratio after the trade.
If an amount of
xx
is swapped for a tToken
ii
, the weight
wiw_i
and ratio
rr
after the swap would be
wi=ui+xsix+ui+xxx+j=1n(sj+uj)x+j=1nuj=ui+xsi+uiU+SU+xw_i = \frac{u_i + x}{s_i - x + u_i +x} \cdot \frac{x - x + \sum_{j=1}^n (s_j + u_j)}{x + \sum_{j=1}^n u_j} = \frac{u_i + x}{s_i + u_i} \cdot \frac{U+S}{U+x}
ri=(x+j=1ujL)k=(U+xL)k\\r_i = \left(\frac{x + \sum_{j=1} u_j}{L}\right)^k = \left(\frac{U+x}{L}\right)^k
This motivates us to define the main fee function as follows
f(x)=xui+xsi+uiU+SU+x(U+xL)k f(x) = x \cdot \frac{u_i + x}{s_i + u_i} \cdot \frac{U+S}{U+x} \cdot \left(\frac{U+x}{L}\right)^k
This is not our final formula however to calculate the fee, as there is an issue. When swapping an amount
xx
the user pays
f(x)=yf(x) = y
fees. However, if the user were to partition the swapped amount
xx
into multiple swaps
x1,x2,,xnx_1, x_2, \dots, x_n
, such that
x1+x2++xn=xx_1 + x_2 + \dots + x_n = x
, then it's often true that the sum of the resulting fees
f1(x1)=y1,f2(x2)=y2,,fn(xn)=yn f_1(x_1) = y_1, f_2(x_2) = y_2, \dots, f_n(x_n) = y_n
would be lower
(y1+y2++yn<y(y_1 + y_2 + \dots + y_n < y
) than if the swap were not partioned.
It always holds that
y1+y2++ynyy_1 + y_2 + \dots + y_n \leq y
, a fact that is proven in the yellow paper, given the constrictions of the parameters:
0xmin(si,LU)0sS0uU0L0 \leq x \leq \min(s_i, L-U)\\0\leq s \leq S\\ 0 \leq u \leq U\\ 0 \leq L
Also, note the subscript of
ff
. This is done, because after unlocking an amount of
x1x_1
,
uiu_i
and
sis_i
will change, and hence the fee function changes.
Below is an example illustrating this behaviour, as well as our solution to make sure that
(y1+y2++yn=y(y_1 + y_2 + \dots + y_n = y
. Let the system state have the following parameters
ui=10,si=30,U=90,S=200,L=200,k=2u_i=10, s_i=30,U=90, S=200,L=200,k=2
A user comes in and swaps 10 tokens (
x=10x=10
). For this swap the fee paid is
f(x)=3.625f(x) = 3.625
If the user were to partition this swap into
x1=2x_1=2
and
x2=8x_2=8
, the fee would be lower and instead be
f1(2)+f2(8)3.3 f_1(2) + f_2(8) \approx 3.3
If we change the order the swap is partitioned in, the resulting fee will be even lower
f1(8)+f2(2)3.2828 f_1(8)+f_2(2) \approx 3.2828
This requires us to create a function which conceptually would express what the least amount of fee paid by a user, regardless of if and how a swap is partitioned. This brings us to the partitioned fee function, which forms the lower bound of every possible way of partitioning a swap. The partitioned fee function is found to be:
ϕ(x)=(S+U)(((u+x)kU+u)(U+xL)k(ukU+u)(UL)k)k(k+1)(u+s)\phi(x) = \frac{(S+U) \cdot \left(\left((u+x)\cdot k - U + u\right)\cdot\left(\frac{U+x}{L}\right)^k-\left(u \cdot k - U + u\right)\cdot\left(\frac{U}{L}\right)^k\right)}{k \cdot (k+1) \cdot (u+s)}
The derivation of this formula is far from trivial and outside of the scope of this paper. If one is interested in the derivation, and the proof that this function forms the lower bound of all possible partitions, please refer to the yellow paper.
Using this function in our example, we can indeed see that:
ϕ(10)=ϕ1(8)+ϕ2(2)=ϕ1(2)+ϕ2(8)2.598\phi(10) = \phi_1(8) + \phi_2(2) = \phi_1(2)+\phi_2(8) \approx 2.598
Even though this is only one example, in the yellow paper it is proven that regardless of how a swap is partitioned, the result for the sum of parts will always be equal to the whole. Analogous, the following example yields an identical result as well:
ϕ1(1)+ϕ2(2)+ϕ3(3)+ϕ4(4)=ϕ1(4)+ϕ2(3)+ϕ3(2)+ϕ4(1)2.598\phi_1(1)+\phi_2(2)+\phi_3(3)+\phi_4(4) = \phi_1(4)+\phi_2(3)+\phi_3(2)+\phi_4(1) \approx 2.598
That concludes our motivation to choose the partitioned fee function,
ϕ\phi
, as the fee function that is used in Tenderswap.

Fee Distribution

Fee distribution is flexible, and are redistributed to incentives where they are most needed. Fees charged for utilisation for a pool are handled two ways depending on whether an unlock has reached maturity.
Under normal operations, when liquidity utilisation is considered healthy, the bulk of the fees is distributed to liquidity providers and relayers (for processing withdrawals). The protocol could also retain a portion of the fees to create additional ecosystem incentives, or build up a treasury of protocol owned liquidity.
However under high load, the fee charged for an exchange is used as an incentive for sophisticated traders or market makers to purchase the unlock NFT created during the exchange. Hereby market makers take over the time risk until maturity from the protocol, in return for instantly replenishing the underlying assets that would otherwise be replenished at maturity. Since risk decreases as time to maturity decreases, the possible reward linearly decreases to 0 as it approaches. The remainder of the reward not paid out is then distributed to liquidity providers. The possible reward at any point in time
tt
, is calculated by multiplying the original fee by the decay rate
d(t)d(t)
at point
tt
.
reward(t)=fee×d(t)reward(t) = fee \times d(t)
The decay rate
d(t) d(t)
is calculated by taking the remaining time to unlock divided by the total unlock time.
Once an unlock reaches maturity its fee (or reward) is no longer isolated, but enters in a bucket of matured unlocks. This bucket is then used to pay relayers to redeem matured unlock NFTs and complete the withdrawal on behalf of the pool. The amount received by a relayer equals the pro-rata share of the bucket based on the size of the unlock.

Providing Liquidity

Liquidity providers can deposit their tokens to earn a pro-rate portion of the fees generated by exchange events. While in theory there is no impermanent loss in this model, LPs must be aware that they might be forgoing instant access to their capital, depending on the utilisation rate of the pool. If not enough assets are available to provision the withdrawal of an LP, the LP will enter in a priority queue to be able to withdraw the assets as redemption events occur.
Given that fee distribution is deferred until a redemption event occurs, new LPs will only start earning rewards after one duration of the unlock window has elapsed. Otherwise an attack vector to earn a risk-free reward could occur where a redemption event is sandwiched between a LP deposit and withdraw.

Recovery Mode

Under very extreme conditions (e.g. slashing) it is possible that the amount exchanged is less than the amount eventually unlocked and redeemed by TenderSwap. This would result in a haircut loss for liquidity providers, which isn’t ideal. To prevent this risk we will enter ‘recovery’ mode when TenderSwap detects that a slash occurred on one of the unlocks held in its inventory.
During recovery mode, market makers can no longer buy up NFTs at a discount. All unlocks much reach their maturity and be redeemed by relayers at this point. The fees from the unlocks will replenish the assets that are missing to make liquidity providers whole. The tToken that incurred the slash will see an increased spread, until its debt is paid off.