RADIX WikiRADIX Wiki

Introduction

Radix's native pool blueprints – OneResourcePool, TwoResourcePool, and MultiResourcePool – provide canonical liquidity-pool primitives implemented in native Rust rather than Scrypto. Contributors deposit underlying buckets and receive pool units (themselves a resource) representing their share. These blueprints power staking pools, AMMs, and yield-bearing positions across the ecosystem.

What the package provides

The three blueprints live in one native package at a fixed address, POOL_PACKAGE, and are declared in v1/constants.rs as OneResourcePool, TwoResourcePool and MultiResourcePool. They differ only in how many reserves they hold. Every one of them refuses to be created over a non-fungible resource — instantiation checks the resource type and fails with NonFungibleResourcesAreNotAccepted — so a pool is always an arrangement between fungible balances.

Instantiating a pool creates three things at once: a vault per reserve resource, a component to hold them, and a brand-new fungible resource for the pool units. The pool-unit resource is fixed at divisibility 18 and its mint and burn rules require the pool component's own global caller badge, with both updater roles set to deny_all. Those roles cannot be changed afterwards by anyone, the owner included, which is the guarantee that matters to a holder: pool units can come into existence only by contributing to the pool, and can leave only by redeeming against it.

The two objects are also wired to each other in locked metadata at instantiation. The component records pool_vault_number, pool_resources and pool_unit; the pool-unit resource records pool, pointing back. A wallet or explorer holding one side can therefore resolve the other without a registry, and neither entry can later be rewritten.

Contributing and redeeming

The public surface is small. contribute takes buckets and returns pool units; redeem takes pool units, burns them and returns the underlying; get_redemption_value and get_vault_amount (get_vault_amounts on the multi-resource variants) are read-only. Two further methods, protected_deposit and protected_withdraw, move reserves without minting or burning anything, and are gated by the pool_manager_role the instantiator sets — the hook that lets a staking or lending protocol add yield to a pool, or remove principal from it, while every holder's share stays denominated in the same units.

On the multi-reserve blueprints a contribution has to arrive at the pool's current ratio. Whatever is offered in excess of that ratio is not accepted and is returned to the caller as change in the same transaction, so a contributor is never silently diluted by a badly proportioned deposit. The first contribution to an empty pool is the exception, because there is no ratio yet to meet.

The redemption arithmetic rounds one way only. calculate_amount_owed takes the redeemer's share of reserves and rounds it to the resource's divisibility with RoundingMode::ToNegativeInfinity — down, always, to the remaining holders' benefit. The source enumerates the four states a pool can be in as a pair of pool-unit supply and reserves, and marks one of them illegal: units outstanding against zero reserves would mean people owning a percentage of nothing.

The Anemone precision fix

The package ships in two logic versions. v1/package.rs declares a PoolV1MinorVersion of Zero or One and dispatches every export to the matching implementation, so both remain in the engine and which one runs is decided by the protocol version, not by the pool.

The switch came with Anemone, enacted at epoch 70575 on 7 February 2024, whose release notes describe it in a clause: the native pool blueprints were tweaked "to improve precision and their behaviour with resources whose divisibility is not 18". The engine's own migration function is named after the substance — generate_pool_math_precision_fix_state_updates — and notes that no schema changed, only logic: the package's code substate is repointed from PoolCode1 to PoolCode2 and the blueprint definitions' function exports follow it. Existing pools kept their addresses, their reserves and their pool units, and began executing different arithmetic at an epoch boundary.

Two things changed inside it. Redemption now computes the share in PreciseDecimal and converts back to Decimal only at the end, instead of dividing and multiplying in Decimal throughout — which is what "improve precision" means concretely, and why a pool over a resource with low divisibility no longer loses a little on every redemption. And contribute gained a check that the bucket's resource actually belongs to the pool, failing with ResourceDoesNotBelongToPool rather than relying on the vault to reject the deposit further down.

HydrateLast updated Aug 19, 2026v2.0.04 revisionsVerified Aug 19, 2026