Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue: Unauthorized Error during Local Testing with CCIPLocalSimulator in CrossChainNameService Project #17

Open
meitedaf opened this issue Aug 22, 2024 · 0 comments

Comments

@meitedaf
Copy link

Issue: Unauthorized Error during Local Testing with CCIPLocalSimulator in CrossChainNameService Project

Description:

When I clone the smartcontractkit/ccip-cross-chain-name-service repository: https://github.com/smartcontractkit/ccip-cross-chain-name-service into VSCode and follow the documentation Hardhat and Foundry Integration, I install Foundry in the Hardhat project using:

npm install --save-dev @nomicfoundation/hardhat-foundry

I wanted to use CCIPLocalSimulator for local testing of the CrossChainNameService project. After running:

forge install smartcontractkit/chainlink-local --no-commit

I wrote the following test code:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import {CrossChainNameServiceLookup} from "contracts/CrossChainNameServiceLookup.sol";
import {CrossChainNameServiceReceiver} from "contracts/CrossChainNameServiceReceiver.sol";
import {CrossChainNameServiceRegister} from "contracts/CrossChainNameServiceRegister.sol";
import {Test, console} from "lib/forge-std/src/Test.sol";
import {CCIPLocalSimulator} from "lib/chainlink-local/src/ccip/CCIPLocalSimulator.sol";
import {
    IRouterClient, WETH9, LinkToken, BurnMintERC677Helper
} from "lib/chainlink-local/src/ccip/CCIPLocalSimulator.sol";

contract CrossChainNameServiceTest is Test {
    CCIPLocalSimulator public ccipLocalSimulator;
    CrossChainNameServiceRegister public ccnsRegister;
    CrossChainNameServiceReceiver public ccnsReveiver;
    CrossChainNameServiceLookup public ccnsLookup;
    uint256 public constant GAS_LIMIT = 200000;
    uint256 public constant REQUEST_LINK_AMOUT = 1 ether;
    address public Alice = makeAddr("Alice");
    uint64 public chainSelector;
    IRouterClient public sourceRouter;
    IRouterClient public destinationRouter;
    WETH9 public wrappedNative;
    LinkToken public linkToken;
    BurnMintERC677Helper public ccipBnM;
    BurnMintERC677Helper public ccipLnM;

    function setUp() public {
        ccipLocalSimulator = new CCIPLocalSimulator();
        (chainSelector, sourceRouter, destinationRouter, wrappedNative, linkToken, ccipBnM, ccipLnM) =
            ccipLocalSimulator.configuration();

        ccnsLookup = new CrossChainNameServiceLookup();
        ccnsRegister = new CrossChainNameServiceRegister(address(sourceRouter), address(ccnsLookup));
        ccnsReveiver = new CrossChainNameServiceReceiver(address(destinationRouter), address(ccnsLookup), chainSelector);

        ccnsLookup.setCrossChainNameServiceAddress(address(ccnsReveiver));
        console.log("Authorized address set to:", address(ccnsReveiver));
    }

    function testCCNSSuccess() public {
        // Arrange
        ccnsRegister.enableChain(chainSelector, address(ccnsReveiver), GAS_LIMIT);
        ccipLocalSimulator.requestLinkFromFaucet(address(ccnsRegister), REQUEST_LINK_AMOUT);
        // ACT
        vm.prank(Alice);
        ccnsRegister.register("alice.ccns");
        address expectAddress = ccnsLookup.lookup("alice.ccns");
        // Assert
        assert(expectAddress == Alice);
    }
}

Problem:

While using CCIPLocalSimulator for local testing, it seems that both sending and receiving occur on the same chain, simulating cross-chain behavior. When the following part of the test is executed:

vm.prank(Alice);
ccnsRegister.register("alice.ccns");

An issue arises.

The CrossChainNameServiceLookup contract's register function has a modifier onlyCrossChainNameService, and we need to set:

ccnsLookup.setCrossChainNameServiceAddress(address(ccnsReveiver));

However, during the execution of ccnsRegister.register("alice.ccns");, the CrossChainNameServiceRegister contract first calls the MockCCIPRouter to send the message. The CrossChainNameServiceReceiver contract’s ccipReceive function receives the message. The CrossChainNameServiceReceiver then calls the CrossChainNameServiceLookup contract's register function to map the domain name and user address to the destination chain.

Once the registration is completed on all destination chains, it tries to call i_lookup.register(_name, msg.sender) on the source chain. At this point, the CrossChainNameServiceAddress is still set to CrossChainNameServiceReceiver (ccnsReveiver), not CrossChainNameServiceRegister (ccnsRegister), causing the function to revert with an Unauthorized() error.

Addition:

If I remove the onlyCrossChainNameService modifier from the CrossChainNameServiceLookup contract’s register function and run the test again, it throws a [Revert] AlreadyTaken() error, proving that the issue exists.

Expected Solution:

Cross-chain registration should be split into two functions: one for source chain registration and another for handling cross-chain registration. Alternatively, the authorization mechanism should be adjusted to accommodate the multi-chain registration process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant