feat(EXSC-413): S5 — pause (instance + global-read; withdrawals-always-open)#1982
Draft
gvladika wants to merge 3 commits into
Conversation
Contributor
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
9 tasks
S5. Add VaultWrapperPausable abstract mixin with two independent instance flags (emergencyPaused via the LI.FI emergency multisig read live from the factory, integratorPaused via the vault admin) plus a live factory.globalPaused() read. The pause guard is wired into deposit/mint only; withdraw/redeem stay structurally open under every pause combination. _requireNotPaused was removed from the shared _beforeOperation (which previously gated exits too) and replaced by _requireDepositsNotPaused on inflows — fixing the latent freeze-on-exit defect. ILiFiVaultWrapperFactory gains globalPaused()/emergencyPauser() view declarations (already satisfied by the factory's public getters). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adversarial review gaps: add a real-factory end-to-end suite proving factory.globalPause() freezes a live instance's deposits (and unpause resumes), plus the documented carve-out that a deploy while globally paused yields a frozen-from-birth instance. Cover mint() under integrator and global pause, and withdraw-open under global-pause-alone. Blank line after pragma in LiFiVaultWrapper. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Append-only upgrade gap so the pause mixin can gain state without shifting the storage of the contracts that inherit it, consistent with the wrapper's own gap. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
b0e15d6 to
f83fbb7
Compare
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.
Which Linear task belongs to this PR?
EXSC-413 — S5: Pause (instance + global-read; withdrawals-always-open)
Stacked PR. Base is
feature/exsc-408-s11-access-interfaces-reference-adapter(#1981, S11). Review the incremental diff against the base; do not merge before its parents (S1 → S11) land. Stack: S1 → S11 → S5 → S3.Why did I implement it this way?
S5 is the clone-side pause: enforcement + the live reads. The factory-side global flag and emergency-role plumbing already exist from S8 (merged into S1); this PR makes instances honour them and adds the two instance-level pauses.
VaultWrapperPausablemixin (the ticket's "pause module"). Two independent instance flags so neither authority can lift the other's pause:emergencyPaused(toggled by the LI.FI emergency multisig) andintegratorPaused(toggled by the integrator). Plus a livefactory.globalPaused()read.depositsPaused() = emergencyPaused || integratorPaused || globalPaused()._emergencyPauseAuthority()returnsfactory.emergencyPauser()so rotating the emergency multisig at the factory propagates to every instance with no clone change;_integratorPauseAuthority()is the per-vaultvaultWrapperAdmin. The wrapper supplies these via threevirtualhooks the mixin declares, keeping the mixin storage-agnostic._requireDepositsNotPaused()is wired intodeposit/mintonly. Critically, the prior no-op_requireNotPaused()lived inside the shared_beforeOperation()that also runs onwithdraw/redeem— so implementing it there would have frozen user exits during an emergency, the opposite of a circuit breaker. It was removed from_beforeOperation()(now access + accrual only) and replaced by the inflow-only guard. Self-withdraw therefore works under every pause combination; the fee sweep bypass lands with S3.globalPaused()/emergencyPauser()view declarations — already satisfied by the factory's existing public-getter state vars, so no factory code change and no version bump (subsystem is unreleased).Tests
VaultWrapperPause.t.sol(16) uses aMockPauseFactorythat deploys the proxy (so it is thefactorythe instance reads back) and toggles the global flag: deposit/mint revert under each of the three pause sources; withdraw/redeem succeed under emergency, integrator, and all-combined pauses; integrator vs LI.FI authority separation (each cannot drive or lift the other's pause; strangers rejected); unpause resumes; thedepositsPaused()view and pause events. The existingLiFiVaultWrapper.t.sol(whosefactoryis the test contract) gainedglobalPaused()/emergencyPauser()shims so its deposits still resolve.Checklist before requesting a review
/pr-ready(local CodeRabbit) on this branch and resolved (or explicitly documented) all findings — see.agents/commands/pr-ready.mdChecklist for reviewer (DO NOT DEPLOY and contracts BEFORE CHECKING THIS!!!)