Skip to main content

SPEC 006 — Convertible Instruments

FieldValue
StatusDRAFT
PriorityP1 — Core Product
Backendequa-server/modules/persistence/src/captable/
APIequa-server/modules/api/src/endpoints/captable-endpoints.ts
Frontendequa-web/src/modules/convertibles/
Confluence source incorporated: “Convertible Note Fully Diluted Equation” — see section 6.1a below

1. Feature Purpose

Convertible Instruments manages pre-equity financing instruments — SAFEs (Simple Agreements for Future Equity), convertible notes, SAFTs (Simple Agreements for Future Tokens), and custom instruments. Investors provide capital via these instruments, which later convert into equity shares upon a qualifying event (funding round, acquisition, or maturity). The module tracks instrument terms, calculates accrued interest, models conversion scenarios, and executes conversions that create new shareholdings on the cap table.

2. Current State (Verified)

2.1 Backend

ComponentPath
Entity definitionsequa-server/modules/persistence/src/schema.ts
Cap table readingequa-server/modules/persistence/src/captable/reading.ts
Cap table writingequa-server/modules/persistence/src/captable/writing.ts
API endpointsequa-server/modules/api/src/endpoints/captable-endpoints.ts

2.2 Frontend

ComponentPath
Convertibles moduleequa-web/src/modules/convertibles/
Utility functionsequa-web/src/modules/convertibles/utility.ts
Type definitionsequa-web/src/modules/convertibles/types.ts
Cap table serviceequa-web/src/service/services/captable/
Route pathsequa-web/src/logic/paths.ts lines 118–126

3. Data Model

3.1 ConvertibleInstruments

Core instrument terms stored as content-addressed records.
ColumnTypeConstraintsDescription
(hash)HashPK (from HashedTable)Content-addressed identifier
instrumentTypeConvertibleInstrumentTypeInstrument classification (see enum below)
authorizedRaiseAmountnumericMaximum capital the instrument can raise
interestRatenumericnullableAnnual interest rate (decimal, e.g., 0.05 for 5%)
accrualFrequencysmallintnullableInterest compounding period (1=daily, 2=monthly, 3=annual)
maturityDatedatenullableDate the instrument matures
valuationMaxnumericnullableValuation cap (upper bound for conversion price)
valuationMinnumericnullableValuation floor
conversionDiscountnumericnullableDiscount rate applied at conversion (e.g., 0.20 for 20%)
earlyExitMultiplenumericnullableMultiple returned on early exit/acquisition
estimatedConversionPricenumericnullablePre-calculated estimated price per share at conversion
qualifiedFinancingAmountnumericnullableMinimum financing amount to trigger automatic conversion
Source: schema.ts lines 1501–1534

3.2 ConvertibleInstrumentType Enum

9 instrument types, each identified by a UUID constant (utility.ts lines 4–14):
TypeDescription
convertibleNoteStandard convertible note with interest and maturity
startupsConvertibleNoteStartups.com variant convertible note
ycConvertibleNoteY Combinator convertible note template
preMoneySafePre-money SAFE (no valuation cap on existing shares)
startupsConvertibleSecurityStartups.com convertible security
ycvcSafeYC/VC SAFE template
postMoneySafePost-money SAFE (valuation cap includes the SAFE amount)
saftSimple Agreement for Future Tokens
customUser-defined instrument terms

3.3 AccrualFrequency Enum

ValueMeaning
1Daily compounding
2Monthly compounding
3Annual compounding
Source: utility.ts lines 28–32

3.4 InstrumentConversions

Records when a convertible instrument converts to equity.
ColumnTypeConstraintsDescription
(hash)HashPK (from HashedTable)Content-addressed identifier
convertibleInstrumentHashFK → ConvertibleInstrumentsSource instrument
sharesnumericTotal shares issued in conversion
valuationnumericOrganization valuation used for conversion price
Source: schema.ts lines 1536–1546

3.5 NoteConversions

Per-note distribution details within a conversion event.
ColumnTypeConstraintsDescription
(hash)HashPK (from HashedTable)Content-addressed identifier
conversionHashFK → InstrumentConversionsParent conversion event
destinationHashFK → HoldingsDestination shareholding created
sourceHashFK → HoldingsSource holding (the note)
sharesOwednumericCalculated shares owed to this note holder
valuenumericUSD value of the note at conversion
Source: schema.ts lines 1548–1564

3.6 Repayments

Records when a convertible instrument is repaid instead of converted.
ColumnTypeConstraintsDescription
(hash)HashPK (from HashedTable)Content-addressed identifier
convertibleInstrumentHashFK → ConvertibleInstrumentsRepaid instrument
issueDatedateDate of repayment
Source: schema.ts lines 1566–1573

3.7 Holdings (Relationship)

Convertible instruments are tracked as Holdings with a convertibleInstrument field:
ColumnTypeDescription
convertibleInstrumentHashnullable, FK → ConvertibleInstruments
Source: schema.ts lines 1417–1498 (Holdings entity, convertibleInstrument field)

Relationships


4. API Endpoints

Convertible instruments are managed through the Holdings API (shared with other holding types on the cap table).
MethodPathAuth GuardDescription
POST/holdingcanEditCapTableCreate holding with convertibleInstrument field
PUT/holding/:holdingcanEditCapTableUpdate holding and instrument terms
PATCH/holding/:holdingcanEditCapTablePartial update
DELETE/holding/:holdingcanEditCapTableDelete holding
POST/holding/:holding/convertcanEditCapTableExecute instrument conversion
POST/holding/:holding/repaycanEditCapTableRecord instrument repayment
Source: captable-endpoints.ts lines 429–442 (convert/repay), holdings CRUD throughout file

Request Schemas

// POST /holding (convertible-specific fields within NewHoldingRequest)
interface ConvertibleInstrumentRequest {
  accrualFrequency?: number;
  authorizedRaiseAmount: number;
  conversionDiscount?: number;
  earlyExitMultiple?: number;
  estimatedConversionPrice?: number;
  instrumentType: ConvertibleInstrumentType;
  interestRate?: number;
  maturityDate?: string;
  qualifiedFinancingAmount?: number;
  valuationMax?: number;
  valuationMin?: number;
}

// POST /holding/:holding/convert
interface NewConversionRequest {
  holding: Hash;
  valuation: number;
  distributions: DistributionRequest[];
}

5. Frontend Components

Pages

ComponentFilePurpose
ListConvertibleInstrumentsPagepages/list-convertible-instruments.tsxLists all instruments in a block
NewConvertibleInstrumentPagepages/new-convertible-instrument.tsxCreate instrument form
EditConvertibleInstrumentPagepages/edit-convertible-instrument.tsxEdit instrument terms
ViewConvertibleInstrumentPagepages/view-convertible-instrument.tsxInstrument detail view with notes
NewConvertibleNotePagepages/new-convertible-note.tsxIssue a new note against an instrument
EditConvertibleNotePagepages/edit-convertible-note.tsxEdit note details
ConversionPagepages/conversion-page.tsxExecute conversion with valuation and share distribution

Components

ComponentFilePurpose
ConvertibleInstrumentsFormcomponents/convertible-instruments-form.tsxShared create/edit form for instrument terms
ConvertibleNoteFormcomponents/convertible-note-form.tsxNote issuance form (principle, owner, date)
InstrumentDetailscomponents/instrument-details.tsxRead-only display of instrument terms and calculated values
ConversionFormcomponents/conversion-form.tsxConversion valuation input + per-note share distribution

Routes

RouteComponent
/organization/:org/capitalization/block/:block/convertibleListConvertibleInstrumentsPage
/organization/:org/capitalization/block/:block/convertible/newNewConvertibleInstrumentPage
/organization/:org/capitalization/block/:block/convertible/view/:holdingViewConvertibleInstrumentPage
/organization/:org/capitalization/block/:block/convertible/view/:holding/editEditConvertibleInstrumentPage
/organization/:org/capitalization/block/:block/convertible/view/:holding/note/newNewConvertibleNotePage
/organization/:org/capitalization/block/:block/convertible/view/:holding/note/:note/editEditConvertibleNotePage
/organization/:org/capitalization/block/:block/convertible/view/:holding/conversionConversionPage
Source: paths.ts lines 118–126, routes.ts lines 689–715

Form Fields

ConvertibleInstrumentFormFields (17 fields, types.ts lines 3–21):
FieldTypeDescription
instrumentTypeConvertibleInstrumentTypeSelected instrument template
namestringDisplay name
abbreviationstringShort label
authorizedRaiseAmountnumberMax capital
interestRatenumberAnnual rate
accrualFrequencyAccrualFrequencyCompounding period
maturityDateDateMaturity date
valuationMaxnumberValuation cap
valuationMinnumberValuation floor
conversionDiscountnumberDiscount percentage
earlyExitMultiplenumberEarly exit return multiple
estimatedConversionPricenumberEstimated share price
qualifiedFinancingAmountnumberAuto-conversion threshold
pricePerUnitnumberPrice per unit
senioritynumberLiquidation priority
convertsTostringTarget security type for conversion
approvalDocumentstringAuthorization document reference
ConvertibleNoteFormFields (3 fields, types.ts lines 23–27):
FieldTypeDescription
principlenumberInvestment amount (USD)
ownerstringNote holder (member reference)
issueDateDateDate the note was issued

6. Business Rules and Validation

6.1 Interest Calculations

The module provides 17 calculation functions (utility.ts):
FunctionPurpose
calculateSimpleInterest(steps, principle, rate)Simple interest: steps * principle * rate
calculateCompoundInterest(steps, principle, rate)Compound: principle * (1 + rate)^steps - principle
getAccrualSteps(start, end, frequency)Count accrual periods between dates
getInterestFromConvertible(instrument, issueDate, value, current?, total?)Full interest calculation using instrument terms
optionalInterestFromConvertible(...)Null-safe wrapper for optional instrument data
getSharePrice(usd, totalUnits, discount)Price per share: usd / totalUnits * (1 - discount)
convertToShares(usdAmount, price)Shares: usdAmount / price
getMaxShares({maxUsd, valuationMin, totalUnits, discount})Maximum shares at conversion
getOrganizationTotalUnits(securities)Sum outstanding across all security types

6.1a Fully Diluted Equation (from Confluence KnowledgeBase)

Source: Confluence KnowledgeBase — Convertible Note Fully Diluted Equation (by Christopher Johnson, extracted from source code)
Inputs:
  • From Convertible Instrument: Accrual Frequency, Discount Rate, Interest Rate, Maturity Date (optional), Minimum Valuation
  • From Convertible Note: Issue Date, Principle
  • From Organization: Total Units
Step 1 — Calculate Price Per Share:
Base Price Per Share = Minimum Valuation / Total Units
Discount = Base Price Per Share * Discount Rate / 100
Price Per Share = Base Price Per Share - Discount
Step 2 — Calculate Interest:
  • End Date = Maturity Date (if specified), otherwise Today
  • If End Date is before Issue Date, Fully Diluted = 0
  • Accrual Steps calculation:
    • Daily: number of days from Issue Date to End Date (not counting Issue Date)
    • Monthly: days rounded down to the most recent day-of-month matching Issue Date
    • Annual: days rounded down to the most recent matching day-of-month AND month
  • Interest = Principle * Accrual Steps * Interest Rate / 365 / 100
Step 3 — Final Calculation:
P&I = Principle + Interest
Fully Diluted = P&I / Price Per Share

6.2 Conversion Rules

  1. User enters organization valuation at time of conversion
  2. System calculates shares owed per note: note value (principle + accrued interest) divided by conversion price
  3. Conversion price = min(valuation cap / total units, valuation / total units) * (1 - discount)
  4. Per-note share distributions can be manually adjusted before execution
  5. Conversion creates new Holdings (destination) linked back to source notes via NoteConversions
  6. The InstrumentConversions record captures the total shares and valuation used

6.3 Validation

RuleEnforcement
Valuation must be non-zeroConversion form: nonZeroCurrencyField validator
Instrument type is requiredForm validation
Authorized raise amount is requiredEntity constraint (non-nullable numeric)
All content-addressed records are immutableHashedTable base class — updates create new hash entries

6.4 Instrument Type Behavior

Different instrument types control which form fields are displayed (dynamic fields in utility.ts lines 200–206):
  • SAFEs: No interest rate, no maturity date, no accrual frequency
  • Convertible notes: Interest rate, accrual frequency, maturity date are active
  • Custom: All fields available

7. Acceptance Criteria

  • All 9 instrument types can be created with the correct fields active/hidden per type
  • Convertible notes accrue interest correctly using simple or compound calculation based on accrual frequency
  • Interest calculation matches the formula: simple = steps * principle * rate, compound = principle * (1 + rate)^steps - principle
  • Conversion calculates shares owed per note using valuation, discount, and cap
  • Conversion creates new destination Holdings and NoteConversion records
  • Repayment creates a Repayment record with the instrument reference and date
  • Instrument terms are immutable (content-addressed via HashedTable)
  • Form validation prevents zero-valuation conversions
  • The convertibles list page shows all instruments in a capitalization block
  • Note issuance captures principle, owner, and issue date
  • Share distribution amounts in the conversion form default to calculated shares owed
  • getMaxShares correctly computes maximum shares using valuation floor and discount
  • All 8 frontend routes resolve to the correct page components

8. Risks and Edge Cases

RiskImpactMitigation
Numeric precision loss in share calculationsIncorrect share countsUse numeric (arbitrary precision) in DB; decimal library in frontend
No server-side validation in persistence layerInvalid instrument data could be storedAdd validation at API request handler level before persistence calls
Conversion form allows manual share adjustment without total validationOutput shares may not equal calculated totalAdd frontend validation that sum(distributions) equals expected total
Zero-interest instruments with accrual frequency setUnnecessary calculation cyclesSkip interest calculation when interestRate is 0 or null
Multiple concurrent conversions on same instrumentDouble-converted sharesSerialize conversion requests per instrument; check conversion status before executing
SAFE vs note field confusionUser enters interest rate on a SAFEDynamic field visibility per instrument type already handles this
Valuation cap below valuation floorContradictory termsValidate valuationMax >= valuationMin in form

9. Dependencies

DependencyTypeStatus
003-Cap Table (Holdings, SecurityTypes)Required beforeDRAFT
012-Team Members and Roles (member references)Required beforeDRAFT
002-Organization ManagementRequired beforeDRAFT