Skip to content

Multi instance PSM#12245

Draft
Szegoo wants to merge 7 commits into
masterfrom
szegoo-psm-multi-instance
Draft

Multi instance PSM#12245
Szegoo wants to merge 7 commits into
masterfrom
szegoo-psm-multi-instance

Conversation

@Szegoo
Copy link
Copy Markdown
Contributor

@Szegoo Szegoo commented Jun 1, 2026

Summary

This reworks pallet-psm from a single, governance-seeded Peg Stability Module into a multi-instance design where many independent PSMs can coexist, each created permissionlessly and managed by its own admins. It replaces the old model in which a single PSM was configured through the pallet's Config and seeded via a one-off migration controlled by a privileged origin.

Motivation

The original pallet supported exactly one PSM, whose parameters were hardcoded into the runtime configuration and whose setup required governance. This change makes PSMs permissionlessly created, configured in storage, and governed by the accounts that create them.

What changed

Multiple instances. A runtime can now hold any number of PSMs at once. Each is identified by its internal (stablecoin) asset and tracks its own configuration, backing assets, fees, and debt independently of the others.

Configuration lives in storage, not in Config. Per-PSM parameters that used to be compile-time constants or single-value storage now live in maps keyed per PSM. A module can therefore be created and tuned at runtime without a code change or migration.

Multiple backing assets per PSM. Each PSM can be backed by several external assets. All per-asset state (status, ceilings, debt, decimal information) is keyed by the (PSM, backing-asset) pair, so adding or removing a backing asset is a self-contained operation that cleans up after itself.

Permissionless creation with a refundable deposit. Anyone can create a PSM by locking a deposit in the native token. The creator becomes the module's admin and chooses its initial parameters. Removing the PSM refunds the deposit to the original creator. This removes the dependency on a privileged manager origin for setup

Creation is restricted to the asset owner. Creating a PSM requires the caller to be the owner of the internal asset. A PSM mints and burns its internal asset through a privileged path that does not perform the usual issuer check, so without this restriction anyone could register a PSM over an asset they do not control and mint it against worthless collateral. Tying creation to ownership ensures a PSM can only be set up by the party that actually controls the asset.

Per-PSM admin model. Each PSM carries a full admin and an emergency admin, allowing management and emergency actions to be delegated separately.

State separation. The data touched on every mint and redeem is stored separately from the rarely-used administrative data, keeping the swap path small and cheap.

Removed migrations. There is no data migration. The pallet is redeployed cleanly (its old storage is removed and the storage version reset), so existing per-instance state is not carried over.

Szegoo and others added 7 commits May 22, 2026 16:43
Implements 1.1 from: #12134 

## Summary

First step of the multi-instance PSM refactor. Behaviour-preserving. The
pallet still serves a single PSM instance configured via the runtime.

The end goal of this and the upcoming PRs is to make pallet-psm
multi-instance: many PSMs registered permissionlessly, each keyed by its
own internal stablecoin, mirroring how pallet-assets works.

Per-instance configuration is moved out of `Config` and standalone
storage values into a single `PsmInfo` record stored in `Psms`, keyed by
the internal asset id.

The debt ceiling is restated as an absolute balance instead of a
fraction of a system-wide cap, which doesn't compose across instances
later.

## What changes

- The internal asset id, fee destination, debt ceiling, and decimals
snapshot move into a single per-instance record kept in storage.
- The debt ceiling becomes an absolute balance instead of a fraction of
a system-wide cap; the matching extrinsic and event are renamed.
- Genesis takes the fee destination and ceiling as fields; leaving the
fee destination unset is a no-op.
- Storage version bumped. A `MigrateV2ToV3` migration is provided to
carry existing state forward. Runtimes already running the pallet must
include it in their migration tuple.

TODO:

- [x] update migrations
- [ ] update weight
Implements 1.2 of #12134

## Summary

This PR re-keys pallet-psm so a single runtime can host multiple PSMs
instead of just one. Each PSM is identified by its internal asset and
runs independently: it has its own reserve account, its own debt ceiling
and
fee destination, its own set of approved externals, and its own
per-external fees and circuit breaker.

Externals can be shared across PSMs without state crossing over, since
every per-external storage item is now keyed by `(internal_asset,
external)`.

Every extrinsic and event gains `internal_asset` as its first parameter
so callers explicitly pick which PSM they're acting on.

`Config` drops the `InternalAssetId` constant (there's no single
internal asset any more) and the previously-separate
`ExternalDecimals` map is folded into `ExternalAssets` as a struct, so
approving or removing an external touches one storage item instead of
two.

Because the pallet's storage shape has changed end-to-end and we're
treating this as a fresh deployment, Asset Hub Westend's migration tuple
wipes the prior PSM state with `RemovePallet` and reinstalls a fresh v1
deployment via `InitializePsm` + `SetPsmStorageVersionV1`.

The kitchensink runtime, remote-tests, the `PsmInterface` trait, and the
docs are all rewired to the new multi-instance shape.
Implements 1.3 of #12134

## Summary

Makes pallet-psm permissionless. Any signed origin can now register a
PSM keyed by an internal asset that exists in the fungibles backend; the
signer reserves a `CreationDeposit` of native currency and becomes the
PSM owner, sovereign over every governance dispatchable on that
instance. `ManagerOrigin` has no authority over owned PSMs.

Governance retains a parallel `force_create_psm` path for owner-less
PSMs, which only `ManagerOrigin` can manage.

A symmetric `remove_psm` tears down a PSM once all externals have been
removed and aggregate debt is zero, refunding
the deposit to the owner.
@Szegoo Szegoo added the T2-pallets This PR/Issue is related to a particular pallet. label Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T2-pallets This PR/Issue is related to a particular pallet.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant