Skip to content

fix: prevent over-allocation double-collection in presentPOI auto-downsize#1342

Draft
RembrandtK wants to merge 3 commits into
mainfrom
fix/over-allocation-double-collect
Draft

fix: prevent over-allocation double-collection in presentPOI auto-downsize#1342
RembrandtK wants to merge 3 commits into
mainfrom
fix/over-allocation-double-collect

Conversation

@RembrandtK
Copy link
Copy Markdown
Contributor

When an over-allocated indexer presents a POI, presentPOI collects rewards and updates the allocation in storage (snapshotRewards / clearPendingRewards), then auto-downsizes it. It was passing the stale memory snapshot captured at the top of the function into _resizeAllocation, which recomputed the accumulator delta from the pre-snapshot value and re-credited accRewardsPending with the rewards just paid out. The indexer could then collect them again on the next POI.

_resizeAllocation now reads the current allocation state from storage instead of accepting a caller-supplied copy, removing the stale-snapshot hazard for both the auto-downsize and explicit-resize paths.

Includes failing-then-passing unit and integration regression tests.

Incidental, in separate commits:

  • a small refactor narrowing _distributeIndexingRewards to take the indexer address rather than the full allocation struct (no behavioural change).
  • a test-comment cleanup reframing a few regression tests to state the expected invariant instead of narrating the original bug.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes reward accounting in presentPOI over-allocation auto-downsize by ensuring resize logic reads the current allocation state from storage, preventing stale snapshots from re-crediting already collected rewards.

Changes:

  • Updates _resizeAllocation to load allocation state internally and adjusts callers accordingly.
  • Adds unit and integration regression coverage for over-allocation reward collection and zero-token resize behavior.
  • Cleans up related test comments to describe invariants rather than historical bugs.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/subgraph-service/contracts/libraries/AllocationHandler.sol Updates resize internals to avoid stale allocation snapshots and narrows reward distribution inputs.
packages/subgraph-service/test/unit/subgraphService/SubgraphService.t.sol Tightens expected post-collection pending reward invariant.
packages/subgraph-service/test/unit/subgraphService/collect/indexing/indexing.t.sol Adds unit regressions for over-allocation resize and double-collection prevention.
packages/subgraph-service/test/integration/after-transition-period/subgraph-service/indexer.test.ts Adds integration coverage for second POI collection after over-allocation resize.
packages/subgraph-service/test/integration/after-transition-period/subgraph-service/permisionless.test.ts Updates stale-allocation expectations to match resize-to-zero behavior.
packages/testing/test/harness/FullStackHarness.t.sol Makes RewardsManager deployment pluggable for real-rewards integration tests.
packages/testing/test/harness/RealRewardsHarness.t.sol Adds harness support for loading the production RewardsManager artifact.
packages/testing/test/integration/IndexingRewardsCollection.t.sol Adds real RewardsManager regression test for single collection per accrual.
packages/testing/foundry.toml Grants read access to RewardsManager artifact path for bytecode-loaded tests.
packages/issuance/test/unit/agreement-manager/fundingModes.t.sol Reframes escrow deficit test comments around the invariant.
packages/issuance/test/unit/agreement-manager/cancelWithPendingUpdate.t.sol Reframes pending-update cancellation test comments and name.
packages/contracts-test/tests/unit/rewards/rewards-snapshot-inversion.test.ts Cleans up reward snapshot inversion invariant documentation.
packages/contracts-test/tests/unit/rewards/rewards-signal-allocation-update.test.ts Cleans up signal/allocation accounting invariant documentation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/testing/foundry.toml Outdated
@openzeppelin-code
Copy link
Copy Markdown

openzeppelin-code Bot commented May 29, 2026

fix: prevent over-allocation double-collection in presentPOI auto-downsize

Generated at commit: f3b6a93481bd0c1eb688837d6784ee73e600bd99

🚨 Report Summary

Severity Level Results
Contracts Critical
High
Medium
Low
Note
Total
3
5
0
14
38
60
Dependencies Critical
High
Medium
Low
Note
Total
0
0
0
0
0
0

For more details view the full report in OpenZeppelin Code Inspector

@codecov
Copy link
Copy Markdown

codecov Bot commented May 29, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.16%. Comparing base (67c3428) to head (f3b6a93).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1342   +/-   ##
=======================================
  Coverage   91.16%   91.16%           
=======================================
  Files          81       81           
  Lines        5318     5319    +1     
  Branches     1128     1128           
=======================================
+ Hits         4848     4849    +1     
  Misses        448      448           
  Partials       22       22           
Flag Coverage Δ
unittests 91.16% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…nsize

When an over-allocated indexer presents a POI, presentPOI takes rewards and
updates the allocation in storage (snapshotRewards / clearPendingRewards),
but passed the stale memory snapshot captured at the top of the function
into _resizeAllocation. That snapshot recomputed the reward accumulator
delta from the pre-snapshot value and re-credited accRewardsPending with the
rewards just paid out, letting the indexer collect them again on the next POI.

_resizeAllocation now reads the current allocation state from storage itself
instead of accepting a caller-supplied copy, so neither caller has to keep a
memory copy in sync with storage. This removes the stale-snapshot hazard for
both the auto-downsize and explicit-resize paths.

Includes failing-then-passing unit and integration regression tests.
_distributeIndexingRewards only needs the (immutable) indexer, not the full
allocation struct. Pass allocation.indexer instead of the whole IAllocation.State,
so a post-snapshot distribution path cannot hand a stale allocation copy to a
callee. Preventative follow-up to the over-allocation double-collection fix; no
behavioural change.
…gression tests

Several regression tests narrated the bug they were born from ("THE BUG: with
the original buggy code...", "Old code: A.sub(S).add(P) reverts...", "the old
buggy ... approach") in comments and assertion messages. Once the underlying fix
lands, that narration is stale and misleading: it describes code that no longer
exists rather than the invariant the test guards.

Reframe the comments and assertion messages to state the expected behaviour as a
permanent property (snapshot-delta distribution regardless of same-block ordering;
underflow-safe A.add(P).sub(S) under an inverted snapshot state; per-provider
escrow deficit; pending-update escrow freed on cancel). Also rename two tests whose
identifiers referenced the old bug: PendingUpdateEscrowNotFreed -> ...Freed (the
test verifies escrow IS freed) and a snapshot test's "post-fix steady state" ->
"synced snapshot steady state".

Comments and message strings only; no test logic, values, or assertions changed.
@RembrandtK RembrandtK force-pushed the fix/over-allocation-double-collect branch from e3ebef9 to f3b6a93 Compare May 29, 2026 15:25
@RembrandtK RembrandtK requested a review from Maikol May 29, 2026 15:45
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.

3 participants