Repository navigation
Bailsec Parallel Savings Fix — audit remediation (Issues 01-05, 07) - #31
Merged
FabienCoutant merged 9 commits intoJul 13, 2026
Conversation
added 9 commits
June 26, 2026 08:10
…overnor for atomic upgrade
…cannot mint paused yield
…toredAssets after non-atomic upgrade
…orized deposit/redeem
FabienCoutant
force-pushed
the
audit/bailsec-june-2026-savings-donation
branch
from
July 13, 2026 08:44
e1c1b77 to
21a1b7a
Compare
FabienCoutant
merged commit Jul 13, 2026
aeb3262
into
feat/savings-donation-and-pause-refactor
4 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Remediation of the Bailsec "Parallel Fix" report (June 2026), stacked on top of the audited base (
61942aa, post-Cyfrin). One commit per finding.Final report: all findings Resolved / Acknowledged. Both the 1st and final reports are in
docs/audits/savings-fix/.Code findings
initializeStoredAssetsselector, so the prescribed atomicupgradeToAndCallreverts in production whenever the upgrading governor is not also the AccessManager admin. Granted the selector toGOVERNOR_ROLEinSetSavingRoles.s.soland in the test access config.initializeStoredAssetsseededstoredAssetsbut did not re-anchorlastUpdate, so the first accrual minted the pre-upgrade idle window. It now setslastUpdate = block.timestampafter seeding.totalAssets()projected yield while paused, overvaluing shares for external integrations. It now returnsstoredAssetsdirectly when paused.setRate/setMaxRateare callable while paused and accrued the paused interval._accrue()is now paused-aware: while paused it advanceslastUpdateand mints nothing, so the paused span is dropped.deposit/mint/withdraw/redeembypassed the parent ERC4626max*checks (those live in the public functions, not the internal_deposit/_withdraw). Re-introduced theERC4626ExceededMax*checks in each override. Follow-up (final report flagged it as partially resolved): the samemax*checks now also cover the EIP-3009 entry pointsdepositWithAuthorizationand_redeemWithAuthorization(inlined indepositWithAuthorizationto avoid stack-too-deep).storedAssets == 0whiletotalSupply != 0, breaking deposits and letting redeemers burn shares for nothing. Added anonlyInitializedguard (NotInitializedwhenstoredAssets == 0 && totalSupply != 0) on every vault entry point, including the EIP-3009 variants.Acknowledged (no code change)
initializeStoredAssetsremains callable once on a fresh deployment. It isrestrictedand only overwritesstoredAssetswith the current balance (already correctly seeded), so the practical risk is minimal.Tests
Added coverage for the re-anchored
lastUpdate, paused-statetotalAssets/rate-setters, the non-atomic-upgrade guard, and the authorized-redeem max check (test_RedeemWithAuthorization_RevertWhen_ExceedsMaxRedeem); updated the fuzz over-withdraw assertion to the earlierERC4626ExceededMaxWithdrawrevert. Local CI green: solhint,forge build --sizes, Savings units (39/39) + fuzz (27/27).