NEAR testnet · Social Money

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

1

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.

2

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.

3

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.

4

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.

Score = (sum over distinct givers of the square root of effective points times giver weight) squared

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

RuleValue
Points per member, every round100
Minimum distinct recipients3
Self allocationNot allowed
Reason on every allocationRequired, 1 to 200 characters
Cap per member25% of the envelope
Reciprocity discount50% of the mutual portion, both directions
Giver weightStanding, starts at 100, moves at each settle
Standing gain+2 per distinct giver, capped at +10 per round
Standing penaltyMinus 5 for submitting no allocations in a round
Standing floor and cap50 and 200
Propose a roundStanding 100 or more (owner and DAO excepted)
Close a round earlyStanding 150 or more (owner excepted)
Round length7 days, unless the owner closes it early
Ownership units decay10% 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

MethodKindWhat it does
new(owner_id, dao_id)initSets the owner and the Sputnik DAO that funds rounds
create_round(round_id, envelope_yocto)call, payableOpens 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)callRecords one member's points, each with a to, points and reason
close_round(round_id)callThe owner or a member with standing 150 or more closes a round early so it can settle before the deadline
settle_round(round_id)callSettles the round and pays each member from the envelope
distribute_inflow(amount)call, payableShares an inflow, like freezer rent, in proportion to ownership units
sync_dao_members()callReads the DAO council live and mirrors it into the member set; anyone can call it
get_dao_role(account)callLive check: reads the DAO policy and returns whether the account is in the role right now
get_cached_dao_role(account)viewThe last synced DAO membership state for one account
get_dao_info()viewThe DAO id, the member role, the member count, and the last sync time
add_member(member)callOwner seeds a member for local testing only; production membership comes from the DAO
get_round(round_id)viewRound state, envelope and status
get_allocations(round_id)viewEvery allocation in the round
explain_payout(round_id, account)viewOne member's payout broken down by giver
get_payouts(round_id)viewEvery payout in the round
get_members()viewMembers of the round
get_standing(account)viewOne member's standing, which is their giver weight
get_units(account)viewOwnership units held by one member
get_params()viewRound 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.