feat: add Blue callback limit-order maker/taker flow - #5
Conversation
Signed-off-by: Oliver Tipton <oliver@morpho.xyz>
|
@codex review the work, knowing we found this:
• Medium — repeated maker setup silently adds funds: maker.ts:173-184 reuses an existing callback but always calls supplyBlue(). Calling prepareBlueCallbackPosition() twice with the same salt tops up the existing callback instead of failing or detecting already-funded state. The app-side implementation checks for an existing position and fails closed. Add the same guard, or document/parameterize top-up behavior. • Test hygiene — market-ID validation happens after writes: callback-flow.test.ts:144-180 creates the callback, approves/supplies Blue, authorizes the ratifier, and signs the offer before validating MIDNIGHT_MARKET_ID. Move the touchMarket check before maker-side setup so stale constants fail without leaving partial state, even on the local fork. |
|
|
||
| async function blueSupplyAssets(callback: Address) { | ||
| // Position assets prove what the callback owns; buyerAssetsBound only measures immediately executable capacity. | ||
| return (await fetchAccrualPosition(callback, BLUE_MARKET_ID as MarketId, publicClient)).supplyAssets |
There was a problem hiding this comment.
Fixed: the test now reads the callback’s accrued Blue position for the 100→75→65 assertions and keeps buyerAssetsBound only as executable capacity.
| args: [new MarketParams(blueMarket).id, callback], | ||
| }) | ||
| // An empty deployment can resume after failure, but a funded per-offer callback must not be silently topped up. | ||
| if (position[0] !== 0n) throw new Error('callback already has a Blue supply position') |
There was a problem hiding this comment.
Fixed: preparation now rejects a callback with existing supply shares while still allowing an empty deployment to resume.
| assert.notEqual(await publicClient.getCode({ address: CALLBACK_FACTORY }), '0x', 'callback factory is not deployed') | ||
|
|
||
| // Validate pinned market constants before any test funding or maker-side transactions. | ||
| const { result: computedMarketId } = await publicClient.simulateContract({ |
There was a problem hiding this comment.
Fixed: the pinned Midnight market is now validated before funding or maker-side transactions.
antoncoding
left a comment
There was a problem hiding this comment.
Logic here looks good and very clean and helpful!
Summary
Adds production-shaped TypeScript maker and taker functions for a callback-backed Midnight lend offer, plus a deterministic Base-fork integration test. A lender can keep USDC supplied in Morpho Blue while a signed fixed-rate Midnight offer rests offchain.
Reusable functions
Anvil impersonation, fixture funding, collateral setup, and assertions remain isolated in callback-flow.test.ts.
Proven flow
API boundary
The example creates and signs offers with the Midnight SDK and settles them directly through Midnight.take. It intentionally excludes live API publication and discovery because a public order book cannot index state that exists only on a private Anvil fork.
Verification