Founding as a Developer — Validate Before You Build
Run the Cap Table Through a Funding Round Yourself
Goal
Apply to a hypothetical company's cap table, in order, vesting, repurchase from the person who left, post-money SAFE conversion, and a seed round that includes an option pool increase, and calculate who is diluted by how much at each step.
Why it matters
Equity terms are written in the contract, but their consequences cannot be seen until you calculate them. Equity with no vesting, SAFEs that dilute each other, and a pool increase put into the pre-money quietly change the founders' share. Only if you can calculate it yourself can you read the numbers on the negotiating table. (This is not legal or tax advice.)
Materials — /opt/fixtures/founder/equity/company.json
founders:name, shares, vesting_start, cliff_months, vesting_months, left_on(the day they left, null if none)pool:granted(granted options),unissued(the unissued pool)safes:investor, amount, post_money_capround:date, investor, pre_money, investment, pool_target
Definitions
- Full months: from the start date to the reference date, (year difference × 12 + month difference), minus 1 if the day of the reference date is smaller than the day of the start date (0 if negative).
- Vesting: if months < cliff it is 0, otherwise
shares × min(달 수, vesting_months) // vesting_months(the Korean word in the code means months). Someone who left keeps only the vested share as ofleft_on, and the rest is repurchased and canceled. A founder who stays holds everything. - Pre-round shares C = founders' holdings + pool_granted + pool_unissued.
- SAFE conversion:
f_i = amount / post_money_cap,F = Σf_i,S_i = floor(f_i × C / (1 − F)). Shares after conversion D = C + ΣS. - Round:
k = (pre_money + investment) / pre_money,U = pool_unissued,p = pool_target. Pool increaseP = max(0, floor((p·D·k − U) / (1 − p·k))), price per share= pre_money / (D + P), investor shares= floor(investment / 주당 가격), effective pre-money= 주당 가격 × D(the Korean words in the code mean price per share). - Ownership is a ratio between 0 and 1, rounded to four decimal places.
Steps
- In
/root/founder/equity/equity.py, createvested(shares, start, cliff, total, on)(dates are "YYYY-MM-DD" strings, and it returns an integer). - In
/root/founder/equity/departures.json, write{"left_on", "months", "vested", "repurchased"}for each person who left (the key is the name). - In
/root/founder/equity/cap_pre.json, writeholders(names, pool_granted, and pool_unissued → shares, with people who left included at their remaining shares),total, andownership. - In
equity.py, createsafe_shares(C, safes)(safes is the list from the materials as is, and it returns the list of share counts in the same order), and in/root/founder/equity/safes.json, writeshares(investor → shares),total_after(D), andownership(investor → ratio to D). - In
/root/founder/equity/naive.json, writesharesfor the common mistake — giving the SAFE the shares off_i × Crounded down — and theownershipat that point (relative to C + the sum of the mistaken shares). - In
equity.py, createpriced_round(D, U, pre_money, investment, pool_target)→{"pool_increase", "price", "investor_shares", "post_fd", "effective_pre_money"}, and in/root/founder/equity/round.json, write the result calculated from the materials (price rounded to two decimal places, effective_pre_money to an integer). - In
/root/founder/equity/cap_post.json, write the post-roundholders(add the increase to pool_unissued, and add the round investor),total, andownership. - In
/root/founder/equity/dilution.json, writeminji(three ownership ratios: [before the round, after SAFE conversion, after the round]),founders_after(the post-round ownership of all remaining founders together),headline_pre_money,effective_pre_money, andinvestor_ownership(the round investor).
Notes
- Keep integer division and rounding down (
//,math.floor) exactly as defined. The grader notices even a one-share difference. - Common mistakes: giving vesting to someone who left before the cliff, counting months by rounding days, simply multiplying the SAFE ratio by C, putting the pool increase into the post-investment shares, and writing ownership as a percentage (53.35).
Vesting — full months and the cliff
In /root/founder/equity/equity.py, create vested(shares, start, cliff, total, on).
First count the full months. If the "day" of the reference date is smaller than the "day" of the start date, that month has not yet been completed. Before the cliff it is 0, and after that it is integer division (//).
The share of the person who left
In /root/founder/equity/departures.json, write left_on, months, vested, and repurchased for each person who left.
Write only the founders who have left_on. repurchased is the original shares − the vested shares.
The cap table before the round
In /root/founder/equity/cap_pre.json, write holders, total, and ownership.
Put only the vested share for the person who left, everything for the founders who remain, and pool_granted and pool_unissued in one table. Ownership is a 0-to-1 ratio.
Convert two post-money SAFEs
Add safe_shares(C, safes) to equity.py, and in /root/founder/equity/safes.json write shares, total_after, and ownership.
Each SAFE must hold investment ÷ cap of all shares after conversion. SAFEs dilute each other too, so calculate C × f / (1 − F) using the ratio sum F.
A common mistake — if you simply multiply the ratio
In /root/founder/equity/naive.json, write shares with f_i × C rounded down and the ownership at that point (relative to C + Σ).
This step is a deliberately wrong calculation. Confirm that the investor's share comes out smaller than the promised ratio (investment ÷ cap).
A seed round that puts the pool increase into the pre-money
Add priced_round(D, U, pre_money, investment, pool_target) to equity.py, and in /root/founder/equity/round.json write the result.
k = post ÷ pre. Get the pool increase P from the formula in the definitions and round down, then price per share = pre ÷ (D + P), and investor shares = investment ÷ price, rounded down.
The cap table after the round
In /root/founder/equity/cap_post.json, write holders, total, and ownership.
In the table with the SAFE investors added, add the increase to pool_unissued, and put the round investor (round.investor in the materials) in as a new line.
Who was diluted by how much
In /root/founder/equity/dilution.json, write minji (three points in time), founders_after, headline_pre_money, effective_pre_money, and investor_ownership.
Minji's ownership after SAFE conversion = minji's shares ÷ D. For the effective pre-money, use the step 6 result as is.