You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor(sra): strip review-process references and line-number anchors
Code comments: drop 'review B1/S1/S3/#7/Bug A' process wrappers per the
comments/content instructions — keep the design rationale (quarter is a
time property, mirror advances only forward, map/aggregate exclusion).
The B1/S1/S3 numbering collided with the docs' own decision registry
(minLot audit bound / QA-system fixes) — removing the code-side
references resolves the ambiguity.
Docs: replace line-number references (SRAQuarter:269, submitShares:547,
admit:324, ...) with stable file::symbol anchors (test names / invariant
names / function names). Line numbers are a fragile anchor — the id
identity rework shifted them +56-69 lines; symbol anchors never drift.
41 insertions / 41 deletions across 7 files, zero logic changes.
|**G2**| 64-full + submitShares combination untested |`SRAShares:300``test_SubmitShares_AtFullCapacity_SixtyFourRecipients`| all 64 post → map has exactly 64 recipients (mock MAX_RECIPIENTS boundary), 64-way even split with 1e18/64 each, Σ exact |
524
-
|**G3**| band exact ±20% boundary untested |*(removed with the PRICE_BAND check, FIPs#1275 — no on-chain band arithmetic remains; the tests `SRAQuarter:245...306`were deleted with the mechanism)*|`_checkPriceBand` boundary-inclusive semantics — obsolete (band machinery deleted) |
|**G2**| 64-full + submitShares combination untested |`SRAShares::test_SubmitShares_AtFullCapacity_SixtyFourRecipients`| all 64 post → map has exactly 64 recipients (mock MAX_RECIPIENTS boundary), 64-way even split with 1e18/64 each, Σ exact |
524
+
|**G3**| band exact ±20% boundary untested |*(removed with the PRICE_BAND check, FIPs#1275 — no on-chain band arithmetic remains; the tests were deleted with the mechanism)*|`_checkPriceBand` boundary-inclusive semantics — obsolete (band machinery deleted) |
525
525
|**G4**| MAX_PRICE_PERIODS exactly 32 untested |*(removed with the pricing-period vector, FIPs#1275 — no periods reach the chain; `test_PostVolume_MaxPricePeriods_ExactlyAccepted` deleted)*| on-chain price-period length cap — obsolete |
526
-
|**G5**| multi-quarter share isolation untested |`SRAShares:322``test_SubmitShares_MultiQuarter_Isolated`| quarter 0 posts A/B → quarter 1 only C posts → quarter 1 map contains only C (no residue), quarter 0 result unaffected |
527
-
|**G6**| failure-path asymmetry |`SRARegistry:328``test_Replace_AlreadyAdmittedTarget_Reverts` (replace target already admitted)<br>`SRARegistry:344``test_ReassignBinding_NotAdmittedTarget_Reverts` (target not admitted)<br>`SRARegistry:363``test_Remove_NotAdmitted_Reverts` (non-orchestrator)<br>`SRARegistry:375``test_Remove_FrozenOrch_Succeeds` (frozen orchestrator can be removed; implementation does not block) | governance failure branches: errors thrown at the third permissionless execution of the function body |
528
-
|**G7**| no fuzzing |`SRAShares:400``test_SubmitShares_Fuzz_SumAlwaysExact(uint256,uint256,uint256)`| 3 random usdValues (bounded < 1e30, aligned with the code-enforced MAX_FPV_USD — S3: sampling domain = enforced input domain, not a test-side shrink) → Σ shares always exactly == 1e18 (largest-remainder core invariant, 256 runs) |
526
+
|**G5**| multi-quarter share isolation untested |`SRAShares::test_SubmitShares_MultiQuarter_Isolated`| quarter 0 posts A/B → quarter 1 only C posts → quarter 1 map contains only C (no residue), quarter 0 result unaffected |
527
+
|**G6**| failure-path asymmetry |`SRARegistry::test_Replace_AlreadyAdmittedTarget_Reverts` (replace target already admitted)<br>`SRARegistry::test_ReassignBinding_NotAdmittedTarget_Reverts` (target not admitted)<br>`SRARegistry::test_Remove_NotAdmitted_Reverts` (non-orchestrator)<br>`SRARegistry::test_Remove_FrozenOrch_Succeeds` (frozen orchestrator can be removed; implementation does not block) | governance failure branches: errors thrown at the third permissionless execution of the function body |
528
+
|**G7**| no fuzzing |`SRAShares::test_SubmitShares_Fuzz_SumAlwaysExact(uint256,uint256,uint256)`| 3 random usdValues (bounded < 1e30, aligned with the code-enforced MAX_FPV_USD — S3: sampling domain = enforced input domain, not a test-side shrink) → Σ shares always exactly == 1e18 (largest-remainder core invariant, 256 runs) |
529
529
530
530
**Implementation issue found**: while writing the G1 tests it was found that the reference updates with each qualifying print (C6 semantics: the last one becomes the new reference) — the "new band applies" test was accordingly changed to directly verify that a value accepted under the old band is rejected after the band change (+20% over-band at band 10%, boundary at band 20%), avoiding reference-update interference with the assertion. (Later superseded by the anchored-reference semantics of deviation-D alignment, §4.3.9.)
**S2 — security-claim → code-enforcement map** (§5.1 table): every "Safe"/"Conditionally safe" conclusion now cites the enforcing code point (require / mechanism); a claim without an enforcement reference fails review. Maps all 8 categories (e.g. Integer overflow → the single `MAX_FPV_USD` bound @ postVolume + correctVolume; DoS caps → `MAX_PAIRS(64)` / `MAX_ALLOWLIST(64)` / `MAX_ORCHESTRATORS(64)`).
698
698
699
-
**S3 — evidence-application-condition annotation**: the fuzz sampling domain `(0,1e30)` is re-annotated as **equal to the code-enforced MAX_FPV_USD** (not a test-side shrink — `SRAShares:400` + `SRAInvariant:255,268`); the largest-remainder algorithm properties are covered by the differential suite (bit-exact fixed cases) + invariant fuzz, with the enforced absolute domain's arithmetic safety independently covered by the §5.5 domain-math bounds (docs §4.3.8 S3 note).
699
+
**S3 — evidence-application-condition annotation**: the fuzz sampling domain `(0,1e30)` is re-annotated as **equal to the code-enforced MAX_FPV_USD** (not a test-side shrink — `SRAShares::test_SubmitShares_Fuzz_SumAlwaysExact` + `SRAInvariant::invariant_NonZeroTotal_ValidShareMap`); the largest-remainder algorithm properties are covered by the differential suite (bit-exact fixed cases) + invariant fuzz, with the enforced absolute domain's arithmetic safety independently covered by the §5.5 domain-math bounds (docs §4.3.8 S3 note).
700
700
701
701
**S4 — threat model matrix** (§5.13): all 15 external write functions × (malicious orchestrator / compromised owner) → impact → mitigation → sufficiency; every function is closed either by unanimous dual-Safe governance or by code-enforced input bounds + timing gates.
702
702
@@ -780,9 +780,9 @@ forge coverage --match-contract SRA # SRA line coverage 100% (branch 67% is
| 1 | Reentrancy | ✅ Safe | no value transfer; the only external call is an fvm precompile with no callback surface | no value transfer (no `payable`/`call`/`transfer` anywhere in `src/ServiceRewardsActor.sol`); the only external call is `FVMRewards.setShares` (fvm precompile, no callback), `submitShares:547`|
784
-
| 2 | Denial of Service (DoS) | ✅ Safe (S13) | all traversals have hard caps (64); replace is an O(1) wallet re-point — no alias chain |`registerPairs``pairs.length <= MAX_PAIRS(64)``:262`; `setAdmittedLists``length <= MAX_ALLOWLIST(64)``:451`; `admit``admittedIds.length < MAX_ORCHESTRATORS(64)``:324`; `postVolume`/`correctVolume` take a single USD value — no period array to traverse (FIPs#1275). Freeze determination is O(1) (stored flag, mirror refactor); the former alias-chain growth point is structurally eliminated (S13) |
| 1 | Reentrancy | ✅ Safe | no value transfer; the only external call is an fvm precompile with no callback surface | no value transfer (no `payable`/`call`/`transfer` anywhere in `src/ServiceRewardsActor.sol`); the only external call is `FVMRewards.setShares` (fvm precompile, no callback), `submitShares`|
784
+
| 2 | Denial of Service (DoS) | ✅ Safe (S13) | all traversals have hard caps (64); replace is an O(1) wallet re-point — no alias chain |`registerPairs``pairs.length <= MAX_PAIRS(64)`; `setAdmittedLists``length <= MAX_ALLOWLIST(64)`; `admit``admittedIds.length < MAX_ORCHESTRATORS(64)`; `postVolume`/`correctVolume` take a single USD value — no period array to traverse (FIPs#1275). Freeze determination is O(1) (stored flag, mirror refactor); the former alias-chain growth point is structurally eliminated (S13) |
| 4 | Integer overflow | ✅ Safe | 0.8.x checked arithmetic fully on; **input-domain bound enforced at the entries** (single `MAX_FPV_USD=1e30`, audit V3 fix); the enforced absolute domain's arithmetic safety is covered by the §5.5 domain-math bounds (S3: proof premise = code-enforced domain) | the single `MAX_FPV_USD` bound at **both** input entries — `postVolume` and `correctVolume`; `_computeShares` chain: per-orch usd × 1e18 ≤ 1e48, total ≤ 6.4e31 ≪ 2^256 (§5.5); checked arithmetic (0.8.36 default) |
787
787
| 5 | Encoding and boundaries (ABI/CBOR) | ⚠️ Conditionally safe | input side protected by the ABI decoder; output side bounded CBOR; wire contract pending f02 implementation check | input side: Solidity ABI decoder (compile-time, rejects malformed calldata); output side: bounded CBOR in f02 mock (`test/mocks/FVMRewardActor.sol`); wire contract vs real f02 implementation is a protocol-layer premise (no contract-layer code can enforce it) |
788
788
| 6 | Precision issues | ✅ Safe | floor + largest-remainder Σ==1e18; conservation/monotonicity/floor bound covered by the differential suite (bit-exact) + invariant fuzz (SumShares) — the Halmos symbolic checks were removed with the FixedU18 adoption (§5.10) |`_computeShares` largest-remainder method `:683` (Σ shares == SHARE_TOTAL exactly, remainder descending + residue top-ups); shares depend only on USD ratios — no rate arithmetic on chain (FIPs#1275) |
0 commit comments