Skip to content

feat: add DepositCapStateGuard batch pre-check#2

Open
maxencerb wants to merge 4 commits into
mainfrom
feat/deposit-cap-state-guard
Open

feat: add DepositCapStateGuard batch pre-check#2
maxencerb wants to merge 4 commits into
mainfrom
feat/deposit-cap-state-guard

Conversation

@maxencerb

@maxencerb maxencerb commented Jul 6, 2026

Copy link
Copy Markdown

Summary

Adds src/checks/DepositCapStateGuard.sol, a small stateless, read-only guard that asserts a Facility intent's deposit cap and total supply match caller expectations, and reverts otherwise.

Intended usage

The guard must be used as the first call of a batch transaction (e.g. an EIP-7702 batch) executed in the mode where any failing call reverts the whole batch. The batch calls requireState first; if the on-chain state no longer matches what was expected when the batch was signed (a deposit cap was changed, or deposits/withdrawals moved the supply), the read-only call reverts and the rest of the batch reverts with it — so no state-changing call ever executes against stale state.

Design notes

  • Supply is checked against an inclusive [minSupply, maxSupply] range rather than an exact value, so benign concurrent deposits/withdrawals within the tolerated band don't race the batch into a revert. Passing minSupply == maxSupply degenerates to an exact-supply check.
  • The deposit cap is checked for exact equality, since cap changes are exactly the state transitions the guard is meant to catch.
  • The contract is stateless and permissionless: it holds no storage, grants no roles, and takes the Facility as a call parameter, so a single deployment serves any Facility.
  • Facility.totalSupply(uint256) is a public getter on the implementation but is not declared on IFacility, so the guard declares the one view it needs locally.

Testing

  • New test/DepositCapStateGuard.t.sol suite (11 tests, incl. a fuzz test over the supply range logic) covering in-range/edge/exact passes, below/above range, stale cap, inverted range, multi-intent batches, and empty checks.
  • MockFacility gained totalSupply/setTotalSupply knobs; full suite passes (45/45).

Summary by CodeRabbit

  • New Features

    • Added DepositCapStateGuard, a read-only batch precheck that validates each intent’s total supply is within an inclusive range and that the deposit cap matches exactly.
    • Supports multiple checks per call and reverts with clear, specific failure reasons.
  • Tests

    • Added a full Forge test suite covering success cases, failure cases, multi-intent batches, and fuzzed supply-range validation.
    • Updated test mocks to provide total supply lookups needed by the guard.
  • Documentation

    • Documented how to use the guard as the first step in batch execution, including expected cap/supply behavior.

Deployment

  • script/DeployDepositCapStateGuard.s.sol deploys the guard through the canonical CREATE2 factory (0x4e59b44847b379578588920cA78FbF26c0B4956C) with a salt ground for a 0x3fa77e57 ("3F ATTEST") vanity prefix, so it lands on the same address on every chain:

    DepositCapStateGuard: 0x3Fa77E57baC28940621d1aaE1a136058c4064623
    
  • The script asserts the deterministic address post-deploy and reverts on mismatch; the address is also documented in the README. It is a pure function of the init code, so the salt must be re-ground if the guard source or compiler profile changes.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a new DepositCapStateGuard contract that validates intent deposit caps and total supply against batch-signed expectations, along with tests, mock facility support, deployment tooling, and README documentation.

Changes

Deposit Cap State Guard

Layer / File(s) Summary
Guard contract core
src/checks/DepositCapStateGuard.sol
Defines the total-supply interface, guard inputs, custom errors, and requireState validation over each check.
MockFacility totalSupply support
test/MorphoAllocator.t.sol
Adds per-intent total supply storage and accessors to the test mock facility.
Guard tests
test/DepositCapStateGuard.t.sol
Adds setup helpers, passing cases, revert cases, and fuzz coverage for requireState.
Deployment script, docs, and artifacts
script/DeployDepositCapStateGuard.s.sol, README.md, broadcast/DeployDepositCapStateGuard.s.sol/*
Adds deterministic CREATE2 deployment code, README notes, and broadcast JSON outputs for the guard deployment.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding the DepositCapStateGuard batch pre-check.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/deposit-cap-state-guard

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 54-56: The fenced address snippet in the README is missing a
language tag and triggers markdownlint MD040. Update that fenced block to use a
deterministic text language tag (for example, a plain text fence) so the address
line is still rendered as code while satisfying the linter.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3cfe7a38-796f-44c0-b072-1780acf57556

📥 Commits

Reviewing files that changed from the base of the PR and between bad86a0 and a15c80a.

📒 Files selected for processing (9)
  • README.md
  • broadcast/DeployDepositCapStateGuard.s.sol/1/run-1783338513185.json
  • broadcast/DeployDepositCapStateGuard.s.sol/1/run-1783338539903.json
  • broadcast/DeployDepositCapStateGuard.s.sol/1/run-latest.json
  • broadcast/DeployDepositCapStateGuard.s.sol/11155111/run-1783338690064.json
  • broadcast/DeployDepositCapStateGuard.s.sol/11155111/run-1783338727468.json
  • broadcast/DeployDepositCapStateGuard.s.sol/11155111/run-1783338776508.json
  • broadcast/DeployDepositCapStateGuard.s.sol/11155111/run-latest.json
  • script/DeployDepositCapStateGuard.s.sol
✅ Files skipped from review due to trivial changes (8)
  • broadcast/DeployDepositCapStateGuard.s.sol/1/run-latest.json
  • script/DeployDepositCapStateGuard.s.sol
  • broadcast/DeployDepositCapStateGuard.s.sol/11155111/run-1783338727468.json
  • broadcast/DeployDepositCapStateGuard.s.sol/1/run-1783338513185.json
  • broadcast/DeployDepositCapStateGuard.s.sol/11155111/run-1783338776508.json
  • broadcast/DeployDepositCapStateGuard.s.sol/11155111/run-latest.json
  • broadcast/DeployDepositCapStateGuard.s.sol/11155111/run-1783338690064.json
  • broadcast/DeployDepositCapStateGuard.s.sol/1/run-1783338539903.json

Comment thread README.md
Comment on lines +54 to +56
```
DepositCapStateGuard: 0x3Fa77E57baC28940621d1aaE1a136058c4064623
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a language tag to the fenced address block.

This trips markdownlint (MD040) and is easy to fix. Use something like text for the deterministic address snippet.

Proposed fix
-```
+```text
 DepositCapStateGuard: 0x3Fa77E57baC28940621d1aaE1a136058c4064623

</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 54-54: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 54 - 56, The fenced address snippet in the README is
missing a language tag and triggers markdownlint MD040. Update that fenced block
to use a deterministic text language tag (for example, a plain text fence) so
the address line is still rendered as code while satisfying the linter.

Source: Linters/SAST tools

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.

1 participant