> For the complete documentation index, see [llms.txt](https://docs.kpk.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kpk.io/funds/infrastructure/onchain-accounting/balance-adapters/ethena-cooldown.md).

# Ethena Cooldown

A plain adapter that reports the **USDe owed to an account that is in the sUSDe unstaking cooldown**. When a holder calls `cooldownShares` / `cooldownAssets` on Ethena's `StakedUSDeV2`, the sUSDe is burned and the underlying USDe is moved to a silo, recorded against the holder until `cooldownEnd` passes and they `unstake`. While cooling, this value is invisible to wallet and receipt-token adapters.

* **Type:** Plain adapter
* **protocolSubId:** `keccak256("ethena-cooldown")`
* **Source:** [`EthenaCooldownBalanceAdapter.sol`](https://github.com/karpatkey/onchain-accounting/blob/main/src/balances/BalanceAdapters/EthenaCooldownBalanceAdapter.sol)

***

## Positions returned

A **single** leg per account — non-zero only while an unstake is in flight. Unlike the queue adapters, sUSDe keeps one cooldown record per account, so this is one leg whose `isLocked` toggles, not two legs:

| Leg              | PositionKind | isDebt  | isLocked | Description                                                                       |
| ---------------- | ------------ | ------- | -------- | --------------------------------------------------------------------------------- |
| Pending cooldown | `Supplied`   | `false` | toggles  | Full pending USDe; `isLocked=false` once claimable, `isLocked=true` while cooling |

The pending USDe is carried in `balanceAsset`. There is one cooldown per account, so the leg carries `positionInstanceId = bytes32(0)`. The position is dropped if USDe is not registered in NAVCalculator, if the pending amount is zero, or if filtered out by `assetFilter`.

***

## Balance calculation

<figure><img src="/files/RhyAS5cCb57Oqdxq3BUz" alt="Flowchart of the Ethena Cooldown balance adapter: read calls derive position legs into PositionBalance entries."><figcaption><p>Ethena Cooldown adapter — how the underlying balances reported to the NAV Calculator are derived.</p></figcaption></figure>

There is exactly **one** cooldown slot per account (a new cooldown adds to it), so no enumeration is needed — a single read gives the full pending amount, and a second read sets `isLocked`:

```
(cooldownEnd, underlyingAmount) = StakedUSDeV2.cooldowns(account)
amount   = underlyingAmount      // full pending USDe; zeroed by the protocol on `unstake`
isLocked = not (block.timestamp >= cooldownEnd or StakedUSDeV2.cooldownDuration() == 0)
```

`underlyingAmount` is the full pending USDe, claimable once `cooldownEnd` passes; the protocol zeroes the slot on claim, so a closed or never-opened cooldown reads as 0. The leg is reported with `isLocked=false` iff `block.timestamp >= cooldownEnd` **or** `cooldownDuration() == 0` (cooldown disabled); otherwise `isLocked=true`. The adapter checks the cheap `cooldowns` read first and bails before scanning the registered-asset list when there is nothing pending.

***

## Identity

* **positionId:** `abi.encode(sUSDe)` (static; the Ethena `StakedUSDeV2` address)
* **positionKind:** `Supplied`
* **positionInstanceId:** `bytes32(0)` (one cooldown per account — no per-item handle)
* **Labels:** the adapter implements `positionLabels(positionId)`, returning `["Unstaking Cooldown", "sUSDe"]` (surfaced only on the verbose read path; full breadcrumb = `["Ethena", "Unstaking Cooldown", "sUSDe"]`).

sUSDe keeps a single cooldown record per account, so this adapter emits **one** leg under this positionId (not two). Its `isLocked` field toggles — `false` once claimable, `true` while still cooling — and the pending USDe rides in `balanceAsset`. The reconciliation key is `keccak256(abi.encode(chainId, protocolSubId, positionId, balanceAsset.asset, positionKind))` — `isLocked` is a mutable per-leg attribute and is **not** part of the key, so this single leg keeps one stable key as its flag toggles `true→false`.

***

## Constructor

```solidity
constructor(address stakedUSDe_, address underlyingToken_, address navCalculator_)
```

| Parameter          | Description                                                                                             |
| ------------------ | ------------------------------------------------------------------------------------------------------- |
| `stakedUSDe_`      | Ethena `StakedUSDeV2` (sUSDe) contract, which holds the per-account cooldown record. Must be a contract |
| `underlyingToken_` | Asset positions are denominated in — USDe (what the cooldown pays on `unstake`)                         |
| `navCalculator_`   | NAVCalculator address, used for asset-registry filtering. Must be a contract                            |

***

## Registration

Registered as a plain adapter with `addBalanceAdapters([adapter])` and removed with `removeBalanceAdapters([adapter])`.


---

# 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, and the optional `goal` query parameter:

```
GET https://docs.kpk.io/funds/infrastructure/onchain-accounting/balance-adapters/ethena-cooldown.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
