Hartii Labs camel mark Hartii Labs× Quai mainnet

16 txs.
One block.
One agent.

An AI agent quoted, signed and fired 8 approvals and 8 buys from one wallet. All 16 confirmed in block 11103766. It took three tries, and the agent found its own bug on the way.

Try 1
0/ 20
Try 2 · one block
15/ 16
Try 3 · one block
16/ 16
node trade-batch.mjs --buy hbome qaxe hrt hash camel art tung qman --approve --execute
quote8 bonding curves, 8 router approvals, simulated on mainnetok
access16 access lists fetched (the fix from try 1)ok
sign16 transactions, nonces 745 → 760, nothing sent yetok
waithold for a fresh blockseen
fire16 broadcasts, back to backsent
landblock 1110376616 / 16 confirmed
Block #11103766
+ 17th in the same block: nonce 761, a zero-value marker transfer from the same wallet
#1110376616 / 16 · one block
Tap a transaction in the block to see its hash.

Three tries, one evening

22:18 UTC · block 11103458
0 / 20

Mined, all reverted

19 of 20 landed in one block, and every one failed. The agent traced it from the receipts.

22:38 UTC · block 11103684
1 / 1

Fix, then a canary

One small HBOME buy went first to prove the fix on chain before anything bigger.

22:40 UTC · block 11103709
15 / 16

All confirmed, one late

16 of 16 succeeded. 15 shared a block; the last buy landed six blocks later.

22:45 UTC · block 11103766
16 / 16

One block

8 approvals and 8 buys, nonces 745 to 760, all in block 11103766. A 17th transaction from the same wallet, a zero-value marker, landed in the same block. Cost 38.73 QUAI, gas included.

The bug it found

Quai enforces access lists. A contract call has to declare the storage it will touch. The normal send path asks the node for that list automatically.

To sign a whole batch up front, the agent built each transaction by hand and left the list out. Simulation does not check it, so the dry run passed and try 1 reverted on chain.

The agent read the receipts, saw every call had used its full gas limit with an empty access list, added the list to every transaction, wrote a test for it, and proved it with a single canary before retrying.

- tx = { to, data, value, nonce, gasLimit, gasPrice }
+ accessList = await provider.createAccessList(tx)
+ gasLimit   = estimateGas({ ...tx, accessList }) × 1.3
+ tx = { ...tx, accessList }

+ // a call with no access list is never built
+ // one canary transaction before any batch

Proof · block 11103766

NonceTypeTokenBlockStatusTransaction

Signer 0x00606Ee2fF3A26B20213906a41aa8CAfCB251237 (Hartii treasury). Buys of 0.25 QUAI per token, held. Approvals are for the HartiiSwap router and are capped at each buy's minimum output. The 17th transaction (nonce 761) is a plain zero-value transfer from the wallet to itself: it carries no data and writes nothing on chain beyond being in the block. Block numbers, nonces and hashes are from chain receipts; the replay animation is an illustration of the sequence, not recorded timing.