Try   HackMD

Flashloan fee of Uniswap v2

tags: uniswap flashloan fee uniswap-v2

Refer to Uniswap v2 Whitepaper, each swap should satisfy following formula:

\[ (x_1 - 0.003 \cdot x_{in}) \cdot (y_1 - 0.003 \cdot y_{in}) \ge x_0 \cdot y_0 \tag{1} \]

To simplify the calculation on-chain:

\[ (1000 \cdot x_1 - 3 \cdot x_{in}) \cdot (1000 \cdot y_1 - 3 \cdot y_{in}) \ge 1000000 \cdot x_0 \cdot y_0 \tag{2} \]

When we flash loan from Uniswap v2 pair, what is the amount including fee we should repay?

Suppose we flash loan amount of token \(y\): \(y_{out}\).

\(x_{in}\) and \(y_{in}\) are the amount of token \(x\) and token \(y\) to repay.

\(x_0\) and \(x_1\) are the balance of token \(x\) before and after flash loan, respectively, \(y_0\) and \(y_1\) are the balance of token \(y\) before and after flash loan.

The problem is to calculate \(y_{in}\) using \(y_{out}\).

Since we don't flash loan token \(x\), so \(x_{in} = 0\), \(x_{out} = 0\), \(x_0 = x_1\), we can simplify formula (2):

\[ 1000 \cdot y_1 - 3 \cdot y_{in} \ge 1000 \cdot y_0 \tag{3} \]

\[ y_1 - y_0 \ge \frac{3}{1000} \cdot y_{in} \tag{4} \]

The relation between \(y_{in}\) and \(y_{out}\) is:

\[ y_{in} = y_1 - ( y_0 - y_{out}) \tag{5} \]

Using formula (4) and (5):

\[ y_{in} - y_{out} \ge \frac{3}{1000} \cdot y_{in} \tag{6} \]

We can calculate \(y_{in}\):

\[ y_{in} \ge \frac{1000}{997} \cdot y_{out} \tag{7} \]

In Solidity contract, to avoid rouding down error, we should add 1 to round up:

uint256 repayAmount = amountOut.mul(1000).div(997).add(1)

where repayAmount is \(y_{in}\), amountOut is \(y_{out}\).

So the flashloan fee of Uniswap v2 is:

\[ \frac{1000}{997} - 1 \approx 0.0030090271 \approx 0.30090271\% \tag{8} \]