Add claim contract for weight-based fund distribution#405
Conversation
A CosmWasm contract that allows an admin to create distributions by sending funds along with a list of (address, weight) pairs. Users claim their proportional share across all active distributions in a single transaction. Expired distributions can be swept by anyone, returning unclaimed funds to a configured treasury address. Supports multi-denom distributions, duplicate address accumulation, lazy cleanup of expired claim entries, and proper storage error propagation.
There was a problem hiding this comment.
Pull request overview
Introduces a new CosmWasm claim contract that lets an admin create weight-based, multi-denom distributions with expiry, enabling users to claim their proportional share and allowing expired distributions to be swept to a treasury.
Changes:
- Adds the
claimcontract (instantiate/execute/query), including state, messages, errors, and schema generation. - Implements create-distribution, multi-distribution claiming, expiry checks, and sweep-to-treasury behavior.
- Adds unit tests and wires the contract into the workspace +
make schemaflow.
Reviewed changes
Copilot reviewed 11 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| contracts/claim/src/contract.rs | Core contract logic for creating distributions, claiming across active distributions, sweeping expired funds, and queries. |
| contracts/claim/src/state.rs | Defines on-chain storage layout for config, distributions, and per-user claims. |
| contracts/claim/src/msg.rs | Instantiate/execute message types (CreateDistribution, Claim, SweepExpired, UpdateConfig). |
| contracts/claim/src/query.rs | Query message types and response structs (config, distribution, pending claims). |
| contracts/claim/src/error.rs | ContractError definitions for execution failures. |
| contracts/claim/src/lib.rs | Crate module wiring and test module inclusion. |
| contracts/claim/src/testing.rs | Unit tests covering main execute/query paths and edge behaviors. |
| contracts/claim/src/bin/claim_schema.rs | Schema generation entrypoint for make schema. |
| contracts/claim/Cargo.toml | New contract crate manifest and dependencies. |
| Cargo.toml | Adds contracts/claim to the workspace members. |
| Makefile | Includes claim schema generation + TS codegen target for the new contract. |
| .changelog/unreleased/features/claim-contract.md | Changelog entry for the new claim contract feature. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
PR Review: Add claim contract for weight-based fund distribution Overall this is a well-structured new contract with good test coverage and clear separation of concerns. A few issues worth addressing before merge: BUGS / CORRECTNESS 1. Redundant Addresses are validated once when building 2. If all recipients claimed before expiry, 3. Missing CLAUDE.md states that the migration entrypoint must be implemented in GAS / SCALABILITY 4. Unbounded iteration in Both functions iterate over all distributions for a user in a single tx/query. If a user accumulates claims across many distributions, this will eventually exceed gas limits. Adding an optional STATE MANAGEMENT 5. After MISSING TEST COVERAGE The following error paths have no tests:
Also worth adding: a test confirming the 'all claimed before expiry' path, which currently triggers the misleading MINOR 6. No way to enumerate distributions. There is no 7. 8. Distribution IDs start at |
Records what each user claimed (amounts, timestamp, distribution ID) and exposes it via a ClaimHistory query with start_after/limit pagination.
dusan-maksimovic
left a comment
There was a problem hiding this comment.
Except from minor things, LGTM.
- Fix claim cleanup rollback: return Ok (no BankMsg) when only expired entries are cleaned up, instead of Err which rolls back state changes - Rename DistributionAlreadySwept to NoFundsToSweep (covers both swept and fully-claimed cases) - Use Addr as HashMap key to avoid double addr_validate - Sum weights during iteration instead of separate pass - Filter out zero-weight claim entries - Add funds attribute to create_distribution response - Add swept_funds attribute to sweep_expired response - Record claim history even for 0 funds claimed (leaves a trace)
Summary
claimcontract: admin creates distributions by sending funds with(address, weight)pairsClaimto receive their proportional share across all active distributions (multi-denom)Test plan
make compileto generate WASM artifactmake schemato generate JSON schemas and TS types