以下情境为教学假设,人物与数字不代表经核实的真实案例。
融资的账单有两张:第一张是稀释,第二张是治理。稀释写在 term sheet 的股权比例里,容易看见;治理藏在董事会席位、否决权、信息权和优先清算权里,通常在退出时才真正付账。两张账单都不是一次性的,它们会在每一轮融资后重新计算。
这一节用 LedgerLite 的种子轮和 A 轮做一条完整的持股曲线:创始人从 100% 出发,经过两轮融资降到 65%,再把期权池从 10% 扩到 15%,看创始人还要让出多少。然后把这 65% 放回退出分配里,算清楚「持股比例」和「到手金额」为什么不是同一件事。所有比例、估值和条款都是教学假设,不构成投资或法律意见。
稀释是乘法,不是加法
先看两轮融资的持股变化。种子轮按 1.1 的条款:pre-money 1,500,000 美元,融资 300,000 美元,post-money 1,800,000 美元,稀释 16.67%。A 轮假设 pre-money 3,900,000 美元,融资 1,100,000 美元,post-money 5,000,000 美元,稀释 22.00%。
| 轮次 | pre-money | 融资额 | post-money | 本轮稀释 | 创始人持股 |
|---|---|---|---|---|---|
| 种子轮 | $1,500,000 | $300,000 | $1,800,000 | 16.67% | 83.33% |
| A 轮 | $3,900,000 | $1,100,000 | $5,000,000 | 22.00% | 65.00% |
创始人最终持股是 100% × (1 − 16.67%) × (1 − 22.00%) = 65.00%。如果把两个稀释比例直接相加,会得到 38.67%,再用 100% 去减,得到 61.33%。两个结果相差 3.67 个百分点。差额来自第二轮的分母:A 轮的 22% 是按已经缩小的 83.33% 计算的,不是按 100% 计算的。
轮次越多,加法和乘法的差距越大:
| 轮次结构 | 加法结果 | 乘法结果 | 差额 |
|---|---|---|---|
| 两轮各 20% | 60.0% | 64.0% | 4.0 个百分点 |
| 三轮各 20% | 40.0% | 51.2% | 11.2 个百分点 |
| 种子 16.67% + A 22% | 61.33% | 65.00% | 3.67 个百分点 |
这就是稀释的复利效应。每一轮都在一个更小的基数上再打折,所以「每轮只稀释 20%」在第三轮之后留下的不是 40%,而是 51.2%。创始人能控制的不是单轮比例,而是轮次数量和每轮之间的估值增长;估值涨得越快,同样的融资额对应的稀释越小。
期权池:从 10% 到 15% 的两种算法
期权池是第二张稀释账单。A 轮后创始人 65%、投资人 35%,没有期权池。先设立一个 10% 的期权池:按 pre-money top-up 的常见做法,10 个百分点由创始人独自承担,创始人从 65% 降到 55%,投资人仍是 35%,池子 10%。
现在要把期权池从 10% 扩到 15%。多出来的 5 个百分点由谁承担,取决于条款怎么写。
第一种是 pre-money top-up:在下一轮融资前把池子补到 15%,仍由创始人独自承担。创始人从 55% 降到 50%,投资人仍是 35%,池子变成 15%。
第二种是 pro-rata:新发股份由所有现有股东按比例分担。设新发股份为 x,解 (10% + x) ÷ (100% + x) = 15%,得到 x = 5% ÷ 85% = 5.88% 的新股份。创始人从 55% 降到 51.94%,投资人从 35% 降到 33.06%,池子达到 15%。
| 算法 | 创始人 | 投资人 | 期权池 | 创始人额外稀释 |
|---|---|---|---|---|
| 扩张前 | 55.00% | 35.00% | 10.00% | — |
| pre-money top-up | 50.00% | 35.00% | 15.00% | 5.00 个百分点 |
| pro-rata | 51.94% | 33.06% | 15.00% | 3.06 个百分点 |
两种算法相差 1.94 个百分点。按 5,000,000 美元退出计算,1.94% 是 97,000 美元;按 10,000,000 美元退出计算,是 194,000 美元。池子越大、创始人持股越低,这个差额越明显。期权池不是「预留」出来的,它是从现有股东手里发出去的新股份;条款决定谁承担这笔发行。授予数量、四年归属和回购权见 2.2 期权池与归属 。
把三张账写成一个模型
下面的 dilution.ts 把三张账拆开:applyRounds 按轮次连乘,topUpPool 同时支持 pre-money 和 pro-rata 两种池子算法,liquidationWaterfall 把退出金额按优先清算权分配。三个函数都返回整数基点,避免浮点比例在多层计算里漂移。
// file: src/capital/dilution.ts
// tier: L1
// verify: node --test test/capital/dilution.test.ts
import { type Cents } from "../core/money.ts";
import { type Bps, applyRate, divide } from "../core/rate.ts";
import { type Result, fail, ok } from "../core/result.ts";
export type RoundDilution = {
raiseCents: Cents;
preMoneyCents: Cents;
postMoneyCents: Cents;
dilutionBps: Bps;
};
export type OwnershipAfterRounds = {
startBps: Bps;
roundDilutionsBps: Bps[];
finalBps: Bps;
totalDilutionBps: Bps;
additiveDilutionBps: Bps;
};
export type PoolInput = {
founderBps: Bps;
investorBps: Bps;
currentPoolBps: Bps;
targetPoolBps: Bps;
borneByFounders: boolean;
};
export type PoolResult = {
additionalPoolBps: Bps;
founderBps: Bps;
investorBps: Bps;
poolBps: Bps;
founderDilutionBps: Bps;
investorDilutionBps: Bps;
};
export type WaterfallInput = {
exitCents: Cents;
investedCents: Cents;
investorBps: Bps;
participating: boolean;
preferenceBps: Bps;
};
export type WaterfallResult = {
preferenceCents: Cents;
conversionValueCents: Cents;
investorProceedsCents: Cents;
founderProceedsCents: Cents;
investorMultipleBps: Bps;
};
function validBps(value: Bps, label: string): string | null {
if (!Number.isInteger(value) || value < 0 || value > 10000) {
return `${label} must be between 0 and 10000 bps`;
}
return null;
}
/** One priced round: investor share = new cash / post-money. */
export function roundDilution(
raiseCents: Cents,
preMoneyCents: Cents,
): Result<RoundDilution> {
if (!Number.isInteger(raiseCents) || raiseCents <= 0) {
return fail("raise must be a positive integer amount in cents");
}
if (!Number.isInteger(preMoneyCents) || preMoneyCents <= 0) {
return fail("pre-money must be a positive integer amount in cents");
}
const postMoneyCents = raiseCents + preMoneyCents;
return ok({
raiseCents,
preMoneyCents,
postMoneyCents,
dilutionBps: divide(raiseCents, postMoneyCents),
});
}
/**
* Round dilution compounds: (1 - d1)(1 - d2), not 1 - d1 - d2. The additive
* figure is returned only to show how far the shortcut drifts from the cap
* table.
*/
export function applyRounds(
startBps: Bps,
roundDilutionsBps: Bps[],
): Result<OwnershipAfterRounds> {
const startError = validBps(startBps, "start ownership");
if (startError) {
return fail(startError);
}
if (roundDilutionsBps.length === 0) {
return fail("at least one round is required");
}
for (const dilution of roundDilutionsBps) {
const dilutionError = validBps(dilution, "round dilution");
if (dilutionError) {
return fail(dilutionError);
}
}
let currentBps = startBps;
for (const dilution of roundDilutionsBps) {
currentBps = Math.round((currentBps * (10000 - dilution)) / 10000);
}
return ok({
startBps,
roundDilutionsBps: [...roundDilutionsBps],
finalBps: currentBps,
totalDilutionBps: startBps - currentBps,
additiveDilutionBps: roundDilutionsBps.reduce((sum, d) => sum + d, 0),
});
}
/**
* A pre-money pool top-up takes the whole increase from founders. A pro-rata
* top-up solves (current + x) / (total + x) = target and dilutes every
* existing holder, so the two conventions give different founder numbers.
*/
export function topUpPool(input: PoolInput): Result<PoolResult> {
const checks: Array<[Bps, string]> = [
[input.founderBps, "founder"],
[input.investorBps, "investor"],
[input.currentPoolBps, "current pool"],
[input.targetPoolBps, "target pool"],
];
for (const [value, label] of checks) {
const error = validBps(value, label);
if (error) {
return fail(error);
}
}
if (
input.founderBps + input.investorBps + input.currentPoolBps !==
10000
) {
return fail("founder, investor and current pool must sum to 10000 bps");
}
if (input.targetPoolBps < input.currentPoolBps) {
return fail("target pool cannot be smaller than the current pool");
}
const additionalPoolBps = input.targetPoolBps - input.currentPoolBps;
if (input.borneByFounders) {
if (input.founderBps < additionalPoolBps) {
return fail("founder does not hold enough equity for the pool top-up");
}
return ok({
additionalPoolBps,
founderBps: input.founderBps - additionalPoolBps,
investorBps: input.investorBps,
poolBps: input.targetPoolBps,
founderDilutionBps: additionalPoolBps,
investorDilutionBps: 0,
});
}
if (input.targetPoolBps === 10000) {
return fail("pro-rata top-up requires a target pool below 10000 bps");
}
const newShareUnits =
(10000 * additionalPoolBps) / (10000 - input.targetPoolBps);
const newTotalUnits = 10000 + newShareUnits;
const founderBps = Math.round(
(input.founderBps * 10000) / newTotalUnits,
);
const investorBps = Math.round(
(input.investorBps * 10000) / newTotalUnits,
);
return ok({
additionalPoolBps,
founderBps,
investorBps,
poolBps: input.targetPoolBps,
founderDilutionBps: input.founderBps - founderBps,
investorDilutionBps: input.investorBps - investorBps,
});
}
/**
* A 1x non-participating preference is a floor the investor abandons when
* conversion pays more. A participating preference takes the floor and then
* shares the remaining exit, so the same headline stake pays differently.
*/
export function liquidationWaterfall(
input: WaterfallInput,
): Result<WaterfallResult> {
if (!Number.isInteger(input.exitCents) || input.exitCents < 0) {
return fail("exit must be a non-negative integer amount in cents");
}
if (!Number.isInteger(input.investedCents) || input.investedCents <= 0) {
return fail("invested amount must be a positive integer amount in cents");
}
const investorError = validBps(input.investorBps, "investor ownership");
if (investorError) {
return fail(investorError);
}
if (
!Number.isInteger(input.preferenceBps) ||
input.preferenceBps <= 0
) {
return fail("preference must be a positive integer in basis points");
}
const preferenceCents = applyRate(
input.investedCents,
input.preferenceBps,
);
const conversionValueCents = applyRate(
input.exitCents,
input.investorBps,
);
let investorProceedsCents: Cents;
if (input.exitCents <= preferenceCents) {
investorProceedsCents = input.exitCents;
} else if (input.participating) {
investorProceedsCents =
preferenceCents +
applyRate(input.exitCents - preferenceCents, input.investorBps);
} else {
investorProceedsCents = Math.max(
preferenceCents,
conversionValueCents,
);
}
return ok({
preferenceCents,
conversionValueCents,
investorProceedsCents,
founderProceedsCents: input.exitCents - investorProceedsCents,
investorMultipleBps: divide(
investorProceedsCents,
input.investedCents,
),
});
}
代码里最关键的是 applyRounds 的循环:每一轮都用上一轮的结果乘 (1 − 本轮稀释),而不是从 100% 重新开始。topUpPool 的 pro-rata 分支解的是新发股份方程,不是简单地把 5 个百分点从创始人身上扣掉;这正是两种算法产生 1.94 个百分点差额的原因。
治理代价:席位、否决权、信息权、优先清算权
稀释只改变了「谁拥有多少」,治理条款改变的是「谁能决定什么」。四类条款最常见,也最容易在融资时被低估。
第一是董事会席位。三人董事会通常是一个创始人席位、一个投资人席位、一个独立席位;创始人不再拥有单方面控制权。两轮融资后如果有两家机构,五人董事会可能变成两个创始人席位、两个投资人席位、一个独立席位,独立席位在僵局时决定方向。席位的具体谈法见 3.3 董事会、观察员与信息权 。
第二是否决权。投资人通常会对预算、超过一定金额的招聘或采购、新增债务、并购、增发股份等事项要求否决权。这些条款不改变持股比例,但会把一些原本可以由创始人单方面决定的事,变成必须协商的事。
第三是信息权。月度管理报表、年度预算、股权结构表、重大合同变更,通常都要按约定频率提供。按每月两天、每年二十四天、创始人年薪 60,000 美元、每年 260 个工作日计算,信息权的时间成本大约是 24 × (60,000 ÷ 260) = 5,538 美元/年。这个数字不大,但它是一项持续义务,不会因为公司变小而消失。
第四是优先清算权,也是四类条款里最能用数字检验的一项。为了单独看优先清算权,这里先按两轮后的 65%/35% 计算,暂不计期权池;假设两轮累计融资 1,400,000 美元,投资人合计持股 35%,条款是 1x 优先清算权。退出时,投资人先拿 1,400,000 美元,再按参与与否分配剩余部分。
| 退出估值 | 非参与:投资人 | 非参与:创始人 | 参与:投资人 | 参与:创始人 |
|---|---|---|---|---|
| $3,000,000 | $1,400,000 | $1,600,000 | $1,960,000 | $1,040,000 |
| $5,000,000 | $1,750,000 | $3,250,000 | $2,660,000 | $2,340,000 |
在 3,000,000 美元退出时,参与型优先清算权让投资人多拿 560,000 美元,创始人少拿 560,000 美元;560,000 美元是原始种子轮 300,000 美元的 1.87 倍。在 5,000,000 美元退出时,差额扩大到 910,000 美元。持股比例仍是 65%,但「65% 的什么」被优先清算权改写了。
稀释之后还剩什么
65% 的股份是不是比 100% 的股份更值钱,取决于公司变大了多少。无融资时,创始人按案例锚 3.2× ARR = 768,768 美元退出,拿到全部 768,768 美元。融资后,创始人持股 65%,但投资人先拿 1,400,000 美元优先额;退出介于 1,400,000 和 4,000,000 美元之间时,创始人拿到「退出金额减 1,400,000 美元」,低于 1,400,000 美元时拿 0。
要拿到和无融资时相同的 768,768 美元,退出金额必须达到 768,768 + 1,400,000 = 2,168,768 美元,是当前 768,768 美元锚的 2.82 倍。这就是融资后的真实门槛:不是「公司变大一点」,而是「公司至少变大到 2.17 百万美元,创始人才在绝对金额上不输给不融资的自己」。这里先按两轮后的 65% 计算,暂不计期权池;把 15% 期权池算进去,创始人只剩 50% 到 51.94%,门槛只会更高。
| 退出估值 | 无融资:创始人 100% | 有融资:创始人 65%,1x 非参与 | 创始人差额 |
|---|---|---|---|
| $768,768 | $768,768 | $0 | −$768,768 |
| $1,400,000 | $1,400,000 | $0 | −$1,400,000 |
| $2,168,768 | $2,168,768 | $768,768 | −$1,400,000 |
| $4,000,000 | $4,000,000 | $2,600,000 | −$1,400,000 |
| $5,000,000 | $5,000,000 | $3,250,000 | −$1,750,000 |
这张表不是说服创始人不要融资,而是把「融资后的目标」写清楚:融资买的是速度,速度必须把退出估值推过优先清算权的门槛,否则创始人让渡了 35% 的股份,却在绝对金额上什么也没换来。估值增长、优先清算权倍数、参与条款,三者共同决定这条门槛;只看持股比例,会低估门槛的高度。
小结
- 稀释是乘法:种子轮 16.67% 加 A 轮 22.00%,创始人留下 65.00%,不是 61.33%;两轮各 20% 留下 64%,不是 60%。
- 期权池从 10% 扩到 15%,pre-money top-up 让创始人从 55% 降到 50%,pro-rata 降到 51.94%;两种算法相差 1.94 个百分点。
- 治理代价包括董事会席位、否决权、信息权和优先清算权;信息权按每年 24 天、日成本 231 美元计算,约 5,538 美元/年。
- 1x 优先清算权下,3,000,000 美元退出时参与型比非参与型多拿 560,000 美元,正好是种子轮 300,000 美元的 1.87 倍。
- 融资后的真实门槛是 2,168,768 美元退出:只有超过这条线,创始人才在绝对金额上不输给不融资的 768,768 美元。
阅读导航:上一节:1.1 自力更生、借款、股权融资 · 下一节:1.3 什么时候不该融资 。
常见错误与边界
- 把每轮稀释比例直接相加。 16.67% + 22.00% = 38.67% 会算出创始人只剩 61.33%;正确结果是 65.00%,因为第二轮按缩小后的基数计算。
- 用 pre-money 算 A 轮稀释。 1,100,000 ÷ 3,900,000 = 28.21% 是错的;正确分母是 post-money 5,000,000,稀释是 22.00%。
- 把期权池当成「预留」而不是新发股份。 池子从 10% 扩到 15% 需要发行新股,稀释一定由某方承担;pre-money top-up 和 pro-rata 的差别是 1.94 个百分点。
- 只算持股比例,不算优先清算权。 65% 的股份在 3,000,000 美元退出时可能只拿到 1,040,000 美元,因为投资人先拿 1,400,000 美元优先额。
- 把 1x 优先清算权当成「只拿回本金」。 参与型条款会在拿回本金后继续按比例分配;3,000,000 美元退出时,参与型比非参与型多拿 560,000 美元。
- 忽略信息权的持续成本。 每月两天、每年 24 天、日成本 231 美元,约 5,538 美元/年;金额不大,但它是长期义务。
- 把董事会席位当成「顾问角色」。 三人董事会里投资人占一席,创始人就失去了单方面控制;两轮融资后,独立席位可能成为决定方向的一票。
- 用「公司估值涨了」代替「创始人到手涨了」。 融资后的门槛是 2,168,768 美元退出;低于这条线,创始人绝对金额不如不融资。
- 忽略轮次数量对复利稀释的影响。 每轮 20% 的稀释,三轮后留下 51.2%;减少一轮或提高轮间估值,比在单轮里争 1 个百分点更有效。
- 把本节的比例当成真实报价。 种子轮 16.67%、A 轮 22.00%、期权池 10% 到 15% 都是教学假设;真实条款的治理细节需要专业意见,本节只做算术。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。