T09 · Insecure Skill Coding Practices
- Location
cli.js:139- Finding
Irreversible Partial Mainnet Deployment Caused by Missing Constructor Argument
- Content
View full analysis
Vulnerability Details
File Location:
cli.js, lines 139-175
Vulnerability Type: Incorrect smart-contract deployment sequencing and constructor invocation
Risk Level: MediumVulnerable Code
javascript // Step 1: Register Identity if (!deployment.agentId) { console.log("1. Registering agent identity..."); const identity = new ethers.Contract(IDENTITY_REGISTRY, IDENTITY_ABI, wallet); const tx = await identity["register()"]({ gasLimit: 200000 }); console.log(" TX:", tx.hash); const receipt = await tx.wait(); // Parse agent ID from Transfer event const transferLog = receipt.logs.find(l => l.topics[0] === ethers.id("Transfer(address,address,uint256)") ); const agentId = parseInt(transferLog.topics[3], 16); deployment.agentId = agentId; deployment.identityRegistry = IDENTITY_REGISTRY; deployment.reputationRegistry = REPUTATION_REGISTRY; saveDeployment(deployment); console.log(" ✅ Registered! Agent ID:", agentId); } // Step 2: Deploy ValidationRegistry if (!deployment.validationRegistry) { console.log("2. Deploying ValidationRegistry..."); const ValidationRegistry = require("./artifacts/ValidationRegistry.json"); const factory = new ethers.ContractFactory( ValidationRegistry.abi, ValidationRegistry.bytecode, wallet ); const validationRegistry = await factory.deploy(); await validationRegistry.waitForDeployment(); }The bundled artifact at
artifacts/ValidationRegistry.json, lines 6-12, declares a required constructor argument:json "inputs": [ { "internalType": "address", "name": "_identityRegistry", "type": "address" } ], "stateMutability": "nonpayable", "type": "constructor"Technical Analysis
The CLI invokes
factory.deploy()without the required_identityRegistryaddress. Ethers validates constructor arguments against the ABI, so this call cannot deploy the bundledValidationRegistrycontract successfully.The failure occurs only af ...[truncated 2041 chars]
- Remediation
View remediation
Remediation Suggestions
Pass the required identity-registry address to the constructor:
javascript const validationRegistry = await factory.deploy(IDENTITY_REGISTRY); await validationRegistry.waitForDeployment();Apply the following additional hardening measures:
-
Add a deployment preflight
- Inspect each artifact's constructor ABI.
- Verify that the supplied argument count and types match before sending any transaction.
- Validate the configured RPC chain ID against the expected chain ID of
43114.
-
Reorder irreversible operations
- Deploy and verify prerequisite contracts before registering the identity where protocol semantics permit.
- Avoid permanent mainnet state changes until all local validation has succeeded.
-
Simulate before submission
- Perform gas estimation or transaction simulation for every planned operation.
- Abort before identity registration if any later deployment cannot be constructed or simulated.
-
Improve recovery behavior
- Record explicit deployment phases and transaction hashes.
- Detect partial deployments and print precise recovery instructions.
- Do not represent the deployment as retry-safe unless every phase is idempotent.
-
Add automated integration testing
- Test the complete deployment sequence against a local EVM or Avalanche-compatible test environment.
- Assert that all constructor parameters match the bundled artifacts.
- Verify that identity registration, both deployments, task pricing, and metadata updates complete successfully.
-
Verify deployed contracts
- After deployment, confirm runtime bytecode exists at each saved address.
- Query expected getters such as
identityRegistry(),owner(), andagentId()before persisting completion state.
-
