Swap ETH for DAI

In this simple example, we request a swap from the native ETH for DAI.

// JavaScript

public static async swapETHForDAI(wETHAddress: string, daiAddress: string) {
    // The factory of the Classic Pool.
    const classicPoolFactory: Contract = new Contract(
        this.classicPoolFactoryAddress,
        this.classicPoolFactoryAbi,
        this.provider
    );

    // Gets the address of the ETH/DAI Classic Pool.
    // wETH is used internally by the pools.
    const poolAddress: string = await classicPoolFactory.getPool(wETHAddress, daiAddress);

    // Checks whether the pool exists.
    if (poolAddress === ZERO_ADDRESS) {
        throw Error('Pool not exists');
    }

    // Gets the reserves of the pool.
    const pool: Contract = new Contract(poolAddress, this.poolAbi, this.provider);
    const reserves: [BigNumber, BigNumber] = await pool.getReserves(); // Returns tuple (uint, uint)

    // Sorts the reserves by token addresses.
    const [reserveETH, reserveDAI] = wETHAddress < daiAddress ? reserves : [reserves[1], reserves[0]];

    // The input amount of ETH
    const value = 100000000;

    // Constructs the swap paths with steps.
    // Determine withdraw mode, to withdraw native ETH or wETH on last step.
    // 0 - vault internal transfer
    // 1 - withdraw and unwrap to naitve ETH
    // 2 - withdraw and wrap to wETH
    const withdrawMode = 1; // 1 or 2 to withdraw to user's wallet

    const swapData: string = defaultAbiCoder.encode(
        ["address", "address", "uint8"],
        [wETHAddress, this.signer.address, withdrawMode], // tokenIn, to, withdraw mode
    );

    // We have only 1 step.
    const steps = [{
        pool: poolAddress,
        data: swapData,
        callback: ZERO_ADDRESS, // we don't have a callback
        callbackData: '0x',
    }];

    // If we want to use the native ETH as the input token,
    // the `tokenIn` on path should be replaced with the zero address.
    // Note: however we still have to encode the wETH address to pool's swap data.
    const nativeETHAddress = ZERO_ADDRESS;

    // We have only 1 path.
    const paths = [{
        steps: steps,
        tokenIn: nativeETHAddress,
        amountIn: value,
    }];

    // Gets the router contract.
    const router: Contract = new Contract(this.routerAddress, this.routerAbi, this.provider);

    // Note: checks approval for ERC20 tokens.
    // The router will handle the deposit to the pool's vault account.
    const response = await router.swap(
        paths, // paths
        0, // amountOutMin // Note: ensures slippage here
        BigNumber.from(Math.floor(Date.now() / 1000)).add(1800), // deadline // 30 minutes
        {
            value: value,
        }
    );

    await response.wait();
}

Last updated