Hi team
One root cause with two impacts: the replay key derives from the submitted byte string instead of the canonical transaction identity.
Impact one. PulledThreads is keyed on a hash of the submitted bytes. Re-encoding the varint length prefix changes the key while compute_txid still matches the same Merkle proof and mints again. I executed this at HEAD: the honest claim minted, the 0xfd re-encoding minted again at double balance, the 0xfe re-encoding minted again at triple balance. Proven multiplier is 3 mints per deposit; a fourth 0xff encoding is credible through the same read-varint arm but was not executed. No victim is needed.
Impact two. The sequential_hash helper truncates elements, so two deposits spending vout 0 and vout 1 of one parent share the first 32 bytes and differ at byte 37, producing the same replay key. I built that witness from scratch: the first claim minted 100000, the second claim returned ThreadAlreadyPulled and minted nothing. That is a permanent honest deposit loss for the second depositor, first claimant wins.
witness: two deposits, one parent, vout 0 and vout 1, distinct receivers
first 32 bytes equal, byte 37 differs, txids differ, keys equal
claim 1 -> mints 100000 ; claim 2 -> ThreadAlreadyPulled, mints 0
Warning for the fix: repairing only the sequential_hash helper leaves impact one live and enlarges it, because a full-byte key still derives from the submitted bytes, so re-encoded varints mint fresh keys and the bounded multiplier becomes unbounded. The single change that kills both impacts is keying PulledThreads on the canonical compute_txid result: one logical transaction then gets one key under every accepted encoding.
Both impacts inherit the weaver pool gate at HEAD, so claims are block-author gated until the pool gate ships.
Shahmeer