|
1 | 1 | // Staking milestones for the Gnars Builder subnet campaign. `amountMor` is the |
2 | | -// MOR-staked threshold that unlocks the milestone; `null` means the milestone is |
3 | | -// not amount-gated (tracked manually via `done`). Targets are the current |
| 2 | +// MOR-staked threshold that unlocks the milestone. Targets are the current |
4 | 3 | // program — swap here if the campaign changes. |
5 | 4 | // |
| 5 | +// WHAT THIS LADDER MEANS. It is what Gnars DELIVERS to amplify Morpheus as the |
| 6 | +// subnet grows, not what a staker earns. The two are easy to confuse and the page |
| 7 | +// used to carry the other axis (featured wall / community drop / IRL event), which |
| 8 | +// contradicted the stake dialog's own disclaimer that "rewards accrue to the |
| 9 | +// subnet, not to individual stakers". This ladder is a unilateral Gnars |
| 10 | +// commitment, built on Morpheus's open protocol — it is not a partnership and |
| 11 | +// implies nothing agreed or returned by the Morpheus side. |
| 12 | +// |
| 13 | +// `firmness` is why the ladder can be published before it is fully locked in: only |
| 14 | +// the 10k anchor is a real commitment, so the other five ship labelled `proposed` |
| 15 | +// rather than silently reading as promises. |
| 16 | +// |
6 | 17 | // This file carries NO copy. Milestone labels live in |
7 | 18 | // `stake.page.subnet.milestones.<id>` in messages/{en,pt-br}/stake.json and are |
8 | 19 | // resolved by whoever renders the list, so the checklist follows the page locale |
9 | 20 | // instead of printing English inside a Portuguese section. The thresholds that |
10 | 21 | // appear inside those labels are interpolated as `{n, number}`, which is also |
11 | | -// what makes "10,000" read as "10.000" in pt-BR. |
| 22 | +// what makes "10,000" read as "10.000" in pt-BR. Firmness labels live alongside |
| 23 | +// them under `stake.page.subnet.firmness.<firmness>`. |
12 | 24 |
|
13 | 25 | export const SUBNET_GOAL_MOR = 100_000; |
14 | 26 |
|
| 27 | +/** Committed = Gnars has locked this in. Proposed = direction, not a promise. */ |
| 28 | +export type MilestoneFirmness = "committed" | "proposed"; |
| 29 | + |
15 | 30 | export type StakeMilestone = { |
16 | 31 | /** Also the message key under `stake.page.subnet.milestones`. */ |
17 | 32 | id: string; |
18 | | - amountMor: number | null; |
19 | | - done?: boolean; |
| 33 | + amountMor: number; |
| 34 | + firmness: MilestoneFirmness; |
20 | 35 | }; |
21 | 36 |
|
22 | 37 | export const SUBNET_MILESTONES: StakeMilestone[] = [ |
23 | | - { id: "live", amountMor: 0 }, |
24 | | - { id: "backers10", amountMor: null, done: false }, |
25 | | - { id: "10k", amountMor: 10_000 }, |
26 | | - { id: "50k", amountMor: 50_000 }, |
27 | | - { id: "100k", amountMor: 100_000 }, |
| 38 | + { id: "10k", amountMor: 10_000, firmness: "committed" }, |
| 39 | + { id: "15k", amountMor: 15_000, firmness: "proposed" }, |
| 40 | + { id: "25k", amountMor: 25_000, firmness: "proposed" }, |
| 41 | + { id: "30k", amountMor: 30_000, firmness: "proposed" }, |
| 42 | + { id: "50k", amountMor: 50_000, firmness: "proposed" }, |
| 43 | + { id: "100k", amountMor: 100_000, firmness: "proposed" }, |
28 | 44 | ]; |
29 | 45 |
|
30 | 46 | export function isMilestoneDone(m: StakeMilestone, totalStaked: number) { |
31 | | - return m.amountMor === null ? Boolean(m.done) : totalStaked >= m.amountMor; |
| 47 | + return totalStaked >= m.amountMor; |
32 | 48 | } |
0 commit comments