Johannes Zweng
2 min readJun 27, 2018


Hi! :-)

Edit: Sorry, I just realized that your Ethereum contract only reads the first 32 bytes from the calldata (first argument 0x20 to CALLDATACOPY). This way you are already comitting to a secret size of 32 bytes. Thus the contract isn’t susceptible for the secret size attack (because Alice also wouldn’t be able to redeem the ETH if her secret is longer than 32 bytes). So ignore my considerations below.. :)

Original response below:

Nice to see an actual HTLC swap between Ethereum and BTC! Great work! But your example in the current form would be vulnerable to the “secret size attack”:

In detail: if Alice would be a malicious actor she could choose a secret longer than 520 bytes and publish the resulting hash in her HTLC transaction.

Bob would have no way of knowing that the secret behind the hash is longer than 520 bytes. Alice can proceed in the protocol and use the secret to redeem the ETH out of Bob’s HTLC contract.

At this point in time Bob also knows the secret but he cannot use it to claim the BTC locked into Alice’s HTLC transaction as Bitcoin has a size limitation of 520 bytes for elements being pushed onto the stack:

So Bob knows the secret but is unable to use it due to this technical limitation of Bitcoin.

Alice now just has to wait until her OP_CHECKSEQUENCEVERIFY timeout expires, claims back her BTC and now has both, Bob’s ETH and her BTC.

This attack was described by Dr. Mark Lundeberg here in Februar this year:

He also shows a fix for this, by adding a size check to the redeeming condition so that the initiator (who makes up the secret) has to commit to the length of the secret beforehand (thus allowing the other party to check if the secret would usable on the other chain).