Skip to content

closeYieldVault can leave residual FCM position due to precision/rounding #178

@liobrasil

Description

@liobrasil

Summary

closeYieldVault can succeed while leaving a tiny non-zero FCM position (small residual debt/collateral).

Root cause: close flow relies on UFix64 (8 decimals) plus swap quote rounding, so exact repay amounts are not always representable in one pass.

This is separate from #152.

Why this matters

  • A user expects "close" to mean fully closed.
  • Current behavior can leave a small residual position after close.
  • Residual is usually tiny, but this breaks close invariants and creates inconsistent behavior.

Expected behavior

On close, protocol should either:

  1. Fully unwind debt/collateral to zero (or a defined dust threshold), then burn; or
  2. Revert and keep vault open if full unwind cannot be guaranteed.

Acceptance criteria

  • After closeYieldVault, residual debt/collateral is zero (or <= explicit dust threshold).
  • No successful close that burns strategy while leaving non-zero position above threshold.
  • Precision edge-case tests added around UFix64 minimum unit (0.00000001).

Numerical example (what is happening)

Observed close flow (mainnet investigation):

  • Before close:

    • Collateral: 0.00001000 WETH
    • Debt: 0.02038486 MOET
    • getYieldVaultBalance(): 0.00000996 WETH (less than full collateral)
  • During close:

    • 0.01911391 tauUSDFv swapped to 0.02030333 MOET for repayment
  • After close:

    • Residual debt: 0.00008153 MOET
    • Residual collateral: 0.00000004 WETH

Precision constraint:

  • Price used: 3312.54037990 MOET/WETH
  • Exact collateral needed for residual debt: ~0.00000002461253 WETH
  • UFix64 step is 0.00000001, so exact amount is not representable
    • 0.00000002 underpays
    • 0.00000003 clears debt (with small overpayment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions