Technical Overview
As previously mentioned, every swap collects a native SOL fee which is distributed among the liquidity providers and the protocol. There are four uint8 fee variables that must be initialized for every pool, corresponding to the fee distribution for both the buy and sell transactions. These variables correspond to USDC amounts for which the corresponding SOL fee is calculated on every swap using an on-chain oracle. For example, the pool could be initialized with a 10% fee for buys and 15% for sells. A user decides to sell his tokens, and he must now pay 15% worth of SOL to the protocol and liquidity providers. The protocol-assigned smart contract could use this fee to add permanently locked liquidity, establishing a rising floor price for this token and providing sustainable revenue for creators. A liquidity provider can immediately claim his entitled share of the reward the swap collected.
In this section, we describe how the liquidity provider fee is distributed, and in the next section, we elaborate on how the protocol fee is handled.
The Solavista pair smart contract maintains a sequence of ascending numbers known as Euler amounts. These values are updated each time native SOL is transferred to the pair contract. Each Euler amount is determined by adding the previous Euler amount to the ratio of the fee to the current total supply of liquidity provider tokens (LP). The initial Euler amount is set to zero.
Mathematically, this update can be represented as:
Euler_n = Euler_(n-1) + (fee / LP supply)
With the corresponding sequence of rising numbers:
{ Euler_1, Euler_2, Euler_3, Euler_4 ... Euler_n }
This sequence is particularly of interest to liquidity providers. Each provider is represented by a struct that stores the LP holdings of each user and a variable called euler0, which is suggestively named after the Euler amounts in our sequence.
struct Provider {
uint256 lp;
uint256 euler0;
};
This uint256 number represents the latest Euler amount in our sequence at the time the user adds liquidity, in which case we would have euler0 = Euler_n. Suppose the user decides to claim rewards a thousand swaps later. At that moment, the latest Euler amount is Euler_(n+1000). The exact amount of rewards that this provider accumulated during those thousand swaps is:
Reward = lp * (Euler_(n+1000) - euler0)
This approach operates under the assumption that the LP balance remains constant throughout the period. Therefore, whenever a provider takes any action, such as adding/removing liquidity, the variable euler0 will be refreshed to reflect the latest Euler amount in our sequence. This measure prevents a liquidity provider from manipulating their own share of rewards. As such, it is advisable for a liquidity provider to always claim rewards before adjusting their LP balance. LP tokens are non-transferable except when being burned or added/removed from the liquidity.
The essence of this mathematical approach lies in its ability to accurately determine the share each user receives per individual swap, regardless of the continuous changes in the total supply of LP tokens due to liquidity providers adding or removing liquidity.
Last updated