CommonsBuild / tqf

Processing for the TE grants round based on the Gitcoin Allo protocol
MIT License
5 stars 1 forks source link

Tunable Quadratic Funding

TQF is a research initiative by the Token Engineering Commons that enables transparent and informed quadratic funding round operation with a focus on utilizing token signal inputs to add tunable weights to donations based on donor token holdings.

Table of Contents

  1. Background
  2. Purpose
  3. Scope of the Project
  4. Usage
  5. Adding a New Round
  6. Contributing
  7. Testing and Feedback
  8. Specification
  9. TEGR
  10. Acknowledgements
  11. Contact Information

Background

The Token Engineering Commons has been running community Quadratic Funding on the Grants Stack since the Beta round of April 2023. Since the inception of the Token Engineering Grants Rounds (TEGR), an experimental feature was introduced called subject matter expertise signal boosting (SMESB). In SMESB donations weights are boosted according to a SME boost weight assigned to donor addresses. In TEGR, donor weights are computed as a combination of TE academy credentials and $TEC token holdings. These signals are meant to indicate expertise in the field of Token Engineering.

For more information on the background of TQF, see the original blog post:
Incorporating Expertise into Quadratic Funding.

Purpose

The purpose of this research repository is to provide a data science research environment to the operators of the TEGR rounds and a tool for other community round operators that wish to employ the techniques being highlighted as tunable quadratic funding.

Prospective Benefits of Tunable Quadratic Funding Include:

The TQF tool allows for stepping through the process of quadratic funding and understanding the deeper implications of applying token signals as boosts to donations. This process allows communities to explore the alignment between resource allocation and values. As a general contribution to public goods tooling, we expect this tool to aid in attracting funding to the domain of token engineering public goods and the greater web3 public goods funding ecosystem.

Scope of the Project

Proposed Delivery for Q1 2024:

Usage

TQF is implemented in Python using the HoloViz data science stack. Dependency management is handled by Python Poetry.

Installation Requirements

To run this app locally follow the steps below:

  1. Clone the repository and checkout the development branch.
    git clone git@github.com:CommonsBuild/tqf.git
    cd tqf
  2. Install the dependencies and activate python environment
    poetry install
    poetry shell
  3. Run the app by specifying a round.
    python -m tqf -r tegr3

The app should now be running. Navigite to http://localhost:5006/app in your browser.

  1. To learn about all the available options for running tqf, run
    python -m tqf --help

Adding a New Round

The framework takes in donation datasets, token distributions, a grants dataset, and user input to compute the final funding allocation for each project.

The operations required to utilize TQF are the following:

  1. Input a donation dataset
  2. Input token distribution datasets
  3. Input a grant names dataset
  4. Configure the parameters of your boosts
  5. Output funding allocation results

The following sections describe the required datasets and their required columns. Datasets may have additional columns that are not required. Columns do not need to be in any particular order in the dataset.

Datasets should be added to the tqf/tqf/input directory.

Grants Dataset

This csv is a list of eligible grants in your round.

    columns={"Grant Name", "Grant Address"},

Example:

Note, if your donations dataset has a 'Grant Name' column, then you do not need to provide this dataset.

Donations Dataset

This csv contains all of the donations made in your round.

    columns={"voter", "amountUSD", "grantAddress"},

Example:

Token Distribution Dataset

This csv represents a token as a mapping from address to balance.

    columns={"address", "balance"}

Example:

Wiring The New Round

Once you have added your datasets to the tqf/tqf/input directory, you need to wire the new round to the tqf app. You can start by copying tegr3.

cp tqf/tegr/tegr3.py tqf/tegr/my_round.py

Edit my_round.py

Change the filenames to match the datasets that you have added to tqf/tqf/input. Set the default parameters for tuning as you desire.

# Donations
donations = Donations(
    name="xxx Donations",
    file="tqf/input/xxx.csv",
    grant_names_dataset="tqf/input/xxx.csv",
)

# Donations Dashboard
donations_dashboard = DonationsDashboard(donations=donations)

# Token Distribution
token_distribution = TokenDistribution(
    file="tqf/input/xxx.csv", name="xxx Token"
)

# Token Boost
token_boost = Boost(
    name="xxx Token Boost",
    distribution=token_distribution,
    transformation="LogLinear",
    max_boost=8,
    threshold=10,
)

# Repeat for as many token boosts as needed
# ...

# Boost Factory
boost_factory = BoostFactory(
    name="xxx Boost Factory",
    boosts=[token_boost],
    boost_factor=8,
    combine_method="product",
)

# Tunable Quadratic Funding
qf = TunableQuadraticFunding(
    donations_dashboard=donations_dashboard,
    boost_factory=boost_factory,
    mechanism="Cluster Mapping",
    matching_pool=50_000,
    matching_percentage_cap=0.15,
)

# Assemble the app with sidebar
app = pn.template.MaterialTemplate(
    title="Tunable Quadratic Funding: xxx",
    sidebar=[boost.param for boost in boost_factory.boosts]
    + [boost_factory.param]
    + [qf.param],
)

# Add tabs to the main view
app.main += [
    pn.Tabs(
        (
            "Charts",
            pn.Column(
                boost_factory.view_boost_outputs_chart,
                qf.view_qf_matching_bar,
            ),
        ),
        (
            "Data",
            qf.view_results,
        ),
        active=0,
    )
]

Add my_round to main.py

Add an option to click:

    type=click.Choice(["tegr1", "tegr2", "tegr3", "all", "my_round"], case_sensitive=False),

Add my_round case to main():

# in main()
    if round == "my_round":
        if cli:
            from tqf.tegr.my_round import qf

            print(tegr1_qf.view_results(tabulator=False, to_csv=True))
        else:
            from tqf.tegr.my_round import app

            pn.serve(app.servable(), port=port, show=False, admin=admin)

Running your round

To display round results based on the default parameters and save results to tqf/tqf/output/results.csv:

python -m tqf -r my_round -c

To run the app in the browser for interactively tuning parameters:

python -m tqf -r my_round

For more information on usage:

python -m tqf --help

Contributing

The project is built using the HoloViz data science stack with primary heavy lifting from, Panel, hvplot, and Tabulator. If you are familiar with these tools or would like to learn, please consider taking a look at contributing to the project.

You can get started contributing by picking up issues on this repository.

Testing and Feedback

It is very valuable for us to receive feedback on our work. Please open an issue if you have any questions or topics of discussion that you would like to bring to our attention. Please get in touch with

Specification

Quadratic Funding

Quadratic Funding is a capital allocation protocol that determines the distribution of matching funds across a set of public goods projects. The algorithm determines the funding outcome based off of peer to peer contributions that are made from citizens to public goods. Formally:

\mathbf{F}_p = \left( \sum_{i=1}^{n} \sqrt{c_{ip}} \right)^2

Where $\mathbf{F}_{p}$ is the quadratic funding for project $p$ and $c_{ip}$ is the contribution made by citizen $c_i$ to project $p$ where there are $n$ citizens. In matrix notation, QF is an operation that maps a contributions matrix $\mathbf{C} \in \mathbb{R}^{n \times m}$ to a funding vector $\mathbf{F} \in \mathbb{R}^{m}$ given $m$ public goods projects.

\mathbf{F} = \left( \text{sum}\left( \sqrt{\mathbf{C}} \right) \right)^2

The contributions matrix is radicalized element wise and then project columns are summed on axis 0. The resulting vector is squared element wise to give the quadratic funding per project. The funding outcome is then normalized such that it sums to 1 and represents a distribution to be made by the matching pool.

Contributor Boost Coefficient

Tunable QF introduces a contributor boost coefficient $b_i$ for each citizen $c_i$ that is applied as a multiplicative factor to each donation $c_{ip}$ for each public good $p$, such that the resulting funding mechanism becomes:

\mathbf{F}_p = \left( \sum_{i=1}^{n} \sqrt{b_i\cdot{c_{ip}}} \right)^2

In matrix notation, we are applying the boost vector $\mathbf{B} \in \mathbb{R}^{n}$ as a coefficient for the contribution matrix.

\mathbf{F} = \left( \sqrt{\mathbf{B}^T}\cdot{\sqrt{\mathbf{C}}}  \right)^2

Notice above that we do not need the sum operator anymore due to the nature of vector matrix multiplication.

Token Balances

Consider a token distribution dataset as a vector $\mathbf{T} \in \mathbb{Z}^{n+}$ such that $\mathbf{T_i}$ is the balance of $c_i$.

| Address | Balance | |-----------------------------------|---------| | 0x456...abc | 200 | | 0x123...def | 100 | | ... | ... |

The dataset can represent fungible or non-fungible tokens.

Token Signaling

Given a token distribution, a boost vector can be created using a signal transformation.

The donor coefficients are applied to the donations as part of the QF calculation, ensuring that each donor's influence is weighted according to the community-defined boost vector $B$.

The framework is flexible and can accommodate various methods of determining the donor coefficients, such as:

By providing this level of customization, TQF empowers communities to experiment with and optimize their funding mechanisms, leading to more equitable and effective public goods funding.

TEGR

TEGR3

Screenshot from 2024-01-27 12-04-21

TEGR2

Screenshot from 2024-01-27 12-04-32

TEGR1

Original TQF Formula:

coefficient = 1 + 1 * (int(tec_tokens_flag) or int(tea_flag))

History

September 2023, YGG Continues app development. The project begins to take shape. Refactoring is required.

August 2023, YGG begins assembling a web application oriented towards exploring donations datasets, and tunable QF.

July 2023, YGG creates a series of research notebooks that explore the donations dataset, the qf algorithm, the sme signal boosting, and advanced boosting with normalization and sigmoid applied.

June 2023, Rxx creates a main.ipynb jupyter notebook that applies the tegr1 boost factor as the following:

Acknowledgements

This research repository is maintained by The Token Engineering Commons (TEC) to aid in the operation of the Token Engineering Grant Round (TEGR) series which allocates a target annual $100,000USD funding to token engineering public goods projects via Quadratic Funding.

Funding is provided by TEC Coordination team, and YGG as per the TEC Data Science Fellowship.

This research repository was initialized Rxx from the TEC Tech Team.

Contact Information

Contact us on twitter.

Join the Weekly Open Development Call in TEC Discord Thursdays 12:00-1:00pm PST