Skip to content

feat: Base Sepolia internal funding and controlled test USDC - #46

Merged
ameya-deshmukh merged 1 commit into
seismicfrom
adai__base-sepolia-funding
Sep 3, 2026
Merged

ameya-deshmukh merged 1 commit into
seismicfrom
adai__base-sepolia-funding

Conversation

@ameya-deshmukh

Copy link
Copy Markdown
Collaborator

Faucet counterpart to the sandbox Stage 1 rollout (Base Sepolia + standard ERC20 test USDC + native ETH gas). Everything here is additive: Seismic funding endpoints, budgets, ledger keys, and deployment commands are unchanged.

Summary

  • BaseChainDriver: standard EVM (EIP-1559) driver. The dedicated Base reserve key sends native ETH gas drips and plain ERC20 USDC transfers directly; there is no faucet contract on Base. Transactions are signed locally and persisted before broadcast, same as the Seismic driver.
  • Startup preflight (and --check-base): RPC chain id equals BASE_CHAIN_ID, signer matches INTERNAL_FUNDING_BASE_ADDRESS, token has code and six decimals, native ETH and ERC20 reserves are at or above their configured floors.
  • Routes, all under the existing bearer token, Redis idempotency, budgets, and rate limits:
    • POST /api/internal/base/gas (fixed INTERNAL_FUNDING_BASE_GAS_ETH_AMOUNT)
    • POST /api/internal/base/erc20-usdc/transfers
    • GET /api/internal/base/readiness (reports both reserve balances; 503 reserve_low below either floor)
  • Every Base idempotency key, budget, and rate window is scoped to asset + chain id + token + reserve, so a token redeploy or key rotation never replays the old ledger.
  • A Base key that reuses a Seismic funding key is refused unless INTERNAL_FUNDING_BASE_ALLOW_SHARED_KEY=true is set with explicit approval.
  • contracts/script/DeployBaseTestnetUSDC.s.sol deploys the six-decimal TestnetUSDC on Base Sepolia and mints the initial supply into the reserve; the deployer keeps mint authority. deploy_base_erc20_usdc_contract records the returned token address into the env file and runs the preflight. Integrations must read that address from configuration, never hardcode it.
  • Risk register gains a Base section.

Configuration (no values)

INTERNAL_FUNDING_BASE_ENABLED, BASE_RPC_URL, BASE_CHAIN_ID, INTERNAL_FUNDING_BASE_PRIVATE_KEY, INTERNAL_FUNDING_BASE_ADDRESS, BASE_ERC20_USDC_TOKEN_ADDRESS, INTERNAL_FUNDING_BASE_GAS_ETH_AMOUNT (wei), INTERNAL_FUNDING_MAX_BASE_ERC20_USDC_AMOUNT, INTERNAL_FUNDING_GLOBAL_BASE_GAS_ETH_BUDGET (wei), INTERNAL_FUNDING_GLOBAL_BASE_ERC20_USDC_BUDGET, optional INTERNAL_FUNDING_BASE_ETH_RESERVE_FLOOR, INTERNAL_FUNDING_BASE_ERC20_USDC_RESERVE_FLOOR, INTERNAL_FUNDING_BASE_RATE_LIMIT, INTERNAL_FUNDING_BASE_RATE_WINDOW_SECONDS, INTERNAL_FUNDING_BASE_CONFIRMATIONS, INTERNAL_FUNDING_BASE_ALLOW_SHARED_KEY; BASE_DEPLOYER_PRIVATE_KEY and BASE_ERC20_USDC_INITIAL_RESERVE_SUPPLY for the deploy script only. The human funds INTERNAL_FUNDING_BASE_ADDRESS with Base Sepolia ETH before deploying.

Test plan

  • cargo fmt --all -- --check, cargo clippy --workspace --all-targets --locked -- -D warnings, cargo test --workspace --locked (25 unit + 23 Redis integration), cargo build --workspace --release --locked
  • sforge fmt --check, sforge build, sforge test (34), bun run scripts/check-contract-abi.ts
  • New coverage: Base ledger keys scoped independently of Seismic under a shared idempotency key; concurrent gas replay signs and broadcasts once; independent budgets and rate limits; depleted reserve (insufficient funds) is a terminal 422 that never rebroadcasts; Base requests refused by a Seismic driver and vice versa; rotated deployment identity rejected; routes 401 unauthenticated and 404 when disabled; wire shape; amount limit; readiness diagnostic and 503 reserve_low
  • Consumer: SeismicSystems/orchestration#1736 and its stacked follow-ups

Not included: .env.machine-funding.example was not edited (tooling policy blocks reading env files); the variable list above is authoritative. Commit is unsigned: the signing key's agent refused from the automation shell.

Additive Base Sepolia support for the machine funding server, behind
INTERNAL_FUNDING_BASE_ENABLED. Existing Seismic routes, budgets, ledger
keys, and deployment commands are unchanged.

- BaseChainDriver: standard EVM (EIP-1559) driver where the dedicated
  reserve key sends native ETH gas drips and plain ERC20 USDC transfers;
  startup preflight checks chain id, signer/address match, token code,
  six decimals, and both reserves against configured floors
- routes POST /api/internal/base/gas, POST /api/internal/base/erc20-usdc/
  transfers, GET /api/internal/base/readiness (503 reserve_low below
  either floor); same bearer auth, Redis idempotency, budgets, rate limits
- every Base ledger key is scoped to asset + chain id + token + reserve
- refuses a Base key that reuses a Seismic funding key unless explicitly
  approved via INTERNAL_FUNDING_BASE_ALLOW_SHARED_KEY
- DeployBaseTestnetUSDC.s.sol deploys the six-decimal TestnetUSDC on Base
  and mints the initial supply into the reserve; deploy_base_erc20_usdc_
  contract alias records the returned address and runs --check-base
- risk register: Base section
@ameya-deshmukh
ameya-deshmukh merged commit f4547a6 into seismic Sep 3, 2026
4 checks passed
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