> ## Documentation Index
> Fetch the complete documentation index at: https://tech.ramses.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# DLMM & Liquidity Bins

> Discrete price bins, per-bin LP shares, dynamic fees, and Ramses fee and reward routing.

# Discrete Liquidity Market Maker

Ramses DLMM pools divide price space into discrete **bins**. Each bin has one fixed price and its own reserves. Swaps consume liquidity at the active bin's price and move to the next non-empty bin when that liquidity is exhausted.

This differs from Ramses concentrated-liquidity pools:

|                       | Concentrated liquidity            | DLMM                                         |
| --------------------- | --------------------------------- | -------------------------------------------- |
| Price unit            | Tick interval                     | Bin                                          |
| Price inside the unit | Moves along the pool curve        | Fixed                                        |
| LP position           | ERC721 position over a tick range | Multi-token balance for each bin ID          |
| LP fee accounting     | Claimable fees                    | Fees retained for LPs remain in bin reserves |
| Trader fee            | Pool-level fee set by governance  | Base fee plus an on-chain variable fee       |

<Note title="Current Robinhood deployment">
  At the [Robinhood snapshot at block 22,674,244](/contracts/reference/dlmm/deployments), DLMM is fee-only, the factory is not connected to `Voter`, and sampled pools do not have rewarder hooks. The rewarder and 100%-to-voters flow described below are optional protocol architecture.
</Note>

## Bins and the price grid

Each pool has an immutable `binStep`, expressed in basis points. One basis point is `0.01%`, so `binStep = 1` creates a `0.01%` geometric step between adjacent bins.

For bin ID `id`:

```text theme={null}
price(id) = (1 + binStep / 10,000)^(id - 2^23)
```

The contracts represent this price as an unsigned 128.128 fixed-point number. Use `getPriceFromId()` and `getIdFromPrice()` rather than reimplementing the fixed-point math unless exact parity has been tested.

Inside one bin, liquidity follows a constant-sum relationship:

```text theme={null}
L = price × amountX + amountY
```

The active bin may contain both assets. Relative to the pool's actual `tokenX` and `tokenY` ordering:

* Bins below the active ID may contain only `tokenY`
* The active bin may contain both `tokenX` and `tokenY`
* Bins above the active ID may contain only `tokenX`

Always read `getTokenX()` and `getTokenY()` from the pool. Display order in an interface is not a substitute for contract order.

## Swaps and price impact

A swap executes against the active bin and then traverses the pool's sparse tree of non-empty bins.

* Execution within one bin has no curve-driven price movement
* Crossing `N` bin IDs changes the execution price by `N` geometric steps; sparse traversal may skip empty bins
* A large trade can cross many bins, so its average execution price can differ materially from the starting price
* A swap reverts if the selected route cannot completely satisfy the requested amount

Direct pool swaps expect input tokens to have already been transferred and do not expose caller-facing deadline or minimum-output protection. Users and integrators should normally use `DLMMRouter`.

## LP positions

`DLMMPool` inherits an ERC1155-like multi-token implementation:

* Each bin ID is a separate fungible LP share
* `balanceOf(owner, binId)` returns an owner's share balance in that bin
* `totalSupply(binId)` returns all shares issued for that bin
* `balanceOfBatch()` reads multiple owner/bin pairs
* `approveForAll()` authorizes a router or manager to burn or transfer bin shares

The token intentionally does not implement ERC1155 receiver callbacks or token URIs. Integrations should use the exposed `DLMMToken` interface instead of assuming complete ERC1155 behavior.

When liquidity is removed, each bin returns `tokenX` and `tokenY` pro rata to the shares burned. LP swap fees retained by the pool increase bin reserves and therefore increase the redemption value of those shares. There is no separate LP fee claim for that retained portion.

## Adding liquidity

The router accepts independent token distributions across signed offsets from the pool's active bin at execution:

```text theme={null}
depositBinId = liveActiveId + deltaId
```

When constructing the transaction, read the pool's active ID, use it as `activeIdDesired`, and calculate:

```text theme={null}
deltaId = desiredBinIdAtQuote - activeIdDesired
```

The router checks that `liveActiveId` remains within `idSlippage` of `activeIdDesired`, but it uses `liveActiveId` to calculate the actual deposit bins. If the active ID moves within the permitted range, the entire distribution moves with it. Set `idSlippage = 0` when absolute bin placement is required.

`distributionX` and `distributionY` use `1e18`-scaled weights. Sum a token's array to `1e18` to allocate its full supplied amount. A sum below `1e18` leaves the remainder for `refundTo`; over-allocation can revert and should be rejected by the integration.

Important safeguards:

* Read the active ID immediately before constructing the transaction
* Set `idSlippage`, token minimums, and a deadline
* Set `to` to the router caller; the public add-liquidity functions reject any other LP recipient
* Set `refundTo` deliberately; unused amounts are returned there, which may differ from the LP recipient `to`
* Expect a composition fee when adding an imbalanced amount to the active bin, because the pool performs an implicit composition swap
* Estimate gas and batch very wide distributions

## Swap fees

The trader-paid DLMM fee is:

```text theme={null}
totalFee = baseFee + variableFee
```

The static component is:

```text theme={null}
baseFee = baseFactor × binStep × 1e10
```

where `1e18` represents `100%`. In basis points:

```text theme={null}
baseFeeBps = baseFactor × binStep / 10,000
```

The variable component rises quadratically with the volatility accumulator and `binStep`. The accumulator increases when on-chain swaps move across bins, decays according to the pool's filter and decay settings, and is capped by `maxVolatilityAccumulator`.

<Warning title="On-chain signal only">
  The variable fee does not observe CEX prices or off-chain volatility. It reacts only after DLMM swaps move through the on-chain price grid.
</Warning>

The main fee parameters are:

| Parameter                  | Purpose                                              |
| -------------------------- | ---------------------------------------------------- |
| `baseFactor`               | Static fee multiplier                                |
| `filterPeriod`             | Minimum interval before reference state refreshes    |
| `decayPeriod`              | Time after which the volatility reference resets     |
| `reductionFactor`          | Fraction of volatility retained during partial decay |
| `variableFeeControl`       | Sensitivity of the variable fee                      |
| `maxVolatilityAccumulator` | Cap on the dynamic response                          |
| `protocolShare`            | Portion of swap fees routed out of LP reserves       |

The total trader fee is capped at `10%`. `protocolShare` changes where the collected fee goes; it does not add another fee to the trade.

## Fee and reward routing

Ramses' Robinhood product policy distinguishes fee-only and gauged DLMM pools:

| Pool state                           | LP share of swap fees |                           Protocol/voter share | LP emissions               |
| ------------------------------------ | --------------------: | ---------------------------------------------: | -------------------------- |
| Robinhood fee-only / ungauged policy |                   95% |                        5% to protocol treasury | None                       |
| Gauged policy                        |                    0% | 100% to the pool's `FeeDistributor` for voters | RAM through `DLMMRewarder` |

For an ungauged pool, the protocol portion collected by `DLMMFeeCollector` goes to treasury. The 100%-to-voters gauged policy requires the collector's independently mutable `treasuryFees` value to be zero; otherwise that configured skim goes to treasury before the remainder reaches `FeeDistributor`.

Because fee parameters and protocol share are governance-configurable, integrations must read `getStaticFeeParameters()` from the pool instead of inferring the split from a label.

## Rewarder hooks and anti-JIT behavior

The optional `DLMMRewarder` is a pool hook and the DLMM equivalent of an emission target:

* `Voter` sends RAM emissions to the rewarder
* The rewarder distributes RAM over a configurable band of at most 11 bins around the active bin
* Rewards are weighted by liquidity valued at the active-bin price, then divided among each bin's share holders
* Claims are made by the owner for their own address

When the rewarder hook is linked:

* Minting to a different recipient requires an authorized manager
* All LP-share batch transfers are disabled while the rewarder is linked
* Burning liquidity remains available
* Recently modified liquidity may forfeit only newly accrued rewards during the anti-JIT cooldown; LP principal is not seized

Rewarder implementations are upgradeable through their beacon. Pool contracts are deterministic immutable clones; changing the factory's pool implementation affects future pools rather than existing pool clones.

## Integration checklist

1. Discover pools through `DLMMFactory`; do not manufacture pool addresses from UI data.
2. Confirm the pool's actual token order, active ID, bin step, static fee parameters, and hook state.
3. Quote the full amount and reject partial quotes where `amountInLeft` or `amountOutLeft` is non-zero.
4. Use router deadlines, minimum amounts, and active-ID slippage.
5. Index per-bin balances and `TransferBatch`, `DepositedToBins`, `WithdrawnFromBins`, and `Swap` events.
6. Treat hooks and fee settings as mutable governance-controlled state.
7. Do not assume the generated HyperEVM API Reference indexes Robinhood DLMM data.

## Additional resources

* [DLMM Integration Guide](/contracts/guides/dlmm/integration)
* [DLMM Contract Architecture](/contracts/reference/dlmm/overview)
* [Robinhood DLMM Deployments](/contracts/reference/dlmm/deployments)
* [Fees](/concepts/protocol/fees)
