Problem Statement / Feature Objective
The settlement contract finalizes billing periods by minting utility tokens. Each settlement transaction processes one record per meter, leading to high gas costs. A batch finalization mechanism must be implemented that accepts a Merkle tree root of multiple settlement records, stores only the root on-chain, and supports individual settlement verification via Merkle inclusion proofs. This reduces on-chain storage from O(n) to O(1) per batch.
Technical Invariants & Bounds
- Batch structure:
(batch_id: u64, merkle_root: [u8;32], period_start: u64, period_end: u64, record_count: u32).
- Merkle tree: binary SHA256 tree; leaves are
(meter_id, amount, period_id) serialized with XDR.
- Batch submission cost: < 5000 gas per batch regardless of record count.
- Individual claim:
claim_settlement(batch_id, leaf_index, merkle_proof, meter_id, amount); contract verifies inclusion and emits Settled event.
- Batch expiry: if not fully claimed within 30 days, anyone may call
expire_batch() to free storage.
- Max records per batch: 65,535 (16-level Merkle tree).
Codebase Navigation Guide
contracts/settlement/src/batch.rs — batch struct, storage, lifecycle.
contracts/settlement/src/merkle.rs — Merkle inclusion verification.
contracts/settlement/src/lib.rs — submit_batch(), claim_settlement(), expire_batch() entry points.
lib/merkle-utils/ — off-chain Merkle tree builder.
Implementation Blueprint
- Implement
submit_batch(batch_id, merkle_root, period_start, period_end, record_count) storing only root.
- Implement
claim_settlement(batch_id, leaf_index, proof, meter_id, amount): verify MerkleProof.verify(root, leaf_hash, proof), then mint tokens.
- Implement
expire_batch(batch_id): only callable after 30 days; delete root entry.
- Build off-chain Merkle tree builder in
lib/merkle-utils/.
- Foundry test: submit batch with 1000 records, claim 500 via proofs, expire remaining, verify claims succeed and expiry frees storage.
Problem Statement / Feature Objective
The settlement contract finalizes billing periods by minting utility tokens. Each settlement transaction processes one record per meter, leading to high gas costs. A batch finalization mechanism must be implemented that accepts a Merkle tree root of multiple settlement records, stores only the root on-chain, and supports individual settlement verification via Merkle inclusion proofs. This reduces on-chain storage from O(n) to O(1) per batch.
Technical Invariants & Bounds
(batch_id: u64, merkle_root: [u8;32], period_start: u64, period_end: u64, record_count: u32).(meter_id, amount, period_id)serialized with XDR.claim_settlement(batch_id, leaf_index, merkle_proof, meter_id, amount); contract verifies inclusion and emitsSettledevent.expire_batch()to free storage.Codebase Navigation Guide
contracts/settlement/src/batch.rs— batch struct, storage, lifecycle.contracts/settlement/src/merkle.rs— Merkle inclusion verification.contracts/settlement/src/lib.rs—submit_batch(),claim_settlement(),expire_batch()entry points.lib/merkle-utils/— off-chain Merkle tree builder.Implementation Blueprint
submit_batch(batch_id, merkle_root, period_start, period_end, record_count)storing only root.claim_settlement(batch_id, leaf_index, proof, meter_id, amount): verifyMerkleProof.verify(root, leaf_hash, proof), then mint tokens.expire_batch(batch_id): only callable after 30 days; delete root entry.lib/merkle-utils/.