> For the complete documentation index, see [llms.txt](https://docs.curvance.com/app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.curvance.com/app/developer-docs/position-management/deleverage-fold.md).

# Deleverage / Fold

### Overview

Curvance PositionManagers are router-style contracts that wrap multi-step leverage and deleverage actions inside a single isolated market. For deleveraging, the PositionManager withdraws collateral-side assets, runs the manager-specific exit or swap path, repays debt, and returns defined leftover balances while the cTokens and MarketManager enforce market listing, PositionManager authorization, repayment rules, redemption rules, account liquidity, and cooldown checks.

### Key Components

The deleveraging flow involves:

* `BasePositionManager`: shared `deleverage` and `deleverageFor` entrypoints, callback handling, delegation checks, reentrancy protection, protocol fee handling, and pre/post account-value slippage checks.
* Concrete PositionManagers: asset-specific conversion logic for simple ERC20 routes, vault routes, Pendle routes, Velodrome routes, and Aerodrome routes.
* `MarketManager`: isolated-market listing, PositionManager authorization, account-status checks, repayment review, redemption review, pause state, caps, and cooldown enforcement.
* cTokens and `BorrowableCToken`: the collateral-side cToken executes `withdrawByPositionManager`, and the debt-side borrowable cToken receives repayment through `repayFor`. Live cTokens are not separate "collateral cToken" and "borrowable cToken" contract types; borrowability is a per-market configuration controlled by `debtCaps(cToken)`.

### Deleverage Process Flow

The position unwinding flow follows these key steps:

<figure><img src="/files/G1RHSHn37gyBYBaE0KVs" alt="" width="563"><figcaption></figcaption></figure>

#### Data Flow

1. **Initiation:**\
   The position unwinding flow starts when the user calls `deleverage(action, slippage)` for their own account, or an approved delegate calls `deleverageFor(action, account, slippage)`.\
   \
   The `action` argument is a `DeleverageAction` containing:
   1. `cToken`: the cToken to withdraw from.
   2. `collateralAssets`: the amount of that cToken's underlying asset to redeem, not cToken shares.
   3. `borrowableCToken`: the debt-side cToken to repay.
   4. `repayAssets`: the minimum debt-asset balance the PositionManager must hold after the route.
   5. `swapActions`: manager-specific swap instructions.
   6. `auxData`: manager-specific auxiliary data.
2. **Position Token Withdrawal:**

   The PositionManager validates the action and calls `action.cToken.withdrawByPositionManager(action.collateralAssets, account, action)`. The cToken accrues, computes the shares needed with `previewWithdraw` logic, withdraws the underlying asset to the PositionManager, and then calls `onRedeem(...)` so the PositionManager can run the deleverage callback.
3. **Collateral Conversion:**

   Collateral conversion is implemented by the concrete PositionManager's `_swapCollateralAssetToDebtAsset(action)` hook.\
   \
   The exact route is manager-specific. `SimplePositionManager` requires exactly one collateral-asset-to-debt-asset swap. Vault managers may redeem vault shares first and can skip the external swap when the vault output already matches the debt asset. Pendle and Velodrome or Aerodrome managers exit their protocol position first, then optionally run one or more swaps whose endpoints must match the manager's expected output and final debt asset.
4. **Debt Repayment:**

   Debt repayment happens in the base deleverage callback after the manager-specific route finishes. The PositionManager checks that it holds at least `action.repayAssets` of the debt asset. It then reads the owner's fresh debt with `debtBalanceUpdated(owner)` and repays `min(assetsHeld, currentDebt)` through `borrowableCToken.repayFor(repayAssets, owner)`.<br>

   `repayAssets` is a minimum debt-asset output floor for the deleverage route. It is not always the exact final repayment amount, and setting it to zero reverts in the PositionManager.
5. **Asset Return:**

   After repayment, the base callback returns the balances it explicitly sweeps:

   * remaining debt asset;
   * remaining withdrawn collateral asset;
   * remaining balances of each `swapActions[i].outputToken`.

   Do not describe this as a blanket refund of every possible intermediate token. PositionManagers are router-style contracts and should not be treated as user-specific custody for arbitrary stranded balances.

### State Transitions

During deleverage, validation happens across the PositionManager, the collateral cToken, the debt cToken, and the MarketManager:

<figure><img src="/files/8AF6lF9OTkBvf0f0R0Un" alt="" width="563"><figcaption></figcaption></figure>

* `deleverageFor` checks delegation on the PositionManager contract.
* `_deleverage` rejects `repayAssets == 0` and requires `action.cToken` to be listed in the connected MarketManager.
* `withdrawByPositionManager` requires the caller to be an enabled PositionManager, accrues the cToken, computes the shares needed for `collateralAssets`, withdraws the underlying to the PositionManager, and runs the `onRedeem` callback.
* `onRedeem` requires the debt-side `borrowableCToken` to be listed and verifies that the callback token and amount match the action.
* `repayFor` accrues debt, checks the repayment through `MarketManager.canRepayWithReview(...)`, and can revert during the hold period or if a partial repay would leave debt below `MIN_LOAN_SIZE`.
* The final redemption review runs through `MarketManager.canRedeemWithCollateralRemoval(...)`, which enforces redeem pause state, transfer eligibility, and account liquidity for any posted collateral that is removed.

### Protocol-Specific Implementations

Curvance supports deleverage through concrete PositionManager implementations:

* `SimplePositionManager`: generic non-native ERC20 paths using a single swap.
* `SingleSidedVaultPositionManager`: ERC4626-style vault positions that use the simple deleverage path.
* `DualSidedVaultPositionManager`: vault positions that redeem vault shares before optionally swapping into the debt asset.
* `NativeVaultPositionManager`: native-token vault positions that inherit the simple deleverage path.
* `PendlePTPositionManager`: Pendle principal-token positions.

Each implementation provides specialized logic for handling the unique characteristics of its respective protocol when exiting positions.

### Access Control and Delegation

PositionManager deleverage operations can be initiated by:

* the position owner through `deleverage(action, slippage)`;
* a delegate through `deleverageFor(action, account, slippage)`, if the account approved that delegate on the specific PositionManager contract with `setDelegateApproval(delegate, true)`.

### Slippage Protection

Deleverage has several slippage-related controls:

* the top-level `slippage` parameter on `deleverage` and `deleverageFor`, checked by `BasePositionManager.checkSlippage` against the account's collateral-minus-debt value before and after the action;
* each `SwapperLib.Swap.slippage`, checked by `_swapSafe` using oracle-priced input and output value;
* external swap calldata minimum-output checks, enforced through the approved calldata checker for the swap target;
* manager-specific floors, such as `repayAssets`, Pendle minimum-output fields, or Velodrome PT exit and route constraints.

The top-level `checkSlippage` modifier is a sanity check, not a complete replacement for route quoting and swap-level limits.

### Example Flow

A typical simple ERC20 deleverage flow:

1. The user has a WETH collateral position and USDC debt in the same isolated market.
2. The user calls `deleverage(action, slippage)`, where `action.cToken` is the WETH cToken and `action.borrowableCToken` is the USDC cToken.
3. The PositionManager calls `withdrawByPositionManager(action.collateralAssets, owner, action)` on the WETH cToken.
4. The WETH cToken withdraws WETH underlying to the PositionManager and calls `onRedeem`.
5. The concrete PositionManager route swaps WETH to USDC according to `swapActions`.
6. The base callback checks that the PositionManager holds at least `action.repayAssets` USDC, reads fresh debt, and calls `repayFor(...)` on the USDC cToken.
7. Remaining swept balances are returned to the owner.
8. Swap-target and debt-cToken allowances opened by the flow are removed when the relevant helper reaches its cleanup path.

The flow reduces collateral and debt in one transaction while still relying on cToken and MarketManager checks for repayment, redemption, liquidity, pause state, cooldowns, and route slippage.

### User Interaction Functions

#### deleverage()

**Description:** Deleverages an active Curvance position for `msg.sender` by redeeming collateral-side assets, converting them through the concrete PositionManager route, repaying debt, and checking pre/post account value through `checkSlippage`.

**Contract:** `BasePositionManager`, inherited by the concrete PositionManager used for the market.

**Function signature:**

```solidity
function deleverage(
        DeleverageAction calldata action,
        uint256 slippage
) external;
```

<table><thead><tr><th width="185">Type</th><th width="171">Name</th><th>Description</th></tr></thead><tbody><tr><td>DeleverageAction</td><td>action</td><td>Struct containing the collateral cToken, collateral underlying amount, debt cToken, minimum debt-asset output floor, swap route, and manager-specific auxiliary data.</td></tr><tr><td>uint256</td><td>slippage</td><td>Top-level PositionManager slippage tolerance in WAD, checked against account value before and after the action.</td></tr></tbody></table>

**Events:**

```solidity
// In the collateral cToken path, inherited from ERC20, emitted when shares burn.
event Transfer(address indexed from, address indexed to, uint256 amount);

// In BaseCToken.sol, emitted only if posted collateral is reduced.
event CollateralUpdated(uint256 shares, bool increased, address account);

// In BorrowableCToken.sol.
event Repay(uint256 assets, uint256 debtAssetsOwed, address payer, address account);
```

***

#### deleverageFor()

**Description:** Deleverages an active Curvance position for `account` through PositionManager delegation. The account must approve the caller on the specific PositionManager contract with `setDelegateApproval(delegate, true)`.

**Contract:** `BasePositionManager`, inherited by the concrete PositionManager used for the market.

**Function signature:**

```solidity
function deleverageFor(
        DeleverageAction calldata action,
        address account,
        uint256 slippage
) external;
```

<table><thead><tr><th width="172">Type</th><th width="159">Name</th><th>Description</th></tr></thead><tbody><tr><td>DeleverageAction</td><td>action</td><td>Structure containing deleverage operation details including position token, collateral amount, borrow token, swap data, repay amount, and auxiliary data.</td></tr><tr><td>address</td><td>account</td><td>The account to deleverage an active Curvance position for.</td></tr><tr><td>uint256</td><td>slippage</td><td>Slippage accepted by the user for the deleverage action, in WAD (1e18).</td></tr></tbody></table>

**Events:**

```solidity
// In the collateral cToken path, inherited from ERC20, emitted when shares burn.
event Transfer(address indexed from, address indexed to, uint256 amount);

// In BaseCToken.sol, emitted only if posted collateral is reduced.
event CollateralUpdated(uint256 shares, bool increased, address account);

// In BorrowableCToken.sol.
event Repay(uint256 assets, uint256 debtAssetsOwed, address payer, address account);
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.curvance.com/app/developer-docs/position-management/deleverage-fold.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
