|
| 1 | +# SINT Protocol — Tokenomics |
| 2 | + |
| 3 | +This document describes how SINT's economic layer works. It is grounded in the |
| 4 | +implementation in `packages/bridge-economy/` and is intentionally free of |
| 5 | +on-chain or Solana specifics (those live outside `sint-protocol`). |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## 1. Token Unit |
| 10 | + |
| 11 | +SINT uses an **integer token** — no fractional units. All costs and balances are |
| 12 | +whole numbers. |
| 13 | + |
| 14 | +| Constant | Value | Source | |
| 15 | +|---|---|---| |
| 16 | +| `TOKENS_PER_DOLLAR` | 250 | `pricing-calculator.ts` | |
| 17 | +| `INITIAL_USER_BALANCE` | 250 tokens | `pricing-calculator.ts` | |
| 18 | +| Launch pricing | 1 token ≈ $0.001 | 1 / TOKENS_PER_DOLLAR | |
| 19 | + |
| 20 | +New users start with 250 tokens ($1.00 equivalent), enough for ~27 default MCP |
| 21 | +tool calls before recharging. |
| 22 | + |
| 23 | +--- |
| 24 | + |
| 25 | +## 2. Billing Formula |
| 26 | + |
| 27 | +Every action that passes `PolicyGateway.intercept()` has a cost computed by |
| 28 | +`computeActionCost()` in `packages/bridge-economy/src/pricing-calculator.ts`: |
| 29 | + |
| 30 | +``` |
| 31 | +cost = ceil(baseCost × costMultiplier × globalMarkupMultiplier) |
| 32 | +``` |
| 33 | + |
| 34 | +| Parameter | Default | Notes | |
| 35 | +|---|---|---| |
| 36 | +| `baseCost` | 6 tokens | MCP/tool call | |
| 37 | +| `costMultiplier` | 1.0 | Per-resource or MCP marketplace rate | |
| 38 | +| `globalMarkupMultiplier` | 1.5 | `GLOBAL_MARKUP_MULTIPLIER` constant | |
| 39 | +| **Default MCP result** | **9 tokens** | `ceil(6 × 1.0 × 1.5)` | |
| 40 | + |
| 41 | +The `costMultiplier` comes from `IPricingPort.getPrice()`. If the pricing port is |
| 42 | +absent or returns an error, `costMultiplier` defaults to 1.0 (fail-open). |
| 43 | + |
| 44 | +--- |
| 45 | + |
| 46 | +## 3. Action Cost Table |
| 47 | + |
| 48 | +Costs are derived from the base constants in `pricing-calculator.ts`. Tier |
| 49 | +labels align with the SINT approval tier system (T0–T3). |
| 50 | + |
| 51 | +| Tier | Action type | Base cost | Typical multiplier | **Token cost** | |
| 52 | +|---|---|---|---|---| |
| 53 | +| T0 — Observe | Read/query (sensor, subscribe) | 4–6 | 1.0 | **~6–9** | |
| 54 | +| T1 — Prepare | Low-impact write (save waypoint, file write) | 6 | 1.0 | **9** | |
| 55 | +| T2 — Act | Physical state change (ROS 2 topic publish) | 8 | 1.0 | **12** | |
| 56 | +| T3 — Commit | Capsule execution, irreversible action | 12 | 1.0 | **18** | |
| 57 | + |
| 58 | +The 3x tier escalation in the design spec (1 → 3 → 9 → 27 tokens) reflects a |
| 59 | +conceptual pricing model where each approval tier costs three times the previous. |
| 60 | +The actual constants produce a shallower curve because the billing system |
| 61 | +differentiates by *action category*, not purely by tier label. |
| 62 | + |
| 63 | +Physical-domain bridges carry higher multipliers: |
| 64 | + |
| 65 | +| Bridge / resource prefix | Typical `costMultiplier` | |
| 66 | +|---|---| |
| 67 | +| MCP tool call (default) | 1.0 | |
| 68 | +| ROS 2 publish (`ros2://`) | 1.0–2.0 | |
| 69 | +| MAVLink command | 2.0–5.0 | |
| 70 | +| Capsule execution (`capsule://`) | 1.0–3.0 | |
| 71 | + |
| 72 | +--- |
| 73 | + |
| 74 | +## 4. Budget Enforcement |
| 75 | + |
| 76 | +Budget enforcement runs in `EconomyPlugin.preIntercept()`, called before |
| 77 | +`PolicyGateway` assigns tiers. |
| 78 | + |
| 79 | +### Per-agent budget cap |
| 80 | + |
| 81 | +Each agent has a total budget cap managed by `IBudgetPort`. Before an action |
| 82 | +executes: |
| 83 | + |
| 84 | +1. `checkBudget({ userId, action, resource, estimatedCost })` is called. |
| 85 | +2. If `allowed === false` → the plugin returns a `deny` decision immediately. |
| 86 | +3. If `usagePercent > 80` → a `economy.budget.alert` event is emitted to the |
| 87 | + evidence ledger. |
| 88 | + |
| 89 | +### Session-level collective spend cap |
| 90 | + |
| 91 | +The design supports a `maxCollectiveSpend` field in a `CollectiveConstraintManifest` |
| 92 | +that limits total token spend across all agents in a multi-agent session. This is |
| 93 | +a planned constraint; the per-agent `IBudgetPort` is the current enforcement |
| 94 | +boundary. |
| 95 | + |
| 96 | +--- |
| 97 | + |
| 98 | +## 5. Balance Model |
| 99 | + |
| 100 | +Agents carry a token balance maintained by `IBalancePort`. |
| 101 | + |
| 102 | +**Flow for every request:** |
| 103 | + |
| 104 | +``` |
| 105 | +preIntercept: |
| 106 | + 1. computeActionCost(request) → tokens |
| 107 | + 2. IBudgetPort.checkBudget() → deny if budget exceeded |
| 108 | + 3. IBalancePort.getBalance() → deny if balance < tokens |
| 109 | + 4. ITrustPort.evaluateTrust() → deny if blocked, escalate if high_risk |
| 110 | +
|
| 111 | +postIntercept (only when decision === "allow"): |
| 112 | + IBalancePort.withdraw(userId, tokens, description, "sint_protocol") |
| 113 | +``` |
| 114 | + |
| 115 | +The balance check happens **before** any physical action executes. A balance |
| 116 | +shortfall produces a `deny` — not an escalation. The ledger receives |
| 117 | +`economy.balance.insufficient` and `economy.action.billed` events. |
| 118 | + |
| 119 | +Both the budget check and balance check are fail-open: if the port is |
| 120 | +unreachable, the request proceeds through normal gateway logic. |
| 121 | + |
| 122 | +--- |
| 123 | + |
| 124 | +## 6. Fraud Prevention |
| 125 | + |
| 126 | +### Rate limiting |
| 127 | + |
| 128 | +Capability tokens carry `constraints.rateLimit.{ maxCalls, windowMs }`. |
| 129 | +`PolicyGateway` counts calls per token against a `RateLimitStore`. Exceeding |
| 130 | +`maxCalls` within `windowMs` results in an immediate deny |
| 131 | +(`RATE_LIMIT_EXCEEDED`). This is enforced in the security layer, independently |
| 132 | +of economy billing. |
| 133 | + |
| 134 | +### Circuit breaker |
| 135 | + |
| 136 | +`CircuitBreakerPlugin` tracks denial counts per agent. After `N` consecutive |
| 137 | +denials the circuit trips to `OPEN` and all subsequent requests are denied |
| 138 | +without evaluation. This prevents abusive retry loops from consuming gateway |
| 139 | +resources or economy-service quota. |
| 140 | + |
| 141 | +### Balance insufficient → deny, not escalate |
| 142 | + |
| 143 | +An `InsufficientBalanceError` always produces `action: "deny"` with |
| 144 | +`policyViolated: "INSUFFICIENT_BALANCE"`. The gateway will not escalate to a |
| 145 | +human approver for economic failures — there is nothing a human can authorise |
| 146 | +that would fix a zero balance. |
| 147 | + |
| 148 | +--- |
| 149 | + |
| 150 | +## 7. Revenue Split (Design) |
| 151 | + |
| 152 | +When tokens are spent by an agent, the protocol's intent is: |
| 153 | + |
| 154 | +| Recipient | Share | |
| 155 | +|---|---| |
| 156 | +| Operator (MCP server / bridge host) | 70% | |
| 157 | +| Protocol treasury | 20% | |
| 158 | +| Safety reserve fund | 10% | |
| 159 | + |
| 160 | +This split is aspirational design. The current implementation performs a single |
| 161 | +`IBalancePort.withdraw()` call; distribution to operator, treasury, and safety |
| 162 | +reserve is handled by the external economy service that implements `IBalancePort`, |
| 163 | +not by `sint-protocol` itself. |
| 164 | + |
| 165 | +--- |
| 166 | + |
| 167 | +## 8. What This Document Does Not Cover |
| 168 | + |
| 169 | +- **On-chain mechanics** — Solana token programme, SPL accounts, DEX liquidity. |
| 170 | + These are defined in the `sint-ai-workspace` context, outside this repository. |
| 171 | +- **Fiat on-ramp / off-ramp** — also external. |
| 172 | +- **MCP marketplace pricing catalogue** — operator-set `costMultiplier` values |
| 173 | + per MCP server are resolved at runtime via `IPricingPort`; no static list is |
| 174 | + maintained here. |
| 175 | + |
| 176 | +--- |
| 177 | + |
| 178 | +*Last updated: 2026-04-04. Tied to `@sint/bridge-economy` v0.2.* |
0 commit comments