🟡 Priority: High
Difficulty: Hard
Estimated Effort: 4-5 days
Relevant Files: contracts/src/lib.rs
Labels: enhancement, priority:high, feature
Requirements
-
Multiple Group Types
- The current contract assumes strict Ajo/Esusu (rotational payout). Kolo backend PRD mentions goal-based savings.
- Add an enum
GroupType with variants Rotational and GoalBased.
- Pass
group_type to initialize() and store it in instance data.
-
Goal-Based Logic
- If
GoalBased:
- There is no single
payout to one member per cycle.
- Members contribute towards a personal or group goal.
- Add a
TargetAmount parameter during initialization.
- Members can withdraw their own accumulated contributions at any time, OR only when the target date/amount is reached (configurable).
-
Refactoring State
- Rotational specific state (
HasReceivedPayout, CycleMemberCount) should only be checked and updated if GroupType == Rotational.
- GoalBased groups need a new withdrawal function:
pub fn withdraw_savings(env: Env, member: Address, amount: i128).
- Ensure
withdraw_savings checks that the member actually has amount available in their Contributions balance.
-
Hybrid Validation
contribute() behavior remains mostly the same, but GoalBased groups might not enforce a strict identical ContributionAmount (allow flexible deposits).
- If
GoalBased, skip the amount != expected_amount check.
-
Testing
- Unit test: Initialize as
GoalBased, member deposits varying amounts, member withdraws partial amount.
- Unit test: Initialize as
Rotational, ensure strict exact-amount deposits and rotational payouts still function as before.
- Unit test:
GoalBased member tries to withdraw more than they deposited (panics).
- Target: >85% coverage across both group types.
🟡 Priority: High
Difficulty: Hard
Estimated Effort: 4-5 days
Relevant Files:
contracts/src/lib.rsLabels:
enhancement,priority:high,featureRequirements
Multiple Group Types
GroupTypewith variantsRotationalandGoalBased.group_typetoinitialize()and store it in instance data.Goal-Based Logic
GoalBased:payoutto one member per cycle.TargetAmountparameter during initialization.Refactoring State
HasReceivedPayout,CycleMemberCount) should only be checked and updated ifGroupType == Rotational.pub fn withdraw_savings(env: Env, member: Address, amount: i128).withdraw_savingschecks that the member actually hasamountavailable in theirContributionsbalance.Hybrid Validation
contribute()behavior remains mostly the same, butGoalBasedgroups might not enforce a strict identicalContributionAmount(allow flexible deposits).GoalBased, skip theamount != expected_amountcheck.Testing
GoalBased, member deposits varying amounts, member withdraws partial amount.Rotational, ensure strict exact-amount deposits and rotational payouts still function as before.GoalBasedmember tries to withdraw more than they deposited (panics).