Skip to content

refactor: deduplicate membership lookup in automated claim target - #195

Open
franrolotti wants to merge 1 commit into
devfrom
refactor/dedupe-automated-claim-membership-lookup
Open

franrolotti wants to merge 1 commit into
devfrom
refactor/dedupe-automated-claim-membership-lookup

Conversation

@franrolotti

Copy link
Copy Markdown
Contributor

Closes #168

What

AutomaticSavingCircles._executeAutomatedClaimTarget called getCircleMembers (copying the whole member array across an external call) only to find one member's index, then re-resolved membership again inside isMemberWithdrawable and withdrawFor.

  • Reads the index with SavingCircles.memberIndex, an O(1) mapping lookup, instead of fetching the array. memberIndex already existed on SavingCircles; it is now declared in ISavingCircles (adds override / @inheritdoc, no logic or storage change).
  • Drops the explicit NotMember pre-check: isMemberWithdrawable and withdrawFor already reject non-members.
  • Removes the now-unused _getMemberIndex helper.

The batch/view paths (getEligibleAutomatedClaims, the eligible count) really do iterate every member, so they are unchanged.

Behavior change

A non-member target (an address can opt in to automatic claims without being a member) now fails with NotWithdrawable instead of NotMember. This is visible in the AutomatedClaimFailed event reason, so worth a look if an indexer or the frontend keys off it. Covered by a new test. Nothing can be claimed for a non-member either way.

memberIndex returns 0 for non-members, indistinguishable from the first member, which is why the eligibility check is what rejects them. This is documented on the interface.

Gas

forge snapshot on AutomaticSavingCircles.t.sol, before -> after:

test before after
BatchExecuteAutomatedClaims_ContinuesWhenOneTargetFails 524,883 522,032 (-2,851)
ClaimCheckerPayload_ClaimsForEligibleMembersAcrossAllCircles 1,519,438 1,514,046 (-5,392)
PerformUpkeep_ClaimsForEligibleMembersAcrossAllCircles 1,513,829 1,508,437 (-5,392)

Small on purpose: the test circles have only a few members, and the saved work grows with member count.

Deployment note

AutomaticSavingCircles is not upgradeable and points at SavingCircles via constructor, so this needs a redeploy of the automation contract, and the target network's SavingCircles must already expose memberIndex(uint256,address).

Test plan

  • forge fmt --check
  • forge test (all suites pass; 38 in AutomaticSavingCircles, 1 new)

…er list

_executeAutomatedClaimTarget copied the whole member array across an external
call just to find one index. Read it with the O(1) SavingCircles.memberIndex
getter instead (now part of ISavingCircles), and drop the redundant NotMember
pre-check since isMemberWithdrawable and withdrawFor already reject non-members.

A non-member target now fails with NotWithdrawable instead of NotMember.
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

Metric Coverage
Lines 93.79% (650/693)
Statements 91.44% (791/865)
Branches 76.33% (129/169)
Functions 94.29% (99/105)
Coverage by file
File Lines Statements Branches Functions
src/contracts/AutomaticSavingCircles.sol 95.14% (176/185) 89.30% (217/243) 58.93% (33/56) 100.00% (33/33)
src/contracts/SavingCircles.sol 98.32% (293/298) 96.24% (358/372) 85.19% (69/81) 97.78% (44/45)
src/contracts/SavingCirclesViewer.sol 86.19% (181/210) 86.40% (216/250) 84.38% (27/32) 81.48% (22/27)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deduplicate membership lookup in AutomaticSavingCircles._executeAutomatedClaimTarget

1 participant