Building Your First Uniswap Integration

ยท

Developers new to the Uniswap ecosystem often face challenges when starting on-chain integrations with the protocol. This guide will walk you through the essential steps to overcome those initial hurdles. Here's what we'll cover:

  1. Setting up a reusable development environment for smart contracts interacting with Uniswap
  2. Running a local Ethereum node forked from Mainnet
  3. Creating a basic smart contract for Uniswap V3 swaps
  4. Deploying and testing your contract

Setting Up Your Development Environment

When building on Uniswap, choosing the right development stack is crucial. For this tutorial, we'll use:

Creating an Alchemy Account

RPC services enable off-chain clients to communicate with the blockchain. Follow these steps:

  1. Visit Alchemy and create a free account
  2. Create a new app and note your API key

Cloning the Sample Project

Get started quickly with Uniswap's boilerplate repo:

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

Forking Mainnet

Run this command to start your local Ethereum test node:

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

๐Ÿ‘‰ Learn more about Mainnet forking

Writing Your Swap Contract

We'll create a basic contract that swaps WETH for DAI. Here's the initial setup:

// 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 {
    ISwapRouter public immutable swapRouter;
    address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
    address public constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    uint24 public constant feeTier = 3000;

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

Implementing the Swap Function

Add this function to your contract:

function swapWETHForDAI(uint amountIn) external returns (uint256 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;
}

Testing Your Contract

Use this JavaScript test with Hardhat:

const simpleSwapFactory = await ethers.getContractFactory('SimpleSwap');
const simpleSwap = await simpleSwapFactory.deploy(SwapRouterAddress);
await simpleSwap.deployed();

let signers = await hre.ethers.getSigners();
const WETH = new hre.ethers.Contract(WETH_ADDRESS, ercAbi, signers[0]);
await WETH.deposit({ value: hre.ethers.utils.parseEther('10') });

const DAI = new hre.ethers.Contract(DAI_ADDRESS, ercAbi, signers[0]);
const balanceBefore = await DAI.balanceOf(signers[0].address);

await WETH.approve(simpleSwap.address, hre.ethers.utils.parseEther('1'));
await simpleSwap.swapWETHForDAI(hre.ethers.utils.parseEther('0.1'));

const balanceAfter = await DAI.balanceOf(signers[0].address);
expect(balanceAfter).is.greaterThan(balanceBefore);

Run your tests with:

npx hardhat test --network localhost

Next Steps

Continue your Uniswap journey by:

  1. Building a frontend for your contract
  2. Adding exact output swap functionality
  3. Creating a general swap contract for any ERC-20 pair
  4. Deploying to testnets

๐Ÿ‘‰ Explore advanced Uniswap integrations

FAQ

Q: Why use a Mainnet fork for development?
A: It provides all deployed protocols (including Uniswap) while saving gas costs.

Q: What's the purpose of the fee tier in Uniswap V3?
A: Different pools have different fee structures (0.05%, 0.3%, 1%). We use 0.3% (3000) for this example.

Q: How do I handle token approvals safely?
A: Always use the TransferHelper library from Uniswap for secure token transfers.

Q: Can I use this for other token pairs?
A: Yes! Just change the token addresses in the contract constants.

Q: Where can I learn more about Uniswap development?
A: Visit the Uniswap Docs for comprehensive guides.