Control and safety
Creator controls
A creator sets the terms once, before predict. The launch freezes them. After launch the creator holds the
token's page and the veto over a payout change, and nothing else.
What you set
| choice | where | bound |
|---|---|---|
| the stock | request.stock | a listed stock |
| name, symbol | request | |
| the tax | request.taxBps | 100 to 1500 |
| your share of the tax | request.creatorBps | 0 to 5000 |
| the strategy kind | V2TreasuryDeployer.setStrategyKind(symbol, nonce, kind) | 1 to 5; kind 0 needs no call |
| the strategy numbers | request.tp1Bps, tp2Bps, dipBps, stopBps, lotBps (Lots family); setEngineConfig(symbol, nonce, kind, config) (Spot, Rebalance) | the bounds and floors on Concepts |
| the opening window | CurveDeployer.setCurveConfig(symbol, nonce, 7931, snipeSeconds) | 0 to 180 s; default 3 |
| opening-premium exemptions | CurveDeployer.setOpeningTaxExemptions(symbol, nonce, recipients) | up to 40 |
| the staleness band | request.bandBpsPerHour | 0 to bandCeiling(stock) |
| the payout address | request.creator | an EOA or a Safe that can call vetoCreator |
| the token's page | launchWithMetadata(..., metadata) | logo, description, five links |
Every registration is keyed by keccak256(abi.encode(symbol, msg.sender, nonce)), the salt the factory derives
from (symbol, creator, nonce). A registration from another address lands under that address's salt and never
reaches your launch. A registration can be changed until the launch and not deleted; changing one after predict
makes launch revert Restated, and registering the quoted values again repairs the quote.
What you do not set
The sale share (79.31%), the LP share (70% of the raise, per stock), the opening price ($2,140.38 FDV at
listing), the protocol's share (30%), the pool fee (0.20%), the keeper reward, the buy-back pacing, the gates,
the oracle and the pool. All of them come from the factory's defaults and the listing, and all of them are in
terms.
Frozen at launch
Hashed into terms and immutable afterwards: supply; opening price; sale share; opening window and exemptions;
tax; creator share; protocol share; pool fee and tick spacing; strategy kind and its numbers or engine words;
lpBps; the listing's oracle and V3 pool; the gates and the sell chunk; the keeper reward; the buy-back
parameters; the minimum lot. The curve's fee recipients are immutable. The treasury's logic can be replaced by
the owner through the two-day controller; its numbers cannot.
After launch
- The token's page. The launching address owns the metadata, may appoint one editor and may lock it for good. The protocol has no power over it.
- The veto. If the owner proposes a new creator payout for your pool, one
vetoCreatorcall ends it and bars a new proposal for 180 days. Use an address that can make that call. - A first buy. Your own buy skips the opening premium and pays the tax; through
launchAndBuyit sits in the launch transaction.
You cannot withdraw the treasury's stock, the pool's liquidity or the curve's reserve; change the tax, the split or the strategy numbers; or pause trading.
Owner and upgrades
The factory's owner is a Safe. It lists stocks, sets the defaults future launches freeze, and holds a bounded set of powers over launches that already exist. Ownership moves through a two-step transfer; renouncing it is disabled.
For future launches
| call | what it sets |
|---|---|
setDefaults | the whole Defaults struct: tax bounds, splits, pool fee, gates, keeper reward, buy-back pacing, launch fee |
list, setListingGates, setBandCeiling | listings, their gates and band ceilings |
V2TreasuryDeployer.setLpBps | the per-stock LP share, 10% to 100% |
setLauncher, setPublicLaunch | which routers may launch on a creator's behalf; whether launching is public |
registerKind, registerEngineKind, registerPolicy | append a strategy kind or a policy; never remove one |
disablePolicy | stop new launches on a policy; launched treasuries keep theirs |
A launch quoted before any of these reverts Restated. Nothing launched is touched.
The upgrade controller
Kinds 0 to 6 are proxies whose implementation pointers live in V2TreasuryUpgradeController, so writing a
proxy's storage cannot change its logic.
| step | call | rule |
|---|---|---|
| 1 | schedule(treasury, implementation, migrationCalldata) by the owner | records the implementation's runtime code hash, the calldata hash, the current ownershipEpoch and readyAt = now + UPGRADE_DELAY (2 days) |
| 2 | execute(treasury, migrationCalldata) by anyone, after readyAt | the candidate must have the recorded code hash, report the same config hash and storage-schema identifier as the treasury, and the calldata must hash to the recorded value; a failed migration reverts the change and the proposal together |
cancel(treasury) by the owner | before execution | |
| a completed factory ownership handover | increments ownershipEpoch; every pending proposal becomes invalid, including A→B→A |
An approved implementation can change treasury custody and strategy behaviour. The hash checks are identity checks and not a review of the new code. An upgrade cannot change the frozen numbers, because the candidate must report the same configuration hash. The liquidity vault has no upgrade or removal path, whatever happens to the treasury.
Over a live launch
| power | bound |
|---|---|
| schedule a treasury logic upgrade | the controller: 2-day delay, matching hashes, same configuration |
| halt trading through the calendar | an unscheduled market closure; the price stays the oracle's |
setProtocol(poolId, to) | the protocol's own payout address for a pool |
proposeCreator(poolId, to) | 14 days on chain; the creator's vetoCreator ends it and bars a new proposal for 180 days |
What the owner cannot do
Remove liquidity from the vault; withdraw from a treasury or the curve; change a frozen rate, split or strategy number; move a curve's fee recipients; open a pool on the hook that the factory did not launch; change the sale share.
Safety and recovery
Most of the protocol has no privileged operator. When something is wrong the contracts wait, refuse, or roll back, and the calls that resume are open to anyone.
| situation | what happens | who can act |
|---|---|---|
| the stock feed is stale (nights, weekends, holidays) | health() is false; book(), execute() and stops do not run; the token keeps trading; buyback() keeps working off the token pool | anyone, once the feed is fresh |
oraclePaused() (a corporate action) | the same | anyone, once the issuer's pause ends |
| the market is closed by the calendar | the same, unless the launch carries a staleness band; a stop never fires on a pool-only price | anyone, at the open |
| the stock pool is pushed off the oracle | health() is false while spot is more than 0.5% from the oracle or from the pool's 600 s mean | anyone, once arbitrage re-pegs it |
| the owner halts a day through the calendar | the stock leg trades nothing that day | the owner, to lift it |
| the raise is larger than the stock pool can deliver | the curve can never reach Rg; it stays Active and holders sell back to it | nobody on chain; the listing check refuses such listings before launch |
| a step inside graduation fails | the crossing buy rolls back entirely; the curve stays Active | the next buyer retries by buying |
| graduation stock cannot be booked at once | it waits as unbookedStock() | anyone calls book() when the feed is live |
| the stock issuer refuses delivery to the treasury | the vault keeps the stock and retries on the next collectFees(); the token burn still completes | anyone, by calling again |
| a fee recipient is blocked by the stock issuer | the other recipients' claims and trades are unaffected; the blocked claim waits | the recipient, once unblocked |
| the treasury has 128 lots | booking and dip buys pause; stops and take-profits still execute | anyone, by executing a due sale |
| the keeper falls behind | actions stay due; nothing is lost | anyone sends them and keeps the reward |
| the creator's payout address goes silent | the owner may propose a new one after 14 days on chain | the creator vetoes; anyone accepts after the delay |
| a treasury's logic needs replacing | the owner schedules it with two days' notice | anyone executes after the delay; the owner cancels before |
What never happens
- Nobody removes the vault's liquidity. The vault has no function for it, and the hook's
beforeRemoveLiquidityreverts for everyone. - Nobody withdraws from a treasury. Stock and USDG leave it only through its strategy's trades and buy-backs.
- Nobody opens a pool on the hook that the factory did not launch:
beforeInitializeandbeforeAddLiquidityanswer only for a registered pool and only to its vault. - Nobody taxes a transfer of the token. The hook sees swaps only.
Who can act
| call | who | when |
|---|---|---|
book(), execute(), buyback() | anyone | when due |
claimFees(recipient), sweep(poolId), collectFees() | anyone | when fees are waiting |
graduate(id) | anyone | only for a curve already Ready |
vetoCreator(poolId) | the creator | during a payout proposal |
the calendar halt, setProtocol, proposeCreator, the upgrade controller | the owner | as bounded on owner and upgrades |
Risk disclosures
- The treasury is long one stock. Every strategy holds its stock through a fall. None sells on the way down without a creator-set stop, and a Buy-back treasury never sells.
- Graduation is not guaranteed. A curve that never reaches
RgstaysActive, and its holders can only sell back to the curve. A raise larger than the stock's V3 pool can deliver can never graduate. - Exit depth. Early curve buyers exit into a pool that holds 70% of what was paid in, plus what later buyers add. What a sale realises depends on the pool's depth against the token float.
- A burn is not a price floor. A smaller supply helps the price only if someone still wants the token.
- The owner can change treasury logic after two days' public notice. An approved implementation can change custody and strategy behaviour; the hash checks are identity checks, not a review. The locked liquidity is outside that power.
- The stock token is upgradeable by its issuer, who can pause or deny-list transfers. A treasury's holdings, the vault's stock and every fee claim depend on that token.
- Holders have no claim on the treasury (none today; one may be added later). No redemption, no dividend.
- Review status. The release had internal reviews, fuzzing and fork rehearsals, listed on audits. No external audit report of the v2 code is published.
- A launch is not an endorsement by the stock's issuer, by the protocol or by anyone. Anyone may launch on any listed stock under any name.
- Legal status is unassessed. A token whose treasury accumulates tokenized equities has not been reviewed by counsel. The product is closed to U.S. persons and sanctioned jurisdictions: who may not use it.
Nothing here is investment advice, an offer to sell or a solicitation to buy anything. A Hedgefun is not a fund: no shares, no net asset value, no redemption, no manager. Terms of Use.
Audits
No external audit report of the v2 code is published. The v2.0 tag carries internal engineering reviews, fuzz and invariant campaigns, and fork rehearsals. Each document says so itself: "an internal engineering review, not an external audit", "local reviews are not a third-party audit". The list is what exists at the tag.
Review rounds
| review | date | scope | verdict as recorded |
|---|---|---|---|
Adversarial review (V2_ADVERSARIAL_REVIEW.md) | 2026-09-23 | the v2 curve, factory, hook and treasury paths at 885123e; three review lanes; multi-user ordering, callback defences, independent accounting, a live-venue fork | GO for code review and integration at that ref; not an approval of later changes |
Dual-engine review (V2_DUAL_ENGINE_REVIEW.md) | historical | the move to graduation funding both a pool and a treasury, the fee vault and its risks | superseded by the two-sided-fee change |
Release and testnet reviews (V2_RELEASE_REVIEW_2026_09_29.md, V2_TESTNET_REVIEW.md) | 2026-09-29 | deployment, recipient permissions, creator identity, oracle and calendar configuration, launch flow | conditional GO for the public testnet pilot; NO-GO for mainnet at that snapshot |
| Audit rounds 1 to 4 | up to 2026-09-27 | issue lists in the upstream repository's audit/ folder; round 3 (M-2, M-3) produced the listing check, round 4 produced the engine floors and the tax and raise decisions | findings addressed in source and procedure, as cited in STRATEGY_ENGINE.md, SpotEngineConfig.sol and V2_DEPLOYMENT_REHEARSAL.md |
Cycle review and audit record (V2_CYCLE_INTEGRATION_REVIEW.md, V2_SIMPLE_CYCLE_AUDIT.md) | 2026-10-03 | the Cycle kind and its integration with dust handling | GO, one P2 found and fixed |
Fuzzing and fork campaigns
FUZZ_TESTNET_2026-10-03.mdandV2_FUZZ_SUPPLEMENT_REPORT.md: Foundry fuzz and stateful invariants on the percentage caps, cost accounting and dust handling, plus a public-testnet transaction loop.docs/fuzz/: the upgradeable-kinds campaign of 2026-10-04 (offline suite, three seeded income and upgrade campaigns, storage-layout comparison, a 21-scenario testnet fork) and the treasury-profile campaign with independent audit logs.V2_DEPLOYMENT_REHEARSAL.mdand the release runbook: fork rehearsals of the mainnet deployment and the end-to-end fork suite, nine tests from deployment through one launch per kind to every strategy action against the real pool and oracle, on the release commit.- The repository's test suites, including
V2CurveSecurity.t.sol,V2TradablePercentAudit.t.soland the adversarial suites named in the reviews.
What this means
The contracts have been reviewed by their authors and by separate internal lanes, fuzzed, and rehearsed on forks. They have not been audited by an outside firm. A launch is immutable once live except for the treasury's logic, which the owner can replace with two days' notice. Treat the review status as one of the risks.
Support
| team@hedgehood.app | |
| X | @0xHedgehood |
| Security contact | — |
| Bug bounty | — |
| Status page | — |
| Contracts repository | the Hedgefun-trade repository, tag v2.0 |
Report a vulnerability by email before disclosing it anywhere else. The rows marked "—" are not set up yet and will be filled in when they are.
Nothing here is investment advice. Terms of Use, Privacy Policy.