Incentive Pools
Incentives are board-wide reward pools that distribute tokens to supporters of accepted initiatives. The distribution is time-weighted: earlier supporters earn a larger share than those who lock later. Rewards are auto-claimed when supporters redeem their lock positions.
| Incentive Pools | Bounties (RFC) | |
|---|---|---|
| Scope | Board-wide | Per-initiative |
| Funded by | DAO / board owner | Anyone |
| Token | Single ERC20 | Multiple whitelisted ERC20s |
| Reward basis | Time-weighted (early supporters favored) | Proportional to lock amount |
| Claiming | Auto-claimed on redemption | Not yet implemented |
| Contract | IncentivesPool.sol | Bounties.sol |
See Bounties for details on initiative-specific rewards.
Distribution
When a supporter locks tokens, the pool records an incentive credit with the lock amount and timestamp. The timestamp determines which time bucket the credit falls into. Each initiative tracks 24 time buckets that expand as needed (starting at 1-hour intervals, compressing when full).
Each bucket has a multiplier derived from the incentive curve. Earlier buckets get higher multipliers, later buckets get lower ones. A supporter who locks on day 1 has their credit weighted more heavily than one who locks on day 10.
On redemption, the reward formula is:
supporterReward = totalRewardPerInitiative × (supporterWeightedCredits / totalWeightedCredits)Where weightedCredits = lockAmount × bucketMultiplier for each lock. The pool sums weighted credits across all supporters to determine each individual's share.
Rewards are auto-claimed during redeemLock(). No separate transaction needed. Redeeming before acceptance forfeits incentive rewards. Acceptance itself does not call the pool, and is non-blocking even if the pool is depleted.
Incentive curve
The curve determines how early-supporter bonuses are calculated. Only linear curves are currently supported. Parameters are provided as incentiveParametersWAD (at least 2 values, up to 24) and interpolated across time buckets from opensAt to acceptance.
Earlier buckets receive higher multipliers. A supporter who locks on day 1 earns more per token than one who locks on day 10, even if both lock the same amount for the same duration.
Setup
The incentives pool must be linked to the board before it opens. Once opensAt passes, you cannot attach or change the pool.
Deploy an IncentivesPool contract
The pool manages reward token storage, distribution calculations, and board approvals.
Fund the pool
Transfer reward tokens to the pool using addFundsToPool(). The total amount is shared across all accepted initiatives on the board.
Approve the board
The pool must explicitly approve which boards can draw from it. Call approveBoard() on the pool contract with the board address.
Link pool to board
Call setIncentivesPool(poolAddress, config) on the board. This can only be called once and only before opensAt.
See the Incentives Configuration reference for function signatures and parameters.
Multiple boards, one pool
A single IncentivesPool can serve multiple boards. Each board is approved independently with its own totalRewardPerInitiative and boardRemainingBudget. The pool's total funds are shared across all boards, with each board drawing from the pool as its initiatives are accepted.
Each board has a fixed reward amount per accepted initiative. As initiatives are accepted and supporters redeem, rewards draw down from the board's remaining budget. When a board's budget is exhausted, later acceptances on that board receive reduced or zero rewards, but other boards are unaffected.
Common issues
| Issue | Cause | Solution |
|---|---|---|
| Cannot set pool | Board already opened | Must set before opensAt |
| Pool not approved | Forgot approveBoard() | Approve the board in the pool first |
| Reduced rewards on later initiatives | Pool partially depleted | Monitor pool balance; deploy a new board for a fresh budget |
