tokenizationUniswap v4Permissioned PoolsRWATokenization

Permissioned RWA Liquidity Has a Three-Ledger Problem

Uniswap v4 has separate designs for restricted participation and productive idle inventory. Combining them is a three-ledger settlement problem.

Andrew Nalichaev··12 min read

Two Uniswap v4 releases landed a day apart in July 2026, and the obvious thing to do with them is to put them together.

Permissioned Pools, published on 23 July, give restricted assets controlled participation: the pool checks whether a wallet is eligible before a swap or before an LP position is created or increased, and the issuer retains lifecycle controls over positions. DualPool, published on 22 July, solves an unrelated problem: it lets inventory earn yield in a vault between trades instead of sitting idle inside a pool waiting for flow. One controls who may participate. The other improves what capital does while nobody is trading.

Put them side by side and the product almost writes itself: an eligibility-gated market for tokenized funds where the liquidity is not dead between fills. In the previous article I argued that the permissioned standard removes a genuine protocol barrier without supplying the price anchor, arbitrage path, or balance sheet that make a market liquid. This is the next question, and it is narrower: can the two standard designs be combined without changing where each one expects the asset to live?

Not directly. And the interesting part is why not — because the answer is not a limitation in Uniswap's design. A v4 pool does reference a single hook address, so you cannot simply run two deployed contracts side by side, but a composite implementation can express both behaviors in one contract. If that were the whole obstacle, the problem would primarily be one of interface composition. The real difficulty starts after the callbacks have been merged: the two systems do not expect the asset to rest in the same place, and reconciling that is a settlement and accounting problem rather than an interface one.

A note on terminology: in this article, custody flow refers to the contract-level location and control of tokens. It does not determine legal custody, ownership, or regulatory status.

The asset cannot rest in two canonical places

Start with where each design puts the asset when nothing is happening, because that is where the conflict lives.

In a permissioned pool, the investor's restricted token does not enter the pool at all. It is transferred into a contract called the PermissionsAdapter, which holds the real asset and issues a stand-in representation of it. That representation is what the automated market maker actually trades, and by design it can exist only inside the PoolManager — the single shared contract that holds balances for every v4 pool. When value leaves, the representation is destroyed and the underlying restricted token is delivered to the recipient (architecture). This is deliberate. It is what stops a restricted asset from acquiring a freely circulating shadow version of itself. The pool's own definition even references the adapter rather than the underlying token, so from the market's point of view the tradable currency is the representation (position manager).

DualPool inverts the resting place. Between trades, the inventory is not in the pool: it sits in an ERC-4626 vault — a standard interface for a yield-bearing pool of assets where a depositor holds shares rather than the assets themselves — or as tracked balances and ERC-6909 claims, a lightweight internal accounting form the shared contract uses instead of moving real tokens (inventory and yield). Only when a trade arrives does the hook pull the amount that trade requires, deploy it as temporary liquidity, execute, and return the remainder to productive storage (overview, just-in-time liquidity). There is a further constraint that matters more than it sounds: each connected vault must be denominated in the pool's own currency, and that pairing is fixed when the pool is created (vault requirements, create and operate a pool).

Now overlay them. DualPool's productive path requires the pool currency to be transferable out of the PoolManager and into the hook and an ERC-4626 vault. In a permissioned pool, that currency is the adapter's virtual token, which neither the hook nor the vault can hold. ERC-6909 claims can remain inside the PoolManager, but they earn no vault yield and therefore do not solve the productive-storage side of the design. Meanwhile a real yield vault for a tokenized fund would need to hold the underlying restricted token — and would itself have to be an eligible holder of it — but that underlying is not the pool currency.

The conflict is not over whether a callback can be called. It is over which representation of the asset is allowed to exist at each point in the settlement cycle.

The three-ledger problem

I think this architecture is best understood as a three-ledger problem. The word ledger here does not mean three blockchains. It means three sets of records and invariants — some onchain, some off, often mixed — each of which believes it knows the truth about the same economic position.

The market ledger lives inside the automated market maker. It knows what is available to trade right now, what balances the pool owes or is owed, what fees have accrued, and at what price the curve will execute. Its unit of account is the pool currency, which in a permissioned pool is the adapter representation rather than the asset an investor would recognize.

The yield ledger lives in the vault. It knows how much underlying a share represents, how that ratio has drifted as yield accrued, and — separately and importantly — how much can actually be withdrawn at this instant. Its unit of account is vault shares.

The entitlement ledger is the one that resists a single location. It is not necessarily a single issuer-maintained register: it is the combined record that must connect the hook's internal LP shares to issuer-recognized holders, eligibility rules, distributions, and redemption procedures. Parts of it may be an onchain registry, parts an offchain transfer-agent record. The issuer may recognize the adapter or the vault as the registered holder while the hook sees individual liquidity providers behind it. Its primary key is the investor identity and the rights attached to it.

The AMM sees a currency. The vault sees shares. The issuer sees investors. A productive permissioned pool has to keep all three descriptions of the same economic position in sync, and the canonical DualPool already does part of this work: it reconciles the market and yield ledgers. The missing question is how that combined accounting maps into investor eligibility, distributions, redemption rights, and LP-level entitlements when the pool currency is a permissioned adapter representation.

The desynchronization is easy to produce and hard to notice. Consider a hypothetical combined implementation after a one-way swap. Part of the position may now sit as ERC-6909 claims, another part as vault shares, while the entitlement layer continues to map internal LP shares to eligible recipients. The entitlement ledger then has to answer a question neither of the others is holding: which investor this economic position belongs to, whether that investor may still receive the asset if they exit today, and where the asset goes if they may not. Each ledger is internally consistent. The composite is only consistent if something explicitly maintains the mapping across all three, and the published standard implementations were not built to carry that mapping into the permissioned case.

That mapping is the missing layer. Everything below is an attempt to describe its shape.

One possible underlying-aware settlement layer

What follows is a design proposal, not a description of any Uniswap product. The published standards do not specify this construction, and I am sketching requirements rather than an implementation.

Three accounting domains of a productive permissioned pool

AMM accountingmarket ledger
Vault accountingyield ledger
Investor entitlemententitlement ledger
At restbetween trades
No pool currency outstanding. No deployed liquidity.
holdsUnderlying restricted token in an eligible ERC-4626 vault. LP holds an internal pro-rata claim on shares.
tracksWhich investor is eligible, who holds the economic right to the asset and its distributions.
During executionwithin one transaction
createsStand-in representation exists only inside the shared PoolManager. Temporary liquidity is deployed and the swap executes.
releasesOnly the underlying the trade requires is withdrawn. Remaining shares stay productive.
Eligibility already established. No state change.
After executionsettlement
settlesTemporary position closes. Representation is redeemed. Swap fees are attributed.
returnsAvailable underlying goes back to the vault. Balances that cannot return are tracked separately and earn no vault yield.
reconcilesFees, carry and distributions are attributed to the LP position; exit and revocation routes are applied.

Conceptual design, not an implementation of the published Uniswap contracts. “Custody” here describes contract-level asset location and control, not a legal determination of custodian status.

From “Permissioned RWA Liquidity Has a Three-Ledger Problem” · andrewnalichaev.com

The core move is to stop treating "the asset" as one thing and be explicit that four representations of it coexist: the pool currency used for market accounting, the economic asset that is the underlying restricted token, the productive asset in the form of vault shares backed by that underlying, and the investor claim representing a liquidity provider's internal position and the rights attached to it. Most of the difficulty in a combined design is that these four drift apart and nothing is responsible for pulling them back together.

A settlement layer that could hold them together would work roughly like this. The pool continues to use the adapter representation as its trading currency, so the invariant that keeps restricted assets from circulating freely stays intact. Productive storage holds the underlying restricted token rather than the representation — which is only possible if the vault and every contract in that path are themselves eligible holders under the issuer's rules, and that eligibility is a precondition, not a detail. Between the two sits a layer that knows the unambiguous correspondence between adapter, underlying, vault shares, and each liquidity provider's internal position.

When a trade arrives, that layer withdraws from the vault only the underlying the trade requires, converts it into the representation inside the permitted perimeter, and deploys temporary liquidity. After execution it does the reverse: the temporary position closes, the representation is redeemed back into underlying, and whatever can be returned to productive storage is returned. Balances that cannot yet go back — the internal claim form, for instance, which earns no vault yield while it sits in that state (why claims exist) — have to be tracked as their own category rather than quietly counted as productive.

None of that is exotic individually. What makes it hard is that the settlement path moves value across underlying tokens, adapter currency, and vault shares while the LP's internal claim remains outstanding, and the system must preserve an auditable mapping back to the same economic position and its permitted recipient.

The asymmetric version is usually the better answer

There is a much simpler design hiding inside this problem, and I suspect it is the right one for most teams.

Nothing requires both sides of a pool to be productive. A pool has two legs, and the yield vault can be attached only to the cash or stablecoin leg while the tokenized asset leg rests in issuer-approved or eligibility-compatible storage. The complexity described above exists largely because someone wants the restricted asset itself to be productive between trades. Dropping that requirement does not eliminate the need for underlying-aware settlement on the restricted leg — that leg still has to move between an eligible holder, the adapter, and the PoolManager. It removes the additional vault-share layer from that leg, reducing the number of representations that must be reconciled during withdrawals and revocations.

There is also an economic argument for the asymmetric version, and it is stronger than the engineering one. A tokenized Treasury fund is already yield-bearing. Putting it into a second yield source does not obviously add return — it adds a second layer of vault, operational, and settlement risk on top of carry the asset was already producing. The idle-inventory problem DualPool solves is most acute for cash sitting still. That is exactly the leg where a vault earns its complexity.

Permissioning the liquidity provider is harder than permissioning the trade

Restricting who may trade is the easy half. Restricting who may provide liquidity, and being able to reverse that decision later, is where the two designs diverge most sharply.

In the permissioned standard, a liquidity provider holds a position that cannot be transferred to anyone else, eligibility is checked when the position is created or increased, and the issuer can unwind that position if circumstances require it (position manager). The object being controlled is a single, identifiable position. In DualPool, the liquidity provider does not hold a conventional position at all. Their stake is an internal, non-transferable accounting entry representing a pro-rata claim on shared inventory that may be spread across vault shares, internal claims, and raw balances at any moment (LP shares).

In a combined design, revoking a liquidity provider therefore stops being a single action. It becomes a sequence that has to be defined in advance: stop that provider accruing fees and carry from a specific moment; determine their pro-rata share across underlying, vault shares, and claims as they stand at that moment; establish which of those forms they are still permitted to receive; handle the case where the vault cannot return the full underlying immediately; and route anything they may not receive through a lifecycle the issuer has approved beforehand.

I am deliberately not resolving who "owns" the asset at each step. That is a product-specific legal and compliance question, and it is exactly the sort of question that cannot be answered generically. The architectural point is narrower: the reviewed public documentation does not specify these paths for a combined design, and a team building one would need to settle each of them before launch rather than discover them during a revocation.

Carry has to be measured incrementally

The previous article dealt with whether an underlying's carry reaches the liquidity provider at all. The combined design raises a different and narrower question: whether adding a vault on top produces additional return, and how that return would even be measured.

Underlying carry and incremental vault yield have to be accounted for separately and in the same denomination. If the RWA accrues through a rising NAV, that return sits in the value of each underlying token. If it distributes additional tokens into the vault, the same carry may instead appear as an increase in assets per vault share. Only the return produced over passive custody of the underlying is incremental vault yield. A dashboard that adds the underlying asset's total return to the vault share's total return can therefore count the same carry twice.

ERC-6909 claims and liquid buffers do not earn the vault rate. Any blended return must therefore weight vault shares, claims, and buffers separately; applying the vault's headline rate to total economic reserves would overstate what the position actually earns.

The last requirement is temporal rather than arithmetic. Distributions, deposits, withdrawals, and revocations all need a defined cutoff: the moment at which a liquidity provider stops or starts accruing each component. In a single-position model, that moment can be tied to explicit mint, increase, decrease, or unwind events. In a design where a provider holds a pro-rata claim on inventory distributed across shares, claims, and buffered balances, it has to be specified — and the reviewed public documentation does not specify it for a combined implementation.

Productive does not always mean executable

The last gap is the one most likely to surprise an operator, because it only appears under stress.

A vault position has two different sizes at any moment: what it is economically worth, and what can actually be taken out of it right now. The DualPool documentation is explicit about this distinction between total economic reserves and immediately deployable liquidity (reserves vs. effective liquidity), and the difference is not a rounding error. A vault can be capped, paused, or simply short of liquid assets at the moment a trade arrives.

Just-in-time market making is unforgiving about this, because the inventory has to materialize inside the same transaction as the trade. A liquidity provider can hold a perfectly good economic claim on assets that cannot be summoned in time to fill a swap, and from the market's perspective that liquidity does not exist.

Many tokenized real-world assets use request-based issuance or redemption, which is why ERC-7540 explicitly lists RWA protocols among the use cases for asynchronous vault flows. But two different redemptions must be separated. An issuer-level redemption of the RWA into cash may be asynchronous without preventing the token itself from trading in an AMM. JIT execution is constrained only when the productive vault cannot return the inventory token synchronously. An asynchronous productive vault therefore cannot by itself serve as the atomic inventory source; the design needs a liquid buffer, a separate market-maker balance sheet, or a settlement model that does not depend on same-transaction withdrawal.

Productive custody helps execution only to the extent that productive capital can become executable inventory when the trade arrives.

The missing layer is reconciliation

Every part of this problem is individually solvable. The representation invariant is a good design decision, not an obstacle to work around. The vault mechanics are internally defined. The eligibility model is more considered than most compliance layers I have reviewed. What does not currently exist, as of 2 August 2026, in the published standards or in the reviewed public documentation, is the layer that keeps them describing the same thing.

That is the pattern I keep meeting in this category of infrastructure. The contracts are rarely the hard part by the time a system reaches production. The hard part is that a real financial position exists simultaneously in several accounting systems that were designed independently, each of which is correct on its own terms, and the failure modes live in the gaps between them rather than inside any of them. The existing OpenZeppelin audit covers the canonical DualPool implementation; an underlying-aware permissioned extension would introduce different custody, authorization, and accounting paths, and would require its own review on its own terms.

The difficult part is not calling a vault before a swap. It is preserving the identity of the asset, the identity of the liquidity provider, and the identity of the economic entitlement while the same inventory moves through three accounting systems.

Permissioned productive liquidity is not a two-hook problem. It is a reconciliation problem.