nautechsystems/nautilus_trader · error

Approve authorization does not match the transaction call

Error message

Approve authorization does not match the transaction call

What it means

The client verifies that an authorized Approve operation exactly matches the signed transaction: `to` must be the authorized ERC20 token, value zero, and calldata must be the ABI-encoded approve(spender, amount) with the authorized router and amount. Mismatch is rejected to prevent signing calls beyond the granted approval authorization.

Source

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

        None => Ok(()),
        Some(TransactionAuthorization::Wrap { weth }) => {
            anyhow::ensure!(
                to == *weth && !value.is_zero() && input == WETH9::depositCall::SELECTOR,
                "Wrap authorization does not match the transaction call"
            );
            Ok(())
        }
        Some(TransactionAuthorization::Approve {
            token,
            router,
            amount,
        }) => {
            let expected = ERC20::approveCall {
                spender: *router,
                amount: *amount,
            }
            .abi_encode();
            anyhow::ensure!(
                to == *token && value.is_zero() && input == expected,
                "Approve authorization does not match the transaction call"
            );
            Ok(())
        }
    }
}

fn verification_decision<T>(
    verified: &Verified<T>,
    height_start: Option<u64>,
    height_end: Option<u64>,
) -> ExecutionVerificationDecision {
    ExecutionVerificationDecision {
        read_class: verified.read.as_str(),
        height_start,
        height_end,
        normalized_value_digest: verified.normalized_value_digest.to_string(),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the call is `to == token`, `value == 0`, and input is abi_encode of ERC20::approveCall{spender: router, amount} matching the authorization exactly.
  2. Build the authorization and the transaction from the same source parameters so router/amount cannot diverge.
  3. Verify the token and router addresses in config match the intended chain deployments.
  4. If the approval intent changed, re-issue a new authorization rather than editing the transaction.

Example fix

// before: amount differs from authorization
let input = ERC20::approveCall { spender: router, amount: amount * 2 }.abi_encode();
verify_approve(auth, token, U256::zero(), &input)?; // mismatch
// after
let input = ERC20::approveCall { spender: auth.router, amount: auth.amount }.abi_encode();
verify_approve(auth, token, U256::zero(), &input)?;
Defensive patterns

Strategy: validation

Validate before calling

let expected = ERC20::approveCall { spender: router, amount }.abi_encode();
assert!(value.is_zero() && to == token && input == expected, "approve call mismatch");

Type guard

fn is_approve_auth(auth: &TransactionAuthorization) -> Option<(Address, Address, U256)> {
    if let TransactionAuthorization::Approve { token, router, amount } = auth { Some((*token, *router, *amount)) } else { None }
}

Try / catch

match result { Err(e) if e.to_string().contains("Approve authorization does not match") => { reissue_authorization_and_retry(); } Ok(v) => v }

Prevention

When it happens

Trigger: prepare/sign path invoked with TransactionAuthorization::Approve but the transaction's `to` is not the authorized token, `value` is nonzero, or `input` is not exactly the encoded approveCall{spender: router, amount} — e.g. the approval amount or spender differs from what was authorized.

Common situations: Approval authorization generated for one router but the transaction targets a different spender; amount drift between plan creation and tx building; token address mismatch (wrong ERC20 in config); accidentally sending value with an approve call.

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/a14b98b1be927fcf. Report an issue: GitHub.