Skip to main content

Buyback Workflow

The buyback mechanism allows the DAO to acquire CPLQ from the treasury and either burn it or distribute it to stakers.

Flow

  1. Propose: A ProposalBuyback is created via governance, carrying cnpy_amount, price_micro_cnpy_per_cplq, and mode
  2. Vote: CPLQ stakers vote; proposal must meet quorum and pass threshold
  3. Execute: MessageBuybackExecute triggers the buyback

Execution Details

On execution:

  1. Drains up to cnpy_amount from canoliq/buyback/pool and credits canoliq/treasury/canoliq
  2. Computes cplq_acquired = cnpy_amount * 1_000_000 / price_micro_cnpy_per_cplq
  3. Debts canoliq/treasury/cplq (DAO 15% bucket)
  4. Applies the selected mode

Burn Mode

globals.cplq_total_supply -= cplq_acquired
globals.cplq_circulating_supply -= cplq_acquired

CPLQ is permanently removed from supply. No recipient address.

Distribute Stakers Mode

  • Iterates CPLQStakeIndex.Addresses
  • Each staker's stake is boosted by their vote-escrow lock tier before the split: boosted = stake × (10,000 + boostBps) ÷ 10,000, so longer locks receive a proportionally larger share (e.g. LOCK_24M adds +75%)
  • Computes mulDiv(cplqAcquired, boosted[s], totalBoosted) per staker and credits liquid CPLQ
  • Rounding remainder is credited to the largest-stake LOCK_24M staker, falling back to the largest staker overall — so the total exactly matches cplq_acquired
  • Empty staker set → re-credit treasury/cplq (no-op)

Self-Contained Order

The BuybackOrder stores the full ProposalBuyback payload because the source proposal record is deleted at tally cleanup. Execute is independent of the proposal's lifetime.

Idempotency

Re-execution is rejected with ErrProposalAlreadyExecuted.