{"record":{"id":"7c350a521a0cd230","repo":"datahaven-xyz/datahaven","slug":"invalidupgradeparameters","errorCode":"InvalidUpgradeParameters","errorMessage":"InvalidUpgradeParameters","messagePattern":"InvalidUpgradeParameters","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"operator/pallets/system-v2/src/lib.rs","lineNumber":146,"sourceCode":"        ///\n        /// Fee required: No\n        ///\n        /// - `origin`: Must be `Root`.\n        /// - `impl_address`: The address of the implementation contract.\n        /// - `impl_code_hash`: The codehash of the implementation contract.\n        /// - `initializer`: Optionally call an initializer on the implementation contract.\n        #[pallet::call_index(3)]\n        #[pallet::weight((<T as pallet::Config>::WeightInfo::upgrade(), DispatchClass::Operational))]\n        pub fn upgrade(\n            origin: OriginFor<T>,\n            impl_address: H160,\n            impl_code_hash: H256,\n            initializer: Initializer,\n        ) -> DispatchResult {\n            let origin_location = T::GovernanceOrigin::ensure_origin(origin)?;\n            let origin = Self::location_to_message_origin(origin_location)?;\n\n            ensure!(\n                !impl_address.eq(&H160::zero()) && !impl_code_hash.eq(&H256::zero()),\n                Error::<T>::InvalidUpgradeParameters\n            );\n\n            let initializer_params_hash: H256 = blake2_256(initializer.params.as_ref()).into();\n\n            let command = Command::Upgrade {\n                impl_address,\n                impl_code_hash,\n                initializer,\n            };\n            Self::send(origin, command, 0)?;\n\n            Self::deposit_event(Event::<T>::Upgrade {\n                impl_address,\n                impl_code_hash,\n                initializer_params_hash,\n            });","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/datahaven-xyz/datahaven/blob/edcb13dbbcd3c29489eaa2480a6f60ee4cb1f3ec/operator/pallets/system-v2/src/lib.rs#L128-L164","documentation":"The system-v2 pallet's `upgrade` extrinsic throws `Error::InvalidUpgradeParameters` when the supplied `impl_address` or `impl_code_hash` is zero. Upgrading the system contract to a zero address or zero code hash would brick the EVM-side system contract, so these degenerate values are rejected up front (after governance-origin verification).","triggerScenarios":"Calling `upgrade(origin, impl_address, impl_code_hash, initializer)` via the governance origin where `impl_address == H160::zero()` or `impl_code_hash == H256::zero()` — typically uninitialized parameters or a failed contract deployment whose outputs defaulted to zero.","commonSituations":"Proposal/automation scripts passing default H160/H256 values because the new implementation failed to deploy; copying upgrade calldata with placeholder zeros; indexer or multisig tooling mixing up argument order so zeros land in these fields.","solutions":["Deploy the new implementation contract first and use its real address and code hash in the upgrade call.","Validate `impl_address != H160::zero()` and `impl_code_hash != H256::zero()` in the proposal/submitting script before dispatching.","Verify argument ordering when constructing the extrinsic call data."],"exampleFix":"// before\nlet addr = H160::zero();\nSystemV2::upgrade(origin, addr, H256::zero(), initializer)?; // InvalidUpgradeParameters\n\n// after\nlet addr = deployed_impl_address; // from successful forge/Foundry deploy output\nlet code_hash = keccak256(deployed_impl_code);\nassert!(!addr.is_zero() && !code_hash.is_zero());\nSystemV2::upgrade(origin, addr, code_hash, initializer)?;","handlingStrategy":"validation","validationCode":"if (implAddress === '0x0000000000000000000000000000000000000000' || implCodeHash === '0x' + '00'.repeat(32)) throw new Error('zero upgrade target');","typeGuard":"function isNonZeroUpgradeTarget(addr, hash) { return addr != null && !/^0x0+$/.test(addr) && hash != null && !/^0x(00)*$/.test(hash); }","tryCatchPattern":"try { await api.tx.systemV2.upgrade(implAddress, implCodeHash, initializer).signAndSend(council); } catch (e) { if (String(e).includes('InvalidUpgradeParameters')) abortProposal(); else throw e; }","preventionTips":["Always deploy the implementation before proposing the upgrade","Validate all extrinsic args in the proposal tooling","Check deploy outputs for real address/code hash","Review upgrade calldata in multisim before signing"],"tags":["substrate","governance","upgrade","zero-address","system-contract"],"backgroundTag":"invalid-argument-value","analyzedSha":"edcb13dbbcd3c29489eaa2480a6f60ee4cb1f3ec","analyzedAt":"2026-09-13T19:19:32.206Z","contentChangedAt":"2026-09-13T19:19:32.206Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}