The Liquidity Provider Distribution (LPD) process iterates through each pool and returns a percentage of the native asset to the liquidity providers' addresses. This is done every n’th block over a series of (admin) user specified periods.

LPD Procedure

The following pseudo code specifies the core LPD procedure:

if (current_height - start_height) % distribution_period == 0 {
	for each pool {
		rowan_returned = block_rate * pool_depth_rowan
		for each pool_liquidity_provider {
			provider_percentage = provider_units / total_pool_units
			provider_rowan = provider_percentage * rowan_returned
			StoreCoinTransferInfo(pool, provider_rowan, provider_address)
		}
	}
	TransferCoinsToLiquidityProviders()
}

This code must run at the end of a block, before the rewards procedure. Note that the transfer of coins from the pool to the liquidity providers is broken down into two methods, StoreCoinTransferInfo and TransferCoinsToLiquidityProviders. This allows the transfers to be aggregated, reducing the number of events and allows aggregate events to be fired (see events section below).

The blocks on which LPD is applied and the applied block rate are controlled by the current LPD policy. A policy is defined as a list of periods, where each period specifies a block rate, start block, end block and a distribution period (how often the LPD process is run):

policy: [period]
period:
	block_rate:          0 ≤ block_rate ≤ 1 max 18 decimals
	start_block:         uint64
	end_block:           uint64
	distribution_period: uint64 >0

There must only be one stored policy, it must be possible to overwrite/replace the policy and the content must be immutable. The immutability means that the individual periods and parameters of a policy cannot be changed and that the entire policy (including expired periods) must be stored so that the entire policy, as originally set, can be queried.

A valid policy is defined as above with the following additional constraints:

Policies with the following must be accepted as valid

The first two points mean that a policy might have two active periods on a given block, in which case the period which appears first in the list must be selected.

The policy must be settable with a regular Cosmos transaction however the transaction must be signed by the PMTP/rewards admin key. The policy must be valid as specified above otherwise the transaction is rejected. Given that the LPD procedure is applied at the end of the block, there is no concern here with changing the policy within the block - the old policy can safely be overwritten with the new policy which can then be applied at the end of the block.

No adjustments should be made to the pool units or the liquidity provider units.

Out of Scope

Future work may allow different block rates across the pools.

There is uncertainty about the workload introduced by LPD. It can be set to run every n’th block, this will reduce the overall workload however blocks on which LPD does run may be slower. Future work may be needed if this becomes problematic: