This doc is related to basic implementation of Uniswap V1 and which is maintained in:
- Contracts :
/contracts/amm/uniswap-v1/ - Tests:
/test/amm/uniswap-v1
All the functions are properly documented. Hence we will just explain how we got the formula in the pricing function getAmount.
First of all, if you are not familiar with DEX then get familiar with:
Uniswap is a leading DEX. There have been 3 versions. this tutorial focuses on the 1st version v1 and which was launched in November 2018. The documentation of Uniswap V1 can be found here.
An exchange is a ETH-ERC20 liquidity pool. Allowing :
- Liquidity providers (LP) can deposit equivalent amout of ETH & ERC20 and get liquidity pool tokens in exchange. Allowing them to collect fees on ETH <-> ERC20 swaps
- Users can swap ERC20 for ETH and vice-versa. Fees are 0,3 % per swap
A factory allows creation & deployment of any ETH-ERC20 exchange. Allowing:
- Keep track of all ETH-ERC20 exchanges
- Any ETH-ERC20 can support token to token swaps. E.g. : Let say there is a ETH-LINK exchange & ETH-USDT exchange. One can trade LINK for USDT in a single transaction (ETH is used as a bridge between both exchanges)
The pricing of ETH-ERC20 is based on the constant product formula:
In order to buy some amount of token B, one must sell a proportional amount of token B while maintaining k constant (cf. curve below).
Therefore, after a given amount of token A are sold for tokens B , we still maintain the k constant.
Combining (1) and (2) :
We can then have an equation which gives us the relantionship between amount bought of Token B Δy(aka outputAmount) and the other variables which are known:
- x: current amount of token A (aka token A reserve)
- y : current amount of token B (aka token B reserve)
- Δx : sold amount of token A (aka inputAmount)
Note that this equation is not final as it doesn't take the fees into account. The fees in Uniswap v1 are 0,3%. Fees are always taken from the inputAmount :
Now if we combine (5) and (6):
which is the getAmount function in Exchange.sol:
function getAmount(
uint256 inputAmount,
uint256 inputReserve,
uint256 outputReserve
) private pure returns (uint256 outputAmount) {
require(inputReserve > 0 && outputReserve > 0, "Reserves cannot be null");
uint256 inputAmountWithFee = inputAmount * 997;
uint256 numerator = inputAmountWithFee * outputReserve;
uint256 denominator = (1000 * inputReserve + inputAmountWithFee);
outputAmount = numerator / denominator;
}
- Uniswap V1 Whitepaper
- Ivan Kuznetsov posts on uniswap:







