Users prove they're compliant with your requirements without revealing any other information
sanction_list = {0xb12..., 0x5f2..., 0x107..., ...}
require sender not in sanction_list
fn main(
address: pub Field,
root: pub Field,
lower_leaf: Field,
upper_leaf: Field,
lower_index: Field,
upper_index: Field,
lower_hash_path: [Field; 32],
upper_hash_path: [Field; 32],
proof_type: u8,
) {
if proof_type == 0 {
assert(lower_leaf.lt(address), "lower_leaf must be less than address");
assert(address.lt(upper_leaf), "address must be less than upper_leaf");
assert(upper_index == lower_index + 1, "leaves must be adjacent");
let lower_root = compute_merkle_root(lower_leaf, lower_index, lower_hash_path);
assert(lower_root == root, "lower_leaf merkle proof invalid");
let upper_root = compute_merkle_root(upper_leaf, upper_index, upper_hash_path);
assert(upper_root == root, "upper_leaf merkle proof invalid");
} else if proof_type == 1 {
assert(address.lt(upper_leaf), "address must be less than first leaf");
assert(upper_index == 0, "first leaf must be at index 0");
let upper_root = compute_merkle_root(upper_leaf, upper_index, upper_hash_path);
assert(upper_root == root, "first leaf merkle proof invalid");
} else {
assert(lower_leaf.lt(address), "last leaf must be less than address");
let lower_root = compute_merkle_root(lower_leaf, lower_index, lower_hash_path);
assert(lower_root == root, "last leaf merkle proof invalid");
let empty_root = compute_merkle_root(0, lower_index + 1, upper_hash_path);
assert(empty_root == root, "next position must be empty");
}
}
SafeSwap and CleanMixer require a proof of the same compliance definition: your address is not on a specific sanction list. Generate the proof once and use it for both applications.
VerifiedLend requires a proof that your address is on a specific whitelist.
(These example applications are simply ERC-20 contracts for demonstration purposes)