Skip to content

Release: CD Parameter Update and Limit Orders - #194

Merged
0xJem merged 103 commits into
masterfrom
develop
Jan 13, 2026
Merged

0xJem merged 103 commits into
masterfrom
develop

Conversation

@0xJem

@0xJem 0xJem commented Jan 13, 2026 •

Copy link
Copy Markdown
Member

Note

Introduces limit orders for Convertible Deposits and wires up deployment and ops support.

  • Adds CDAuctioneerLimitOrders contract with createOrder/fillOrder/cancelOrder, incentive handling, sUSDS yield sweep, ERC721 position/receipt token transfers, and IVersioned + ILimitOrders interfaces
  • Deployment: new deployConvertibleDepositAuctioneerLimitOrders() in DeployV3.s.sol, saved deployment configs for mainnet/sepolia, and env/deployments files updated with addresses
  • Ops scripts: new PeripheryEnable batch to call IEnabler.enable, new ConvertibleDepositInstall.configureDepositParameters flow, safeBatchV2.sh adds --verbose, and BatchScriptV2 gains arg array readers and heartbeat validation
  • Minor pragma updates (>=0.8.15/0.8.24) and test scaffolding/mocks for auctioneer/deposit manager/price to support the new flow

Written by Cursor Bugbot for commit 5715d2b. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added limit order functionality for the Convertible Deposit Auctioneer, enabling users to create, fill, and manage limit orders with yield mechanics and order tracking.
    • Added verbose flag to deployment shell script for enhanced debugging output control.
  • Chores

    • Updated Solidity compiler version constraints across multiple contracts for broader compatibility.
    • Added deployment configurations and environment settings for new limit order contract.

✏️ Tip: You can customize this high-level summary in your review settings.

chefomi and others added 30 commits December 5, 2025 17:45
Saves a bit of gas
Allows user to change details of an open order. Functionally equivalent to canceling an existing order and opening a new one, with orderID retained and only one transaction required.
Difference between existing and new order details is transferred from or to user.
Yurii3721 and others added 22 commits December 24, 2025 15:51
fix(cd-limit-orders): inherit `IERC721Receiver`, correct `getRemaining`, optimize
…rs-tweak

Convertible Deposits: Parameters Tweak
@0xJem 0xJem self-assigned this Jan 13, 2026
@coderabbitai

coderabbitai Bot commented Jan 13, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR introduces a comprehensive limit order system for the Convertible Deposit Auctioneer, including a new core contract (CDAuctioneerLimitOrders), interfaces, deployment infrastructure, batch operations, test mocks, and fork tests. Additional changes include compiler pragma updates and script enhancements for verbosity and heartbeat validation.

Changes

Cohort / File(s) Summary
Limit Order Core Contract
src/policies/deposits/LimitOrders.sol
New 776-line contract implementing a feature-complete limit order system with order lifecycle management (create/fill/cancel), yield accrual and sweep mechanics, incentive distribution, position NFT issuance, reentrancy protection, and integration hooks for the Convertible Deposit Auctioneer ecosystem.
Limit Order Interface & Versioning
src/policies/interfaces/deposits/ILimitOrders.sol, src/interfaces/IVersioned.sol
New interface ILimitOrders (343 lines) defining comprehensive API for order management, yield operations, and querying. New interface IVersioned (14 lines) standardizing version metadata across contracts.
Deployment Configuration
src/scripts/deploy/DeployV3.s.sol, src/scripts/deploy/savedDeployments/convertible_deposit_limit_orders*.json
Deploy script additions with helper utilities for reading uint8/address arrays, new deployConvertibleDepositAuctioneerLimitOrders function, and JSON config files specifying deposit periods and receipt tokens.
Environment & Deployment Records
src/scripts/env.json, deployments/.mainnet-*.json, deployments/.sepolia-*.json
Added ConvertibleDepositAuctioneerLimitOrders address mappings for arbitrum/optimism mainnet and sepolia deployments.
Batch Operations & Scripts
src/scripts/ops/batches/PeripheryEnable.sol, src/scripts/ops/batches/ConvertibleDepositInstall.sol, src/scripts/ops/batches/args/*.json
New PeripheryEnable batch script, ConvertibleDepositInstall enhancements with multi-parameter configuration helpers, and JSON batch args for deposit parameter and limit orders configuration.
Batch Script Infrastructure
src/scripts/ops/lib/BatchScriptV2.sol
Enhanced with internal heartbeat validation workflow (_validateHeartBeat, _getPriceModule, _executeHeartBeats) post-simulation and array argument reading utilities.
Shell Script Enhancements
shell/safeBatchV2.sh
Added --verbose flag with dynamic VERBOSITY variable (-vvvv or -vvv) injected into Forge command construction.
Test Mocks & Infrastructure
src/test/mocks/MockConvertibleDepositAuctioneer.sol, src/test/mocks/MockDepositManager.sol, src/test/mocks/MockPrice.sol
MockConvertibleDepositAuctioneer expanded with deposit manager integration, deposit period management, receipt tokens, and position NFT minting. New MockDepositManager implementing IDepositManager. All three updated with pragma >=0.8.20 support.
Fork & Unit Tests
src/test/policies/ConvertibleDepositAuctioneer/LimitOrdersFork.t.sol, src/test/policies/EmissionManager.t.sol
New fork test (182 lines) exercising order creation, filling, and cleanup. EmissionManager test updated for MockConvertibleDepositAuctioneer three-parameter constructor.
Pragma Version Updates
src/modules/CHREG/OlympusClearinghouseRegistry.sol, src/modules/RANGE/OlympusRange.sol, src/modules/RANGE/RANGE.v2.sol, src/test/lib/bonds/*.sol
Solidity pragma bumped from exact 0.8.15 to flexible >=0.8.15 across multiple files, broadening compiler compatibility.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant LimitOrders as LimitOrders Contract
    participant CDAuctioneer as CDAuctioneer
    participant DepositManager as DepositManager
    participant USDS as USDS (ERC20)
    participant sUSDS as sUSDS (ERC4626)
    participant NFT as Position NFT

    User->>LimitOrders: createOrder(period, depositBudget, incentiveBudget, maxPrice)
    LimitOrders->>USDS: transferFrom(user, limitOrders, depositBudget + incentiveBudget)
    LimitOrders->>sUSDS: deposit(depositBudget into sUSDS)
    LimitOrders->>LimitOrders: Store order in mapping
    LimitOrders-->>User: Return orderId

    User->>LimitOrders: fillOrder(orderId, fillAmount)
    LimitOrders->>LimitOrders: Validate order is active
    LimitOrders->>CDAuctioneer: bid(period, fillAmount)
    CDAuctioneer->>DepositManager: deposit(USDS, fillAmount)
    CDAuctioneer-->>LimitOrders: Return (ohmOut, positionId, receiptTokenId, actualAmount)
    LimitOrders->>NFT: transferFrom(limitOrders, filler, positionId)
    LimitOrders->>USDS: transfer(filler, incentivePaid)
    LimitOrders->>LimitOrders: Update order spent amounts
    LimitOrders-->>User: Return (ohmOut, incentivePaid, actualAmount)
Loading
sequenceDiagram
    participant Owner as Owner/Caller
    participant LimitOrders as LimitOrders Contract
    participant sUSDS as sUSDS (ERC4626)
    participant YieldRecipient as Yield Recipient

    Owner->>LimitOrders: getAccruedYield()
    LimitOrders->>sUSDS: balanceOf(limitOrders)
    sUSDS-->>LimitOrders: Return sUSDS balance
    LimitOrders-->>Owner: Return total yield in sUSDS

    Owner->>LimitOrders: sweepYield()
    LimitOrders->>LimitOrders: Calculate accrued shares
    LimitOrders->>sUSDS: transfer(yieldRecipient, accruedShares)
    sUSDS-->>YieldRecipient: Receive sUSDS
    LimitOrders->>LimitOrders: Reset yield tracking
    LimitOrders-->>Owner: Return shares transferred
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Possibly related PRs

Suggested labels

audit-convertible-deposits-trust

Poem

🐰 A limit order system hops in place,
With yield accrual keeping pace,
Incentives bound in sUSDS flow,
Position NFTs reap and sow,
While heartbeats validate with care,
The auction ecosystem fair! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Release: CD Parameter Update and Limit Orders' accurately summarizes the two main changes in the changeset: CD (Convertible Deposit) parameter updates and the new Limit Orders feature implementation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In @src/scripts/ops/batches/ConvertibleDepositInstall.sol:
- Around line 802-879: The batch can re-enable disabled periods because
_configureDepositPeriods zeros reclaim rates for disabled entries but
_configureReclaimRates runs after and will set reclaim rates even for periods
not in enabledPeriods; before calling _configureReclaimRates in
configureDepositParameters, filter reclaimRatePeriods/reclaimRates to include
only periods present in enabledPeriods (or alternatively revert if any
reclaimRatePeriods are not subset of enabledPeriods) so that reclaim-rate
updates are skipped for disabled periods; implement the filtering/validation
immediately prior to the _configureReclaimRates call using the local variables
enabledPeriods, reclaimRatePeriods, and reclaimRates.

In @src/scripts/ops/lib/BatchScriptV2.sol:
- Around line 394-446: The validation currently pranks and calls heart.beat()
which both is unnecessary (beat has no access control) and mutates contract
state; to fix, in _validateHeartBeat wrap the entire heart-beat validation in a
VM snapshot/revert pair (use vm.snapshot() before calling _executeHeartBeats and
vm.revertTo(snapshotId) after) so you can call heartContract.beat() (via
_executeHeartBeats) without persisting lastBeat/reward changes, and remove any
vm.prank around the heart.beat calls (keep vm.prank only where needed for
priceModule.changeUpdateThresholds using priceConfig); reference
_validateHeartBeat, _executeHeartBeats, heartContract.beat(), vm.snapshot(), and
vm.revertTo().

In @src/test/mocks/MockConvertibleDepositAuctioneer.sol:
- Around line 62-112: In bid(), prevent underflow by requiring depositAmount_ >=
actualAmountDifference before computing actualAmount and align behavior with
production by checking that ohmOut != 0 and reverting on zero output before
doing the slippage check; specifically: compute ohmOut as now, if (ohmOut == 0)
revert("Zero output"), then require(ohmOut >= minOhmOut_, "Slippage"), then
require(depositAmount_ >= actualAmountDifference) and set actualAmount =
depositAmount_ - actualAmountDifference, and continue with the existing
deposit/mint flow (references: function bid, variables ohmOut, minOhmOut_,
actualAmountDifference, actualAmount).

In @src/test/mocks/MockDepositManager.sol:
- Around line 20-22: The functions configureDependencies and requestPermissions
currently rely on implicit default returns; explicitly construct and return
zero-length memory arrays of the correct types (Keycode[] for
configureDependencies and Permissions[] for requestPermissions) and return them
to make the ABI and calling code behavior explicit and safe.
🧹 Nitpick comments (9)
src/modules/RANGE/RANGE.v2.sol (1)

2-2: Pragma widened to allow future Solidity versions.

The change from exact 0.8.15 to >=0.8.15 aligns with the broader PR pattern. For production modules, you may optionally consider a bounded pragma (e.g., >=0.8.15 <0.9.0) to guard against potential breaking changes in future major versions, though this is not critical given Solidity 0.8.x stability.

src/modules/CHREG/OlympusClearinghouseRegistry.sol (1)

2-2: Pragma widened for compiler flexibility.

Consistent with the PR-wide pattern. Same optional consideration applies: a bounded upper limit (e.g., <0.9.0) could provide additional safety for production modules against future major version changes, though not strictly necessary.

src/interfaces/IVersioned.sol (1)

1-14: Interface is fine; consider whether you want patch-level versioning and a tighter pragma.

  • Returning (major, minor) is straightforward; if you expect hotfix tracking, consider (major, minor, patch) (or bytes32 semver string) up-front to avoid future interface churn.
  • If the repo is standardizing on >=0.8.20 elsewhere, aligning this pragma helps reduce toolchain variance.
src/scripts/ops/lib/BatchScriptV2.sol (1)

416-433: Temp PRICE thresholds should be derived from frequency * numBeats (not fixed at 2 days).

If Heart frequency is ever > 16 hours (or changes), 2 days might not cover a 3-beat warp window and you can still hit stale feed checks.

Also applies to: 447-475

src/test/mocks/MockDepositManager.sol (1)

26-38: Consider using SafeERC20 (or checking return values) even in mocks to match production ERC20 quirks.

If IERC20.transfer/transferFrom returns bool, ignoring it can make tests pass incorrectly with “false-returning” tokens.

src/scripts/ops/batches/ConvertibleDepositInstall.sol (1)

971-1020: Base-emissions “set” is actually scheduled; ensure that’s intended for this ops flow.

changeBaseRate(changeNeeded, uint48(1), shouldAdd) won’t necessarily make baseEmissionRate == desired immediately; it schedules a change over beats. If this script is meant to converge the parameter immediately, you may want a direct setter (if available) or an explicit note in logs/args schema that this is “next beat”.

src/test/mocks/MockConvertibleDepositAuctioneer.sol (3)

62-112: Enforce minimumBid in bid() (not only previewBid()) to keep mock internally consistent.

Right now previewBid() returns 0 below minimumBid, but bid() will proceed (and may mint/deposit), which can create confusing test behavior.

Also applies to: 114-121


189-206: Implement enableDepositPeriod / disableDepositPeriod to update depositPeriodsEnabled + enabledPeriods (instead of no-ops).

Since other code paths may call the interface functions (not the test helper), leaving these empty can cause silent divergence in tests.

Also applies to: 228-255


93-110: Receipt/NFT minting via low-level calls is permissive; add basic contract-address checks (or use dedicated mocks).

Calling receiptTokenAddr.call(...) can succeed against EOAs (no mint) and still return true, producing false-positive tests. Similarly, positionId is assumed to match minted token id.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea65ec5 and 5715d2b.

📒 Files selected for processing (30)
  • deployments/.mainnet-1767809879.json
  • deployments/.sepolia-1766489520.json
  • deployments/.sepolia-1766582124.json
  • shell/safeBatchV2.sh
  • src/interfaces/IVersioned.sol
  • src/modules/CHREG/OlympusClearinghouseRegistry.sol
  • src/modules/RANGE/OlympusRange.sol
  • src/modules/RANGE/RANGE.v2.sol
  • src/policies/deposits/LimitOrders.sol
  • src/policies/interfaces/deposits/ILimitOrders.sol
  • src/scripts/deploy/DeployV3.s.sol
  • src/scripts/deploy/savedDeployments/convertible_deposit_limit_orders.json
  • src/scripts/deploy/savedDeployments/convertible_deposit_limit_orders_sepolia.json
  • src/scripts/env.json
  • src/scripts/ops/batches/ConvertibleDepositInstall.sol
  • src/scripts/ops/batches/PeripheryEnable.sol
  • src/scripts/ops/batches/args/ConfigureDepositParameters_202512.json
  • src/scripts/ops/batches/args/ConvertibleDepositLimitOrders.json
  • src/scripts/ops/lib/BatchScriptV2.sol
  • src/test/lib/bonds/BondAggregator.sol
  • src/test/lib/bonds/BondFixedTermSDA.sol
  • src/test/lib/bonds/BondFixedTermTeller.sol
  • src/test/lib/bonds/bases/BondBaseSDA.sol
  • src/test/lib/bonds/bases/BondBaseTeller.sol
  • src/test/mocks/MockConvertibleDepositAuctioneer.sol
  • src/test/mocks/MockDepositManager.sol
  • src/test/mocks/MockPrice.sol
  • src/test/policies/ConvertibleDepositAuctioneer/LimitOrders.t.sol
  • src/test/policies/ConvertibleDepositAuctioneer/LimitOrdersFork.t.sol
  • src/test/policies/EmissionManager.t.sol
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: 0xJem
Repo: OlympusDAO/olympus-v3 PR: 29
File: src/policies/deposits/BaseDepositFacility.sol:631-639
Timestamp: 2025-11-07T11:09:53.808Z
Learning: OlympusDAO/olympus-v3: BaseDepositFacility.setAssetPeriodReclaimRate now uses a dedicated reclaim-rate error (not InvalidAddress) when reclaimRate_ > ONE_HUNDRED_PERCENT, fixed in a follow-up PR (#180). Avoid re-flagging this in earlier PRs.
Learnt from: 0xJem
Repo: OlympusDAO/olympus-v3 PR: 29
File: src/modules/TRSRY/TRSRY.v1.sol:2-2
Timestamp: 2025-07-18T00:21:49.138Z
Learning: 0xJem prefers to avoid changing historical/already-deployed contracts to minimize risk and maintain stability, even when it would improve consistency across the codebase.
Learnt from: 0xJem
Repo: OlympusDAO/olympus-v3 PR: 29
File: remappings.txt:35-40
Timestamp: 2025-07-18T00:22:32.511Z
Learning: 0xJem prefers to keep OpenZeppelin 4.8.0 as the standard/default dependency in remappings.txt for stability, with newer versions like 5.3.0 available only through explicit versioned dependency paths (e.g., openzeppelin-5.3.0/) to ensure intentional opt-in to newer versions.
📚 Learning: 2025-08-08T07:33:13.575Z
Learnt from: 0xJem
Repo: OlympusDAO/olympus-v3 PR: 86
File: src/policies/deposits/DepositManager.sol:271-320
Timestamp: 2025-08-08T07:33:13.575Z
Learning: DepositManager (src/policies/deposits/DepositManager.sol) is deployed as non-upgradeable; when releasing a new version, existing receipt tokens and underlying deposits remain with the previous DepositManager instance. No migration path is expected or required when introducing facility scoping.

Applied to files:

  • src/scripts/deploy/savedDeployments/convertible_deposit_limit_orders.json
  • src/test/mocks/MockDepositManager.sol
  • src/scripts/deploy/DeployV3.s.sol
  • deployments/.mainnet-1767809879.json
  • src/scripts/deploy/savedDeployments/convertible_deposit_limit_orders_sepolia.json
  • src/test/policies/EmissionManager.t.sol
  • deployments/.sepolia-1766582124.json
  • src/policies/deposits/LimitOrders.sol
  • src/scripts/ops/batches/ConvertibleDepositInstall.sol
  • src/test/policies/ConvertibleDepositAuctioneer/LimitOrdersFork.t.sol
  • src/test/mocks/MockConvertibleDepositAuctioneer.sol
  • src/policies/interfaces/deposits/ILimitOrders.sol
📚 Learning: 2025-08-08T11:14:54.317Z
Learnt from: 0xJem
Repo: OlympusDAO/olympus-v3 PR: 88
File: src/test/policies/ConvertibleDepositAuctioneer/ConvertibleDepositAuctioneerTest.sol:413-416
Timestamp: 2025-08-08T11:14:54.317Z
Learning: In ConvertibleDepositAuctioneer (src/policies/deposits/ConvertibleDepositAuctioneer.sol), bid() reverts with ConvertibleDepositAuctioneer_ConvertedAmountZero when ohmOut == 0, before evaluating the minOhmOut slippage check. Therefore, setting minOhmOut=0 does not guarantee acceptance in zero-output scenarios; the zero-output revert triggers first.

Applied to files:

  • src/scripts/deploy/DeployV3.s.sol
  • deployments/.mainnet-1767809879.json
  • src/test/policies/EmissionManager.t.sol
  • src/scripts/ops/batches/ConvertibleDepositInstall.sol
  • src/test/mocks/MockConvertibleDepositAuctioneer.sol
  • src/policies/interfaces/deposits/ILimitOrders.sol
📚 Learning: 2025-11-07T11:09:53.808Z
Learnt from: 0xJem
Repo: OlympusDAO/olympus-v3 PR: 29
File: src/policies/deposits/BaseDepositFacility.sol:631-639
Timestamp: 2025-11-07T11:09:53.808Z
Learning: OlympusDAO/olympus-v3: BaseDepositFacility.setAssetPeriodReclaimRate now uses a dedicated reclaim-rate error (not InvalidAddress) when reclaimRate_ > ONE_HUNDRED_PERCENT, fixed in a follow-up PR (#180). Avoid re-flagging this in earlier PRs.

Applied to files:

  • deployments/.mainnet-1767809879.json
  • src/scripts/ops/batches/ConvertibleDepositInstall.sol
  • src/test/mocks/MockConvertibleDepositAuctioneer.sol
📚 Learning: 2025-08-04T11:03:24.007Z
Learnt from: 0xJem
Repo: OlympusDAO/olympus-v3 PR: 84
File: src/test/policies/YieldDepositFacility/execute.t.sol:41-43
Timestamp: 2025-08-04T11:03:24.007Z
Learning: In YieldDepositFacility, 0xJem intentionally allows snapshots to be overwritten/updated within the same block to ensure they reflect the latest vault conversion rates. This is not a gaming vulnerability but desired behavior - the gaming fix was removing timestamp hints, not preventing snapshot updates within blocks.

Applied to files:

  • src/scripts/ops/batches/ConvertibleDepositInstall.sol
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: run-ci
  • GitHub Check: run-ci
  • GitHub Check: run-ci
  • GitHub Check: run-ci
  • GitHub Check: run-ci
  • GitHub Check: run-ci
  • GitHub Check: run-ci
🔇 Additional comments (35)
src/test/mocks/MockPrice.sol (1)

2-2: LGTM!

Pragma widening for test mocks is appropriate and consistent with the PR-wide compiler compatibility updates.

src/test/lib/bonds/bases/BondBaseSDA.sol (1)

2-2: LGTM!

Pragma widening for the test bond library is consistent with the PR-wide updates.

src/test/lib/bonds/BondFixedTermTeller.sol (1)

2-2: LGTM!

Pragma widening for the test bond teller library aligns with the PR-wide compiler compatibility updates.

src/modules/RANGE/OlympusRange.sol (1)

2-2: Pragma relaxation acknowledged.

The pragma change from exact 0.8.15 to >=0.8.15 allows broader compiler compatibility. Since no logic changes accompany this update, the risk is minimal. Based on learnings, this appears intentional despite the preference to avoid changes to deployed contracts.

src/test/lib/bonds/bases/BondBaseTeller.sol (1)

2-2: LGTM!

Pragma relaxation for a test library file is appropriate and allows broader compiler compatibility for testing purposes.

src/test/lib/bonds/BondFixedTermSDA.sol (1)

2-2: LGTM!

Consistent pragma relaxation for test library files.

src/test/lib/bonds/BondAggregator.sol (1)

2-2: LGTM!

Consistent pragma relaxation for test library files.

src/scripts/ops/batches/args/ConfigureDepositParameters_202512.json (1)

1-16: Configuration parameters look reasonable.

The parameter values appear well-formed:

  • enabledPeriods and reclaimRatePeriods arrays are correctly aligned (both contain period 3)
  • reclaimRates value of 9750 (97.5% in basis points) is within valid bounds (< 100%)
  • minPriceScalar of 1.1e18 represents a 10% floor above base price

Consider adding a companion documentation file or inline comments in the consuming script to explain the rationale for these specific parameter choices for future maintainers.

src/scripts/ops/lib/BatchScriptV2.sol (1)

384-393: Verify stdJson.readUintArray is available in your forge-std version.

If readUintArray isn’t supported (or behaves differently), this will fail at runtime when parsing args files.

src/test/policies/EmissionManager.t.sol (1)

3-3: Ctor callsite updates look consistent; just ensure no tests invoke bid() with depositManager = address(0).

If any test path starts exercising bid/limit-order flows against this mock instance, the zero depositManager will revert on deposit.

Also applies to: 317-321, 845-846, 3263-3267

deployments/.mainnet-1767809879.json (1)

1-3: Verify this address matches the deployed bytecode for the intended mainnet release artifact.

At minimum, confirm it matches your deploy script output and any saved deployment JSON used by ops tooling.

deployments/.sepolia-1766582124.json (1)

1-3: LGTM!

The deployment mapping follows the established naming convention and contains a valid checksummed Ethereum address.

deployments/.sepolia-1766489520.json (1)

1-3: LGTM!

Valid deployment mapping with proper address format. This appears to be an earlier Sepolia deployment compared to the 1766582124 timestamp file.

src/scripts/deploy/savedDeployments/convertible_deposit_limit_orders_sepolia.json (1)

1-13: LGTM!

The Sepolia deployment configuration correctly uses a different receipt token address from the mainnet config while maintaining the same deposit period structure.

src/scripts/ops/batches/args/ConvertibleDepositLimitOrders.json (1)

1-10: LGTM!

The batch configuration correctly references the PeripheryEnable function with the matching contract identifier used in the deployment mappings.

src/scripts/deploy/savedDeployments/convertible_deposit_limit_orders.json (1)

1-13: Configuration structure is correct; external verification needed for token validity.

The JSON structure is valid with matching array lengths. The CDAuctioneerLimitOrders contract validates that the receipt token address is non-zero (line 173 in src/policies/deposits/LimitOrders.sol) and that the deposit period is enabled in the auctioneer (line 181). However, the contract does not validate that the provided address is the actual CDR (Convertible Deposit Receipt) token for deposit period 3. Confirm that 0x03d95a2f9A29228ea6D0690f2d1Bcd15973d926F is the registered receipt token for period 3 on mainnet through blockchain inspection or deployment records.

shell/safeBatchV2.sh (1)

17-17: LGTM!

The verbose flag implementation follows the established patterns for boolean flags in this script. The verbosity levels (-vvv default, -vvvv verbose) are appropriate for Forge script debugging.

Also applies to: 40-40, 54-54, 66-66, 111-119

src/scripts/deploy/DeployV3.s.sol (3)

293-309: LGTM!

The helper correctly uses SafeCast.encodeUInt8 which will revert if any value exceeds 255, ensuring safe downcasting from uint256 to uint8.


311-319: LGTM!

Follows the established pattern for deployment argument readers.


799-854: LGTM!

The deployment function follows established patterns. Array length validation is appropriately delegated to the CDAuctioneerLimitOrders constructor which will revert with ArrayLengthMismatch if lengths don't match.

src/scripts/env.json (1)

445-445: LGTM!

The new ConvertibleDepositAuctioneerLimitOrders addresses are correctly placed under olympus.periphery for mainnet and sepolia, consistent with the deployment script's return prefix.

Also applies to: 642-642

src/scripts/ops/batches/PeripheryEnable.sol (1)

13-34: LGTM!

The batch script correctly reads the contract key, resolves the address, and encodes the enable call. The empty payload abi.encode("") is appropriate since CDAuctioneerLimitOrders._enable is a no-op.

src/test/policies/ConvertibleDepositAuctioneer/LimitOrdersFork.t.sol (2)

48-100: LGTM!

The fork test setup is well-structured. It correctly fetches deposit periods from the on-chain auctioneer, resolves receipt tokens via the deposit manager, and initializes the LimitOrders contract with realistic mainnet state.


102-180: LGTM!

The test provides comprehensive coverage of the order lifecycle. The use of assertGe at line 174 is appropriate since the filler could potentially have pre-existing USDS balance or receive additional tokens from other sources during the fill.

src/policies/deposits/LimitOrders.sol (9)

87-121: LGTM!

The constructor properly validates all inputs, sets immutables, and initializes the deposit period mapping. The max approval to sUSDS is a standard pattern for vault contracts.


221-254: LGTM!

The _deposit function correctly handles sUSDS rounding by adjusting budgets based on the actual withdrawable amount. The check for zero shares prevents deposits that would round to nothing.


271-331: LGTM!

The createOrder function has comprehensive validation including ERC721 receiver check for early failure, minimum bid validation against the auctioneer, and proper accounting of totalUsdsOwed.


375-446: LGTM!

The fillOrder function is well-implemented with proper validation, accounting, and transfers. The approval to DEPOSIT_MANAGER (line 417) is correct—the auctioneer's bid function pulls tokens through the deposit manager. The re-deposit of remaining USDS (lines 436-437) handles dust appropriately by only depositing if it would result in at least 1 share.


457-479: LGTM!

The cancelOrder function intentionally omits the onlyEnabled modifier to allow users to withdraw funds even when the contract is disabled. The use of saturatingSub is a defensive measure against potential accounting edge cases.


486-515: LGTM!

The yield functions correctly use previewWithdraw (which rounds up) to calculate the maximum shares needed to cover obligations, ensuring the protocol never sweeps funds that belong to users. The saturatingSub provides additional safety.


340-357: LGTM!

The incentive calculation correctly handles the final fill by allocating all remaining incentive, avoiding rounding dust. The multiplication in line 355 is safe for realistic deposit amounts.


581-619: LGTM!

The canFillOrder view function correctly mirrors all the validation checks in fillOrder, providing consistent off-chain fillability preview.


681-774: LGTM!

The _getFillableOrders function uses a standard pattern for building dynamic arrays in view functions. The supportsInterface correctly declares support for all implemented interfaces.

src/policies/interfaces/deposits/ILimitOrders.sol (2)

9-105: LGTM!

The error and event definitions are comprehensive and well-documented, matching all usages in the implementation.


107-343: LGTM!

The LimitOrder struct and all function signatures are well-defined with comprehensive NatSpec documentation. The interface correctly captures the full public API surface of CDAuctioneerLimitOrders.

Comment thread src/scripts/ops/batches/ConvertibleDepositInstall.sol
Comment thread src/scripts/ops/lib/BatchScriptV2.sol
Comment thread src/scripts/ops/lib/BatchScriptV2.sol
Comment thread src/test/mocks/MockConvertibleDepositAuctioneer.sol
Comment thread src/test/mocks/MockDepositManager.sol
@0xJem
0xJem merged commit e49abfe into master Jan 13, 2026
9 checks passed
This was referenced Mar 20, 2026
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.

3 participants