foundry icon indicating copy to clipboard operation
foundry copied to clipboard

Error with Anvil & Cast - 'Error: Contract 0x0116686e2291dbd5e317f47fadbfb43b599786ef does not exist'

Open ms4ever7 opened this issue 1 year ago • 7 comments

Component

Cast, Anvil

Have you ensured that all of these are up to date?

  • [X] Foundry
  • [ ] Foundryup

What version of Foundry are you on?

forge 0.2.0 (950d863 2023-10-25T11:55:34.079539100Z)

What command(s) is the bug in?

cast call 0x0116686e2291dbd5e317f47fadbfb43b599786ef --private-key 0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba "pairInfo()(uint, uint, uint)" --rpc-url http://127.0.0.1:8545

Operating System

Windows

Describe the bug

Hi all, I am currently in the stage of learning Solidity and the env it has, and I was suggested to use Foundry to test everything I am leaning, and its seems to be really powerfull. When I am testing the basic Counter that Foundry provide us with initizaliztion - everything works fine, but with my contract it does not.

So here is my contract:

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

import "@v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "@openzeppelin/contracts/interfaces/IERC20.sol";
import '@v2-core/contracts/interfaces/IUniswapV2Pair.sol';
import '@v2-periphery/contracts/libraries/UniswapV2Library.sol';

contract UniswapV2Swap {
    address private constant UNISWAP_V2_ROUTER =
        0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;

    address private constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    address private constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
    address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;

    IUniswapV2Router02 private router = IUniswapV2Router02(UNISWAP_V2_ROUTER);
    IERC20 private weth = IERC20(WETH);
    IERC20 private dai = IERC20(DAI);

    address public factory;
    constructor(address factory_) {
        factory = factory_;
    }
    // Swap WETH to DAI
    function swapSingleHopExactAmountIn(
        uint amountIn,
        uint amountOutMin
    ) external returns (uint amountOut) {
        weth.transferFrom(msg.sender, address(this), amountIn);
        weth.approve(address(router), amountIn);

        address[] memory path;
        path = new address[](2);
        path[0] = WETH;
        path[1] = DAI;

        uint[] memory amounts = router.swapExactTokensForTokens(
            amountIn,
            amountOutMin,
            path,
            msg.sender,
            block.timestamp
        );

        return amounts[1];
    }

    // Swap DAI -> WETH -> USDC
    function swapMultiHopExactAmountIn(
        uint amountIn,
        uint amountOutMin
    ) external returns (uint amountOut) {
        dai.transferFrom(msg.sender, address(this), amountIn);
        dai.approve(address(router), amountIn);

        address[] memory path;
        path = new address[](3);
        path[0] = DAI;
        path[1] = WETH;
        path[2] = USDC;

        uint[] memory amounts = router.swapExactTokensForTokens(
            amountIn,
            amountOutMin,
            path,
            msg.sender,
            block.timestamp
        );

        return amounts[2];
    }

    // Swap WETH to DAI
    function swapSingleHopExactAmountOut(
        uint amountOutDesired,
        uint amountInMax
    ) external returns (uint amountOut) {
        weth.transferFrom(msg.sender, address(this), amountInMax);
        weth.approve(address(router), amountInMax);

        address[] memory path;
        path = new address[](2);
        path[0] = WETH;
        path[1] = DAI;

        uint[] memory amounts = router.swapTokensForExactTokens(
            amountOutDesired,
            amountInMax,
            path,
            msg.sender,
            block.timestamp
        );

        // Refund WETH to msg.sender
        if (amounts[0] < amountInMax) {
            weth.transfer(msg.sender, amountInMax - amounts[0]);
        }

        return amounts[1];
    }

    // Swap DAI -> WETH -> USDC
    function swapMultiHopExactAmountOut(
        uint amountOutDesired,
        uint amountInMax
    ) external returns (uint amountOut) {
        dai.transferFrom(msg.sender, address(this), amountInMax);
        dai.approve(address(router), amountInMax);

        address[] memory path;
        path = new address[](3);
        path[0] = DAI;
        path[1] = WETH;
        path[2] = USDC;

        uint[] memory amounts = router.swapTokensForExactTokens(
            amountOutDesired,
            amountInMax,
            path,
            msg.sender,
            block.timestamp
        );

        // Refund DAI to msg.sender
        if (amounts[0] < amountInMax) {
            dai.transfer(msg.sender, amountInMax - amounts[0]);
        }

        return amounts[2];
    }

    function pairInfo() public view returns (uint reserveA, uint reserveB, uint totalSupply) {
        IUniswapV2Pair pair = IUniswapV2Pair(UniswapV2Library.pairFor(factory, DAI, WETH));
        totalSupply = pair.totalSupply();
        (uint reserves0, uint reserves1,) = pair.getReserves();
        (reserveA, reserveB) = DAI == pair.token0() ? (reserves0, reserves1) : (reserves1, reserves0);
    }
}

interface IWETH is IERC20 {
    function deposit() external payable;

    function withdraw(uint amount) external;

    function balanceOf(address account) external view returns (uint256);
}

Here I am tryring to write & test simple swap function but for at least getting result of pairInfo function would be enough.

I've done next steps to test it:

  • anvil - to simply have local chain where I can test everything
forge create --rpc-url "http://127.0.0.1:8545" --private-key "0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba" src/UniswapV2Swap.sol:UniswapV2Swap --constructor-args 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f
[⠆] Compiling...
No files changed, compilation skipped
Deployer: 0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc
Deployed to: 0x0116686E2291dbd5e317F47faDBFb43B599786Ef
Transaction hash: 0xc32955e9cf1ad6d1671d5c04f90911ae49a3dee1cf136e59d307e2bb35131ec7
  • deploying the contract
  • cast call 0x0116686e2291dbd5e317f47fadbfb43b599786ef --private-key 0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba "pairInfo()(uint, uint, uint)" --rpc-url http://127.0.0.1:8545 - trying to call it with cast and have next error: Error: Contract 0x0116686e2291dbd5e317f47fadbfb43b599786ef does not exist

I've also tried to do that with cast send for other function but I am not sure how to check does they work or not, as I am not so familiar with responses in foundry: image

So please let me know if I am at least on the right path to do that, I am still not sure what aruments I should provide there and should I check the liquidity or provide it at first.

Also attaching logs from anvil: image

I've tried to google that but nth, also tried to get help from AI but same result, so will appreciate any help, thank you :)

ms4ever7 avatar Nov 16 '23 17:11 ms4ever7