Recently, I saw that Blur had a twitter dependent airdrop. So basically you had to tweet and then you would get the option to claim tokens. I went to analyze the code, but it is overwhelming for me.
This is the claim function:
function claim(
address account,
uint256 amount,
bytes32[] memory proof
) external {
bytes32 leaf = keccak256(abi.encodePacked(account, amount));
require(!claimed[leaf], "Airdrop already claimed");
MerkleVerifier._verifyProof(leaf, merkleRoot, proof);
claimed[leaf] = true;
require(IERC20(token).transfer(account, amount), "Transfer failed");
emit Claimed(account, amount);
}
This is the Merklee Verifier:
pragma solidity 0.8.17;
/**
* @title MerkleVerifier
* @dev Utility functions for Merkle tree computations
*/
library MerkleVerifier {
error InvalidProof();
/**
* @dev Verify the merkle proof
* @param leaf leaf
* @param root root
* @param proof proof
*/
function _verifyProof(
bytes32 leaf,
bytes32 root,
bytes32[] memory proof
) public pure {
bytes32 computedRoot = _computeRoot(leaf, proof);
if (computedRoot != root) {
revert InvalidProof();
}
}
/**
* @dev Compute the merkle root
* @param leaf leaf
* @param proof proof
*/
function _computeRoot(
bytes32 leaf,
bytes32[] memory proof
) public pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
bytes32 proofElement = proof[i];
computedHash = _hashPair(computedHash, proofElement);
}
return computedHash;
}
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
}
function _efficientHash(
bytes32 a,
bytes32 b
) private pure returns (bytes32 value) {
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}
My theory is that each time a user tweets, the website recognizes this and embeds a special proof in the transaction, which is then computed with the amount and address and finally verified with the root proof(the only owner function). What I don't understand is why can't this system be cheated? Can't we just copy one of the proofs into the transaction and avoid the twitter verfication?