The Liquidity Pools pallet is a fully permissionless Substrate pallet that enables the creation and management of liquidity pools for any asset pair. It provides a flexible framework for users to stake their assets in pools and earn rewards, with automatic rollover capabilities to maintain continuous participation across successive pools.

Calls

create_pool

Creates a new liquidity pool specifying reward and staked asset IDs, interest rate, maximum token limit, and lock period (start and end blocks). Anyone can create a pool without special permissions. Namespace
api.tx.liquidityPools.createPool
Type
function create_pool(reward_asset_id: u32, staked_asset_id: u32, interest_rate: u32, max_tokens: u128, lock_start_block: u32, lock_end_block: u32)

set_pool_succession

Links a predecessor pool to a successor pool, enabling automatic rollover of user stakes when the predecessor pool completes its cycle. Namespace
api.tx.liquidityPools.setPoolSuccession
Type
function set_pool_succession(predecessor_pool_id: u32, successor_pool_id: u32)

set_pool_rollover

Lets users opt in or out of automatic rollover to the successor pool when the current pool matures. Namespace
api.tx.liquidityPools.setPoolRollover
Type
function set_pool_rollover(id: u32, should_rollover: bool)

close_pool

Allows a pool creator to close their pool, returning any unclaimed rewards and unstaked assets to the creator. Namespace
api.tx.liquidityPools.closePool
Type
function close_pool(id: u32)

enter_pool

Enables users to join an open pool by staking their assets up to the pool’s maximum capacity. Namespace
api.tx.liquidityPools.enterPool
Type
function enter_pool(pool_id: u32, amount: u128)

exit_pool

Permits users to withdraw their staked assets from an open pool before the lock period begins. Namespace
api.tx.liquidityPools.exitPool
Type
function exit_pool(id: u32)

claim_reward

Allows users to claim their earned rewards after a pool matures. If the user opted out of rollover, their principle is also returned. Namespace
api.tx.liquidityPools.claimReward
Type
function claim_reward(id: u32)

rollover_unsigned

An internal extrinsic executed by the offchain worker to process the automatic rollover of user stakes. Namespace
api.tx.liquidityPools.rolloverUnsigned
Type
function rollover_unsigned(id: u32, current_block: u32)

Storage

Pools

Stores information about each liquidity pool Namespace
api.query.liquidityPools.pools
Type
function pools(pool_id: u32) -> Option<PoolInfo>

PoolUsers

Tracks user participation in pools Namespace
api.query.liquidityPools.poolUsers
Type
function poolUsers(pool_id: u32, account_id: AccountId) -> Option<UserInfo>

PoolRelationships

Maps predecessor pools to successor pools Namespace
api.query.liquidityPools.poolRelationships
Type
function poolRelationships(pool_id: u32) -> Option<PoolRelationship>

NextPoolId

Increment-only unique pool id Namespace
api.query.liquidityPools.nextPoolId
Type
function nextPoolId() -> u32

NextRolloverUnsignedAt

Tracks when next rollover should occur Namespace
api.query.liquidityPools.nextRolloverUnsignedAt
Type
function nextRolloverUnsignedAt() -> u32

RolloverPivot

Tracks progress during batch rollover operations Namespace
api.query.liquidityPools.rolloverPivot
Type
function rolloverPivot(pool_id: u32) -> BoundedVec<u8, MaxStringLength>

Events

PoolOpen

When a new pool is created Namespace
api.events.liquidityPools.PoolOpen
Type
struct PoolOpen {
  pool_id: u32, 
  reward_asset_id: u32, 
  staked_asset_id: u32, 
  interest_rate: u32, 
  max_tokens: u128, 
  lock_start_block: u32, 
  lock_end_block: u32
}

PoolStarted

When a pool enters lock period Namespace
api.events.liquidityPools.PoolStarted
Type
struct PoolStarted {
  pool_id: u32
}

PoolRenewing

When a pool starts rollover process Namespace
api.events.liquidityPools.PoolRenewing
Type
struct PoolRenewing {
  pool_id: u32
}

PoolMatured

When a pool is ready for rewards claiming Namespace
api.events.liquidityPools.PoolMatured
Type
struct PoolMatured {
  pool_id: u32
}

PoolClosed

When a pool is closed Namespace
api.events.liquidityPools.PoolClosed
Type
struct PoolClosed {
  pool_id: u32, 
  reward_asset_amount: u128, 
  staked_asset_amount: u128, 
  receiver: AccountId
}

SetSuccession

When pools are linked for rollover Namespace
api.events.liquidityPools.SetSuccession
Type
struct SetSuccession {
  predecessor_pool_id: u32, 
  successor_pool_id: u32
}

UserInfoUpdated

When user rollover preference is updated Namespace
api.events.liquidityPools.UserInfoUpdated
Type
struct UserInfoUpdated {
  pool_id: u32, 
  account_id: AccountId, 
  should_rollover: bool
}

UserJoined

When user joins a pool Namespace
api.events.liquidityPools.UserJoined
Type
struct UserJoined {
  account_id: AccountId, 
  pool_id: u32, 
  amount: u128
}

UserExited

When user exits a pool Namespace
api.events.liquidityPools.UserExited
Type
struct UserExited {
  account_id: AccountId, 
  pool_id: u32, 
  amount: u128
}

UserRolledOver

When user is rolled over to successor pool Namespace
api.events.liquidityPools.UserRolledOver
Type
struct UserRolledOver {
  account_id: AccountId, 
  pool_id: u32, 
  rolled_to_pool_id: u32, 
  amount: u128
}

RewardsClaimed

When rewards are claimed Namespace
api.events.liquidityPools.RewardsClaimed
Type
struct RewardsClaimed {
  account_id: AccountId, 
  pool_id: u32, 
  amount: u128
}

Errors

NotPoolCreator

Caller is not the pool creator Namespace
api.errors.liquidityPools.NotPoolCreator

InvalidBlockRange

Invalid block range for pool Namespace
api.errors.liquidityPools.InvalidBlockRange

PoolAlreadyExists

Pool already exists Namespace
api.errors.liquidityPools.PoolAlreadyExists

PoolDoesNotExist

Pool does not exist Namespace
api.errors.liquidityPools.PoolDoesNotExist

SuccessorPoolDoesNotExist

Successor pool does not exist Namespace
api.errors.liquidityPools.SuccessorPoolDoesNotExist

PredecessorPoolDoesNotExist

Predecessor pool does not exist Namespace
api.errors.liquidityPools.PredecessorPoolDoesNotExist

SuccessorPoolSizeShouldBeGreaterThanPredecessor

Successor pool too small Namespace
api.errors.liquidityPools.SuccessorPoolSizeShouldBeGreaterThanPredecessor

SuccessorPoolSizeShouldBeLockedAfterPredecessor

Invalid successor timing Namespace
api.errors.liquidityPools.SuccessorPoolSizeShouldBeLockedAfterPredecessor

RolloverPoolsShouldBeTheSameAsset

Asset mismatch between pools Namespace
api.errors.liquidityPools.RolloverPoolsShouldBeTheSameAsset

NoTokensStaked

No tokens staked for operation Namespace
api.errors.liquidityPools.NoTokensStaked

PoolNotOpen

Pool not in open state Namespace
api.errors.liquidityPools.PoolNotOpen

NotReadyForClaimingReward

Pool not mature for claiming Namespace
api.errors.liquidityPools.NotReadyForClaimingReward

NoAvailablePoolId

Exceeds maximum pool ID Namespace
api.errors.liquidityPools.NoAvailablePoolId

StakingLimitExceeded

Pool capacity limit reached Namespace
api.errors.liquidityPools.StakingLimitExceeded

OffchainErrNotValidator

Offchain worker not validator Namespace
api.errors.liquidityPools.OffchainErrNotValidator

OffchainErrTooEarly

Offchain worker called too early Namespace
api.errors.liquidityPools.OffchainErrTooEarly

OffchainErrSubmitTransaction

Offchain transaction submission error Namespace
api.errors.liquidityPools.OffchainErrSubmitTransaction

OffchainErrWrongTransactionSource

Offchain transaction source error Namespace
api.errors.liquidityPools.OffchainErrWrongTransactionSource

PivotStringTooLong

Pivot string exceeds maximum length Namespace
api.errors.liquidityPools.PivotStringTooLong