test(market-making): add MKT-1491 workflow e2e coverage - #112
test(market-making): add MKT-1491 workflow e2e coverage#112prd-carapulse[bot] wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 53ed32453c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
|
Current-head follow-up: hardened mock ladder fills against non-positive, over-published, and over-credit amounts; added partial/full rung-consumption coverage; counted individual rungs; and added strict-cross plus adjacent-safe spread cases. Scope blocker: cleanup-enabled lifecycle coverage and existing-buy/prospective-sell coverage have no production path on the current branch. The composition root exposes setup-check and one-shot bootstrap only, with no startup/shutdown cleanup boundary and no composed production ladder make adapter. The prior direct mock hard-halt test was removed rather than presenting a test-only method as production E2E coverage. Head: |
|
@codex review |
|
Codex Review: Didn't find any major issues. You're on a roll. 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". |
|
<@U09LHAWUK3M> review |
3 similar comments
|
<@U09LHAWUK3M> review |
|
<@U09LHAWUK3M> review |
|
<@U09LHAWUK3M> review |
|
@codex review |
1 similar comment
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 757f768ae0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
e825326 to
45856c1
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 45856c12f9
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d2eb9dfba8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 32c48ac602
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
| JSON.stringify({ | ||
| strategy: 'ladder', | ||
| maker: config.maker, | ||
| marketIds: config.marketIds.toSorted() |
There was a problem hiding this comment.
Use a stable namespace for ladder ownership
When an operator adds a ladder market after publishing groups for an existing market, including the full marketIds list in this hash changes the state filename, so ownership.read() no longer returns the already-live groups. The default setup gate only allowlists groups read from the current namespace before constructing the ladder writer, so those live ladder groups become unknownNamespaces and the normal mm ladder path is blocked before it can replace or invalidate them; key ownership by a stable maker/strategy namespace, or read/migrate prior market-list namespaces.
Useful? React with 👍 / 👎.
| market: parameters.market.params, | ||
| buy: side === 'higher', | ||
| maker: parameters.maker, | ||
| tick: tickAtRate(rung.rateBps, parameters.market, parameters.timestamp), |
There was a problem hiding this comment.
Validate the rounded ladder tick against hard bounds
For lower-side rungs configured at or near minimumRateBps, TickLib.priceToTick rounds the target price up to the next accessible tick, which corresponds to an APR below the requested rung rate when the rate is not exactly on tick spacing. generateLadder only checked the pre-rounded rung.rateBps, and after this tick assignment there is no check that the encoded offer still satisfies the documented hard range (docs/decisions/TIB-2026-07-27-midnight-market-making-bot.md:446), so the bot can publish a ladder offer outside the operator's minimum rate bound.
Useful? React with 👍 / 👎.
|
|
||
| const read = async (): Promise<LadderOwnedGroup[]> => { | ||
| try { | ||
| const parsed = JSON.parse(await readFile(path, 'utf8')) as Record<string, unknown> |
There was a problem hiding this comment.
Reject insecure ladder ownership files
In environments where XDG_STATE_HOME or this state file is pre-created or shared, this reads and trusts the path without the regular-file, symlink, mode, and owner checks that the bootstrap ownership reader applies before parsing. A poisoned ladder state file can inject group IDs into both setup allowlisting and activeOwnedIds, hiding unknown groups from readiness and causing reconcile or hard-halt to target groups the ladder strategy did not persist itself; fail closed on insecure metadata before parsing.
Useful? React with 👍 / 👎.
| parameters.currentCredit < parameters.creditSaleCapacityAssets | ||
| ? parameters.currentCredit | ||
| : parameters.creditSaleCapacityAssets | ||
| const market = cash + credit |
There was a problem hiding this comment.
Subtract current credit from market ladder room
When a ladder market already has accrued credit but still has wallet cash, this reports the target-market capacity as the new cash room plus sellable credit, without subtracting currentCredit from the per-market target exposure. Since generateLadder later also receives the static targetMarketExposureAssets, a market with 90 credit, a 100 target cap, 100 cash, and plenty of total room can still publish 100 higher-rate lend assets, letting fills push that market far over its configured cap; derive market room from the remaining target cap before exposing fresh lend capacity.
Useful? React with 👍 / 👎.
Why
The market-making bot needs a deterministic regression boundary before V0 is operated unattended. The prior workflow tests injected in-memory application ports, so they could not detect regressions in production composition, Router HTTP DTOs, SDK encoding/signing, Midnight transactions, or forked on-chain state.
Why now
MKT-1491 requires genuine E2E coverage before the V0 market-making workflow is relied on operationally.
What changed
48,900,000Verification
eth_chainIdreturned8453and block48,900,000was availablePATH=/home/hermes/.bun/bin:$PATH RPC_URL_8453=<canonical Morpho Base archive RPC> bun test bots/market-making/test/e2e/market-making.fork.e2e.test.ts bots/market-making/test/e2e/setup-check.e2e.test.ts— 12 passed, 0 failed, 108 assertionsPATH=/home/hermes/.bun/bin:$PATH RPC_URL_8453=<canonical Morpho Base archive RPC> bun test bots/market-making/test— 408 passed, 0 failed, 1,097 assertionsbun run --filter @morpho-org/market-making-bot typecheck— passedbun run --filter @morpho-org/market-making-bot jsdoc:build— passed; 216 public declarations inventoried and HTML generatedbun lint— 0 warnings, 0 errorsbun knip— passedbun format— passed; no working-tree changesgit diff --check origin/main...HEAD— passedLinear: https://linear.app/morpho-labs/issue/MKT-1491/add-e2e-testing-for-each-step
TIB: https://github.com/morpho-org/morpho-bots/blob/main/docs/decisions/TIB-2026-07-27-midnight-market-making-bot.md
Requested by: @julien (Slack)