fix(market-making): batch invalidation with Midnight multicall - #125
Conversation
|
@codex review |
|
Codex Review: Didn't find any major issues. Breezy! Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
| export const invalidateOffersBatch = async (parameters: { | ||
| wallet: BatchOfferInvalidationWallet | ||
| midnight: Address | ||
| maker: Address | ||
| groupIds: readonly Hex[] | ||
| receiptTimeoutMs: number | ||
| onTransactionSubmitted?: (txHash: Hex) => void | Promise<void> | ||
| }) => { |
There was a problem hiding this comment.
🟡 New public code file is left out of the documentation coverage inventory
The new batch invalidation helper file is added to the bot's public source surface (invalidateOffersBatch at bots/market-making/src/infrastructure/invalidation/batch-offer-invalidation.utils.ts:25) without being registered in the documentation inventory and generator configuration, so its documentation is never verified or published.
Impact: The documentation build silently skips this new public code, so missing or wrong docs for it go undetected.
Mandatory boundary-file registration in check-jsdoc.ts and typedoc.json
.agents/skills/build-jsdoc/SKILL.md states: "When adding another boundary file, add it to both scripts/check-jsdoc.ts and typedoc.json in the same change." The inventory in bots/market-making/scripts/check-jsdoc.ts:300-386 is a static allowlist and lists the sibling invalidation files (infrastructure/invalidation/offer-invalidation-group.utils.ts, offer-invalidation-transaction.utils.ts, production-offer-invalidation.ts) but not infrastructure/invalidation/batch-offer-invalidation.utils.ts. The same omission exists in bots/market-making/typedoc.json:58-61.
Prompt for agents
The new public boundary file bots/market-making/src/infrastructure/invalidation/batch-offer-invalidation.utils.ts exports invalidateOffersBatch but is not registered in the JSDoc coverage inventory (bots/market-making/scripts/check-jsdoc.ts, static sourceFiles allowlist around line 355) nor in the TypeDoc entry points (bots/market-making/typedoc.json, invalidation entries around line 58). The build-jsdoc skill requires adding any new boundary file to both in the same change. Add the path alongside the other infrastructure/invalidation entries in both files and re-run the jsdoc check/build to confirm the printed inventory includes the new callable exactly once.
Was this helpful? React with 👍 or 👎 to provide feedback.
main gained #121/#124/#125 after this branch's merge-base, which is why GitHub reported the stack as conflicting and suppressed its checks entirely — the mergeability of a stacked PR is computed against main, not the immediate parent. This is the "six open PRs add new bun:test files and Bun.* calls" follow-up the PR body anticipated, now due for the three that merged. Applied the same mechanical port to what main brought in: - 8 test files from bun:test to vitest (`mock()` -> `vi.fn()`), plus 2 more where 130 had already converted the import and main added new `mock(` sites - Bun.file -> readFile, Bun.serve -> the node:http adapter this branch already uses, Bun.sleep -> node:timers/promises, in the setup-state test - 3 more floating `expect(...).rejects` awaited — the same latent bug class this branch documents, arriving from main where bun's typings still hid them Verified: 1459 pass / 1 skip / 141 files, zero failures; vitest collects exactly the 141 tracked *.test.ts files (diffed, zero delta); pnpm lint 0/0; knip clean; 12/12 typecheck; jsdoc:build exits 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
main gained #121/#124/#125 after this branch's merge-base, adding test files that still import bun:test and call bun's mock(). Linearizing the stack dropped these conversions along with the merge commit that carried them, so they are restored here as their own commit: 7 files moved to vitest imports and mock() -> vi.fn(). Tree is byte-identical to the verified pre-rebase state. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
main gained #121/#124/#125 after this branch's merge-base, adding test files that still import bun:test and call bun's mock(). Linearizing the stack dropped these conversions along with the merge commit that carried them, so they are restored here as their own commit: 7 files moved to vitest imports and mock() -> vi.fn(). Tree is byte-identical to the verified pre-rebase state. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
main gained #121/#124/#125 after this branch's merge-base, adding test files that still import bun:test and call bun's mock(). Linearizing the stack dropped these conversions along with the merge commit that carried them, so they are restored here as their own commit: 7 files moved to vitest imports and mock() -> vi.fn(). Tree is byte-identical to the verified pre-rebase state. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Why
Explicit maker-wide invalidation previously submitted one Midnight transaction per offer group. Midnight already exposes an atomic native multicall, so using it reduces nonce pressure and transaction count without adding a helper deployment, authorization, configuration, or dependency surface.
What changed
multicall(bytes[])invalidateBatchon every invalidation port, with a read-only no-op implementation, so maker-wide scope cannot fall through to serial invalidationsetConsumed(groupId, MAX_OFFER_CAP, maker)using@morpho-org/midnight-sdk@1.3.0's ABI and constantonBehalfinputsetConsumedpath for explicit single-group invalidation and preserve read-only behaviorRevokeOfferscontract, Foundry test, deployment script, generated export, package script/dependency,REVOKE_OFFERS_ADDRESSconfiguration/YAML, and authorization/deployment documentationSafety guarantees
delegatecall, preserving the maker EOA asmsg.senderfor each internalsetConsumedinvalidateis reserved for explicit single-group scopeProtocol evidence
The installed
@morpho-org/midnight-sdk@1.3.0exports:multicall(bytes[])setConsumed(bytes32,uint128,address)MAX_OFFER_CAP = 340282366920938463463374607431768211455(type(uint128).max)Validation
invalidate; GREEN invokesinvalidateBatchexactly once and never callsinvalidatebun run --filter @morpho-org/market-making-bot typecheck: passedbun lint: 0 warnings, 0 errorsbun format: completedbun run --filter @morpho-org/market-making-bot jsdoc:build: passedbun run --filter @repo/contracts build: passed (required to generate workspace contract exports before the full suite)bun test: 1,426 passed, 3 skipped, 0 failedRevokeOffersorREVOKE_OFFERS_ADDRESSRequested by: @julien (Slack)