返回博客

Grant 奖金分配算法 (累进税 V2.0)

Grant 奖金分配算法 (累进税 V2.0)

Grant 奖金分配算法(下简称算法)主要解决了在有一定准入门槛的去中心化二次方投票中,部分项目奖金分配过于悬殊的问题。算法在保证项目排名、分配奖金数量与投票数的关联性的基础上,能够有效的控制第一名和最后一名间奖金的差异,避免活动中部分项目所得激励过少,影响活动者的参与积极性。 并且算法本身计算比较简单,需要储存在链上的数据较少,奖金分配的结果原则上可以在每一个投票行为发生时即时更新。

算法逻辑

算法要求合约中储存一下信息:

算法针对 Grant 每个 Round 的 每个 Category 独立计算分配结果,因此以下数据都以 Round + Category 作为索引分别储存。
  • 总项目数 N
  • 每个项目的得票数 V_n
  • 最多得票数 V_max
  • 最少(非0的)得票数 V_min
  • 总票数 V_sum
vote() 发生时,以上数据都可以即时更新。

算法还要求设置并在合约中储存一个系数 RR 的含义是第一名项目与最后一名项目所获得的奖金之间的最大相差比例。即:

matching_max / matching_min <= R

算法的主要逻辑是:将所有的项目票数向平均票数按照同一比例 s 进行缩放,在这一过程中,所有项目的调整后票数之和仍然不变,因此针对每个项目的分配都可以单独计算,而不需要依赖其他项目的得票情况。

根据定义,可以得到关系:

V_avg = V_sum / N

// V_max >= V_avg >= V_min
V_max_final = (V_max - V_avg) * s + V_avg
V_min_final = (V_min - V_avg) * s + V_avg

V_max_final / V_min_final = R

整理可以得到:

// (V_max - V_avg) * s + V_avg = R * ((V_min - V_avg) * s + V_avg)

// (V_max - V_avg + (V_avg - V_min) * R) * s = V_avg * R - V_avg

s = V_avg * (R - 1) / (V_max - V_min * R + V_avg * (R - 1))
如果计算出来 s 的值大于1,则表明只有放大项目间的差距才能达到 R 的比例。这时的 V_max / V_min 已经小于 R,因此不会实际进行放缩了。

最终项目的匹配奖金池为:

// 合约中会判断处理计算中的正负号和取整问题
V_n_final = (V_n - V_avg) * s + V_avg

// Sigma(V_n_final) == Sigma(V_n) == V_sum

matching_n = TotalMatchingPool * V_n_final / V_sum

备注

  • 算法在所有可能出现小数的计算中总会向下取整,以保证最终每个项目的权重之和不会大与1。总权重之和可能会略微小于1,但是这造成的误差会在 N * 10^-6 票之内。
  • 算法要求项目至少要获得一次投票。否则会认为这个项目根本不存在,从而不保证其最终分配奖金与第一名的比例关系。