-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdex.tex
147 lines (119 loc) · 5.34 KB
/
dex.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
\let\mypdfximage\pdfximage
\def\pdfximage{\immediate\mypdfximage}
\documentclass{article}
\usepackage{lipsum}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage{tikz}
\usepackage{xcolor}
\usepackage{float}
\usepackage{array}
\usepackage{tabu}
\usepackage{amsfonts}
\usepackage{bold-extra}
\usepackage{multirow}
\usepackage[colorlinks=true,linkcolor=webgreen,filecolor=webbrown,citecolor=webgreen]{hyperref}
\usepackage[capitalise,noabbrev]{cleveref}
\usepackage{longtable}
\usepackage{listings}
\usepackage[a4paper]{geometry}
\tabulinesep=1.2mm
\title{DEX Specification}
\author{Tomasz Maciosowski}
\date{}
\begin{document}
\begin{center}
\vskip 10mm {\LARGE\bf
Constant Product DEX Specification
}
\vskip 10mm
Tomasz Maciosowski \\
MLabs\\
\href{mailto:[email protected]}{\tt [email protected]} \\
\end{center}
\vskip 5mm
\begin{abstract}
This document describes a simple DEX validator designed for the Cardano blockchain.
This validator allows users directly interact with the liquidity pool, and swap tokens at a predetermined fixed price in any Cardano native tokens.
The implementation of this validator will be carried out across multiple programming languages, compiled into UPLC, and tested with a uniform test suite.
While the validator is engineered with security in mind, certain functionalities necessary for a production environment may be absent.
\end{abstract}
\section{Introduction}
The validator implements a constant product liquidity pool, where users can swap tokens at a predetermined fixed price interacting with the script-owned UTxO directly, rather than through a batching/escrow contract.
Users can also deposit and withdraw liquidity from the pool, by providing the necessary pair of tokens to the script-owned UTxO, and receive a proportional amount of the pool's liquidity tokens (LP tokens) in return.
LP tokens are specific to each pool, and are used to track the amount of liquidity a user has deposited into the pool.
By burning LP tokens, users can withdraw liquidity from the pool, and receive a proportional amount of the tokens from the pool at the current exchange rate.
The design does not address concurrency issues, and is not suitable for a production environment, without utilizing tx chaining or batching which are out of scope for this specification.
\section{Pool Validator}
DEX is a constant product, meaning that after every token swap, the product of the amount of each token in the pool remains constant.
Users can interact with the Pool Validator by swapping tokens, depositing liquidity, and withdrawing liquidity.
The Pool Validator is parametrized by the following data types:
\subsection{Data Types}
\begin{lstlisting}[language=Haskell]
data Redeemer
= Swap
| DepositLiquidity
| WithdrawLiquidity
data Datum = Datum
{ tokenA :: AssetClass
, tokenB :: AssetClass
, poolNft :: AssetClass
, lpToken :: CurrencySymbol
, mintedLpTokens :: Integer
, swapFee :: Integer
}
\end{lstlisting}
\subsection{Validation Checks}
\hspace{0mm}
\textbf{Case 1: Swap}
\begin{itemize}
\item Output datum remains unchanged.
\item The product of the amount of tokens in the pool scaled down by fee did not change.
\item No LP tokens are minted.
\item Pool NFT is returned.
\end{itemize}
\textbf{Case 2: Deposit Liquidity}
\begin{itemize}
\item Square of minted LP tokens is less than or equal to the product of the tokens deposited.
\item Output datum contains the new \verb|mintedLpTokens| value with minted LP amount added.
\item Pool NFT is returned.
\end{itemize}
\textbf{Case 3: Withdraw Liquidity}
\begin{itemize}
\item Output datum contains the new \verb|mintedLpTokens| value with burned LP amount subtracted
\item The product of the amount of tokens in the pool equals the square of new \verb|mintedLpTokens| value.
\item Pool NFT is returned.
\end{itemize}
\section{Pool NFT Minting Policy}
Pool NFT is a state token that validates that the liquid pool UTxO holding it has been properly initialized.
Pool NFT Minting Policy has one redeemer used to bootstrap a new liquidity pool.
The redeemer takes the initial spent UTxO as an argument that needs to be spent in order to create a new pool.
Token name of the NFT is derived from the initial spent UTxO to ensure that only one NFT of each name will be ever created.
\subsection{Data Types}
\begin{lstlisting}[language=Haskell]
data Redeemer = CreatePool TxOutRef
\end{lstlisting}
\subsection{Validation Checks}
\begin{itemize}
\item Initial spent UTxO is spent.
\item Only one NFT is minted with name set to initial spent.
\end{itemize}
\section{LP Minting Policy}
LP tokens represent ownership of a share of the pool.
LP tokens are minted when liquidity is deposited into the pool, and burned when liquidity is withdrawn from the pool.
LP tokens are specific to each pool, and are used to track the amount of liquidity a user has deposited into the pool.
All minting and burning checks are being performed by Pool Validator, so LP Minting Policy forwards all checks to it by making sure that they are being invoked.
Minting policy is parametrized by the symbol of Pool NFT.
\subsection{Data Types}
\begin{lstlisting}[language=Haskell]
data Redeemer = ForwardCheck
\end{lstlisting}
\subsection{Validation Checks}
\begin{itemize}
\item Pool NFT is spent.
\end{itemize}
\nocite{*}
\bibliographystyle{plain}
\bibliography{bibliography}{}
\end{document}