{"record":{"id":"250ae0abea822b72","repo":"nautechsystems/nautilus_trader","slug":"eth-call-execution-reverted","errorCode":null,"errorMessage":"eth_call execution reverted","messagePattern":"eth_call execution reverted","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/rpc/http.rs","lineNumber":504,"sourceCode":"    /// # Errors\n    ///\n    /// Returns an error if the RPC call fails or the result is missing or malformed.\n    #[cfg(feature = \"hypersync\")]\n    #[allow(\n        dead_code,\n        reason = \"Used by the independent verification read inventory\"\n    )]\n    pub(crate) async fn call_at(\n        &self,\n        from: Option<&Address>,\n        to: &Address,\n        value: U256,\n        data: &[u8],\n        block: u64,\n    ) -> anyhow::Result<Bytes> {\n        match self.call_result_at(from, to, value, data, block).await? {\n            RpcCallResult::Success(bytes) => Ok(bytes),\n            RpcCallResult::Reverted => anyhow::bail!(\"eth_call execution reverted\"),\n        }\n    }\n\n    /// Executes an explicit-height `eth_call`, preserving a recognized EVM revert as data.\n    #[cfg(feature = \"hypersync\")]\n    pub(crate) async fn call_result_at(\n        &self,\n        from: Option<&Address>,\n        to: &Address,\n        value: U256,\n        data: &[u8],\n        block: u64,\n    ) -> anyhow::Result<RpcCallResult> {\n        let mut call = serde_json::json!({\n            \"to\": to,\n            \"value\": format!(\"0x{value:x}\"),\n            \"data\": hex::encode_prefixed(data),\n        });","sourceCodeStart":486,"sourceCodeEnd":522,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/rpc/http.rs#L486-L522","documentation":"Raised by `call_at` in the blockchain HTTP RPC adapter when an explicit-height `eth_call` is recognized as having reverted on-chain. The underlying `call_result_at` preserves the revert as data via `RpcCallResult::Reverted`, but the plain `call_at` API discards the revert data and converts it into this anyhow error. It means the contract executed the calldata and deliberately reverted (e.g. require/assert failed), not that the RPC itself failed.","triggerScenarios":"Calling `call_at(from, to, value, data, block)` where the contract at `to` reverts when executed at the given historical block: failed `require`/`assert`, custom error, or explicit `revert()` in the contract logic.","commonSituations":"Simulating a token transfer that would fail (insufficient allowance/balance); calling a view function guarded by state checks that don't hold at the queried block; probing historical state where the contract wasn't deployed or a check like `onlyOwner` fails.","solutions":["Decode the revert reason instead: use `call_result_at` which returns `RpcCallResult::Reverted` and preserves the revert data.","Check preconditions on-chain before the call (allowance, balance, role, state at `block`).","Verify the calldata encoding (function selector and ABI arguments) — malformed calldata often reverts.","Confirm the target contract is deployed at the queried `block` height."],"exampleFix":"// before\nlet out = rpc.call_at(from, to, value, data, block).await?;\n// after\nmatch rpc.call_result_at(from, to, value, data, block).await? {\n    RpcCallResult::Success(bytes) => bytes,\n    RpcCallResult::Reverted => decode_revert_reason(data) /* handle revert */, \n}","handlingStrategy":"try-catch","validationCode":"// Check state preconditions before the call\nlet allowance: U256 = erc20.allowance(owner, spender).call().await?;\nanyhow::ensure!(allowance >= amount, \"insufficient allowance, eth_call would revert\");","typeGuard":"fn is_reverted(err: &anyhow::Error) -> bool {\n    err.to_string().contains(\"eth_call execution reverted\")\n}","tryCatchPattern":"match rpc.call_at(from, to, value, data, block).await {\n    Ok(bytes) => process(bytes),\n    Err(e) if is_reverted(&e) => handle_revert(decode_revert_data(&e)),\n    Err(e) => return Err(e),\n}","preventionTips":["Simulate or static-check state (allowance, balance, roles) before eth_call","Prefer `call_result_at` when you need the revert payload","Unit-test calldata encoding against the contract ABI","Verify contract deployment height relative to the queried block"],"tags":["evm","rpc","contract-revert","eth-call"],"backgroundTag":"api-error-response","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"}