pico-quorum

Running the GS021 reproduction

repro.mjs shows Safe{Wallet}’s GS021 with a contract-owner confirmation, and the fix, on your own machine. It needs about ten seconds and no keys or funds. Everything happens on a local Anvil fork of Base Sepolia, with throwaway keys, and nothing is sent to a real chain.

What you need

Run it

Terminal 1: the fork. Leave it running.

~/.foundry/bin/anvil --fork-url https://sepolia.base.org --port 8547

It prints a banner and ends with Listening on 127.0.0.1:8547. Its test accounts aren’t used.

Terminal 2: the reproduction.

cd ~/git/pico-quorum/docs/upstream/safe-wallet-gs021/repro
npm ci            # first time only: viem, @noble/curves and @safe-global/protocol-kit at the locked versions
node repro.mjs

What you should see

fork of Base Sepolia at http://127.0.0.1:8547, block 47298253

2-of-2 EOA + passkey: Safe 1.5.0, 2-of-2; confirmations sorted by owner: EOA, contract
  current (createExistingTx) 450 bytes -> reverts GS021
  fixed (toSafeSignature)    450 bytes -> simulation OK
  executed with the fixed layout: ExecutionSuccess true, recipient +1000000000000 wei, logged signatures = fixed: true

3-of-3 passkey + EOA + passkey: Safe 1.5.0, 3-of-3; confirmations sorted by owner: contract, EOA, contract
  current (createExistingTx) 835 bytes -> reverts GS021
  fixed (toSafeSignature)    835 bytes -> simulation OK
  executed with the fixed layout: ExecutionSuccess true, recipient +1000000000000 wei, logged signatures = fixed: true

1-of-2 control: Safe 1.5.0, 1-of-2; confirmations sorted by owner: contract, EOA
  current (createExistingTx) 450 bytes -> simulation OK
  fixed (toSafeSignature)    450 bytes -> simulation OK
  executed with the fixed layout: ExecutionSuccess true, recipient +1000000000000 wei, logged signatures = fixed: true

Only the block number changes from run to run. How to read each line:

More

If something goes wrong: