I was reading the wonderful paper Computationally sound Bitcoin tokens linked in this forum post. It introduced more powerful form of covenants, called “neighbourhood covenants” that makes it possible to efficiently implement fungible tokens (ERC20-like) on Bitcoin.
It claims to prevent forging attacks, where an attacker forges tokens with the same token id. However, it assumes the attacker has to forge from the minting transaction. What if the attacker forges a transaction after minting as follows.
T0’ can a normal P2PKH transaction. The attacker can create T1 spending T0’ and copies from a legit FooToken’s output and pastes it in its output. From then on, T1 can be spent like a FooToken and can be joined with other real FooToken’s. Am I missing something?
the attack scenario you are considering is exactly the one described in the paragraph “Thwarting forgery attacks” in Section II of the paper, where we show that an adversary can successfully mint units of any existing token (in your example, FT).
Although in general one cannot prevent the adversary from minting units of existing tokens, the script proposed in the paper makes it impossible to spend them. This is achieved by requiring, in the script, that:
the token identifier (tkid) is preserved along the chain of transactions, and
in a token-minting transaction, tkid corresponds to the txid of the spent parent transaction output. More precisely, the script requires that ctxo.arg.4 = txid(ptxo(1)), where ctxo.arg.4 is the token identifier and txid(ptxo(1)) is the hash of the spent transaction output.
In your chain of transactions, the latter check fails when trying to redeem T1. Indeed, T1 is not spendable, because the script FT requires that ctxo.arg.4 = txid(ptxo(1)), but: