Section 11 of 16

Build
+15 Lynx

Library: Helpers and Math

What You Are Building

UniswapV2Library is a stateless library that provides the mathematical foundation the Router depends on. Every swap amount calculation, every pair address lookup, every reserve fetch goes through this library.

The library contains eight functions, each building on the previous ones. By the end of this section you will have implemented all the math that powers Uniswap V2 trading.

Token Sorting

Uniswap V2 always stores tokens in ascending address order. Token0 is the token with the smaller address. This is not arbitrary. It ensures that for any pair of tokens, there is exactly one canonical ordering. Without this, you could create two pairs for the same token combination.

sortTokens takes two addresses, validates they are different and non-zero, then returns them in ascending order. Every other function in the library calls this first.

CREATE2 Address Calculation

pairFor computes the address of a pair contract without making any external calls. This is possible because the Factory uses CREATE2 to deploy pairs. The CREATE2 address formula is:

address = keccak256(0xff ++ factory ++ salt ++ init_code_hash)[12:]

The salt is the keccak256 hash of the two sorted token addresses packed together. The init code hash is a constant that depends on the pair contract's bytecode. Since the bytecode never changes, the hash never changes.

This means anyone can compute where a pair lives (or will live) without querying the blockchain. The Router uses this to find pairs instantly.

Reserve Fetching

getReserves calls the pair's getReserves() function and returns the reserves sorted to match the input token order. This is important because the pair always stores reserves as (reserve0, reserve1) based on its internal token ordering, but callers might pass tokens in any order.

The Quote Function

quote calculates the proportional amount of tokenB given an amount of tokenA and the current reserves. The formula is:

amountB = amountA * reserveB / reserveA

This is used when adding liquidity to determine how much of the second token matches a given amount of the first token at the current price ratio.

Swap Amount Calculations

The core of Uniswap V2 math lives in getAmountOut and getAmountIn.

getAmountOut: Given an exact input amount, how much output do you receive? The 0.3% fee is applied to the input:

amountInWithFee = amountIn * 997
numerator = amountInWithFee * reserveOut
denominator = reserveIn * 1000 + amountInWithFee
amountOut = numerator / denominator

The 997/1000 ratio implements the 0.3% fee. The fee stays in the pool, increasing the reserves and the value of LP positions.

getAmountIn: Given a desired output amount, how much input do you need? This is the inverse:

numerator = reserveIn * amountOut * 1000
denominator = (reserveOut - amountOut) * 997
amountIn = numerator / denominator + 1

The + 1 rounds up to ensure the pool always receives enough input. Without rounding up, precision loss could leave the pool with slightly less than expected.

Path Chaining

getAmountsOut and getAmountsIn chain the single-hop calculations across multi-hop paths. For a path [WETH, USDC, DAI]:

getAmountsOut starts with the input amount and calculates each hop forward: WETH amount in, USDC amount out (which becomes the next input), DAI amount out.

getAmountsIn starts with the desired output and calculates each hop backward: DAI amount out, USDC amount in (which becomes the next output), WETH amount in.

Your Task

Implement all eight functions in UniswapV2Library. The starter code gives you the library declaration and the INIT_CODE_HASH constant placeholder. You write everything else.

Your Code

Solution.sol
Solidity
Loading editor...

Requirements

sortTokens requires different addresses
sortTokens requires non-zero address
sortTokens uses ternary or comparison to sort
pairFor uses CREATE2 prefix
pairFor uses INIT_CODE_HASH
pairFor packs token addresses as salt
getReserves calls pair contract
getReserves sorts output by token order
quote validates amountA > 0
quote calculates proportional amount
getAmountOut applies 997 fee multiplier
getAmountOut uses 1000 in denominator
getAmountIn rounds up with + 1
getAmountIn uses 997 in denominator
getAmountsOut validates path length
getAmountsOut creates amounts array
getAmountsOut chains forward through path
getAmountsIn chains backward through path