Skip to content

Kazopl/amm-uniswap-v2-plus

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

20 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Uniswap-Style AMM (V2-based + Extensions)

License: MIT Solidity

A production-grade Uniswap V2-style Automated Market Maker with extensions including TWAP oracle, adjustable fees, and sandwich protection. Built with Foundry.

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                            AMM SYSTEM OVERVIEW                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                              β”‚   AMMRouter      β”‚
                              β”‚                  β”‚
                              β”‚ β€’ addLiquidity   β”‚
                              β”‚ β€’ removeLiquidityβ”‚
                              β”‚ β€’ swap*          β”‚
                              β”‚ β€’ getAmounts*    β”‚
                              β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                      β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚                 β”‚                 β”‚
                    β–Ό                 β–Ό                 β–Ό
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚   AMMPair    β”‚  β”‚   AMMPair    β”‚  β”‚   AMMPair    β”‚
            β”‚   (A/B)      β”‚  β”‚   (B/C)      β”‚  β”‚   (A/WETH)   β”‚
            β”‚              β”‚  β”‚              β”‚  β”‚              β”‚
            β”‚ β€’ LP tokens  β”‚  β”‚ β€’ LP tokens  β”‚  β”‚ β€’ LP tokens  β”‚
            β”‚ β€’ TWAP oracleβ”‚  β”‚ β€’ TWAP oracleβ”‚  β”‚ β€’ TWAP oracleβ”‚
            β”‚ β€’ swap()     β”‚  β”‚ β€’ swap()     β”‚  β”‚ β€’ swap()     β”‚
            β”‚ β€’ mint()     β”‚  β”‚ β€’ mint()     β”‚  β”‚ β€’ mint()     β”‚
            β”‚ β€’ burn()     β”‚  β”‚ β€’ burn()     β”‚  β”‚ β€’ burn()     β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚                 β”‚                 β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                      β”‚
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
                              β”‚  AMMFactory   β”‚
                              β”‚               β”‚
                              β”‚ β€’ createPair  β”‚
                              β”‚ β€’ getPair     β”‚
                              β”‚ β€’ setFeeTo    β”‚
                              β”‚ β€’ setSwapFee  β”‚
                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜


β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           SWAP FLOW                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

    User                Router                  Pair                 Tokens
      β”‚                    β”‚                      β”‚                     β”‚
      β”‚  swapExact...()    β”‚                      β”‚                     β”‚
      β”‚ ──────────────────►│                      β”‚                     β”‚
      β”‚                    β”‚                      β”‚                     β”‚
      β”‚                    β”‚  transferFrom(user)  β”‚                     β”‚
      β”‚                    β”‚ ◄────────────────────┼─────────────────────│
      β”‚                    β”‚                      β”‚                     β”‚
      β”‚                    β”‚  transfer(pair)      β”‚                     β”‚
      β”‚                    β”‚ ─────────────────────┼────────────────────►│
      β”‚                    β”‚                      β”‚                     β”‚
      β”‚                    β”‚  swap(out, to)       β”‚                     β”‚
      β”‚                    β”‚ ────────────────────►│                     β”‚
      β”‚                    β”‚                      β”‚                     β”‚
      β”‚                    β”‚                      β”‚  verify K invariant β”‚
      β”‚                    β”‚                      β”‚  update reserves    β”‚
      β”‚                    β”‚                      β”‚  update TWAP        β”‚
      β”‚                    β”‚                      β”‚                     β”‚
      β”‚                    β”‚                      β”‚  transfer(user)     β”‚
      β”‚                    β”‚                      β”‚ ────────────────────►
      β”‚  receive tokens    β”‚                      β”‚                     β”‚
      β”‚ ◄──────────────────┼──────────────────────┼─────────────────────│

AMM Mathematics

Constant Product Formula

The core invariant of the AMM:

x Γ— y = k

where:
  x = reserve of token A
  y = reserve of token B
  k = constant (increases with fees)

Swap Calculation

For a swap of Ξ”x tokens in:

Ξ”y = (y Γ— Ξ”x Γ— (10000 - fee)) / (x Γ— 10000 + Ξ”x Γ— (10000 - fee))

where:
  Ξ”x = input amount
  Ξ”y = output amount
  fee = swap fee in basis points (default: 30 = 0.3%)

Price Impact

Price Impact = 1 - (output_amount / (input_amount Γ— spot_price))

Spot Price = reserve_out / reserve_in

Liquidity Token Minting

First deposit:

LP_tokens = sqrt(amount0 Γ— amount1) - MINIMUM_LIQUIDITY

Subsequent deposits:

LP_tokens = min(
    (amount0 Γ— totalSupply) / reserve0,
    (amount1 Γ— totalSupply) / reserve1
)

TWAP Oracle

Time-Weighted Average Price calculation:

price0CumulativeLast += (reserve1 / reserve0) Γ— timeElapsed
price1CumulativeLast += (reserve0 / reserve1) Γ— timeElapsed

TWAP = (priceCumulative_end - priceCumulative_start) / timeElapsed

Features

AMMPair

  • Constant Product AMM: x Γ— y = k invariant
  • LP Tokens: ERC-20 liquidity provider tokens
  • TWAP Oracle: Cumulative price tracking for external use
  • Flash Loans: Borrow tokens within a single transaction
  • Skim/Sync: Balance recovery utilities

AMMFactory

  • Pair Creation: CREATE2 for deterministic addresses
  • Adjustable Fees: Configurable swap fee (max 1%)
  • Protocol Fees: Optional fee recipient for protocol revenue

AMMRouter

  • Liquidity Management: Add/remove with slippage protection
  • Token Swaps: Single and multi-hop swaps
  • ETH Support: Native ETH via WETH wrapper
  • Deadline Protection: Transaction expiration

Installation

# Clone the repository
git clone https://github.com/Kazopl/amm-uniswap-v2-plus.git
cd amm-uniswap-v2-plus

# Install dependencies
forge install OpenZeppelin/openzeppelin-contracts@v5.0.1
forge install foundry-rs/forge-std

# Build
forge build

# Run tests
forge test

Environment Setup

Create a .env file:

PRIVATE_KEY=your_private_key_here
ARBITRUM_SEPOLIA_RPC_URL=https://sepolia-rollup.arbitrum.io/rpc
ARBISCAN_API_KEY=your_arbiscan_api_key
WETH_ADDRESS=0x... # WETH on Arbitrum Sepolia

Testing

# Run all tests
forge test

# Run with verbosity
forge test -vvv

# Run unit tests
forge test --match-path "test/unit/*"

# Run fuzz tests
forge test --match-path "test/fuzz/*"

# Run invariant tests
forge test --match-path "test/invariant/*"

# Gas report
forge test --gas-report

Deployment

source .env

WETH_ADDRESS=0x... forge script script/DeployAll.s.sol:DeployAll \
  --rpc-url $ARBITRUM_SEPOLIA_RPC_URL \
  --private-key $PRIVATE_KEY \
  --broadcast \
  --verify \
  --etherscan-api-key $ARBISCAN_API_KEY

Security

Threat Model

Threat Mitigation
Reentrancy ReentrancyGuard on all state-changing functions
Price Manipulation TWAP oracle, not spot price for external use
Sandwich Attacks Slippage protection via amountMin parameters
Flash Loan Attacks K invariant check after callback
Integer Overflow Solidity 0.8.24 built-in checks
Front-Running Deadline parameter, user-set slippage
LP Drain Minimum liquidity permanently locked

Attack Surfaces

  1. MEV/Sandwich: Mitigated by slippage parameters
  2. Oracle Manipulation: TWAP smooths price over time
  3. Liquidity Removal: Proportional burning ensures fairness
  4. Flash Loans: K invariant must hold after callback

Invariants Verified

  1. reserve0 Γ— reserve1 never decreases (K invariant)
  2. LP total supply β‰₯ MINIMUM_LIQUIDITY
  3. Token balances β‰₯ reserves
  4. Swap fee ≀ MAX_SWAP_FEE_BPS

Gas Optimization

Function Gas (approx)
createPair() ~2,500,000
addLiquidity() ~150,000
removeLiquidity() ~120,000
swapExactTokensForTokens() ~100,000
mint() ~120,000
swap() ~80,000

Project Structure

amm-uniswap-v2-plus/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ AMMPair.sol          # Pair with LP tokens + TWAP
β”‚   β”œβ”€β”€ AMMFactory.sol       # Pair factory
β”‚   β”œβ”€β”€ AMMRouter.sol        # User-facing router
β”‚   β”œβ”€β”€ interfaces/
β”‚   β”‚   β”œβ”€β”€ IAMMPair.sol
β”‚   β”‚   β”œβ”€β”€ IAMMFactory.sol
β”‚   β”‚   β”œβ”€β”€ IAMMRouter.sol
β”‚   β”‚   └── IWETH.sol
β”‚   β”œβ”€β”€ libraries/
β”‚   β”‚   └── AMMLibrary.sol   # Math helpers
β”‚   └── mocks/
β”‚       β”œβ”€β”€ MockERC20.sol
β”‚       └── WETH.sol
β”œβ”€β”€ test/
β”‚   β”œβ”€β”€ BaseTest.sol
β”‚   β”œβ”€β”€ unit/
β”‚   β”‚   β”œβ”€β”€ AMMFactory.t.sol
β”‚   β”‚   β”œβ”€β”€ AMMPair.t.sol
β”‚   β”‚   └── AMMRouter.t.sol
β”‚   β”œβ”€β”€ fuzz/
β”‚   β”‚   └── AMMFuzz.t.sol
β”‚   └── invariant/
β”‚       └── AMMInvariant.t.sol
β”œβ”€β”€ script/
β”‚   β”œβ”€β”€ DeployAll.s.sol
β”‚   └── Interactions.s.sol
β”œβ”€β”€ foundry.toml
└── README.md

License

MIT License - see LICENSE for details.

Acknowledgments

About

Uniswap V2 implementation with extensions: TWAP oracle, configurable swap fees, flash loans and slippage protection

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors