Skip to content

feat: add liquidation margin collateral planner - #67

Open
Seranged wants to merge 1 commit into
mainfrom
feature/lite-228-liquidation-with-margin
Open

feat: add liquidation margin collateral planner#67
Seranged wants to merge 1 commit into
mainfrom
feature/lite-228-liquidation-with-margin

Conversation

@Seranged

Copy link
Copy Markdown
Contributor

Summary

  • add an execution-service planner for liquidations that first supplies margin collateral into the liquidator sub-account
  • avoid duplicate collateral-enable planning by evaluating the liquidation against a collateral-aware account view
  • export the liquidation planner argument types from the execution-service barrel

Tests

  • pnpm --filter @eulerxyz/euler-v2-sdk typecheck
  • pnpm --filter @eulerxyz/euler-v2-sdk test -- executionService.test.ts
  • pnpm --filter @eulerxyz/euler-v2-sdk build
  • pnpm exec biome lint src/services/executionService/executionService.ts src/services/executionService/executionServiceTypes.ts src/services/executionService/index.ts test/executionService.test.ts
  • packed local tarball and installed it into euler-lite with npm install --no-save --package-lock=false /tmp/eulerxyz-euler-v2-sdk-0.0.0-lite-228.0.tgz
  • in euler-lite: npm run typecheck
  • in euler-lite: npm run test:run -- tests/utils/stepDecoding.test.ts

Adds an execution-service helper that supplies margin collateral before liquidating and avoids duplicate collateral-enable planning for the liquidator sub-account.

@LeonardEulerXYZ LeonardEulerXYZ 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.

Leonard Review — Changes requested

Reviewed head ee850dc2c04b9e27a6b9cd908861b43f87d7b085.

Walkthrough

This PR adds planLiquidationWithMarginCollateral, exports the new argument type, and adds execution-service tests around zero-margin fallback, approval/deposit ordering, wrapped-native handling, and duplicate collateral-enable suppression.

Verdict

Requesting changes for one correctness/API-safety issue in the exported planner. The helper currently suppresses the seized-collateral enable whenever the liquidator sub-account asks about args.collateral, even though the preceding deposit only enabled marginCollateral.vault. If those vaults differ, the generated liquidation batch can omit the required enable for the seized collateral vault.

Validation performed

  • git diff origin/main...HEAD --stat and full changed-file review.
  • Prior comment lifecycle scan: inspected issue comments, formal reviews, and review comments; no prior Leonard comments or active bot/reviewer feedback found.
  • Security/supply-chain sweep over the whole diff: no package/lock/workflow/script/dependency changes and no suspicious diff patterns found.
  • pnpm --filter @eulerxyz/euler-v2-sdk test -- test/executionService.test.ts → pass (26 files / 347 tests; repo script currently runs the package suite despite the path arg).
  • pnpm --filter @eulerxyz/euler-v2-sdk typecheck → pass.
  • pnpm --filter @eulerxyz/euler-v2-sdk build → pass.
  • Focused invariant probe for distinct margin-vault vs seized-collateral-vault liquidation planner → fails on this head: expected a second enableCollateral for the seized collateral vault, actual batch omits it. Temporary probe was removed afterward; worktree is clean.

Scalability / maintainability hygiene pass

I checked sibling execution planners and downstream Lite-style transaction call sites for similar readiness-gate / transaction-path patterns. The new helper is a narrow wrapper around existing planDeposit + planLiquidation, which is the right reusable shape. The missing piece is the abstraction boundary: the wrapper should model exactly what the preceding deposit made true (marginCollateral.vault enabled for the liquidator sub-account), not a broader assumption about the seized collateral vault. Add a focused regression test for the distinct-vault case, or enforce/document same-vault-only semantics at the API boundary if that is truly the intended invariant.

Screenshots: not applicable; SDK transaction-construction change, no user-visible UI captured.

comment lifecycle: none found / no cleanup needed.

) => {
if (
getAddress(subAccount) === getAddress(liquidatorSubAccountAddress) &&
getAddress(vault) === getAddress(collateral)

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.

This wrapper makes the liquidation account report the seized collateral vault as enabled, but the preceding deposit only enabled marginCollateral.vault. When those two addresses differ, planLiquidation skips the enableCollateral call for the seized collateral vault, so the generated batch can be missing the collateral enable needed for the liquidation output. I reproduced it with a focused probe using distinct margin/seized vaults: the batch is [enableCollateral(margin), deposit, enableController, liquidate] instead of also appending enableCollateral(seized). Either compare this override against marginCollateral.vault (so only the actually-enabled vault is faked as enabled), or enforce a same-vault invariant in the exported API with a runtime guard + test.

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.

2 participants