> ## 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 Contract Architecture

> Core pools, periphery, fee routing, optional rewards, events, and privileged controls.

# DLMM Contract Architecture

Ramses DLMM is an LFJ v2.2-style Liquidity Book implementation integrated with Ramses fee routing and optional voter-directed rewards.

## Contract map

| Contract              | Responsibility                                                                                                                      |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `DLMMFactory`         | Deploys deterministic pools, stores fee presets and quote assets, manages routing state, pool parameters, protocol share, and hooks |
| `DLMMPool`            | Holds reserves, executes swaps, tracks bins and active ID, accrues fees, stores oracle state, and issues per-bin LP shares          |
| `DLMMToken`           | ERC1155-like per-bin share accounting embedded in each pool                                                                         |
| `DLMMRouter`          | User-facing pool creation, liquidity, swap, native-asset, and slippage/deadline flows                                               |
| `DLMMQuoter`          | Searches registered, non-ignored bin steps for exact-input and exact-output routes                                                  |
| `DLMMFeeCollector`    | Pulls the protocol share from pools and sends it to treasury or a live pool `FeeDistributor`                                        |
| `DLMMBaseHooks`       | Base validation and callback surface for pool hooks                                                                                 |
| `DLMMRewarder`        | Optional RAM emission hook with rewarded-bin and anti-JIT accounting                                                                |
| `DLMMRewarderFactory` | Deploys beacon-proxy rewarders and links pool-to-rewarder state                                                                     |

```text theme={null}
DLMMFactory ──creates──> DLMMPool / DLMMToken
     │                       │
     ├──used by──> DLMMRouter│<──quotes── DLMMQuoter
     │                       │
     └──fee recipient──> DLMMFeeCollector
                              │
                              ├──ungauged/dead──> Treasury
                              └──alive rewarder──> FeeDistributor

Voter ──RAM emissions──> DLMMRewarder ──hooked to──> DLMMPool
```

## Factory

### Pool identity

There is at most one pool for an unordered token pair and bin step. The factory sorts tokens for storage, but initialization preserves the supplied `tokenX` and `tokenY` order.

Key reads:

```solidity theme={null}
getLBPairInformation(tokenX, tokenY, binStep)
getAllLBPairs(tokenX, tokenY)
getLBPairAtIndex(index)
getNumberOfLBPairs()
isPool(pool)
getAllBinSteps()
getOpenBinSteps()
getPreset(binStep)
getLBPairImplementation()
```

Pools are deterministic immutable clones. Updating `getLBPairImplementation()` changes the implementation used for future pools; it does not upgrade an existing clone.

### Creation constraints

`createLBPair(tokenX, tokenY, activeId, binStep)` requires:

* An existing preset for `binStep`
* An open preset unless the caller is the factory owner
* A whitelisted `tokenY` quote asset
* Distinct, non-zero tokens
* No existing pool for that token pair and bin step
* A valid active-bin price

The `LBPairCreated` event is the canonical discovery event.

### Mutable configuration

The factory owner controls:

* Preset parameters and whether a preset is open
* Fee parameters on an existing pool
* Pool protocol share
* Quote-asset membership
* Routing-ignore state
* Hook installation and removal through the hook-manager role
* Fee recipient and flash-loan fee
* Forced volatility decay
* The implementation used for future pools

The owner or configured `Voter` may change an existing pool's `protocolShare`.

## Pool

### Core reads

```solidity theme={null}
getTokenX()
getTokenY()
getBinStep()
getReserves()
getActiveId()
getBin(id)
getNextNonEmptyBin(swapForY, id)
getProtocolFees()
getStaticFeeParameters()
getVariableFeeParameters()
getLBHooksParameters()
getPriceFromId(id)
getIdFromPrice(price)
getSwapIn(amountOut, swapForY)
getSwapOut(amountIn, swapForY)
```

`getReserves()` reports pool reserves net of accrued protocol fees. `getBin(id)` reports the token reserves assigned to one bin.

### State-changing entrypoints

```solidity theme={null}
swap(swapForY, to)
mint(to, liquidityConfigs, refundTo)
burn(from, to, ids, amountsToBurn)
flashLoan(receiver, amounts, data)
collectProtocolFees()
increaseOracleLength(newLength)
```

These core functions are low-level. `swap()` relies on pre-transferred input and `mint()` expects packed liquidity configurations. Public integrations should normally use `DLMMRouter`.

### LP share behavior

Each bin ID has independent `balanceOf()` and `totalSupply()` accounting. Initial shares are derived from the square root of bin liquidity; later deposits mint proportionally to the bin's existing reserves and supply.

`DLMMToken` is ERC1155-like, but:

* It does not call receiver hooks
* It has no URI surface
* Operator approval for all bin IDs uses `approveForAll()`
* A linked rewarder hook can disable batch transfers

Burning requires the holder or an approved operator. The reviewed pool contracts do not expose an administrator function that withdraws arbitrary user LP principal.

## Router and quoter

`DLMMRouter` is the intended safety boundary for end-user transactions. It adds:

* Deadlines
* Token and active-ID slippage checks
* ERC20 and native-asset handling
* Refund routing
* A caller-only LP recipient check on public add-liquidity functions
* Exact-input and exact-output swaps
* Fee-on-transfer swap variants
* Batched per-bin liquidity operations

The router's current executable path version is `V2_1`. Its `V1` and `V2` enum members are compatibility placeholders.

`DLMMQuoter` evaluates every registered, non-ignored bin-step candidate for a hop and returns the best complete fill. It catches failing candidates, so callers must still verify that every selected pair and amount is non-zero.

## Fees

Pool static parameters are:

```solidity theme={null}
baseFactor
filterPeriod
decayPeriod
reductionFactor
variableFeeControl
protocolShare
maxVolatilityAccumulator
```

The base fee scales linearly with `baseFactor × binStep`. The variable fee scales quadratically with `volatilityAccumulator × binStep` and is capped. The maximum total swap fee is `10%`.

`protocolShare` is measured out of `10,000` and applies to the swap fee, not to trade notional:

```text theme={null}
protocol fee amount = total swap fee × protocolShare / 10,000
```

The remainder stays in bin reserves and compounds into LP share value.

`DLMMFeeCollector.collectProtocolFees(pool)`:

1. Pulls the pool's accrued protocol fees
2. Sends them to treasury if no live rewarder exists
3. Otherwise applies its configured treasury skim and notifies the rewarder's `FeeDistributor`

Ramses gauged policy targets a zero skim so 100% of collected pool fees reach voters. Rewarder creation does not enforce that collector setting, and it remains independently configurable, so integrations must verify live state.

Protocol-fee collection intentionally leaves one smallest unit of each non-zero token in the pool.

Flash-loan fees are entirely protocol fees. The factory owner can set the flash-loan fee up to `10%`.

## Oracle

Each pool contains an oracle of cumulative active ID, volatility, and bins crossed. It remains inactive until `increaseOracleLength()` allocates storage.

```solidity theme={null}
getOracleParameters()
getOracleSampleAt(lookupTimestamp)
increaseOracleLength(newLength)
```

Samples have a 120-second maximum lifetime. Integrations must inspect oracle parameters before assuming historical observations are available.

## Hooks and rewards

Hooks can execute before or after swaps, flash loans, mints, burns, and batch transfers. Hook calls are synchronous; an enabled hook that reverts or returns an invalid selector can block the corresponding pool operation until governance replaces or removes it.

`DLMMRewarder` enables Ramses voter-directed emissions:

* `Voter` treats the rewarder as the pool's emission target
* RAM streams over a configurable, upper-exclusive range of at most 11 bins
* The default `(0, 1)` range rewards only the active bin
* Reward weight is calculated from bin liquidity at the active-bin price
* Each bin then distributes pro rata to its share holders
* Owners claim only for their own address

Anti-JIT controls can forfeit newly accrued rewards for recently modified positions. Burns remain possible and principal is not forfeited.

Rewarders are beacon proxies. Updating the factory's rewarder implementation can change all existing rewarders. Removing or replacing a rewarder hook makes the old rewarder unlinked; its pending-reward view returns zero and claims revert until linkage is restored.

<Warning title="Not live on Robinhood">
  At the [Robinhood snapshot at block 22,674,244](/contracts/reference/dlmm/deployments), the factory reported `voter() == address(0)` and sampled pools had no hook. Do not expose RAM claims or gauged fee behavior unless a newer live read confirms that state changed.
</Warning>

## Voter and AccessHub integration

When configured, `Voter` reuses its existing pool/gauge mappings:

| Mapping                            | DLMM value                               |
| ---------------------------------- | ---------------------------------------- |
| `gaugeForPool[pool]`               | `DLMMRewarder`                           |
| `poolForGauge[rewarder]`           | `DLMMPool`                               |
| `feeDistributorForGauge[rewarder]` | Pool `FeeDistributor`                    |
| `isAlive[rewarder]`                | Controls emissions and voter fee routing |

`AccessHub` exposes dedicated DLMM operations for pool and rewarder creation, fee changes, hook managers, reward ranges, fee collector settings, and factory ownership. Regular users call an open factory preset directly; protocol operators use `createDLMMPool()`.

## Events

### Factory

```solidity theme={null}
LBPairCreated
PresetSet
PresetOpenStateChanged
LBPairIgnoredStateChanged
QuoteAssetAdded
QuoteAssetRemoved
DLMMVoterSet
```

### Pool

```solidity theme={null}
Swap
DepositedToBins
WithdrawnFromBins
TransferBatch
CompositionFees
CollectedProtocolFees
StaticFeeParametersSet
HooksParametersSet
FlashLoan
OracleLengthIncreased
ForcedDecay
```

### Rewards and fee routing

```solidity theme={null}
DLMMRewarderCreated
NotifyReward
ClaimRewards
FeesCollected
```

## Integration invariants

* `binStep = 1` means one basis point, or `0.01%`
* Prices are unsigned 128.128 fixed-point values
* `destinationBin = liveActiveId + deltaId`; `activeIdDesired` is the slippage anchor
* `refundTo` receives unused mint inputs
* Public router adds require `to == msg.sender`
* Router paths execute `Version.V2_1`
* `protocolShare` is basis points of swap fees
* Pool settings and hook state are mutable
* Current deployment state takes precedence over generic factory constants or documentation labels

## Additional resources

* [DLMM & Liquidity Bins](/concepts/protocol/dlmm)
* [DLMM Integration Guide](/contracts/guides/dlmm/integration)
* [Robinhood DLMM Deployments](/contracts/reference/dlmm/deployments)
