-
Notifications
You must be signed in to change notification settings - Fork 4
Open
Description
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 runtimeRisk 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'
)
})Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels