The mechanism, in full
How FairShare works, with nothing hidden.
FairShare pays for the work no task list can describe: hosting, moderating, mentoring, showing up. A group funds a round together, the people in the group say who did the work, and a contract turns what they said into payouts. This page explains every step, every number, and every limit.
The problem
Bounties pay for work you can specify in advance. Communities run on work you cannot specify in advance. The person who keeps the freezer running, covers a shift, or mentors a new member does work the group feels every day and no ticket ever describes. A manager could decide who gets paid for that work, but a manager is a single point of failure and a single point of bias. A token vote could decide it, but a token vote rewards whoever holds the most tokens, not whoever did the work. FairShare takes a third path, the one Coordinape proved with GIVE circles: the people inside the group know more about who contributed than any central allocator, so let them say so, and let the contract do the arithmetic.
FairShare is not the first peer allocation tool. Coordinape ran GIVE circles from 2021 to 2025 across more than 500 DAOs. What FairShare adds is deterministic onchain settlement with an explainable payout, a cap, a reciprocity discount, and DAO membership read live from a Sputnik role. The settlement is not a vote and not a committee. It is arithmetic anyone can repeat.
The four steps
Fund a round
A Sputnik DAO funds a round with one envelope. The DAO votes, the proposal executes, and the envelope sits in escrow in the contract. The attached deposit must equal the envelope exactly.
Give points
Every member gets 100 points and gives them to at least 3 other members, with a short reason for each gift. You cannot point at yourself, and you cannot spend points you do not have. One submission per member; sending again replaces the old one.
Settle onchain
The contract turns points into payouts. A score rewards breadth: points from many distinct givers count for more than the same points from one giver. Mutual giving is discounted by half, and nobody takes more than 25% of the envelope.
Explain every payout
Anyone can ask the contract why a member was paid what they were paid, giver by giver, discount by discount. No hidden inputs. The explanation is stored onchain with the payout.
A round lasts 7 days unless the owner, or a member with standing 150 or more, closes it early. Allocating is rejected after close, settle, or deadline. Settling twice fails. A round settles only after the deadline or an early close, and anyone may call settle.
The maths
Three ideas, in order. First, breadth beats concentration. Second, mutual giving is discounted. Third, nobody takes more than a quarter of the envelope.
Effective points start as the points a giver gave you. For each mutual pair, the smaller of the two allocations is the mutual portion, and 50% of it is discounted from both directions, integer division, floor. Giver weight is the giver standing, which starts at 100 for everyone and then moves: at each settle a member gains +2 per distinct giver who gave them points that round, capped at +10 a round, and loses 5 for submitting no allocations that round. Standing is clamped between 50 and 200. So reputation compounds: members the group keeps recognising vote heavier in later rounds.
Worked example one: the discount
Amina gives Chidi 35 points and Chidi gives Amina 40 points. The mutual portion is 35, the smaller of the two. The discount is floor(35 divided by 2), which is 17. So Chidi gift to Amina counts as 40 minus 17, which is 23 effective points. Amina gift to Chidi counts as 35 minus 17, which is 18 effective points. A one way gift of 50 points scores 4900. The same 50 points given mutually scores 2500. The loop keeps less of what it passes around.
Worked example two: breadth
The same 100 points arriving from 2 givers of 50 scores 19600. The same 100 points arriving from 5 givers of 20 scores 48400. That is why a member fed by many distinct givers outearns a member fed by one generous friend, even on the same total points. This is the square root idea from quadratic funding, applied inside a group instead of across donors.
Worked example three: the cap
In the freezer demo round, Chidi raw share is 3.984 NEAR of a 10 NEAR envelope, which is above the 2.500 NEAR cap. Chidi is paid exactly 2.500 NEAR, and the excess flows to the other four members in proportion to score. That is why Amina final payout of 2.316 NEAR sits above her raw payout of 1.857 NEAR. The cap is enforced with water filling redistribution, so the payout sum never exceeds the envelope. Whole number division leaves a few yocto of dust in the contract after each settle. That dust stays there.
Worked example four: a real payout, explained
Round 1 on testnet, Alice. Frank gave 61 points with no discount, root part 78. Carol gave 18 points, discount 9, effective 9, root part 30. Bob gave 8 points, discount 4, effective 4, root part 20. Dave gave 7 points, discount 3, effective 4, root part 20. Root parts add to 148. 148 squared is 21904, which is Alice score. Her payout is 21904 divided by 130468 of 5 NEAR, which is 0.839 NEAR. That whole explanation is stored onchain and shown on the live rounds page.
The rules, all in one place
| Rule | Value |
|---|---|
| Points per member, every round | 100 |
| Minimum distinct recipients | 3 |
| Self allocation | Not allowed |
| Reason on every allocation | Required, 1 to 200 characters |
| Cap per member | 25% of the envelope |
| Reciprocity discount | 50% of the mutual portion, both directions |
| Giver weight | Standing, starts at 100, moves at each settle |
| Standing gain | +2 per distinct giver, capped at +10 per round |
| Standing penalty | Minus 5 for submitting no allocations in a round |
| Standing floor and cap | 50 and 200 |
| Propose a round | Standing 100 or more (owner and DAO excepted) |
| Close a round early | Standing 150 or more (owner excepted) |
| Round length | 7 days, unless the owner closes it early |
| Ownership units decay | 10% each settle |
Reputation: standing that moves
Standing is not a badge. It is a member giver weight, and it moves at every settle. A member gains +2 for each distinct giver who gave them points that round, up to +10. A member who submits no allocations loses 5, even if others gave to them. Standing never falls below 50 or rises above 200. New members start at 100, so they can allocate from day one and propose rounds, but they cannot close a round early until the group has recognised them: closing early needs standing 150, proposing needs 100. The owner and the DAO are excepted from the gates, because the owner is the admin bootstrap and a DAO proposal already needs a council majority vote to pass.
Round 3 proved it live. Ada received points from 9 distinct givers and went from 100 to 110, the capped gain. Tunde received points from 3 givers but submitted nothing and went from 100 to 95. Alice received points from nobody and stayed at 100. Before the settle, Ada at 100 tried to close the round early and was rejected. After the settle, Tunde at 95 tried to propose a round and was rejected. The full record, with scores and transactions, is on the live rounds page.
Ownership units
Settling mints ownership units in proportion to each payout. A capped 25% payout mints 2500 units. Existing units decay 10% at each settle, so recent work weighs more than old work. Units are non transferable. There is no transfer method. When rental income lands in the treasury as a plain deposit, distribute_inflow shares it out in proportion to units. Ownership grows out of work, not out of buying in. The freezer cooperative is the demo for this: the group owns a chest freezer together, rents it out, and the rent reaches the members who kept it running.
Governance: who is a member
Sybil resistance comes from DAO member curation. The contract cannot tell a real member from a second account. The DAO decides who is a member. Membership is a Sputnik DAO role, read live across contracts. The contract mirrors the DAO council into its member set with sync_dao_members, and get_dao_role checks one account live against the DAO policy. A new member joins the council by proposal. The council votes, and the proposal executes. Sputnik decides approval by proposal kind and role, never by amount. A small proposal from the wrong role still fails, and a large proposal from the right role still passes. The live DAO is fairshare-dao.testnet, council of 18, policy 1 of 2 vote to pass, 1 NEAR proposal bond, 7 day proposal period. Full detail, with transactions, is on the live rounds page.
Contract methods
| Method | Kind | What it does |
|---|---|---|
new(owner_id, dao_id) | init | Sets the owner and the Sputnik DAO that funds rounds |
create_round(round_id, envelope_yocto) | call, payable | Opens a round with the attached envelope; the owner, the DAO, or a member with standing 100 or more can call it |
allocate(round_id, allocations) | call | Records one member's points, each with a to, points and reason |
close_round(round_id) | call | The owner or a member with standing 150 or more closes a round early so it can settle before the deadline |
settle_round(round_id) | call | Settles the round and pays each member from the envelope |
distribute_inflow(amount) | call, payable | Shares an inflow, like freezer rent, in proportion to ownership units |
sync_dao_members() | call | Reads the DAO council live and mirrors it into the member set; anyone can call it |
get_dao_role(account) | call | Live check: reads the DAO policy and returns whether the account is in the role right now |
get_cached_dao_role(account) | view | The last synced DAO membership state for one account |
get_dao_info() | view | The DAO id, the member role, the member count, and the last sync time |
add_member(member) | call | Owner seeds a member for local testing only; production membership comes from the DAO |
get_round(round_id) | view | Round state, envelope and status |
get_allocations(round_id) | view | Every allocation in the round |
explain_payout(round_id, account) | view | One member's payout broken down by giver |
get_payouts(round_id) | view | Every payout in the round |
get_members() | view | Members of the round |
get_standing(account) | view | One member's standing, which is their giver weight |
get_units(account) | view | Ownership units held by one member |
get_params() | view | Round rules: 100 points, at least 3 recipients, cap 25%, discount 50%, 7 day round, standing starts at 100, gain +2 per distinct giver capped at +10, minus 5 for no allocation, floor 50, cap 200, propose at 100, close early at 150 |
Members allocate through the site: connect a testnet wallet with the button in the header, and the live rounds page shows your standing and your allocate form when a round is open.
Payouts leave the contract by ordinary Transfer from the round envelope. Trezu manages the DAO, and the local testnet view was verified: the Trezu frontend run locally shows all 16 DAO proposals Executed, all 19 council members, and the 10 of 19 voting policy. Trezu production is mainnet only, so there is no live Trezu testnet payout, and none is claimed here. The full record is on the live rounds page and in TREZU.md in the repo.
What it does not do
Collusion is made costly, not impossible. Popularity bias remains. The contract cannot see physical work. It settles what members said about each other, nothing more. Standing now moves at each settle under the rule above, proved live in round 3, and the gates on proposing and closing are enforced onchain. The full list, stated plainly, is on the home page under honest limits, and the collusion test is on the Attack Lab page.