{"record":{"id":"078b09235c1ec937","repo":"nautechsystems/nautilus_trader","slug":"validated-proxy-storage-value","errorCode":null,"errorMessage":"validated proxy storage value","messagePattern":"validated proxy storage value","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/rpc/verification.rs","lineNumber":657,"sourceCode":"                }\n                VerificationOutcome::Retryable(failure) => {\n                    return VerificationOutcome::Retryable(failure);\n                }\n                VerificationOutcome::LocallyInvalid(failure) => {\n                    return VerificationOutcome::LocallyInvalid(failure);\n                }\n            };\n\n            if code.is_empty() || keccak256(&code) != expected_hash {\n                return VerificationOutcome::Disagreement(\n                    self.failure(VerificationRead::DeploymentIdentity),\n                );\n            }\n\n            if let Some(proxy) = &contract.proxy {\n                let slot = B256::from_str(&proxy.storage_slot).expect(\"validated proxy slot\");\n                let expected =\n                    B256::from_str(&proxy.storage_value).expect(\"validated proxy storage value\");\n                match self.verify_storage(&address, &slot, block).await {\n                    VerificationOutcome::Verified(verified) if verified.value == expected => {}\n                    VerificationOutcome::Verified(_) => {\n                        return VerificationOutcome::Disagreement(\n                            self.failure(VerificationRead::DeploymentIdentity),\n                        );\n                    }\n                    VerificationOutcome::Disagreement(failure) => {\n                        return VerificationOutcome::Disagreement(failure);\n                    }\n                    VerificationOutcome::Unavailable(failure) => {\n                        return VerificationOutcome::Unavailable(failure);\n                    }\n                    VerificationOutcome::Retryable(failure) => {\n                        return VerificationOutcome::Retryable(failure);\n                    }\n                    VerificationOutcome::LocallyInvalid(failure) => {\n                        return VerificationOutcome::LocallyInvalid(failure);","sourceCodeStart":639,"sourceCodeEnd":675,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/rpc/verification.rs#L639-L675","documentation":"In the same proxy-verification path, the expected storage value is parsed with `B256::from_str(&proxy.storage_value).expect(\"validated proxy storage value\")`. Like the slot, the manifest is pre-validated by `validate_config` (verification.rs:1291), which guarantees `storage_value` is valid 32-byte hex, making this expect an internal invariant. Reaching it means an unvalidated or hand-built manifest reached `verify_deployment_manifest`.","triggerScenarios":"Verifying a manifest whose `proxy.storage_value` is not valid 32-byte hex (truncated value, missing 0x, non-hex chars) without first passing `validate_config` — typically manifests loaded directly from JSON or constructed in tests.","commonSituations":"Hand-edited manifest files with a truncated storage value; copying a value of the wrong length (e.g. 32 hex chars instead of 64); test manifests built bypassing validation; older schema manifests with differently formatted values.","solutions":["Validate the manifest with `validate_config` before calling `verify_deployment_manifest`.","Correct `proxy.storage_value` in the manifest to exactly 64 hex digits (with 0x).","In your own code, parse with `B256::from_str` and map the error instead of expecting.","Re-generate the manifest through its official source/generator rather than editing by hand."],"exampleFix":"// before\nlet expected = B256::from_str(&proxy.storage_value).expect(\"validated proxy storage value\");\n// after\nlet expected = B256::from_str(&proxy.storage_value)\n    .map_err(|e| anyhow::anyhow!(\"invalid proxy storage_value {:?}: {e}\", proxy.storage_value))?;","handlingStrategy":"validation","validationCode":"fn validate_proxy_storage_value(proxy: &ProxyInfo) -> Result<B256, String> {\n    let s = proxy.storage_value.trim();\n    let hex = s.strip_prefix(\"0x\").unwrap_or(s);\n    if hex.len() != 64 || !hex.chars().all(|c| c.is_ascii_hexdigit()) {\n        return Err(format!(\"storage_value must be 32-byte hex, got {s:?}\"));\n    }\n    B256::from_str(s).map_err(|e| e.to_string())\n}","typeGuard":null,"tryCatchPattern":"// Validate at load time, not at verification time\nvalidate_config(&manifest).map_err(|e| anyhow::anyhow!(\"invalid manifest: {e}\"))?;","preventionTips":["Generate manifests via the official generator; never hand-edit hex fields.","Enforce 64-hex-digit storage values with a schema/validator on the manifest file.","Diff regenerated manifests in CI to catch corrupted values early."],"tags":["panic","rust","hex","manifest-validation","proxy"],"backgroundTag":"internal-invariant-violation","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}