$LP24 & Vesting
$LP24 is the protocol token. It is launched by the same factory, on the same curve, under the same rules as any other token — with three deliberate exceptions.
LP24 is the protocol — the factory, the curves, the hooks. $LP24 is the token symbol of the protocol token those contracts launch. Contract code refers to it as PROTOCOL_TOKEN, and the factory function that creates it is deploy_protocol_token(); neither identifier changes.
One-shot deployment
The factory has a separate entry point, deploy_protocol_token(name, symbol), callable exactly once and only by the system deployer. It uses CREATE rather than CREATE2, so the resulting address depends only on the factory address and its internal nonce — not on a salt.
That is why the factory reserves its first internal deployment slot: deploy_pair() reverts with Protocol token not yet deployed until the protocol pair exists. The deployer key was mined so that the factory sits at a nonce where its first CREATE lands on a 0x24 address, and a user deployment slipping in first would consume that slot.
Factory.deploy_protocol_token(name, symbol)
├─→ assert msg.sender == system_deployer
├─→ assert not protocol_deployed // permanent one-shot lock
├─→ token = create_minimal_proxy_to(token_master) // no salt
├─→ curve = create_minimal_proxy_to(bonding_curve_master)
├─→ TokenTemplate.initialize(name, symbol, curve, system_deployer, vesting_contract)
└─→ BondingCurve.initialize(token, system_deployer, True) // msg.value == 0
No fee is charged, no socials record is created, and the initial mint goes to the vesting contract rather than to a wallet.
How $LP24 differs
| Regular token | $LP24 | |
|---|---|---|
| Deployment | deploy_pair, CREATE2 + salt | deploy_protocol_token, CREATE, once |
| Deployment fee | Charged | None |
| Initial mint recipient | Deployer wallet | TokenVesting contract |
| Refund mode | Available after 3 days | Never — FLAG_PROTOCOL blocks it |
| Graduation envelope | Split 90/10 across two pools | Full envelope, one pool — it cannot pair with itself |
| Swap fees | Split 30 / 10 / 60 | 100% to protocolBalance |
| Deployer fee share | Yes | None — withdrawDeployerFees rejects it |
| CTO eligible | Yes | No — rotating its deployer has no fee effect, so allowing it would only enable cheap griefing |
| Secondary pool | Yes (V4 family) | No |
Same address on every chain
Because the protocol pair is created by CREATE at a known factory nonce, and the factory itself is deployed at a mined nonce on each chain, $LP24 lands on the same address across all 5 deployments. One address, five chains, four native assets — Base and Robinhood both price it in ETH, so those two pools are directly comparable without a cross-asset leg.
Where protocol fees go
protocolBalance accumulates from several sources:
- 10% of every token's distributed swap fees (20% on Gnosis)
- 100% of $LP24's own swap fees
- 10% of curve fees at graduation, and 10% of curve fees on refund
- Unclaimed refunds swept after the claim window
- CTO vote fees
- Native excess and dust that would otherwise become untracked contract balance
Anyone may call processProtocolFees(). It buys $LP24 and burns it when the pool holds enough tokens, and deepens the pool when it does not. See Fee Distribution.
TokenVesting
The protocol token's 60,000,000 × 10⁹ (60M) initial mint is sent to an ownerless vesting contract at deployment. It has no owner, no emergency withdrawal, and no admin function of any kind. The schedule is fixed at construction and cannot be altered.
| Parameter | Value |
|---|---|
CLIFF_WEEKS | 24 weeks |
TOKENS_PER_WEEK | 240,000 × 10⁹ (240k tokens) |
SECONDS_PER_WEEK | 604,800 |
| Beneficiary | Immutable, set at construction |
| Start | block.timestamp at construction |
Nothing is releasable for the first 24 weeks. After that, 240,000 × 10⁹ (240k tokens) become releasable per elapsed week, capped by the contract's balance. release() is callable by anyone — it always pays the beneficiary, so there is nothing to gain by calling it and nothing to lose by someone else doing so.
The vesting contract's beneficiary, start time and total released are all public view functions. Anyone can confirm that the protocol's initial allocation is subject to the schedule described here rather than sitting in a wallet.