Skip to content

[scanner] ChainProvider::connect does not validate configured chain_id against eth_chainId from RPC — testnet URL with mainnet chain_id silently accepted #248

@obchain

Description

@obchain

PR: #51 (feat/23-testnet-config)
File: crates/charon-scanner/src/lib.rs (ChainProvider::connect), crates/charon-core/src/config.rs (ChainConfig)
Refs #51

Problem

ChainConfig stores chain_id: u64 (mainnet = 56, Chapel = 97). ChainProvider::connect() establishes a WS connection but never calls eth_chainId to verify the RPC matches the configured chain.

An operator who:

  1. Copies config/testnet.toml and accidentally supplies a mainnet WS URL in the env var, or
  2. Switches --config from testnet to mainnet but forgets to update .env,

gets a bot that:

  • Connects successfully (RPC responds to WS handshake)
  • Looks up Venus Chapel Comptroller (0x94d1820b...) on BSC mainnet — address returns empty bytecode or is a different contract
  • All eth_call results are zero / revert
  • Scanner runs silently, emitting zero positions, with no indication of the mismatch

First flagged in PR #31 review (finding 2). This PR's introduction of a second chain profile makes the gap load-bearing: testnet→mainnet config promotion is now a documented operator workflow.

Impact

Silent misconfiguration. Bot appears healthy (WS connected, blocks arriving) but processes no real data. No error surface until an operator manually inspects RPC responses.

Fix

In ChainProvider::connect() (or immediately after in run_listen):

let rpc_chain_id = provider.get_chain_id().await
    .context("failed to read chain_id from RPC")?;
if rpc_chain_id != chain_cfg.chain_id {
    return Err(anyhow!(
        "chain '{}': configured chain_id={} but RPC returned chain_id={} — wrong endpoint?",
        name, chain_cfg.chain_id, rpc_chain_id
    ));
}

One eth_chainId call at startup eliminates the entire class of endpoint/config mismatch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinglayer:rustRust crates (core / scanner / protocols / executor / cli)priority:p1-coreCore MVP scopestatus:readyScoped and ready to pick up

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions