Fresh repository history for elektrine/tarakan hosted at https://git.elektrine.com/elektrine/tarakan.
60 lines
2.9 KiB
Markdown
60 lines
2.9 KiB
Markdown
# 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 `verified` label.
|