0.1.0 • Published 4 years ago

sortition-sum-tree-factory v0.1.0

Weekly downloads
77
License
MIT
Repository
github
Last release
4 years ago

SortitionSumTreeFactory

This is a data structure that allows efficient O(log(n)) weighted selection. This package is an extraction from the Kleros project.

The majority of this code was written by Enrique Piqueras. For an explanation of the code see the Medium article.

Thanks to the Kleros team for MIT licensing this extremely useful code.

Setup

To install use yarm or npm and install sortition-sum-tree-factory:

$ yarn add sortition-sum-tree-factory
$ npm i sortition-sum-tree-factory

Usage

The SortitionSumTreeFactory is a library that should be attached to the struct SortitionSumTreeFactory.SortitionSumTrees. This data structure allows you to create many different sortition sum trees.

For example, here we use the library to create a single global sortition sum tree:

contract WeightedSelection {
    bytes32 constant private TREE_KEY = keccak256("PoolTogether/SingleRandomWinnerPrizeStrategy");
    uint256 constant private MAX_TREE_LEAVES = 5;

    using SortitionSumTreeFactory for SortitionSumTreeFactory.SortitionSumTrees;

    SortitionSumTreeFactory.SortitionSumTrees sumTreeFactory;

    constructor () public {
        sortitionSumTrees.createTree(TREE_KEY, MAX_TREE_LEAVES);
    }
}

Let's assume the sortition sum tree is storing user token balances.

Now you can set the balances using the set function:

function updateBalanceOf(address user, uint256 amount) external override {
    sortitionSumTrees.set(TREE_KEY, amount, bytes32(uint256(user)));
}

When we want to select someone proportionally we can use draw:

function randomlyDrawUser() public view returns (address) {
    bytes32 entropy = blockhash(1);
    uint256 token = UniformRandomNumber.uniform(uint256(entropy), bound);
    return address(uint256(sortitionSumTrees.draw(TREE_KEY, token)));
}

The probability that a user is selected is proportional to their token balance.

Note the use of UniformRandomNumber. This library eliminates modulo bias when constraining large numbers into a smaller set.

Development

Install the dependencies:

$ yarn

Now run the tests:

$ yarn test