Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/dao-space.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Check the DAO pages against the Snapshot space

on:
pull_request:
paths:
- 'docs/dao/**'
- 'scripts/check-dao-space*.js'
- 'scripts/fixtures/dao-space.json'
- '.github/workflows/dao-space.yml'
schedule:
# Once a week, Monday 06:00 UTC
- cron: '0 6 * * 1'
workflow_dispatch:

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- name: Setup Node
uses: actions/setup-node@v7
with:
node-version: '^24.18.0'

- name: Test the settings checker
run: node --test scripts/check-dao-space.test.js

- name: Compare the pages with the space
run: node scripts/check-dao-space.js
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ node ./libs/link-validator.js http://localhost:8082 ./docs/.vitepress/dist/

Hosts that block automated requests are listed in [`libs/link-validator-ignore.json`](./libs/link-validator-ignore.json).

The DAO pages describe the `api3.eth` space on Snapshot. [`scripts/fixtures/dao-space.json`](./scripts/fixtures/dao-space.json) records its documented configuration, including the complete voting power strategy parameters, privacy, eligibility and multisigs. [`scripts/check-dao-space.js`](./scripts/check-dao-space.js) compares the hub's settings with that configuration and checks the contracts, reads and settings named on the pages. Update the configuration and the pages together when an approved governance change takes effect, never just to make the check pass. The [workflow](./.github/workflows/dao-space.yml) tests the checker and runs the comparison on relevant pull requests and once a week. Reproduce it locally with:

```sh
pnpm test
node scripts/check-dao-space.js
```

## Issues and pull requests

Check the existing issues before opening a new one. Open pull requests against `main` and reference the issue in the description, for example `Closes #1`. CI runs the format check, the build and the link validator on every pull request, and the preview workflow posts a link to a Firebase preview of the site. Merging to `main` deploys the live site.
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ New to API3 data feeds? Start with the [Quickstart](https://docs.api3.org/dapps/
- **[dApps](https://docs.api3.org/dapps/)**: activating a data feed on [API3 Market](https://market.api3.org), reading it from a contract through `Api3ReaderProxyV1`, integration and security considerations, and how OEV Rewards pay dApps for using the feeds.
- **[OEV](https://docs.api3.org/oev/)**: what Oracle Extractable Value is, how API3 data feeds and OEV feeds work at the contract level, and how searchers use the public Signed APIs.
- **[Curation](https://docs.api3.org/curation/)**: the Morpho vaults API3 curates, their roles and operations, risk management and disclosure.
- **[DAO](https://docs.api3.org/dao/)**: governance on the `api3.eth` Snapshot space, what counts as voting power, delegation, voting, posting a proposal and how a result is verified before execution.

## AI assistants

Expand Down
6 changes: 6 additions & 0 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ module.exports = {
'/dapps/': require('../dapps/sidebar.js'),
'/oev/': require('../oev/sidebar.js'),
'/curation/': require('../curation/sidebar.js'),
'/dao/': require('../dao/sidebar.js'),
},
nav: nav(),
},
Expand All @@ -107,5 +108,10 @@ function nav() {
link: '/curation/',
activeMatch: '/curation/.*',
},
{
text: 'DAO',
link: '/dao/',
activeMatch: '/dao/.*',
},
];
}
49 changes: 49 additions & 0 deletions docs/dao/api3-token.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: API3 token
pageHeader: DAO
outline: deep
---

<PageHeader/>

# API3 token

API3 is the governance token of the API3 DAO, an ERC-20 token on Ethereum mainnet.

| Property | Value |
| ------------ | --------------------------------------------------------------------------------------------------------------------- |
| Contract | [`0x0b38210ea11411557c13457D4dA7dC6ea731B88a`](https://etherscan.io/token/0x0b38210ea11411557c13457D4dA7dC6ea731B88a) |
| Symbol | API3 |
| Decimals | 18 |
| Total supply | 200,000,000 API3 |

## Supply

The contract minted 100,000,000 API3 when it was deployed.
Minting is restricted to addresses its owner marks as minters.
The DAO pool minted the staking rewards of the legacy DAO.

The migration to Snapshot closed the supply.
The pool's minter status was revoked, a final mint to the DAO's [Treasury multisig](/dao/#treasuries) brought the supply to 200,000,000 API3, and the contract's ownership was transferred to the dead address, so no address can mint and none can be made a minter.

Any holder can burn their own API3 by opting in as a burner on the contract and calling `burn`.
Nothing can mint it back, so the supply can only fall from here.

## Governance

Each API3 in your wallet, in the DAO pool, scheduled for unstaking or posted as collateral in the Kabu API3/USDC market on Morpho is one vote in the `api3.eth` space (see [Voting power](/dao/voting-power)).
Exchange balances, liquidity pool tokens and tokens bridged to another chain do not count as your voting power.
Other contracts can explicitly delegate their own API3 token balance on Snapshot (see [Voting power](/dao/voting-power#what-counts)).
Posting a proposal takes 500,000 API3 of voting power (see [Posting a proposal](/dao/voting#posting-a-proposal)).

## Staking

The DAO pool of the legacy DAO holds staked API3.
Staking rewards ended with the migration and the pool mints nothing further.
Staking is no longer needed to vote, staked API3 keeps voting as described under [Voting power](/dao/voting-power#what-counts), and unstaking and withdrawing work as before.
The [legacy documentation](https://dao-docs.api3.org/members/staking.html) describes the pool.

## Collateral on Morpho

The [Kabu API3/USDC market](https://app.morpho.org/ethereum/market/0x70dfbd2705d10d5dfb4d89e07e2bb860b5a624ce2f97e209ab9f5308bf6c67a1) on Morpho takes API3 as collateral for borrowing USDC.
API3 posted there counts as voting power for the owner of the position, borrowed or not.
51 changes: 51 additions & 0 deletions docs/dao/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
title: Overview
pageHeader: DAO
outline: deep
---

<PageHeader/>

# DAO

The API3 DAO governs through the Snapshot space [api3.eth](https://snapshot.box/#/s:api3.eth), where holders of the [API3 token](/dao/api3-token) vote on proposals.
Voting is off-chain: a vote is a signed message that Snapshot collects, and the voting power behind it is read from Ethereum mainnet at the block the proposal names.
The API3 multisigs execute a proposal once it has passed and its result has been verified.

::: info 💡 Tip

For quick reference, you can copy-paste [`llms-full.txt`](https://docs.api3.org/llms-full.txt) to your choice of AI assistant.

:::

## How it works

- [Voting power](/dao/voting-power) is counted per API3 in your wallet, in the DAO pool, during unstaking and as collateral in the Kabu API3/USDC market on Morpho, at the block a proposal names.
[Delegation](/dao/voting-power#delegation) hands it to another address, either for your stake alone, inside the pool, or for everything you hold, on Snapshot.
- [Voting](/dao/voting) is a gasless signature on snapshot.box, For or Against, during the seven days a proposal is open.
Anyone with 500,000 API3 of voting power can [post a proposal](/dao/voting#posting-a-proposal), and it passes with at least 10,000,000 API3 in favour and more votes for than against.
- [Independent verification](/dao/verification) recomputes a result from the chain before the API3 multisigs execute it.

## Governing proposal

The [DAO migration proposal](https://api3.eth.limo/#/history/primary-17), passed in the legacy DAO, sets out the governance rules, the mandate and the charter.
These pages explain how to participate under those rules.

## Treasuries

The space lists three multisigs as its treasuries.
They hold the DAO's assets and execute what passes (see [Execution](/dao/voting#execution)).

| Multisig | Role |
| ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Vault](https://etherscan.io/address/0x8e03609ed680B237C7b6f8020472CA0687308b24) | Holds the DAO's assets other than API3 and controls `api3.eth` and its Snapshot settings. Posts proposals and votes with the pool stake delegated to it. |
| [Agent](https://etherscan.io/address/0xBBE0dE9757F93e3306aDBfeBE906AB285EDD13DA) | Runs day-to-day operations and holds only what they need. Its own voting power is delegated to a dead address. |
| [Treasury](https://etherscan.io/address/0xb7fa2Cb302C5dC127e61F27b92beC411cbf0AE4A) | Holds the DAO's API3. Its voting power is delegated to a dead address, and it does not post proposals. |

Changes to the Snapshot settings and other rules of governance follow the [rule-change execution period](/dao/voting#execution).

## Legacy DAO

Governance used to run on Aragon contracts, with a staking pool and a dashboard for it.
The pool is still in use: stake in it counts as voting power and pool delegations still apply to the stake, but staking is no longer needed to vote.
The [legacy documentation](https://dao-docs.api3.org/) covers the pool, the dashboard and the contracts.
22 changes: 22 additions & 0 deletions docs/dao/sidebar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module.exports = [
{
text: 'Overview',
link: '/dao/',
},
{
text: 'API3 token',
link: '/dao/api3-token',
},
{
text: 'Voting power',
link: '/dao/voting-power',
},
{
text: 'Voting',
link: '/dao/voting',
},
{
text: 'Independent verification',
link: '/dao/verification',
},
];
37 changes: 37 additions & 0 deletions docs/dao/verification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: Independent verification
pageHeader: DAO
outline: deep
---

<PageHeader/>

# Independent verification

The DAO relies on Snapshot to run its votes.
The space settings, the strategies that compute voting power and the sequencer and hub that collect and tally the votes are Snapshot's, and the DAO trusts them to work as described.
A vote's signature proves who signed it and what they signed, not when Snapshot received it: Snapshot cannot forge a vote, but it could omit a signed vote or accept one after the deadline with a backdated timestamp.
Voters should check that their vote appears in the proposal's vote list while voting is open.

The DAO verifies the rest.
A passed vote moves nothing by itself: before executing a proposal, the [API3 multisigs](/dao/#treasuries) recompute its result from the chain with the [Snapshot voting verifier](https://github.com/api3dao/snapshot-voting-verifier), never taking a result off a website.
The tool's source is public, anyone can run it on any proposal of the space, and its README says how.

The DAO's rules also go further than Snapshot's settings can express, such as counting only the votes in favour toward the quorum and the window for the snapshot block.
The verification enforces those too, so a proposal that Snapshot shows as passed can still fail a check and not be executed.

## What it establishes

Given a proposal, the tool reads every vote the Snapshot hub lists and establishes, independently of Snapshot's own computation, that:

- Every listed vote was signed by the voter it is listed under, names one of the proposal's choices and has a signed timestamp within the voting window.
- Every listed voter's power matches the proposal's recorded strategies at the proposal's block, delegations included, recomputed from an Ethereum archive node and the delegate registry rather than from Snapshot's scoring service (see [Voting power](/dao/voting-power)).
- The tally follows from those powers.
- The proposal met the posting rules: the proposer's 500,000 API3 at the proposal's block, a snapshot block within its window (see [Snapshot block](/dao/voting#snapshot-block)), and seven days of voting with no delay.

It then judges the result on what it recomputed: at least 10,000,000 API3 in favour and more votes for than against (see [Passing](/dao/voting#passing)).
The run ends by saying whether the result is verified, and lists every problem it found.
A verified result is one whose votes and tally match the recomputation, so it can still be a rejected proposal, and only a verified and passed proposal is executed.

Matching the recorded strategies does not by itself establish that a change to the strategies or the space settings was authorized, and the tool does not judge whether a proposal is a change of the rules of governance.
The multisig signers check both from the proposal's content (see [Execution](/dao/voting#execution)).
Loading
Loading