Here we are about to explain the process behind QuipuSwap. For a prior basic understanding of what QuipuSwap actually is, please, check out our previous article.
We totally get that the explanation of an algorithm can be quite complicated, but we tried to hit a medium (no pun intended) to make a technical explanation yet comprehensible for the readers of different backgrounds.
Exchange pair creation
Meet John, an online entrepreneur, who operates his own e-commerce website. John wants to tokenize his e-commerce “ vouchers” and with Tezos he successfully creates his own token.
John doesn’t want to get involved with any trade platforms and provide market-making — he just wants to proceed with his business development. Nevertheless, it’s essential for his customers to have at least one easy way to exchange that Token.
Thus John has found QuipuSwap and now sees numerous possibilities for its application. He sees that every exchange pair has so-called tokens pools:
- Tokens(tokenPool) — tokens on Tezos network
- Tezos coins(tezPool) — XTZ
Also, John discovers an interesting detail — every exchange pair has several abstractions:
- totalShares — conventional units displaying the share of the total contribution
- shares of every liquidity provider — conventional units displaying the share of each contributor
Let’s imagine that John finds this solution suitable for his business and goes to the interface to set up a new exchange pair. John as the first liquidity provider initializes the exchange process where he inputs the address of his smart contract and sends tokens and Tezos to the exchange address. His current setup looks like this:
- tezPool —the amount in Tezos he would like to make available for exchange (let it be 100 XTZ ≈ 300$)
- tokenPool — the number of his own tokens (let it be 20 Tokens)
Now his “share” and “totalShares” of his exchange pair equals 1000. The price of one “voucher” is 15$ in that case. John will receive all exchange fees from this trading pair, of course, if anybody uses it 🙂
Let’s say there’s another user named Bob in the Tezos ecosystem, one of John’s customers with a few “vouchers”. He wants to add liquidity to this exchange pair. Thus Bob allows the smart contract to spend the exact amount of Tokens from his address and sends the exact amount of Tezos (amount) and setting up a minimal share (minShares), which he wants to receive. Here are the calculations:
- tezPerShare = tezPool / totalShares - price of "share" in XTZ - sharesPurchased = amount / tezPerShare - share, which user would reiceve after XTZ send
If sharesPurchased not less than minShares, then the contract is to calculate the number of Tokens on each “share” and the price of “sharesPurchased” in Tokens. Tokens are debited from Bob’s account. After that, the “Pools” and “Shares” get updated to:
tokensPerShare = tokenPool / totalShares - price of "share" in Tokens tokensRequired = sharesPurchased * tokensPerShare - total price of acquired share - Actions of Tokens debit Balance updates: shares[sender] += sharesPurchased tezPool += amount tokenPool += tokensRequired
So, if Bob tried to provide two “voucher” Tokens he would need to place 2 Tokens and 10 XTZ (≈ $30).
In case something has changed and he would like to receive his Tokens and XTZ back, he may indicate which share he would like to receive back (sharesBurned) and how many of minimum tokens (minTokens) or abstracts (minTez) when withdrawing the funds. Everything vice versa to providing liquidity:
- tezPerShare = tezPool / totalShares - price of "share" in XTZ - tokensPerShare = tokenPool / totalShares - price of "share" in Tokens - tezDivested = tezPerShare * sharesBurned - how much Tezos user will receive - tokensDivested = tokensPerShare * sharesBurned - how much Tokens user will receive If "minTokens" and "minTez" are OKBalances update: shares[sender] -= sharesBurned tezPool -= tezDivested tokenPool -= tokensDivested invariant = tezPool * tokenPool Sending tokensDivested and Tezos`tezDivested
But now Alice comes into our game. She wants to buy a “voucher”. So, in exchange she sends one currency — XTZ in our case (_CURRENCY_In), setting up a minimal sum of Tokens (min_CURRENCY_Out) that she wants to receive in exchange:
fee = tezIn / feeRate - fees calculation, 0.2% now newTezPool += tezIn tempTezPool = newTezPool - fee newTokenPool = invariant / tempTezPool tokensOut = tokenPool / newTokenPool If "minTokensOut" OK and exchange have enought tokens tezPool = newTezPool tokenPool = newTokenPool Sending tokens "tokensOut"
She spends 5 XTZ and will get =
5 XTZ (exchange amount) /
100 XTZ (old Tezos pool)+ 5 XTZ (exchange amount) / 20 Tokens (amount of Tokens in pool)
She will receive 5/((100+5)/20) ≈ 0.9524.
In this example, we can see that the price goes up because of the increasing demand.
Worth noticing: every pair is a separate contract with unique liquidity, balances, rates. You will need to deploy your own contract for every new pair.
We have finished a few things:
- Fees for liquidity providers
- The concept of providing liquidity and delegating stake at the same time (governance and consensus on how liquidity providers will choose Baker are still in progress)
- Concept of “fabric” — the automatic creation of new pairs for exchange
- Started to develop SDK
- Logo and design concepts
Check it out
QuipuSwap — main repo with all the code
Check out our projects on GitHub