Now that we have a reliable way to add/remove liquidity from our Automated Market Maker (AMM), and liquidity provider tokens (LP tokens) to keep track of who provided our liquidity, we can create an incentive for our liquidity providers.
As the DeFi ecosystem develops, we see lots of projects trying out weird and baroque ways to incentivise different actors in different ways; especially liquidity providers. But, the original and simplest way is probably the way version 1 of Uniswap did it:
- Every time someone trades on our AMM, take a small commission (0.3% for Uniswap V1)
- Put the commission amount back into the AMM’s asset reserves
This is the code for the Uniswap V1
# @dev Pricing function for converting between ETH and Tokens. # @param input_amount Amount of ETH or Tokens being sold. # @param input_reserve Amount of ETH or Tokens (input type) in exchange reserves. # @param output_reserve Amount of ETH or Tokens (output type) in exchange reserves. # @return Amount of ETH or Tokens bought. @private @constant def getInputPrice(input_amount: uint256, input_reserve: uint256, output_reserve: uint256) -> uint256: assert input_reserve > 0 and output_reserve > 0 input_amount_with_fee: uint256 = input_amount * 997 numerator: uint256 = input_amount_with_fee * output_reserve denominator: uint256 = (input_reserve * 1000) + input_amount_with_fee return numerator / denominator
By multiplying the numerator by 997, and the denominator by 1000, the effect here is to factor in a 0.3% commission before the figure is returned and used in the trade calculation.
Although the method is called
getInputPrice, it actually returns the amount of tokens/ether bought
There is a similar adjustment in the
method, so whether the counterparty is buying tokens or selling them, the AMM
keeps 0.3% of the value of the trade.
You can see the full code here.
Liquidity providers hold LP tokens which represent their share of the AMM’s total asset reserves (ether and tokens, in our case). If a liquidity provider has tokens representing 5% of the pool’s assets, then adding the 0.3% commission from every trade to the AMM’s asset pools makes the LP tokens more valuable, creating an incentive for the liquidity provider to deposit their assets into the AMM.
Let’s see how that works out with our AMM.
Adding 0.3% commission to the AMM
We need to tweak our
trade method to incorporate the 0.3% fee:
def trade(amount, input_reserve, output_reserve) konst = @token_reserve * @ether_reserve new_input_reserve = input_reserve + amount gross_output = konst / new_input_reserve proceeds = output_reserve - gross_output proceeds_with_fee = proceeds * 0.997 new_output_reserve = output_reserve - proceeds_with_fee return [proceeds_with_fee, new_input_reserve, new_output_reserve] end
First, we work out what the output amount would be, then we reduce it by 0.3%. The net amount is what we take out of our asset pool, and give back to the counterparty. The effect is to increase the reserve of whichever asset was bought by 0.3% of the value of the trade.
Rewarding liquidity providers
To see how this rewards liquidity providers, we’ll create a script in which a liquidity provider adds liquidity to the AMM, then a bunch of trades happen, then the liquidity provider removes her liquidity again:
zoe add 10 1000 alice buy 1 alice sell all # ... repeat 99 more times ... zoe remove 10 counterparties
Now let’s see what happens (some lines omitted for clarity):
$ cat script.txt | bin/amm.rb > Amm eth: 10.0, tokens: 1000.0, price: 0.01 eth/token ... > alice gets 90.63636363636361 tokens for 1.0 ether, price 0.0110 Amm eth: 11.0, tokens: 909.3636363636364, price: 0.012096371088673398 eth/token > alice gets 0.9940089999999999 ether for 90.63636363636361 tokens, price 0.0110 Amm eth: 10.005991, tokens: 1000.0, price: 0.010005991 eth/token ... > Amm eth: 0.0, tokens: 0.0, price: NaN eth/token > alice ether: 9.4009, tokens: 0.0000, lp_tokens: 0.0000 zoe ether: 10.5991, tokens: 1000.0000, lp_tokens: 0.0000 Amm eth: 0.0, tokens: 0.0, price: NaN eth/token > bye.
When zoe removes her 100% share of the AMM’s liquidity, she’s made a profit of 0.5991 ether, all of which comes from fees extracted from the counterparties who trade on the AMM.
In this very simplified case, we had alice do all the trading. In a more realistic scenario, there would be lots of liquidity providers, and lots of counterparties trading back and forth, but the principle is the same:
more trading => more fees going into the asset reserves => LP tokens increase in value
So, we have a virtuous cycle of incentives:
- Liquidity providers want to supply liquidity to earn a profit
- More liquidity means less slippage
- With low slippage, our AMM attracts more traders
- More trading means more fees to reward liquidity providers