{
  "tool_id": "art-605-merkle-airdrop-proof-verifier",
  "kernel_id": "art-605-merkle-airdrop-proof-verifier",
  "display_name": "Merkle Airdrop-Proof Verifier",
  "tool_version": "1.0.0",
  "mandate_type": "payment_policy",
  "purpose": "Recomputes a Merkle airdrop-claim proof from caller-declared leaf fields (address, uint256 amount, encoding_variant) and a sibling path, OpenZeppelin MerkleProof.verify shape (processProof/_hashPair over chaingraph/kernels/_noble-secp256k1.bundle.mjs's already-vendored keccak256, no new vendoring, no hand-rolled hashing). Leaf derivation follows OpenZeppelin StandardMerkleTree's (address,uint256) convention: encoding_variant selects the double-hash leaf (keccak256(keccak256(abi.encode(address,amount))), the default, second-preimage-resistant) or a single-hash variant some deployed contracts use instead -- never assumed, always a declared param. Sibling-pair hashing is sorted/commutative (OpenZeppelin's default _hashPair, pair_sort:true) or explicit per-step left/right position (pair_sort:false) -- also a declared param, never an assumption. Given an optional claimed_path (a prior run's per-step running hashes), re-verifies and reports the earliest step at which the recompute diverges, instead of only a final match/no-match. This node never reads any chain: it cannot know whether claimed_root is the root actually recorded on-chain, whether the leaf's allocation was already claimed or redeemed, or whether the underlying tree was built correctly from the full allocation list -- it only recomputes hashes from what the caller supplies.",
  "control_description": "Recomputes a Merkle airdrop-claim proof from caller-declared leaf fields (address, uint256 amount, encoding_variant) and a sibling path, OpenZeppelin MerkleProof.verify shape (processProof/_hashPair over chaingraph/kernels/_noble-secp256k1.bundle.mjs's already-vendored keccak256, no new vendoring, no hand-rolled hashing). Leaf derivation follows OpenZeppelin StandardMerkleTree's (address,uint256) convention: encoding_variant selects the double-hash leaf (keccak256(keccak256(abi.encode(address,amount))), the default, second-preimage-resistant) or a single-hash variant some deployed contracts use instead -- never assumed, always a declared param. Sibling-pair hashing is sorted/commutative (OpenZeppelin's default _hashPair, pair_sort:true) or explicit per-step left/right position (pair_sort:false) -- also a declared param, never an assumption. Given an optional claimed_path (a prior run's per-step running hashes), re-verifies and reports the earliest step at which the recompute diverges, instead of only a final match/no-match. This node never reads any chain: it cannot know whether claimed_root is the root actually recorded on-chain, whether the leaf's allocation was already claimed or redeemed, or whether the underlying tree was built correctly from the full allocation list -- it only recomputes hashes from what the caller supplies.",
  "declared_inputs": [],
  "declared_outputs": [],
  "kernel_digest": "sha256:b4ca349f69674d520b252804bfdcfb4e76d917db449c46bfdfa2ac1632ea2763",
  "trust_label": "independently verified: zkVM execution proof (risc0/groth16-bn254)",
  "data_vintage": "2026-08-12",
  "last_validated": "2026-08-12",
  "conformance_fixtures_vendored": true,
  "compute_proof_ready": "ready",
  "wave": 99,
  "source_url": "https://ainumbers.co/chaingraph/art-605-merkle-airdrop-proof-verifier.html",
  "generated_at": "2026-08-15T11:12:17.704Z"
}
