Skip to content

Conversation

@0xferrous
Copy link
Contributor

Motivation

There is no way to determine the validity of the authorizations just looking at the RPC responses with cast tx or cast receipt.

Solution

So, we need to build a new command that manually validates the authorizations with the logic laid out in EIP-7702.

PR Checklist

  • Added Tests
  • Added Documentation
  • Breaking changes

@0xferrous 0xferrous marked this pull request as draft November 22, 2025 01:14
@0xferrous 0xferrous marked this pull request as ready for review November 22, 2025 01:20
Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no way to determine the validity of the authorizations just looking at the RPC responses with cast tx

this isn't quite accurate because: we display: recoveredAuthority if the auth is valid

authorizationList    [
        {recoveredAuthority: 0x6d88AED96570f99f17803AAadCB7d52a903A8000, signedAuthority: {"chainId":"0x1","address":"0xa845c74344fc9405b1fcf712f04668979573c1bf","nonce":"0x0","yParity":"0x0","r":"0x65f49a34f31703fec5612c7022ad9ad3411524f3265f926ff3ad9710ee3c0495","s":"0x254672cc95922e76b069ee1458155cb74d1b179ba1d26239ffb4b220816982e2"}}
]

#[command(visible_aliases = &["decode-auth"])]
RecoverAuthority { auth: String },

/// Validate EIP-7702 authorizations in a transaction and print validity status.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is being validated here?
just the auth itself?
because for this we only need to fetch the tx itself and perform recovery on this, then this can be simplified

this info is also already included in cast tx (only displays the recovered auth if valid)
so I'm not actually sure how exactly this new command is different

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the recoveredAuthority in itself tells you whether the authorization was valid because, the signature can be valid, but the nonce may be outdated or too ahead(there is only one acceptable nonce), the chain id can be invalid, etc. Essentially, my intention was to determine which authorizations got "executed", and which got rejected, and this is my attempt at displaying that information.

I think it shows the decoded data and recovered authority from the signature, but it doesn't show the the validity. I had to refer to etherscan for instance when I couldn't figure out why my eoa was not getting delegated
image

Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still a bit unclear what this exactly validates

could you please add some additional docs

Comment on lines +13 to +22
#[derive(Debug, clap::Parser)]
pub struct ValidateAuthArgs {
/// Transaction hash.
tx_hash: B256,

#[command(flatten)]
rpc: RpcOpts,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs some docs, what this actually does

Comment on lines 57 to 65
// Extract authorization list from EIP-7702 transaction
let auth_list = match &*tx.inner.inner {
AnyTxEnvelope::Ethereum(TxEnvelope::Eip7702(signed_tx)) => {
signed_tx.tx().authorization_list.clone()
}
_ => {
eyre::bail!("transaction is not an EIP-7702 transaction");
}
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we can use the trait Transaction's function for this

Comment on lines 45 to 47
// Build a map of address -> running nonce from txs in this block up to and including
// our tx
let mut running_nonces: HashMap<Address, u64> = HashMap::new();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i assume this is because naively getting the nonce at the block before this assumes there is only 1 transaction from the sender account in the current block, so we need to account for the fact that the account might send 1 or more txs before their eip7702 authorization which would bump the nonce.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, although i have realized my implementation is still incomplete, because all the valid authorizations before the current tx in the given block can also have an authorization that can affect the running nonce of current recovered authority, which means i have to validate authorizations for all txs before current tx to get the real running nonce and accurate validation.

@0xferrous 0xferrous marked this pull request as draft November 29, 2025 18:37
@0xferrous 0xferrous marked this pull request as ready for review December 1, 2025 07:47
Comment on lines +60 to +75
/// Validates all the authorizations in an EIP-7702 transaction. It does so by validating the
/// nonce and chain id for each of the recovered authority from the given authorizations.
///
/// For nonce validation, it builds a "running nonce" map by processing all transactions
/// before the target transaction in the same block:
/// - For each transaction sender, tracks their next expected nonce (tx.nonce + 1)
/// - For each valid authorization in previous transactions, also increments that authority's
/// running nonce (since valid authorizations execute and increment the authority's nonce)
/// - If an authority is not in the running nonce map, fetches their nonce at block - 1
///
/// Then, for each authorization in the target transaction:
/// - Validates nonce against the running nonce
/// - If the authorization is valid (both chain and nonce), increments the running nonce for
/// that authority (for subsequent authorizations in the same transaction)
///
/// For chain id validation, it checks if it is zero or the same chainid as the current chain.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this clarify things @mattsse ?

There is no way to determine the validity of the authorizations just
looking at the RPC responses with `cast tx` or `cast receipt`. So, we
need to build a new command that manually validates the authorizations
with the logic laid out in EIP-7702.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants