Uniswap V3
Explore the docs Ā»
View Demo
Ā·
Report Bug
Ā·
Request Feature
Table of Contents
Arbitrage between USDC/ETH 0.3% fee pool and USDC/ETH 0.05% fee pool
To get a local copy up and running follow these simple example steps.
-
npm
npm init -y
-
hardhat
npm install --save-dev hardhat
run:
npx hardhat
verify:
npx hardhat verify --network goerli "contract address" "pair address"
-
Clone the repo
git clone https://github.com/Aboudoc/Uniswap-V3-Arbitrage.git
-
Install NPM packages
npm install
-
Dependencies
npm add @uniswap/v3-periphery @uniswap/v3-core npm add --save-dev dotenv
If you need testnet funds, use the Alchemy testnet faucet.
This project shows a simple arbitrage strategy
You can find a deep overview of Uniswap v3 in this repo
In this arbitrage example we will:
-
Borrow
USDC
from one pool -
Swap
USDC
back toWETH
in another pool -
Repay first pool with
WETH
If the amount of WETH bought back in step 2 is greater than the amount repaid in step 3, then there is profit from the the arbitrage. Otherwise there was a loss.
This function will start the arbitrage by borrowing USDC from pool0
. pool0
will send USDC to this contract and then call uniswapV3SwapCallback
Inside uniswapV3Callback, we will need to send wethAmountIn amount of WETH to pool0.
-
Encode
data
to be later decoded insideuniswapV3SwapCallback
. The data to encode aremsg.sender
,pool0
andfee1
. -
Initiate the arbitrage by calling
IUniswapV3Pool.swap
onpool0
. Below are the inputs to pass.recipient
: Address to receive output tokenzeroForOne
: Direction of the swap, true for token0 to token1amountSpecified
: Amount to swapsqrtPriceLimitX96
: Limit for the change in pricedata
: Data to be passed touniswapV3SwapCallback
Swap tokenIn
for tokenOut
by calling router.exactInputSingle
- Approve
amountIn
- Prepare
params
- Call
exactInputSingle
onrouter
and storeamountOut
This function returns amountOut
This function is called by pool0
immediately after we call IUniswapV3Pool.swap
.
amount0
is amount of USDC we borrowed. This variable will be a negative number since USDC is taken out of the pool.
amount1
is amount of WETH we owe to pool0
.
data
is the data we've encoded inside the function flashSwap
.
- Decode
data
msg.sender
must bepool0
- Store
amount0
andamount1
asusdcAmountOut
andwethAmountIn
- Call
_swap
to swap USDC for WETH and storewethAmountOut
- Repay WETH back to
pool0
. If there is profit, transfer tocaller
. Otherwise transfer the loss fromcaller
.
let's see some equations related to the arbitrage profit for a constant product AMM
First, assume that a CEX has infinite liquidity
The AMM has token X
and token Y
, and the price P = Y / X
On the CEX the price is lower, p - dp
An arbitrageur can make a profit: The difference in the token Y that he sold on the CEX and then got back from the AMM is the profit A
The green line represents the current price of the AMM. There are X0 amount of token X and Y0 amount of token Y => P = Y0 / X0
On the CEX (red line), the price is quoted as P - dp
The trade in purple will lower the price for P
to P - dp
. But before the arbitrageur can execute this trade, he first has to get dx
amount of token X
.
To do that, the arbitrageur will go to the CEX and then sell dy0
amount of token Y
to get dx
amount of token X
. Next he will go to AMM and sell this exact amount of token X
to get back in return dy1
amount of token Y
.
=> On the AMM the price has shifted from P to P - dp.
We can also write this equation in terms of price change and the amount of token X
that was sold (dx).
To do that we'll need to get two prices, the price of the CEX and the price of the AMM
Take the difference, multiply it by dx and this is the arbitrage profit
Let's start with the AMM price
Let's find the blue slope:
Let's also rewrite dy0 in terms of price and dx
We are now ready to rewrite the arbitrage profit
In some cases, we can further sumplify this equation:
Finally:
hardhat.config.js
networks: {
hardhat: {
forking: {
url: `https://eth-mainnet.alchemyapi.io/v2/${process.env.ALCHEMY_API_KEY}`,
},
},
}
Note: Replace the ${}
component of the URL with your personal Alchemy API key.
npx hardhat test test/flashSwap.test.js
You can find Uniswap pools referenced below. Select a pool with the highest TVL
You can find official Uniswap documentation below:
- [-] Maths
- [-] Test on mainnet fork
- Deploy on mainnet?
- Further reading
See the open issues for a full list of proposed features (and known issues).
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE.txt
for more information.
Reda Aboutika - @twitter - [email protected]
Project Link: https://github.com/Aboudoc/Uniswap-V3-Arbitrage.git