nautechsystems/nautilus_trader · error

ERC-20 approve simulation reverted for token {token}

Error message

ERC-20 approve simulation reverted for token {token}

What it means

During the pre-sign approval flow, the simulation of the ERC-20 approve call reverted (VerifiedSimulation::Denied). This means executing approve on current state would revert on-chain, so the client refuses to sign and spend gas on a doomed transaction.

Source

Thrown at crates/adapters/blockchain/src/execution/client.rs:2668

                                if result.is_empty() {
                                    Ok(true)
                                } else {
                                    ERC20::approveCall::abi_decode_returns_validate(result)
                                        .map_err(Into::into)
                                }
                            },
                        )
                        .await,
                    "pre-sign approval simulation",
                )?;

                match &simulation.value {
                    VerifiedSimulation::Succeeded(true) => {}
                    VerifiedSimulation::Succeeded(false) => {
                        anyhow::bail!("ERC-20 approve returned false for token {token}")
                    }
                    VerifiedSimulation::Denied => {
                        anyhow::bail!("ERC-20 approve simulation reverted for token {token}")
                    }
                }
                Ok(vec![
                    verification_decision(&allowance, Some(block), Some(block)),
                    verification_decision(&simulation, Some(block), Some(block)),
                ])
            }
        }
    }

    async fn verify_swap_anchors_before_sign(
        &self,
        anchors: &SwapQuoteAnchors,
    ) -> anyhow::Result<Vec<ExecutionVerificationDecision>> {
        let checkpoint = required_verification(
            self.verification.verify_checkpoint().await,
            "pre-sign checkpoint reread",
        )?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the simulation revert reason to find the failing condition
  2. Check token pause/freeze/blacklist status before approving
  3. Retry after the token state changes (unpause) or use a different spender
  4. Re-run simulation against a current, correctly configured fork/RPC state

Example fix

// before
token.approve(spender, amount).send().await?; // reverts on-chain, gas lost
// after
match client.simulate_approve(token, spender, amount).await {
    Ok(_) => token.approve(spender, amount).send().await?,
    Err(e) => log::error("approve would revert: {e}"),
}
Defensive patterns

Strategy: validation

Validate before calling

// Simulate the approve before sending; bail if it would revert
let sim = client.simulate_approve(&token, spender, amount).await?;
anyhow::ensure!(sim.succeeded(), "approve would revert: {:?}", sim.reason);

Try / catch

match res {
    Err(e) if e.to_string().contains("approve simulation reverted") => {
        let reason = client.last_simulation_revert_reason().await?;
        // check paused/blacklist state, then decide
    }
    r => r?,
}

Prevention

When it happens

Trigger: Pre-sign approval simulation returns VerifiedSimulation::Denied — the approve call would revert, e.g. because the token is paused, the owner lacks balance/roles, or the token contract enforces conditions that fail at simulation time.

Common situations: Token contract paused or frozen; approval amount violates contract rules (e.g. some tokens cap max approval); simulation fork state diverges from mainnet; spender address blacklisted by the token.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/b4aca5ef8baf3809. Report an issue: GitHub.