mirror of
https://github.com/Twigpine/node.git
synced 2026-11-09 18:08:02 -10:00
* chore: add live-safe OSS readiness pass * fix(node): verify optional peer signatures during rollout * docs: rewrite README for node roadmap
157 lines
6.4 KiB
Markdown
157 lines
6.4 KiB
Markdown
# gitlawb economics
|
||
|
||
How $GITLAWB flows through the protocol and how stakers earn.
|
||
|
||
---
|
||
|
||
## TL;DR
|
||
|
||
- Every protocol fee (5% of completed bounties, plus future services) flows into `GitlawbFeeDistributor` — the protocol's reward wallet.
|
||
- Once per week, anyone can call `distribute()` to split the accumulated balance.
|
||
- **75%** goes to **node operators** (PoS staking — skin in the game).
|
||
- **24%** goes to **user stakers** (tier-weighted passive yield).
|
||
- **1%** goes to **the caller** of `distribute()` (keeper reward).
|
||
|
||
---
|
||
|
||
## Fee sources
|
||
|
||
All routed to `GitlawbFeeDistributor`:
|
||
|
||
| Source | Rate | How it gets there |
|
||
|---|---|---|
|
||
| Bounty protocol fee | 5% of payout | `GitlawbBounty.treasury` is set to the distributor — arrives on `approveBounty()` |
|
||
| Manual deposits (bankr) | variable | `token.transfer(feeDistributor, amount)` — any $GITLAWB sent to the address counts |
|
||
| Future: push/PR fees | TBD | node fees collected by operators, routed to distributor |
|
||
|
||
The distributor is a plain ERC20 holder — anything sent to it is fair game for the weekly split.
|
||
|
||
---
|
||
|
||
## The weekly split
|
||
|
||
```
|
||
distribute() — permissionless, enforced ≥ 7 days since last call
|
||
├── 1% → msg.sender (keeper reward)
|
||
├── 75% → GitlawbNodeStaking (operator PoS rewards)
|
||
└── 24% → GitlawbStaking (user tier-weighted rewards)
|
||
```
|
||
|
||
Split is owner-adjustable but capped to ±5% change per update (prevents abrupt reallocations).
|
||
|
||
---
|
||
|
||
## Node operator staking (75% track)
|
||
|
||
**Contract:** `GitlawbNodeStaking.sol`
|
||
|
||
Node operators **must** stake to run a node and earn rewards.
|
||
|
||
| Parameter | Value |
|
||
|---|---|
|
||
| Minimum stake | 10,000 $GITLAWB |
|
||
| Heartbeat cadence | 24 hours |
|
||
| Inactive threshold | 3 days (no heartbeat → excluded from rewards) |
|
||
| Unstake cooldown | 7 days |
|
||
|
||
**Reward formula** (per node, per weekly distribution):
|
||
|
||
```
|
||
nodeReward_i = nodeShare × (myStake / totalActiveStake) if heartbeat within 3 days
|
||
nodeReward_i = 0 otherwise
|
||
```
|
||
|
||
**Worked example — 5 active nodes**, all at 10k stake, weekly pot = 100k $GITLAWB:
|
||
- Node share (75%) = 75k
|
||
- Total active stake = 50k
|
||
- Each node earns: `75k × (10k / 50k)` = **15,000 $GITLAWB/week**
|
||
|
||
If one node goes offline, the active pool shrinks and remaining nodes earn more — the offline node gets nothing, its share redistributes.
|
||
|
||
**Skin in the game:** no automatic token slashing in v1, but offline nodes earn zero. Repeated offenses + inflated stake = dead capital.
|
||
|
||
---
|
||
|
||
## User staking (24% track)
|
||
|
||
**Contract:** `GitlawbStaking.sol`
|
||
|
||
Anyone can stake $GITLAWB for passive yield. Four tiers with multipliers:
|
||
|
||
| Tier | Min stake | Multiplier |
|
||
|---|---|---|
|
||
| Observer | 1,000 | 1x |
|
||
| Curator | 10,000 | 2x |
|
||
| Steward | 100,000 | 4x |
|
||
| Validator | 1,000,000 | 8x |
|
||
|
||
**Reward formula** (per staker, per weekly distribution):
|
||
|
||
```
|
||
userReward_i = userShare × (myStake × myMultiplier / totalWeightedStake)
|
||
```
|
||
|
||
**Worked example — mixed tiers**, weekly pot = 100k → user share = 24k:
|
||
|
||
| Staker | Stake | Multiplier | Weight |
|
||
|---|---|---|---|
|
||
| 5× Observer | 1k each | 1x | 5,000 |
|
||
| 3× Curator | 10k each | 2x | 60,000 |
|
||
| 2× Steward | 100k each | 4x | 800,000 |
|
||
| **Total weighted** | | | **865,000** |
|
||
|
||
- Each Observer: `24k × (1k / 865k)` ≈ **27.7 $GITLAWB/week**
|
||
- Each Curator: `24k × (20k / 865k)` ≈ **555 $GITLAWB/week**
|
||
- Each Steward: `24k × (400k / 865k)` ≈ **11,098 $GITLAWB/week**
|
||
|
||
**Unstake cooldown:** 7 days.
|
||
|
||
---
|
||
|
||
## Keeper reward (1% track)
|
||
|
||
The caller of `distribute()` receives 1% of the pot. At 100k weekly, that's 1,000 $GITLAWB.
|
||
|
||
Why: removes operational burden. Even if the official keeper misses a run, any staker or searcher has financial incentive to call it.
|
||
|
||
Operators can run a weekly keeper job that calls `distribute()`; the caller wallet self-funds its gas from the 1% reward.
|
||
|
||
---
|
||
|
||
## End-to-end flow
|
||
|
||
```
|
||
┌─────────────────────────────────────────┐
|
||
│ Fee sources │
|
||
│ ┌─────────────┐ ┌─────────────┐ │
|
||
│ │Bounty 5% │ │Bankr manual │ ··· │
|
||
│ └──────┬──────┘ └──────┬──────┘ │
|
||
└─────────┼─────────────────┼─────────────┘
|
||
↓ ↓
|
||
┌─────────────────────────────────────────┐
|
||
│ GitlawbFeeDistributor │
|
||
│ (the protocol reward wallet) │
|
||
└──────────────────┬──────────────────────┘
|
||
│
|
||
distribute() │ weekly, permissionless
|
||
↓
|
||
┌──────────────────────┼──────────────────────┐
|
||
│ │ │
|
||
┌────▼────┐ ┌────────▼────────┐ ┌──────▼──────┐
|
||
│ 1% │ │ 75% │ │ 24% │
|
||
│ caller │ │ NodeStaking │ │ UserStaking │
|
||
└─────────┘ │ (pro-rata: │ │ (pro-rata: │
|
||
│ stake × active)│ │ stake × m) │
|
||
└─────────────────┘ └─────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## Tuning
|
||
|
||
- `FeeDistributor.setSplit(nodeBps, userBps, keeperBps)` — owner only, sum must = 10000, each field can change ≤ 500 bps per update.
|
||
- `FeeDistributor.setSinks(...)` — swap staking contracts if upgrading.
|
||
- `GitlawbBounty.setProtocolFee(bps)` — fee cap 1000 bps (10%).
|
||
|
||
Any change is observable on-chain before it takes effect — integrators watch events.
|