Skip to content

01 · Before you sign ​

Paste what the dapp asked you to sign. Grub decodes it, replays it on the live chain state, and lists every asset that moves and every permission you would grant.

Transactions ​

Give it the calldata, or the JSON your wallet shows (from, to, data, value). Chain id must be 56 if present.

Decoding, in order ​

  1. Known patterns. approve, setApprovalForAll, transfer, transferFrom, ERC-2612 permit, Permit2 permit single and batch, Permit2 approve, Universal Router execute, multicall (recursive, up to two levels), PancakeSwap and V3-style swaps, WBNB deposit and withdraw, claim, stake, Safe execTransaction, Seaport fulfils.
  2. Verified ABI. If the contract is verified on Sourcify, its ABI decodes every argument.
  3. Selector databases. OpenChain, then 4byte, give a function name for anything else.
  4. Unknown stays unknown. Grub never guesses an intent. It shows the effect instead.

Replay ​

The call runs through eth_simulateV1 with a state override that gives the sender enough BNB for the value and gas, and with native transfers traced. From the resulting logs Grub builds the diff for the sender:

  • tokens and BNB that leave the wallet, tokens, BNB and NFTs that enter it;
  • permissions granted: ERC-20 Approval, ERC-721 approvals, ApprovalForAll, Permit2 allowances.

If no sender is given, a placeholder account is used and the page says so: balances and allowances are then generic.

Findings ​

LevelTrigger
dangerapproval to a plain wallet · approval to a flagged address · unlimited approval to an unverified contract · assets out and nothing in · target on a drainer blocklist
warnlimited approval to an unverified contract · unlimited approval to a known router (never expires) · setApprovalForAll to a known operator · a claim that pays nothing · call reverts · target is an EOA delegated to code (EIP-7702) · unknown function on an unverified contract
okrevokes · nothing alarming beyond the listed effects

The verdict is the worst level found. The stamp and the grub's face follow it.

Signatures (EIP-712) ​

A typed-data request executes nothing by itself, so Grub analyses it by structure:

  • Permit2 PermitSingle / PermitBatch: spender profile, every token with its amount (unlimited = uint160 max) and expiry.
  • ERC-2612 Permit: token, spender, value, deadline. A permit is an approval that costs you no gas; once signed the spender can call transferFrom any time before the deadline.
  • Seaport orders: what you offer against what the consideration pays you. A listing whose consideration pays you nothing is the classic NFT drain.
  • Safe transactions: operation = 1 is a delegatecall and is flagged as danger.
  • Delegation frameworks: granting rights over your account to another address is flagged unless you set it up yourself.
  • Anything else: fields named spender / operator / allowance are treated as approvals; nonce / sign-in messages are marked harmless.

Chain id mismatches and verifying contracts on a blocklist are always flagged.

What a replay cannot tell you ​

A simulation shows the effect now, at this block. It cannot show what a spender will do with an approval next week, and a contract can behave differently when it detects it is being simulated. That is why spenders are profiled separately, and why "verified" and "measured" are evidence, not proof. See Limits, honestly.

Grub · @grubonchain on X · open tools, no account · contracts unaudited · the official $GRUB address is published on the Contracts page first, anything before that is a scam.