Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Two facilitators exist today, covering the two ends of a fund DEPOSIT order's li
| `CommitDeposit` | Order creation | pull bridge funds → create DEPOSIT order → commit |
| `MorphoAllocator` | Order maturation | unlock → rebalance Morpho Vault V2 → deposit collateral & borrow |

`src/checks/` additionally holds permissionless, read-only guard contracts meant to be called as the first step of a batch transaction to make the rest of the batch revert on stale state; they hold no roles and no storage.

## CommitDeposit (`src/CommitDeposit.sol`)

`run(intentId, pullAmount, commitAmount, minSharesOut)`:
Expand All @@ -34,6 +36,27 @@ Two facilitators exist today, covering the two ends of a fund DEPOSIT order's li

Success emits `Allocated(intentId, unlocked, allocateAdapter, gatheredTotal, borrowAmount)`.

## DepositCapStateGuard (`src/checks/DepositCapStateGuard.sol`)

`requireState(facility, checks)` — a stateless, read-only guard that reverts unless every intent in `checks` matches the caller's expectations:

- **Deposit cap** must equal `expectedCap` exactly (`StaleCap` otherwise) — cap changes are precisely the state transitions the guard exists to catch.
- **Total supply** must lie within the inclusive `[minSupply, maxSupply]` range (`SupplyOutOfRange` otherwise), so benign concurrent deposits/withdrawals inside the tolerated band do not fail the batch. Pass `minSupply == maxSupply` for an exact check; an inverted range reverts with `InvalidSupplyRange`.

**Usage: this contract must be called as the FIRST transaction of a batch** (e.g. an EIP-7702 batch) executed in the mode where any failing call reverts the whole batch. The batch calls this read-only function first; if the on-chain cap/supply state no longer matches what was expected when the batch was signed, the guard reverts and the rest of the batch reverts with it, so no state-changing call executes against stale state.

The guard is unpermissioned (anyone may call it with any arguments), holds no storage, and takes the Facility as a call parameter, so one deployment serves any Facility.

### 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, giving the same address on every chain:

```
DepositCapStateGuard: 0x3Fa77E57baC28940621d1aaE1a136058c4064623
```
Comment on lines +54 to +56

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


The script asserts the deployment lands on this address and reverts otherwise. The address is a pure function of the init code and the salt: re-grind the salt (and update the script constants and this README) if the guard source or the compiler profile changes.

## Roles & trust assumptions

- **Owner / executor.** Both contracts use Solady `OwnableRoles`. The owner (set at initialization) grants and revokes `EXECUTOR_ROLE`; only executors can call `run`. Executors are trusted operators: parameters like the pull/commit split, `depositAmount`, and the rebalance shape are their judgment calls — the contracts enforce invariants (order states, slippage minima, utilisation caps, balance audits), not strategy.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"transactions": [
{
"hash": "0x23cef0168b2aee10048138e696cde700a0673b2faf54ddaa677faf19df254b96",
"transactionType": "CREATE2",
"contractName": "DepositCapStateGuard",
"contractAddress": "0x3fa77e57bac28940621d1aae1a136058c4064623",
"function": null,
"arguments": null,
"transaction": {
"from": "0xabff377a1f7a0b061c9d4395b53f1488b153333f",
"to": "0x4e59b44847b379578588920ca78fbf26c0b4956c",
"gas": "0x575fc",
"value": "0x0",
"input": "0x7fde142edeac1c4c898e276a070df232a649cda0a4e930355b1f72abb019de8a608080604052346015576103b3908161001a8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c632a1620d914610024575f80fd5b3461024a57604036600319011261024a576004356001600160a01b0381169081900361024a5760243567ffffffffffffffff811161024a573660238201121561024a5780600401359067ffffffffffffffff821161024a573660248360071b8301011161024a575f5b828110156102f1578060071b82016024810160648201356084830135918282116102d85735916040519163bd85b03960e01b83528360048401526020836024818c5afa928315610269575f936102a5575b50808310801561029c575b6102745750505060405163906e277b60e01b8152816004820152610180816024818a5afa908115610269575f91610150575b50604001519160440135908183036101385750505060010161008d565b636e77284760e11b5f5260045260245260445260645ffd5b90506101803d8111610262575b61016781836102f3565b8101818103610180811261024a576101201361024a576040519060e082019082821067ffffffffffffffff83111761024e576101b5916040526101aa8185610336565b835260408401610336565b6020820152608082015160408201526101d060a08301610315565b606082015260c082015164ffffffffff8116810361024a57608082015260e08201519060ff8216820361024a5761024261016060449460409460a085015261021b6101008201610329565b60c085015261022d6101208201610315565b5061023b6101408201610315565b5001610329565b50915061011b565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b503d61015d565b6040513d5f823e3d90fd5b608494506040519363e016ae5560e01b85526004850152602484015260448301526064820152fd5b508183116100e9565b9092506020813d82116102d0575b816102c0602093836102f3565b8101031261024a5751915f6100de565b3d91506102b3565b635e4aefe960e01b5f523560045260245260445260645ffd5b005b90601f8019910116810190811067ffffffffffffffff82111761024e57604052565b51906001600160a01b038216820361024a57565b5190811515820361024a57565b919082604091031261024a576040516040810181811067ffffffffffffffff82111761024e57604052602061037881839561037081610315565b855201610329565b91015256fea26469706673582212200cf1aea5547025eafdd9a16c8ed54a7ff01a00dbcc5c313365d3208df9a9ff4464736f6c634300081c0033",
"nonce": "0x231",
"chainId": "0x1"
},
"additionalContracts": [],
"isFixedGasLimit": false
}
],
"receipts": [
{
"type": "0x2",
"status": "0x1",
"cumulativeGasUsed": "0x21fc964",
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"transactionHash": "0x23cef0168b2aee10048138e696cde700a0673b2faf54ddaa677faf19df254b96",
"transactionIndex": "0xde",
"blockHash": "0xa8df0e30539a0a0044a1a2dc9d6801580c680760a94548f26e0dde2ec6ce061d",
"blockNumber": "0x184b10c",
"gasUsed": "0x3f41f",
"effectiveGasPrice": "0x6a31b99",
"from": "0xabff377a1f7a0b061c9d4395b53f1488b153333f",
"to": "0x4e59b44847b379578588920ca78fbf26c0b4956c",
"contractAddress": "0x3fa77e57bac28940621d1aae1a136058c4064623"
}
],
"libraries": [],
"pending": [],
"returns": {},
"timestamp": 1783338513185,
"chain": 1,
"commit": "7ed90f5"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"transactions": [
{
"hash": "0x23cef0168b2aee10048138e696cde700a0673b2faf54ddaa677faf19df254b96",
"transactionType": "CREATE2",
"contractName": "DepositCapStateGuard",
"contractAddress": "0x3fa77e57bac28940621d1aae1a136058c4064623",
"function": null,
"arguments": null,
"transaction": {
"from": "0xabff377a1f7a0b061c9d4395b53f1488b153333f",
"to": "0x4e59b44847b379578588920ca78fbf26c0b4956c",
"gas": "0x575fc",
"value": "0x0",
"input": "0x7fde142edeac1c4c898e276a070df232a649cda0a4e930355b1f72abb019de8a608080604052346015576103b3908161001a8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c632a1620d914610024575f80fd5b3461024a57604036600319011261024a576004356001600160a01b0381169081900361024a5760243567ffffffffffffffff811161024a573660238201121561024a5780600401359067ffffffffffffffff821161024a573660248360071b8301011161024a575f5b828110156102f1578060071b82016024810160648201356084830135918282116102d85735916040519163bd85b03960e01b83528360048401526020836024818c5afa928315610269575f936102a5575b50808310801561029c575b6102745750505060405163906e277b60e01b8152816004820152610180816024818a5afa908115610269575f91610150575b50604001519160440135908183036101385750505060010161008d565b636e77284760e11b5f5260045260245260445260645ffd5b90506101803d8111610262575b61016781836102f3565b8101818103610180811261024a576101201361024a576040519060e082019082821067ffffffffffffffff83111761024e576101b5916040526101aa8185610336565b835260408401610336565b6020820152608082015160408201526101d060a08301610315565b606082015260c082015164ffffffffff8116810361024a57608082015260e08201519060ff8216820361024a5761024261016060449460409460a085015261021b6101008201610329565b60c085015261022d6101208201610315565b5061023b6101408201610315565b5001610329565b50915061011b565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b503d61015d565b6040513d5f823e3d90fd5b608494506040519363e016ae5560e01b85526004850152602484015260448301526064820152fd5b508183116100e9565b9092506020813d82116102d0575b816102c0602093836102f3565b8101031261024a5751915f6100de565b3d91506102b3565b635e4aefe960e01b5f523560045260245260445260645ffd5b005b90601f8019910116810190811067ffffffffffffffff82111761024e57604052565b51906001600160a01b038216820361024a57565b5190811515820361024a57565b919082604091031261024a576040516040810181811067ffffffffffffffff82111761024e57604052602061037881839561037081610315565b855201610329565b91015256fea26469706673582212200cf1aea5547025eafdd9a16c8ed54a7ff01a00dbcc5c313365d3208df9a9ff4464736f6c634300081c0033",
"nonce": "0x231",
"chainId": "0x1"
},
"additionalContracts": [],
"isFixedGasLimit": false
}
],
"receipts": [
{
"type": "0x2",
"status": "0x1",
"cumulativeGasUsed": "0x21fc964",
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"transactionHash": "0x23cef0168b2aee10048138e696cde700a0673b2faf54ddaa677faf19df254b96",
"transactionIndex": "0xde",
"blockHash": "0xa8df0e30539a0a0044a1a2dc9d6801580c680760a94548f26e0dde2ec6ce061d",
"blockNumber": "0x184b10c",
"gasUsed": "0x3f41f",
"effectiveGasPrice": "0x6a31b99",
"from": "0xabff377a1f7a0b061c9d4395b53f1488b153333f",
"to": "0x4e59b44847b379578588920ca78fbf26c0b4956c",
"contractAddress": "0x3fa77e57bac28940621d1aae1a136058c4064623"
}
],
"libraries": [],
"pending": [],
"returns": {},
"timestamp": 1783338539903,
"chain": 1,
"commit": "7ed90f5"
}
47 changes: 47 additions & 0 deletions broadcast/DeployDepositCapStateGuard.s.sol/1/run-latest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"transactions": [
{
"hash": "0x23cef0168b2aee10048138e696cde700a0673b2faf54ddaa677faf19df254b96",
"transactionType": "CREATE2",
"contractName": "DepositCapStateGuard",
"contractAddress": "0x3fa77e57bac28940621d1aae1a136058c4064623",
"function": null,
"arguments": null,
"transaction": {
"from": "0xabff377a1f7a0b061c9d4395b53f1488b153333f",
"to": "0x4e59b44847b379578588920ca78fbf26c0b4956c",
"gas": "0x575fc",
"value": "0x0",
"input": "0x7fde142edeac1c4c898e276a070df232a649cda0a4e930355b1f72abb019de8a608080604052346015576103b3908161001a8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c632a1620d914610024575f80fd5b3461024a57604036600319011261024a576004356001600160a01b0381169081900361024a5760243567ffffffffffffffff811161024a573660238201121561024a5780600401359067ffffffffffffffff821161024a573660248360071b8301011161024a575f5b828110156102f1578060071b82016024810160648201356084830135918282116102d85735916040519163bd85b03960e01b83528360048401526020836024818c5afa928315610269575f936102a5575b50808310801561029c575b6102745750505060405163906e277b60e01b8152816004820152610180816024818a5afa908115610269575f91610150575b50604001519160440135908183036101385750505060010161008d565b636e77284760e11b5f5260045260245260445260645ffd5b90506101803d8111610262575b61016781836102f3565b8101818103610180811261024a576101201361024a576040519060e082019082821067ffffffffffffffff83111761024e576101b5916040526101aa8185610336565b835260408401610336565b6020820152608082015160408201526101d060a08301610315565b606082015260c082015164ffffffffff8116810361024a57608082015260e08201519060ff8216820361024a5761024261016060449460409460a085015261021b6101008201610329565b60c085015261022d6101208201610315565b5061023b6101408201610315565b5001610329565b50915061011b565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b503d61015d565b6040513d5f823e3d90fd5b608494506040519363e016ae5560e01b85526004850152602484015260448301526064820152fd5b508183116100e9565b9092506020813d82116102d0575b816102c0602093836102f3565b8101031261024a5751915f6100de565b3d91506102b3565b635e4aefe960e01b5f523560045260245260445260645ffd5b005b90601f8019910116810190811067ffffffffffffffff82111761024e57604052565b51906001600160a01b038216820361024a57565b5190811515820361024a57565b919082604091031261024a576040516040810181811067ffffffffffffffff82111761024e57604052602061037881839561037081610315565b855201610329565b91015256fea26469706673582212200cf1aea5547025eafdd9a16c8ed54a7ff01a00dbcc5c313365d3208df9a9ff4464736f6c634300081c0033",
"nonce": "0x231",
"chainId": "0x1"
},
"additionalContracts": [],
"isFixedGasLimit": false
}
],
"receipts": [
{
"type": "0x2",
"status": "0x1",
"cumulativeGasUsed": "0x21fc964",
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"transactionHash": "0x23cef0168b2aee10048138e696cde700a0673b2faf54ddaa677faf19df254b96",
"transactionIndex": "0xde",
"blockHash": "0xa8df0e30539a0a0044a1a2dc9d6801580c680760a94548f26e0dde2ec6ce061d",
"blockNumber": "0x184b10c",
"gasUsed": "0x3f41f",
"effectiveGasPrice": "0x6a31b99",
"from": "0xabff377a1f7a0b061c9d4395b53f1488b153333f",
"to": "0x4e59b44847b379578588920ca78fbf26c0b4956c",
"contractAddress": "0x3fa77e57bac28940621d1aae1a136058c4064623"
}
],
"libraries": [],
"pending": [],
"returns": {},
"timestamp": 1783338539903,
"chain": 1,
"commit": "7ed90f5"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"transactions": [
{
"hash": "0x125480eac10d5ae705868169409335bd3ee5247c9988bf72d35ccbf73ba3b2fb",
"transactionType": "CREATE2",
"contractName": "DepositCapStateGuard",
"contractAddress": "0x3fa77e57bac28940621d1aae1a136058c4064623",
"function": null,
"arguments": null,
"transaction": {
"from": "0x3f7e578d292233aa8bc811cebc357e33001c306c",
"to": "0x4e59b44847b379578588920ca78fbf26c0b4956c",
"gas": "0x575fc",
"value": "0x0",
"input": "0x7fde142edeac1c4c898e276a070df232a649cda0a4e930355b1f72abb019de8a608080604052346015576103b3908161001a8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c632a1620d914610024575f80fd5b3461024a57604036600319011261024a576004356001600160a01b0381169081900361024a5760243567ffffffffffffffff811161024a573660238201121561024a5780600401359067ffffffffffffffff821161024a573660248360071b8301011161024a575f5b828110156102f1578060071b82016024810160648201356084830135918282116102d85735916040519163bd85b03960e01b83528360048401526020836024818c5afa928315610269575f936102a5575b50808310801561029c575b6102745750505060405163906e277b60e01b8152816004820152610180816024818a5afa908115610269575f91610150575b50604001519160440135908183036101385750505060010161008d565b636e77284760e11b5f5260045260245260445260645ffd5b90506101803d8111610262575b61016781836102f3565b8101818103610180811261024a576101201361024a576040519060e082019082821067ffffffffffffffff83111761024e576101b5916040526101aa8185610336565b835260408401610336565b6020820152608082015160408201526101d060a08301610315565b606082015260c082015164ffffffffff8116810361024a57608082015260e08201519060ff8216820361024a5761024261016060449460409460a085015261021b6101008201610329565b60c085015261022d6101208201610315565b5061023b6101408201610315565b5001610329565b50915061011b565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b503d61015d565b6040513d5f823e3d90fd5b608494506040519363e016ae5560e01b85526004850152602484015260448301526064820152fd5b508183116100e9565b9092506020813d82116102d0575b816102c0602093836102f3565b8101031261024a5751915f6100de565b3d91506102b3565b635e4aefe960e01b5f523560045260245260445260645ffd5b005b90601f8019910116810190811067ffffffffffffffff82111761024e57604052565b51906001600160a01b038216820361024a57565b5190811515820361024a57565b919082604091031261024a576040516040810181811067ffffffffffffffff82111761024e57604052602061037881839561037081610315565b855201610329565b91015256fea26469706673582212200cf1aea5547025eafdd9a16c8ed54a7ff01a00dbcc5c313365d3208df9a9ff4464736f6c634300081c0033",
"nonce": "0x1a",
"chainId": "0xaa36a7"
},
"additionalContracts": [],
"isFixedGasLimit": false
}
],
"receipts": [
{
"type": "0x2",
"status": "0x1",
"cumulativeGasUsed": "0x9ad954",
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"transactionHash": "0x125480eac10d5ae705868169409335bd3ee5247c9988bf72d35ccbf73ba3b2fb",
"transactionIndex": "0x47",
"blockHash": "0x07fb28c4387c8933091faf833382889d1cc23e6c6824443efa2b119a3dd139d5",
"blockNumber": "0xab2168",
"gasUsed": "0x3f41f",
"effectiveGasPrice": "0x3e78bc52",
"from": "0x3f7e578d292233aa8bc811cebc357e33001c306c",
"to": "0x4e59b44847b379578588920ca78fbf26c0b4956c",
"contractAddress": "0x3fa77e57bac28940621d1aae1a136058c4064623"
}
],
"libraries": [],
"pending": [],
"returns": {},
"timestamp": 1783338690064,
"chain": 11155111,
"commit": "7ed90f5"
}
Loading