Skip to content

No validation for network configuration JSON (contract addresses, duplicate active versions, schema) #48

@mirhamasala

Description

@mirhamasala

Problem

The network configuration JSON (containing calibration/mainnet networks with contract deployments) has no validation layer, which could lead to runtime errors or deployment issues.

Missing Validations

1. Contract Address Format Validation

No checks that contract addresses are:

  • Properly formatted (valid hex, correct length)
  • Properly checksummed (EIP-55 format)
  • Actually valid Ethereum/Filecoin addresses

Example from current config:

"implementation": "0x88449EcAd119B6c05fa5eFB18C80d86d5781fc10"

There's no validation that these addresses are valid before the app tries to use them.

2. Multiple Active Versions

No validation to prevent multiple versions with "status": "active" within the same network. This could cause ambiguity about which contract version should be used.

Example risk:

"versions": [
  {
    "version": "v0.1.0",
    "status": "active",  // ❌ First active version
    ...
  },
  {
    "version": "v1.0.0",
    "status": "active",  // ❌ Second active version - which one is used?
    ...
  }
]

3. Schema Validation

No validation for:

  • Required fields (chainId, rpcUrl, contracts, etc.)
  • Valid status values (should be enum: "active" | "inactive" | "testing")
  • Nested contract structure completeness
  • Type correctness at runtime

4. Business Logic Validation

No checks for:

  • At least one active version per network
  • Valid version format (semantic versioning)
  • Valid URLs (rpcUrl, explorerUrl, linkToRelease)
  • chainId matches network name expectations (314 for mainnet, 314159 for calibration)

Current Risks

Risk 1: Invalid address format

"proxy": "0xINVALID"  // No validation, app crashes at runtime

Risk 2: Two active versions

"calibration": {
  "versions": [
    { "status": "active", ... },
    { "status": "active", ... }  // Which contracts does the app use?
  ]
}

Risk 3: Missing required fields

{
  "version": "v1.0.0",
  // Missing "status" field - no validation
  "contracts": { ... }
}

Suggested Solution: Zod Schema

import { z } from 'zod'
import { isAddress } from 'viem'

const ContractSchema = z.object({
  implementation: z.string().refine(isAddress, 'Invalid address'),
  proxy: z.string().refine(isAddress, 'Invalid address'),
  stateView: z.string().refine(isAddress, 'Invalid address').optional(),
  // ...
})

const VersionSchema = z.object({
  version: z.string().regex(/^v\d+\.\d+\.\d+$/),
  status: z.enum(['active', 'inactive', 'testing']),
  isNew: z.boolean(),
  linkToRelease: z.string().url().or(z.literal('')),
  contracts: z.object({
    warmStorage: ContractSchema,
    serviceProviderRegistry: ContractSchema,
  })
})

const NetworkSchema = z.object({
  name: z.string(),
  rpcUrl: z.string().url(),
  chainId: z.number(),
  explorerUrl: z.string().url(),
  versions: z.array(VersionSchema)
    .refine(
      (versions) => versions.filter(v => v.status === 'active').length <= 1,
      'Only one version can be active'
    )
})

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions