Fresh repository history for elektrine/tarakan hosted at https://git.elektrine.com/elektrine/tarakan.
2.9 KiB
Credit economy
How credits are minted, spent, and settled - and the rules that keep money out of the security record's truth machinery.
Minting (earned, never bought)
Credits are minted only on verification events, by
Tarakan.Credits.MintWorker, when a canonical finding's status settles. Fixed
amounts (Tarakan.Credits.mint_amounts/0):
| Kind | Amount | Paid to |
|---|---|---|
mint_finding_verified |
50 | The finder (earliest public occurrence), first settle to verified |
mint_check_correct |
10 | Each checker whose verdict matches the settled status |
mint_fix_settled |
25 | Each checker who attested fixed when the finding settles fixed (on top of the correctness mint) |
Every mint carries a subject ({subject_type, subject_id}) and rides a
partial unique index, so minting is idempotent: replays and status
oscillations return :already_minted and never double-pay. Moderators can
correct balances with an audited adjustment entry.
Spending
spend_bounty_escrow- funding a credit bounty escrows the full amount from the sponsor at creation; cancellations and expiries refund it in full.spend_priority_boost- boosts paid for with credits.receive_bounty- the winning side of a settled credit bounty (see take rate).
Debits fail with :insufficient_credits and leave the balance untouched. The
ledger is append-only and public; every entry records balance_after, so any
balance can be replayed.
Take rate
Credit bounties settle net of the platform take rate: the configured rate
(:tarakan, :market_take_rate, 0.15 at launch) is snapshotted onto the
bounty at creation, so later config changes never retroactively change a
live bounty. The winner receives credit_amount * (1 - take_rate); the
remainder is the platform fee.
Fiat payouts are manual (for now)
Fiat bounties are funded through Stripe Checkout, but there is no automated
payout rail this iteration. On settlement a fiat bounty moves to
payout_pending; an admin pays the winner off-platform and records the fact
with Market.mark_paid/2 (payout_pending → paid, audited as
bounty_paid). Cancellation of a funded fiat bounty refunds via Stripe.
Invariants
- Credits are never purchasable. Stripe sells subscriptions and fiat bounties; there is no way to buy a credit balance.
- Credits are non-transferable. The only movements are mints, spends, bounty escrow/settlement, and moderator adjustments.
- Money never influences finding status. Status is decided by independent
checks and verification quorum. Credits are minted because a status
settled; bounties pay for work, not for outcomes on the record. A paid
feature can buy alerts, API limits, or handling - never a
verifiedlabel.