0

Can anyone help me with a foundry test? I don't know the functions when called from the test are working but for some reason, it's not when I'm importing the contract from the src the test reverting.

Here is the test that is passing

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

import {Test} from "forge-std/Test.sol";
import "forge-std/console.sol";
import {CurveSpotPrice} from "src/CurveSpotPrice.s.sol";
import "src/interfaces/IMetaPoolRegistry.sol";

import "src/interfaces/IMetaPoolRegistry.sol";
import "src/interfaces/ICurvePool.sol";

contract GetPrice is Test {
    CurveSpotPrice public spotPriceContract;
    uint256 mainnetFork;
    string MAINNET_RPC_URL = vm.envString("WEB3_INFURA_RPC");

    address immutable metaPoolRegistryContractAddress = 0xF98B45FA17DE75FB1aD0e7aFD971b0ca00e379fC;
    address immutable DAI_ADDRESS = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
    address immutable USDC_ADDRESS = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;

    address public sender = address(1337);

    address public poolAddress;

    IMetaPoolRegistry private metaPoolRegistryContract;
    ICurvePool private poolContract;

    function setUp() public {
        mainnetFork = vm.createFork(MAINNET_RPC_URL);
        // spotPriceContract = new CurveSpotPrice(metaPoolRegistryContractAddress);
    }

    function _curveMetaPool(address pool, address tokenIn, address tokenOut, uint256 amount) public returns (uint256) {
        int128 i = 0;
        int128 j = 0;
        uint128 coinIdx = 0;
        poolContract = ICurvePool(pool);

        while (i == i) {
            address coin = poolContract.coins(coinIdx);

            if (coin == tokenIn) {
                i = int128(coinIdx);
            } else if (coin == tokenOut) {
                j = int128(coinIdx);
            }

            if (i != j) {
                break;
            }
            coinIdx++;
        }
        uint256 amountsOut = poolContract.get_dy(i, j, amount);

        return amountsOut;
    }

    function getSpotPrice(address registryAddress, address[] memory tokens, uint256 realAmountIn)
        public
        returns (uint256)
    {
        metaPoolRegistryContract = IMetaPoolRegistry(registryAddress);

        poolAddress = metaPoolRegistryContract.find_pool_for_coins(tokens[0], tokens[1]);

        require(poolAddress != address(0), "No pools found");

        console.log("Pool Found %s", address(poolAddress));

        uint256 amountsOut = _curveMetaPool(poolAddress, tokens[0], tokens[1], realAmountIn);

        return amountsOut;
    }

    function testGetSpotPrice() public {
        vm.selectFork(mainnetFork);
        vm.startPrank(sender);

        // 1 ETH
        uint256 amount = 1e18;

        address[] memory tokens = new address[](2);
        tokens[0] = DAI_ADDRESS;
        tokens[1] = USDC_ADDRESS;

        uint256 amountsOut = getSpotPrice(metaPoolRegistryContractAddress, tokens, amount);

        console.log(amountsOut);

        assertGt(amountsOut, 0, "Spot price should be greater than 0");
    }
}

enter image description here

But when I'm loading the CurveSpotPrice.sol contract & calling it's methods the getSpotPrice function is failing. Here

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

import "./interfaces/IMetaPoolRegistry.sol";
import "./interfaces/ICurvePool.sol";
import "forge-std/console.sol";

contract CurveSpotPrice {
    // address public metaPoolRegistryContractAddress;
    address public poolAddress;

    IMetaPoolRegistry private metaPoolRegistryContract;
    ICurvePool private poolContract;

    constructor(address _addr) payable {
        metaPoolRegistryContract = IMetaPoolRegistry(_addr);
    }

    function _curveMetaPool(address pool, address tokenIn, address tokenOut, uint256 amount)
        internal
        returns (uint256)
    {
        int128 i = 0;
        int128 j = 0;
        uint128 coinIdx = 0;
        poolContract = ICurvePool(pool);

        while (i == i) {
            address coin = poolContract.coins(coinIdx);

            if (coin == tokenIn) {
                i = int128(coinIdx);
            } else if (coin == tokenOut) {
                j = int128(coinIdx);
            }

            if (i != j) {
                break;
            }
            coinIdx++;
        }
        uint256 amountsOut = poolContract.get_dy(i, j, amount);

        return amountsOut;
    }

    function getSpotPrice(address[] calldata tokens, uint256 realAmountIn) external returns (uint256) {
        poolAddress = metaPoolRegistryContract.find_pool_for_coins(tokens[0], tokens[1]);

        require(poolAddress != address(0), "No pools found");

        uint256 amountsOut = _curveMetaPool(poolAddress, tokens[0], tokens[1], realAmountIn);

        return amountsOut;
    }
}
  • DeployCurveSpotPrice.s.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

// import {Test} from "forge-std/Test.sol";
import {Script} from "forge-std/Script.sol";
import {CurveSpotPrice} from "src/CurveSpotPrice.s.sol";
import "forge-std/console.sol";

contract DeployCurveSpotPrice is Script {
    // CurveSpotPrice public spotPriceContract;
    address immutable metaPoolRegistryContractAddress = 0xF98B45FA17DE75FB1aD0e7aFD971b0ca00e379fC;

    function run() external returns (CurveSpotPrice) {
        vm.startBroadcast();
        CurveSpotPrice spotPriceContract = new CurveSpotPrice(metaPoolRegistryContractAddress);
        console.log("Spot Price Contract deployed to: %s", address(spotPriceContract));
        vm.stopBroadcast();

        return spotPriceContract;
    }
}

  • Test fail
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

import {Test} from "forge-std/Test.sol";
import "forge-std/console.sol";
import {CurveSpotPrice} from "src/CurveSpotPrice.s.sol";
import "src/interfaces/IMetaPoolRegistry.sol";
import {DeployCurveSpotPrice} from "script/DeployCurveSpotPrice.s.sol";

contract GetPrice is Test {
    CurveSpotPrice public spotPriceContract;
    uint256 mainnetFork;
    string MAINNET_RPC_URL = vm.envString("WEB3_INFURA_RPC");

    // address immutable metaPoolRegistryContractAddress = 0xF98B45FA17DE75FB1aD0e7aFD971b0ca00e379fC;
    address immutable DAI_ADDRESS = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
    address immutable USDC_ADDRESS = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;

    address public sender = address(1337);

    //* deploy our CurveSpotPrice contract
    function setUp() external {
        mainnetFork = vm.createFork(MAINNET_RPC_URL);

        DeployCurveSpotPrice deploySpotPrice = new DeployCurveSpotPrice();
        spotPriceContract = deploySpotPrice.run();
    }

    function testGetSpotPrice() public {
        vm.selectFork(mainnetFork);
        vm.startPrank(sender);

        // 1 ETH
        uint256 amount = 1e18;

        address[] memory tokens = new address[](2);
        tokens[0] = DAI_ADDRESS;
        tokens[1] = USDC_ADDRESS;

        // console.log("Tokens: ", tokens);

        uint256 amountsOut = spotPriceContract.getSpotPrice(tokens, amount);
        console.log(amountsOut);

        assertGt(amountsOut, 0, "Spot price should be greater than 0");
    }
}

Test Failed

Repo link: https://github.com/Aviksaikat/Get-Curve-Spot-Price-Foundry

1 Answer 1

0
  • gabr1sr helped with the fix. Use vm.createSelectFork() in setUp function of test files to create and select the fork in the same statement.

Use the [rpc_endpoints] of oundry.toml to store rpc URLs.

  • foundry.toml
[rpc_endpoints]
mainnet = "${WEB3_INFURA_RPC}"

    //* deploy our CurveSpotPrice contract
    function setUp() external {
        mainnetFork = vm.createSelectFork("mainnet");

        DeployCurveSpotPrice deploySpotPrice = new DeployCurveSpotPrice();
        spotPriceContract = deploySpotPrice.run();
    }

    function testGetSpotPrice() public {
        vm.startPrank(sender);

        // 1 ETH

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.