AddLiquid

The objective is figuring out what's the ratio in the pool, and provide liquidity using that ratio.

The formula is weth_to_provide / usdc_to_provide = weth_in_pool / usdc_in_pool -> to maintain the same ratio inside the pool. Multiplying usdc_to_provide on both sides, we get weth_to_provide = (weth_in_pool * usdc_to_provide) / usdc_in_pool. (This isn't solidity naming style, but who cares)

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import "./interfaces/IUniswapV2Pair.sol";

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function transfer(address to, uint256 amount) external returns (bool);
}

contract AddLiquid {
    /**
     *  ADD LIQUIDITY WITHOUT ROUTER EXERCISE
     *
     *  The contract has an initial balance of 1000 USDC and 1 WETH.
     *  Mint a position (deposit liquidity) in the pool USDC/WETH to msg.sender.
     *  The challenge is to provide the same ratio as the pool then call the mint function in the pool contract.
     *
     */
    function addLiquidity(address usdc, address weth, address pool, uint256 usdcReserve, uint256 wethReserve) public {
        IUniswapV2Pair pair = IUniswapV2Pair(pool);

        // We provide all usdc since we have more weth than usdc
        uint256 usdc_to_provide = IERC20(usdc).balanceOf(address(this));

        // Just to align with the naming in my writeup
        uint256 weth_in_pool = wethReserve;
        uint256 usdc_in_pool = usdcReserve;

        // Figure out how much WETH to provide to maintain the pool ratio
        // We only calculate weth to provide since we know we are providing all usdc
        uint256 weth_to_provide = (weth_in_pool * usdc_to_provide) / usdc_in_pool;
        
        // Transfer tokens to the pair
        IERC20(weth).transfer(pool, weth_to_provide);
        IERC20(usdc).transfer(pool, usdc_to_provide);
        
        // Mint LP tokens to msg.sender
        pair.mint(msg.sender);
    }
}

Last updated