ricmoo / ethers-airdrop

A simple tool and library to deploy and manage a Merkle Air-Drop.
https://blog.ricmoo.com/merkle-air-drops-e6406945584d
93 stars 16 forks source link

Make Merkle Proof Check a Generic Solidity Contract #4

Closed NoahMarconi closed 6 years ago

NoahMarconi commented 6 years ago

The hashing is quite specific to AirDrops however the need to verify a Merkle proof is a general need.

contract MerkleTools {
    function verifyProof(uint256 index, bytes32 leaf, bytes32[] merkleProof) returns (bool)
    function hash ...

I can implement. Is there a way to make the hash function signature generic enough to handle a variety of leaf data structures?

ricmoo commented 6 years ago

Keep in mind that there needs to be great care taken in how a leaf hash is computed, or the height must be specified. The concern is a poorly chosen leaf format would result in me being able to provider an intermediate node as a leaf.

In the general case, imagine the poorly chosen leaf format keccak(bytes32:tokenId, bytes32:owner); I am purposefully making a weird choice of the owner being a bytes32 to demonstrate the issue, I will come up with a better example at some point :).

If this tree had a height of 10, the expected input would be a merkle proof of length 10, and I could redeem (tokenId, owner) and all would be happy. However, if I submit only the last 9 elements of the Merkle proof and pass in keccak256(tokenId, owner) as the token ID and merkleProof[9] as the redeemer, it would still validate; I would have assigned ownership of token ID keccak(token, id) to the merkleProof[9].

Ugh. It's hard to explain without a whiteboard. :p

Does that make sense though? I am planning to put an EIP together on Merkle Air-Drops, I should include a bit explaining (concisely) the importance of how to choose the Merkle Tree leaves...

NoahMarconi commented 6 years ago

In that case I'll close this for now. If after the EIP is submitted I still see value in decoupling the functionality I can always open a new issue.