Skip to content

Add Base network support (chainId 8453) - #14

Merged
szhygulin merged 1 commit into
mainfrom
feat/base-chain-support
Apr 14, 2026
Merged

Add Base network support (chainId 8453)#14
szhygulin merged 1 commit into
mainfrom
feat/base-chain-support

Conversation

@szhygulin

Copy link
Copy Markdown
Collaborator

Summary

  • Adds Base as a first-class SupportedChain across the server: core types (CHAIN_IDS.base = 8453, CHAIN_ID_TO_NAME[8453] = "base", SUPPORTED_CHAINS), viem chain registration, Infura/Alchemy/custom RPC URL templates, BASE_RPC_URL env var, DefiLlama (base) and Basescan (api.basescan.org) endpoints, and NATIVE_SYMBOL.base = "ETH".
  • Wires contract addresses for the protocols with canonical Base deployments:
    • Aave V3 — PoolAddressesProvider, UiPoolDataProvider, Pool (hard-pinned so the pre-sign check's allowlist can't be forged by a compromised RPC).
    • Uniswap V3 — Factory + NonfungiblePositionManager.
    • Compound V3 — cUSDCv3, cUSDbCv3 (legacy bridged USDC market), cWETHv3.
    • Tokens — native USDC, USDbC, DAI, WETH, cbETH.

Deliberately NOT enabled on Base in this PR

  • Lido / EigenLayer — L1-only protocols. The staking readers already short-circuit when CONTRACTS[chain].lido / eigenlayer is absent, matching how Polygon is handled.
  • Morpho Blue — Morpho is deployed on Base at the same address as mainnet, but the event-log discovery path in src/modules/morpho/discover.ts needs a verified deployment block to start eth_getLogs from. Guessing risks silently missing positions (block too high) or wasting RPC budget (too low). A tripwire test asserts the absence so the deferral doesn't get silently undone.

Tests

  • test/chains.test.ts — new cases for Base RPC resolution (env override + Infura/Alchemy provider URLs).
  • test/base-chain-support.test.ts (new) — locks down chain-registration invariants: chainId, native symbol, viem Chain wiring, Aave Pool pinned to the canonical Base deployment, Uniswap + Compound present, USDC + WETH addresses pinned, Lido/EigenLayer/Morpho absent.
  • test/session-regression.test.ts — the existing EIP-55 checksum invariant automatically extended to the new addresses and caught two bad checksums during implementation (now fixed).

Test plan

  • npm run build — clean
  • npm test — 235 tests pass (up from 209)
  • Manual: configure a Base RPC URL and call get_token_balance / get_lending_positions / get_portfolio_summary with chain: "base" against a known wallet; verify Aave V3 and Compound V3 Base positions show up.
  • Manual: run recon-crypto-mcp-setup and confirm the new "Base RPC URL" prompt appears in the custom-provider flow.

🤖 Generated with Claude Code

Adds Base as a first-class SupportedChain across the server: core types,
RPC/provider URLs and setup prompts, DefiLlama pricing, Basescan, and
contract registrations for the protocols that have canonical Base
deployments.

Protocols enabled on Base:
- Aave V3 (pinned Pool address for the pre-sign allowlist)
- Uniswap V3 (Factory + NonfungiblePositionManager)
- Compound V3 (cUSDCv3, cUSDbCv3, cWETHv3)

Protocols deliberately NOT enabled on Base in this PR:
- Lido and EigenLayer — L1-only; readers already short-circuit when
  the relevant key is missing from CONTRACTS[chain].
- Morpho Blue — deployed on Base but the discovery scan in
  modules/morpho/discover.ts needs a verified deployment block to
  start the getLogs walk from. Adding it with a wrong block would
  either silently miss positions (too high) or burn RPC budget (too
  low). Tripwire test in base-chain-support.test.ts asserts this
  absence so the deferral isn't undone by accident.

Tests:
- chains.test.ts gets Base RPC resolution cases (env override,
  Infura/Alchemy provider URL).
- base-chain-support.test.ts locks down the chain-registration
  invariants: CHAIN_IDS[base]==8453, ETH as native symbol, viem Chain
  wired, Aave Pool hard-pinned, Uniswap + Compound present, USDC +
  WETH addresses pinned, Lido/EigenLayer/Morpho absent.
- session-regression.test.ts's EIP-55 checksum invariant
  automatically covered the new addresses and caught two bad
  checksums during implementation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@szhygulin
szhygulin merged commit a4cb58d into main Apr 14, 2026
2 checks passed
@szhygulin
szhygulin deleted the feat/base-chain-support branch April 25, 2026 02:14
szhygulin added a commit that referenced this pull request Apr 28, 2026
feat(security): Invariant #14 — durable-binding source-of-truth verification (#460)
szhygulin added a commit that referenced this pull request Apr 28, 2026
Beyond adversarial cases (prompt injection, rogue subagent, malicious
skill, deliberately rogue agent), a safety-tuned non-injected agent
can still produce harmful behavior through hallucinated addresses /
chain IDs, stale knowledge of deprecated contracts, post-training-
cutoff protocols, long-context attention drift, sycophancy under
user pressure, cross-tool reasoning gaps, numeric mistakes, and
tool-name confusion.

Threat-model-wise these are functionally equivalent to a narrow
agent compromise: the agent emits bytes / advice / args that don't
match user intent, with no adversarial intent required. Two edits:

1. "Why trust VaultPilot?" preamble — explicit second paragraph
   naming the honest-model-error category alongside the adversarial
   cases, with the user-facing implication that benign-looking
   responses should not be trusted more than adversarial ones.

2. "Threat → what catches it" — new bullet listing each model-error
   sub-class and which specific defenses (PREPARE RECEIPT, Inv #1.a,
   Inv #2.5, Inv #14, Inv #15, agent-side ABI decode, Ledger device
   display, skill-side unconditional refusals) catch it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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

Successfully merging this pull request may close these issues.

1 participant