nx_captable_lib.nx source
↩ module page · 108 lines · 5326 B
1// nx_captable_lib.nx -- ENTITY MANAGEMENT: capitalisation table arithmetic and corporate-authority limits.
2// The Carta/Athennian-class category we had at zero. A cap table is not a spreadsheet, it is a set of
3// hard corporate-law constraints, and two of them are violated constantly.
4//
5// u2605OVER-ISSUANCE IS VOID, NOT AN OVERDRAFT. A corporation may not issue more shares than its charter
6// AUTHORISES. Shares purportedly issued beyond that number are void -- not "issued pending an amendment",
7// not a rounding problem to fix at the next raise. A cap table that simply shows a larger issued figure
8// is asserting something the corporation had no power to do, so this refuses rather than reports.
9//
10// u2605OWNERSHIP DEPENDS ENTIRELY ON THE BASIS, AND THE BASIS IS USUALLY UNSTATED. The same holder is a
11// different percentage on an OUTSTANDING basis than on a FULLY DILUTED basis (which counts the option
12// pool, warrants and convertibles). Founders hear the outstanding number, investors model the diluted
13// one, and the gap is where disputes live. Both are computed here, separately and explicitly named --
14// there is deliberately no single "ownership" function to call by accident.
15//
16// Percentages are in PER MILLE (0..1000) to stay in integer arithmetic; a permille figure is exact where
17// a truncated percent would silently lose sub-1% holders.
18//
19// u2605FAIL-CLOSED: a zero or negative denominator yields ENT_UNKNOWN, never zero percent. "0% owned"
20// and "we cannot compute this" are different answers.
21// STRUCTURE: pure decision core, zero I/O. license_tier: ORIGINAL LIB.
22
23import "nx_matter_lib.nx"
24
25const ENT_UNKNOWN: i64 = 0 - 1
26const ENT_VOID: i64 = 0 - 2
27
28func ent_is1(v: i64) -> i64 {
29 if v == 1 { return 1 }
30 return 0
31}
32
33// u2605the authority check. Issuing beyond the authorised count is VOID, not merely flagged.
34func ent_issue_ok_pure(authorized: i64, issued: i64) -> i64 {
35 if authorized < 0 { return 0 }
36 if issued < 0 { return 0 }
37 if issued > authorized { return 0 }
38 return 1
39}
40
41// shares available to issue under the current charter; negative capacity is impossible, so an
42// over-issued table reports VOID rather than a negative headroom figure.
43func ent_authorized_remaining_pure(authorized: i64, issued: i64) -> i64 {
44 if ent_issue_ok_pure(authorized, issued) == 0 { return ENT_VOID }
45 return authorized - issued
46}
47
48// outstanding = issued minus treasury. Treasury shares exist but do not vote or participate.
49func ent_outstanding_pure(issued: i64, treasury: i64) -> i64 {
50 if issued < 0 { return ENT_UNKNOWN }
51 if treasury < 0 { return ENT_UNKNOWN }
52 if treasury > issued { return ENT_UNKNOWN }
53 return issued - treasury
54}
55
56// fully diluted adds everything that CAN become a share: granted options, the unissued pool, warrants
57// and convertibles. Omitting the UNISSUED pool is the most common understatement.
58func ent_fully_diluted_pure(outstanding: i64, options_granted: i64, options_available: i64, warrants: i64, convertibles: i64) -> i64 {
59 if outstanding == ENT_UNKNOWN { return ENT_UNKNOWN }
60 if options_granted < 0 { return ENT_UNKNOWN }
61 if options_available < 0 { return ENT_UNKNOWN }
62 if warrants < 0 { return ENT_UNKNOWN }
63 if convertibles < 0 { return ENT_UNKNOWN }
64 return outstanding + options_granted + options_available + warrants + convertibles
65}
66
67// ownership in PER MILLE against an explicit denominator; a non-positive denominator is UNKNOWN,
68// never 0 permille.
69func ent_permille_pure(held: i64, denominator: i64) -> i64 {
70 if denominator <= 0 { return ENT_UNKNOWN }
71 if held < 0 { return ENT_UNKNOWN }
72 return (held * 1000) / denominator
73}
74
75func ent_ownership_outstanding_pure(held: i64, outstanding: i64) -> i64 {
76 return ent_permille_pure(held, outstanding)
77}
78
79func ent_ownership_diluted_pure(held: i64, fully_diluted: i64) -> i64 {
80 return ent_permille_pure(held, fully_diluted)
81}
82
83// u2605dilution can only ever REDUCE a holder's percentage (or leave it equal when nothing is outstanding
84// beyond the shares themselves). 1 when that invariant holds.
85func ent_dilution_consistent_pure(outstanding_permille: i64, diluted_permille: i64) -> i64 {
86 if outstanding_permille == ENT_UNKNOWN { return 0 }
87 if diluted_permille == ENT_UNKNOWN { return 0 }
88 if diluted_permille > outstanding_permille { return 0 }
89 return 1
90}
91
92// the pool as a share of the fully diluted base -- the number investors actually negotiate.
93func ent_pool_permille_pure(options_granted: i64, options_available: i64, fully_diluted: i64) -> i64 {
94 if options_granted < 0 { return ENT_UNKNOWN }
95 if options_available < 0 { return ENT_UNKNOWN }
96 return ent_permille_pure(options_granted + options_available, fully_diluted)
97}
98
99// u2605A CAP TABLE IS VALID only when issuance is within authority, outstanding resolves, and the fully
100// diluted base is at least the outstanding count. Any one failing invalidates the whole table.
101func ent_table_valid_pure(authorized: i64, issued: i64, treasury: i64, fully_diluted: i64) -> i64 {
102 if ent_issue_ok_pure(authorized, issued) == 0 { return 0 }
103 let outs: i64 = ent_outstanding_pure(issued, treasury)
104 if outs == ENT_UNKNOWN { return 0 }
105 if fully_diluted == ENT_UNKNOWN { return 0 }
106 if fully_diluted < outs { return 0 }
107 return 1
108}