Buyback Workflow
The buyback mechanism allows the DAO to acquire CPLQ from the treasury and either burn it or distribute it to stakers.
Flow
- Propose: A
ProposalBuybackis created via governance, carryingcnpy_amount,price_micro_cnpy_per_cplq, andmode - Vote: CPLQ stakers vote; proposal must meet quorum and pass threshold
- Execute:
MessageBuybackExecutetriggers the buyback
Execution Details
On execution:
- Drains up to
cnpy_amountfromcanoliq/buyback/pooland creditscanoliq/treasury/canoliq - Computes
cplq_acquired = cnpy_amount * 1_000_000 / price_micro_cnpy_per_cplq - Debts
canoliq/treasury/cplq(DAO 15% bucket) - 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_24Madds +75%) - Computes
mulDiv(cplqAcquired, boosted[s], totalBoosted)per staker and credits liquid CPLQ - Rounding remainder is credited to the largest-stake
LOCK_24Mstaker, falling back to the largest staker overall — so the total exactly matchescplq_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.