EntryPoint IntelligenceERC-4337 on Avalanche C-Chain Data to 2026-10-25

This page takes one real Oct 18, 2026 C-Chain transaction and reads everything in it: the outer call, the one UserOperation inside, the account's batch, the logs in order, and the money. The goal is that next time you can do this on any EntryPoint transaction.

The transaction: 0xddda920f2fd5092c727088b9916f632bd61628bfa118c6ddd5a2356827214ffe

  • Block 97,857,672, 2026-10-18 06:18:34 UTC, type-2, status 1, to = EntryPoint v0.7 0x0000000071727de22e5e9d8baf0edac6f37da032 evidence level: primary source.
  • In one sentence: a ZeroDev Kernel smart account is deployed and, in the same operation, approves and deposits 64.964131 USDC into Relay's depository (a cross-chain intent). Pimlico's verifying paymaster sponsors the gas, and a 0x4337…-prefixed bundler submits it.
  • Why this one: it is v0.7, paymaster-sponsored, includes an account deployment, and has a clear app call. The earlier population already lists it as existing baseline operation: cross_chain.asset_send.

Everything below comes from the transaction's full calldata and receipt logs, decoded with eth_abi.


1. The outer transaction

Field Value What it tells you
from 0x4337005db25dbad41da5692ba1188751ee5d98b6 evidence level: hint The bundler EOA. It signed this transaction and paid the native gas.
to 0x0000000071727de22e5e9d8baf0edac6f37da032 evidence level: primary source EntryPoint v0.7 (direct call, not wrapped).
value 0 Bundlers don't send AVAX to the EntryPoint here.
gas_used 387,477 Gas for the whole bundle.
effective_gas_price 0x14b1a92c0 = 5.555 gwei Block base fee 5.0 gwei (blocks parquet) + bundler tip 0.555 gwei.
Receipt fee 387,477 × 5,555,000,000 = 2,152,434,735,000,000 wei (0.002152 AVAX) What the bundler paid the chain.
tx nonce 125,722 This bundler EOA has sent a lot of transactions.

2. The outer calldata: handleOps(PackedUserOperation[], address)

The input is 2,244 bytes. Selector 0x765e827f is the packed handleOps shared by v0.7/v0.8/v0.9. The to address says v0.7.

765e827f                                                                 selector
0000…0040                                                                [0x00] offset of ops[] = 0x40
0000…4337005db25dbad41da5692ba1188751ee5d98b6                            [0x20] beneficiary
0000…0001                                                                [0x40] ops.length = 1
0000…0020                                                                [0x60] offset of ops[0]

Already, the beneficiary (0x4337005d…) equals the bundler. That is the normal case: on Oct 18, 1,391 of 1,396 outers had beneficiary = submitter. All 5 exceptions were v0.7, and 2 of those were wrapped calls.

The op's head (static fields and offsets)

000000000000000000000000cb7509e6466632d73a509ec778f88d52fa9096d2    sender
00008104e3ad430ea6d354d013a6789fdfc71e671c4300000000000000000000    nonce
…0120                                                                offset initCode   (→ 408 bytes)
…02e0                                                                offset callData   (→ 996 bytes)
00000000000000000000000000004dcca000000000000000000000000000141e7     accountGasLimits
…eb3e                                                                preVerificationGas
0000000000000000000000003cc91af3000000000000000000000001ddc7d1fc     gasFees
…0700                                                                offset paymasterAndData (→ 130 bytes)
…07c0                                                                offset signature (→ 65 bytes)

3. The PackedUserOperation, field by field

# Field Raw Decoded / meaning
1 sender cb7509e6…96d2 The smart account. It doesn't exist yet when this op starts; initCode creates it.
2 nonce 0x00008104e3ad…1c43 0000 0000000000000000 192-bit key + 64-bit sequence. Sequence = 0 (first op on this key). The key embeds 8104e3ad430ea6d354d013a6789fdfc71e671c43, the ZeroDev ECDSA validator. Kernel v3 selects its validator through the nonce key. (I have not re-verified Kernel's exact nonce byte layout from source; the embedded validator address is directly visible.)
3 initCode d703aae7…42d5 + c5265d5d… factory = 0xd703aae79538628d27099b8c4f621be4ccd142d5 evidence level: primary source, call = deployWithFactory(address,bytes,bytes32) (selector 0xc5265d5d, matches by keccak). See §3a.
4 callData e9ae5c53 01000000… ERC-7579 execute(bytes32 mode, bytes executionCalldata) with a batch of 3 calls. See §4.
5 accountGasLimits …04dcca ‖ …0141e7 verificationGasLimit = 318,666, callGasLimit = 82,407
6 preVerificationGas 0xeb3e 60,222: covers calldata and bundle overhead the EntryPoint can't meter
7 gasFees …3cc91af3 ‖ …01ddc7d1fc maxPriorityFeePerGas = 1.019812595 gwei, maxFeePerGas = 8.015827452 gwei
8 paymasterAndData 130 bytes See §3b
9 signature 6ff89ef3…5f30431c (65 bytes) The account owner's ECDSA signature. See §6.

3a. initCode: who creates the account

d703aae79538628d27099b8c4f621be4ccd142d5                 factory (20 bytes)  = ZeroDev Kernel "meta factory"
c5265d5d                                                 deployWithFactory(address factory, bytes createData, bytes32 salt)
  factory    = 0x6723b44abeec4e71ebe3232bd5b455805badd22f  ZeroDev Kernel v3.0 factory
  salt       = 0x00…00
  createData = 12af322c                                   initialize(bytes21,address,bytes,bytes)
               01 8104e3ad430ea6d354d013a6789fdfc71e671c43  rootValidator = type 0x01 (validator) ‖ ECDSA validator
               …  hook = 0x0
               …  validatorData = 3f98da05dc176902d47e989ecdae9a443ebbbbeb   ← the owner EOA

Identity check: ZeroDev's SDK constants (zerodevapp/sdk packages/core/constants.ts, plugins/ecdsa/constants.ts, fetched 2026-10-19) list 0x6723b44a…d22f evidence level: primary source as the Kernel v0.3.0 factoryAddress, 0xd703aaE7…42d5 evidence level: primary source as metaFactoryAddress, and 0x8104e3Ad…1c43 as the v0.3.0 ECDSA validator. The selectors 0xc5265d5d and 0x12af322c match those function signatures by keccak. This binds the wallet implementation (ZeroDev Kernel v3.0 + ECDSA validator). It says nothing about which app or person uses the wallet.

3b. paymasterAndData: who pays the gas

777777777777aec03fd955926dbf81597e66834c      [0:20]  paymaster = Pimlico singleton paymaster (v0.7)
0000000000000000000000000000b578              [20:36] paymasterVerificationGasLimit = 46,456
00000000000000000000000000000001              [36:52] paymasterPostOpGasLimit = 1
00                                            [52]    Pimlico mode byte: mode 0 (verifying), allowAllBundlers = 0
00006ad46709                                  validUntil = 1,792,304,905 (06:28:25 UTC, ~10 min after inclusion)
000000000000                                  validAfter = 0
112e4e3a…4f4e7f28046cd51b                     65-byte Pimlico signer signature
  • The paymaster address matches Pimlico's documentation for v0.7 (web/pimlico-erc20-paymaster-contract-addresses.mdx).
  • The layout after byte 52 follows Pimlico's BaseSingletonPaymaster._parsePaymasterAndData / _parseVerifyingConfig (earlier source).
  • Verifying mode means Pimlico's off-chain service signed "I'll pay for this exact op until 06:28:25". No token is charged on chain. A postOp gas limit of 1 fits that: verifying mode needs no postOp accounting.
  • I recovered the paymaster signature using Pimlico's V7 getHash (hash of the op fields with paymasterAndData[:65], then chainId, then eth-signed-message). It recovers to 0x4337dd7891df2580890e4f6eab503465efeb6afe. I did not read the paymaster's on-chain signers mapping, so "that address is an authorized Pimlico signer" is implied by the op having validated, not checked directly.

4. callData: what the account was asked to do

e9ae5c53                                   execute(bytes32 mode, bytes executionCalldata)   [ERC-7579]
0100000000000000…00                        mode: callType 0x01 = batch, execType 0x00 = revert on failure
executionCalldata = abi.encode((address target, uint256 value, bytes data)[]) with 3 entries:
Leg Target Value Data Decoded
0 0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e evidence level: primary source (USDC) 0 095ea7b3 …4cd00e38…bc31 …03df4623 approve(0x4cd00e38…, 64,964,131) = 64.964131 USDC
1 0x4cd00e387622c35bddb9b4c962c136462338bc31 (Relay Depository) 0 e8017952 …cb7509e6… …b97ef9ef… …03df4623 e058b445…1f3f depositErc20(depositor=sender, currency=USDC, amount=64,964,131, id=0xe058b445…1f3f)
2 USDC 0 095ea7b3 …4cd00e38… …00 approve(0x4cd00e38…, 0): resets the allowance

The ERC-7579 callType byte meanings come from the ERC-7579 text ("0x00 single, 0x01 batch…"). The (address,uint256,bytes)[] encoding re-encodes exactly.

Identity checks:

  • USDC at 0xb97e…8a6e evidence level: primary source: the earlier asset identity (official Avalanche USDC; the research data).
  • Relay: https://api.relay.link/chains (fetched 2026-10-19) lists Avalanche (43114) protocol.v2.depository = 0x4cd00e387622c35bddb9b4c962c136462338bc31. Etherscan also labels this address "Relay: Depository". The depositErc20(address,address,uint256,bytes32) signature is only a decompiler/signature-database hint in the earlier research data. But the emitted event (§5, log 0x13) has topic0 = keccak(RelayErc20Deposit(address,address,uint256,bytes32)), which I recomputed, and its data echoes exactly the four request words.

What the bytes do NOT say: the destination chain, the recipient, or whether the funds arrived anywhere. The id (0xe058b445…) is Relay's order identifier. The route is defined off chain, in Relay's order book. Proving arrival needs destination-chain evidence.

5. The receipt logs, in order

Ten logs, log indices 0x0c–0x15. (Log indices are block-wide, so this transaction's first log isn't 0.)

logIndex Emitter Event (topic0) Phase What it tells you
0x0c cb7509e6… (new account) RootValidatorUpdated(bytes21) 0x6789ec0c…; data 01 8104e3ad…1c43 validation: deployment Kernel's initialize ran: the root validator is the ECDSA validator.
0x0d 8104e3ad… (ECDSA validator) OwnerRegistered(address kernel, address owner) 0xa5e1f8b4…; topics: cb7509e6…, 3f98da05… validation: deployment The account's owner key is 0x3f98da05dc176902d47e989ecdae9a443ebbbbeb.
0x0e EntryPoint AccountDeployed(userOpHash, sender, factory, paymaster) 0xd51a9c61…; topic1 0x33c4410e…, data: factory 0xd703aae7…, paymaster 0x7777…834c evidence level: primary source validation: deployment EntryPoint confirms the account was created by this op and its gas was paid by this paymaster.
0x0f Pimlico 0x7777…834c evidence level: primary source UserOperationSponsored(bytes32 userOpHash, address user, uint8 mode, address token, uint256 tokenAmountPaid, uint256 exchangeRate) 0x7a270f29…; data all zeros validation: paymaster Mode 0 (verifying). Token, amount and rate are zero: no on-chain token charge.
0x10 EntryPoint BeforeExecution() 0xbb47ee3e… boundary Validation for every op in the bundle is done. Logs after this belong to execution.
0x11 USDC Approval(owner=cb7509e6…, spender=4cd00e38…, 64,964,131) execution, leg 0 The approve ran.
0x12 USDC Transfer(from=cb7509e6…, to=4cd00e38…, 64,964,131) execution, leg 1 Relay pulled the USDC from the account.
0x13 Relay 4cd00e38… RelayErc20Deposit(depositor, currency, amount, id) 0x49fed1d0… execution, leg 1 Relay recorded the deposit under order id 0xe058b445….
0x14 USDC Approval(cb7509e6…, 4cd00e38…, 0) execution, leg 2 Allowance reset.
0x15 EntryPoint UserOperationEvent(userOpHash, sender, paymaster, nonce, success, actualGasCost, actualGasUsed) 0x49628fd1… outcome See below.

Decoding the final UserOperationEvent:

topic1  0x33c4410e4871fe14003d845bf3ad3e2e28b89e9897633541e4c8fa05af329952   userOpHash
topic2  …cb7509e6466632d73a509ec778f88d52fa9096d2                             sender
topic3  …777777777777aec03fd955926dbf81597e66834c                             paymaster
data    00008104e3ad…1c43 0000000000000000                                    nonce (same as the op)
        …01                                                                   success = true
        …0856561a5cedbe                                                       actualGasCost = 2,346,727,623,159,230 wei
        …05f2ca                                                               actualGasUsed = 389,834

How to split one transaction's logs into ops: everything before BeforeExecution is validation (deployments, sponsorship). After it, each op's execution logs end at that op's UserOperationEvent. The next op's logs start right after. The earlier decoder uses exactly this windowing (execution_window_logs).

Logs that never appear here:

  • No log for the AVAX paid to the beneficiary. _compensate is a plain value call. To see it, use a trace (epi explain --trace) or a balance diff. You can derive the amount from logs (§7).
  • No log for the deposit debit. The paymaster's EntryPoint deposit went down by the prefund, then up by the refund. Neither step emits an event; read balanceOf(paymaster) via RPC if you need it.
  • The account's validateUserOp and the paymaster's validatePaymasterUserOp emitted nothing here. Validation is mostly silent; you see it only through its effects.

6. Recomputing the userOpHash and checking the signature

The v0.7 formula:

packed = encode(['address','uint256','bytes32','bytes32','bytes32','uint256','bytes32','bytes32'],
                [sender, nonce, keccak(initCode), keccak(callData),
                 accountGasLimits, preVerificationGas, gasFees, keccak(paymasterAndData)])
inner      = keccak(packed)            # b45cb9e0f096362a895411c837073c27afd1b76a7505022b1e3740200239f8f0
userOpHash = keccak(encode(['bytes32','address','uint256'], [inner, ENTRYPOINT_V07, 43114]))
#          = 0x33c4410e4871fe14003d845bf3ad3e2e28b89e9897633541e4c8fa05af329952

It matches topic1 of UserOperationEvent (0x15) and AccountDeployed (0x0e). That proves the bytes we decoded are exactly the op the EntryPoint processed. It also tells you the signature, gas fields and paymaster data are the real ones, not a lookalike.

Signature check (eth_keys):

The owner registered in log 0x0d and in initCode recovers from the signature. So the chain shows that whoever holds key 0x3f98…bbeb authorized this exact operation: deploy, approve, deposit 64.96 USDC to Relay, with these gas limits, under this sponsorship.

7. The money

Quantity Value Source
UserOp gas price min(8.015827452, 1.019812595 + 5.0 basefee) = 6.019812595 gwei op's gasFees + block basefee
actualGasUsed 389,834 UserOperationEvent
actualGasCost 389,834 × 6,019,812,595 = 2,346,727,623,159,230 wei (exact) UserOperationEvent
Max prefund locked during validation (318,666 + 82,407 + 46,456 + 1 + 60,222) × 8,015,827,452 = 4,070,052,420,407,904 wei v0.7 _getRequiredPrefund
Refunded to paymaster's deposit 4,070,052,420,407,904 − 2,346,727,623,159,230 = 1,723,324,797,248,674 wei derived
Paid to beneficiary 0x4337005d… = sum of actualGasCost in the bundle = 2,346,727,623,159,230 wei derived (one op), trace would confirm
Bundler's receipt fee 2,152,434,735,000,000 wei receipt
Bundler margin on this tx +194,292,888,159,230 wei (~0.000194 AVAX) difference

Why the bundler came out ahead: the op agreed to pay a 1.02 gwei tip on top of basefee, but the bundler only tipped 0.555 gwei to the chain. actualGasUsed (389,834) is also slightly above the receipt's 387,477, because it includes the 60,222 preVerificationGas allowance. Who funded it: Pimlico's deposit inside the EntryPoint. Who paid Pimlico: not visible on chain. Verifying mode means Pimlico or its customer settles off chain.

8. Attribution summary for this transaction

Dimension Answer Evidence grade
Outcome Outer success; UserOp success = true; all three legs left matching logs Chain-proven (receipt + events)
Operation (requested) batch: approve → depositErc20 → approve(0) Chain-proven (calldata, hash-bound)
Operation (realized) 64.964131 USDC moved account → Relay Depository; Relay logged the deposit Chain-proven on C-Chain; destination fill unknown
Application Relay (cross-chain settlement) Supported: exact address in Relay's chains API + matching event signature
Asset USDC (official Avalanche) Supported: exact-address identity record
Route Avalanche → ? via Relay order 0xe058b445… Requested on chain; destination not on C-Chain
Wallet implementation ZeroDev Kernel v3.0, ECDSA validator Supported: factory/validator addresses in ZeroDev SDK + matching selectors/events
Control / signer key 0x3f98da05…bbeb signed the op and is the registered owner Chain-proven cryptographically; real-world identity unknown
Deployment account created in this op via meta factory → Kernel factory Chain-proven (AccountDeployed)
Bundler / beneficiary 0x4337005d… submitted and was paid Chain-proven; operator identity inferred at best (0x4337 vanity prefix is not proof)
Sponsorship Pimlico v0.7 singleton, verifying mode, ~0.00235 AVAX of its deposit Chain-proven that Pimlico's deposit paid; who reimbursed Pimlico unknown
Fees receipt 0.002152 AVAX (bundler → chain); actualGasCost 0.002347 AVAX (paymaster → bundler) Chain-proven; don't add them together
Automation Unknown. One op tells you nothing about scripts vs humans n/a

The general lesson: one EntryPoint transaction answers "what did this smart account request and what happened on this chain" very well. Who the person is, what app UI they used, where the money ended up off chain, and who ultimately paid for gas are separate questions, with separate evidence.