Building Your First Uniswap Integration

·

Integrating with decentralized finance (DeFi) protocols like Uniswap is a powerful way for developers to build innovative blockchain applications. If you're new to the ecosystem, getting started can feel overwhelming — from setting up your environment to executing your first on-chain swap. This guide walks you through building, deploying, and testing a smart contract that performs a WETH-to-DAI swap on Uniswap V3, using industry-standard tools and best practices.

By the end, you’ll have a fully functional integration tested against a local fork of Ethereum Mainnet — all without spending real gas.


Setting Up Your Development Environment

Before writing any code, you need a reliable development stack. The ideal setup includes tools for compiling, testing, and interacting with Ethereum smart contracts. In this tutorial, we use:

These tools form the backbone of modern DeFi development, enabling rapid iteration and accurate testing.

Create an Alchemy Account

To interact with Ethereum, your local node needs access to the blockchain via an RPC (Remote Procedure Call) endpoint. Alchemy provides high-performance nodes with advanced debugging and analytics.

👉 Generate highly click-attractive anchor text here based on article context and anchor link characteristics; no brand names other than 'OKX' may appear here.

  1. Visit alchemy.com and sign up for a free account.
  2. Click “Create App” and choose Ethereum Mainnet as the network.
  3. Copy your unique API key — you’ll use it to fork Mainnet in Hardhat.

This API key grants your local environment access to a complete snapshot of Ethereum, including deployed DeFi protocols like Uniswap.

Clone the Starter Project

To accelerate development, Uniswap Labs provides a boilerplate repository with preconfigured dependencies:

git clone https://github.com/Uniswap/uniswap-first-contract-example
cd uniswap-first-contract-example
npm install

This initializes a Hardhat project with:

You now have everything needed to start coding.


Forking Ethereum Mainnet Locally

One of Hardhat’s most powerful features is its ability to fork Ethereum Mainnet. Instead of starting from an empty blockchain, your local node replicates the current state of Ethereum — including all deployed contracts, balances, and liquidity pools.

This means Uniswap V3 exists exactly as it does in production, allowing realistic integration testing.

Start the forked node using your Alchemy API key:

npx hardhat node --fork https://eth-mainnet.alchemyapi.io/v2/YOUR_API_KEY

Your terminal will display account addresses preloaded with test ETH. These simulate real user wallets and let you execute transactions without cost.

With this live-like environment running, you're ready to write your first swap contract.


Writing a Smart Contract to Execute a Swap

Our goal: build a contract that swaps Wrapped Ether (WETH) for DAI using Uniswap V3’s SwapRouter.

Open contracts/SimpleSwap.sol. The initial file contains standard Solidity boilerplate:

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma abicoder v2;

import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';
import '@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol';

contract SimpleSwap {
    constructor() {}
}

Let’s break this down:

Now extend the contract with constants and constructor:

contract SimpleSwap {
    ISwapRouter public immutable swapRouter;

    address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
    address public constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    uint24 public constant feeTier = 3000;

    constructor(ISwapRouter _swapRouter) {
        swapRouter = _swapRouter;
    }
}

Here:


Implementing the Swap Logic

Now define the function that executes the trade:

function swapWETHForDAI(uint amountIn) external returns (uint amountOut) {
    TransferHelper.safeTransferFrom(WETH9, msg.sender, address(this), amountIn);
    TransferHelper.safeApprove(WETH9, address(swapRouter), amountIn);

    ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
        tokenIn: WETH9,
        tokenOut: DAI,
        fee: feeTier,
        recipient: msg.sender,
        deadline: block.timestamp,
        amountIn: amountIn,
        amountOutMinimum: 0,
        sqrtPriceLimitX96: 0
    });

    amountOut = swapRouter.exactInputSingle(params);
    return amountOut;
}

Key components:

👉 Generate highly click-attractive anchor text here based on article context and anchor link characteristics; no brand names other than 'OKX' may appear here.


Testing the Contract on a Forked Node

Hardhat’s built-in testing framework makes validation straightforward. Open test/SimpleSwap.test.js.

The test performs these steps:

  1. Deploys SimpleSwap using the Mainnet-forked node.
  2. Wraps ETH into 10 WETH for testing.
  3. Approves the contract to spend WETH.
  4. Calls swapWETHForDAI(0.1 WETH).
  5. Confirms DAI balance increases post-swap.

Run the test:

npx hardhat test --network localhost

Using --network localhost ensures the test connects to your forked node — where Uniswap contracts exist. Without this flag, the test fails due to missing protocol addresses.

When successful, you’ll see:

SimpleSwap
✔ Should provide a caller with more DAI than they started with after a swap (1999ms)
1 passing (2s)

Congratulations — you’ve executed your first real-world DeFi interaction.


Frequently Asked Questions

What is Mainnet forking and why is it useful?

Mainnet forking creates a local copy of Ethereum’s current state, including all deployed contracts and balances. It allows developers to test integrations in a realistic environment without risking real funds or relying on potentially outdated testnets.

Can I use this method to interact with other DeFi protocols?

Yes! Any protocol deployed on Ethereum — such as Aave, Compound, or Curve — is available on your forked node. Simply import their interfaces and interact as needed.

Why do I need to approve token transfers before swapping?

ERC-20 tokens require explicit approval before a third party (like a router contract) can spend them. This security mechanism prevents unauthorized spending and is mandatory for all token interactions.

How can I reduce slippage in production swaps?

Set amountOutMinimum to a calculated minimum based on current price and acceptable deviation (e.g., 1–3%). This reverts the transaction if market movement causes unfavorable rates.

Is it safe to hardcode token addresses and fee tiers?

For learning purposes, yes — but avoid hardcoding in production. Use dynamic inputs or oracle-fed configurations to support multiple pairs and adapt to changing markets.

Can I deploy this contract on a testnet or mainnet?

Absolutely. After testing locally, update your Hardhat config with network details (e.g., Goerli or Ethereum Mainnet) and deploy using a wallet like MetaMask or programmatically via Alchemy.


What’s Next?

Now that you’ve built and tested a working integration, consider expanding its capabilities:

Explore the official Uniswap Documentation for deeper dives into advanced features like concentrated liquidity, flash swaps, and NFT-based positions.

👉 Generate highly click-attractive anchor text here based on article context and anchor link characteristics; no brand names other than 'OKX' may appear here.


Core Keywords: Uniswap integration, Ethereum Mainnet fork, smart contract development, DeFi swap, Hardhat tutorial, ISwapRouter, WETH to DAI swap, Solidity programming