Statics begins with a standalone Doppler fixed-supply token, fully backed Genesis NFT vault, and permanent Uniswap v4 Multicurve market. The later multi-asset protocol uses two coordinated EIP-2535 Diamonds for baskets, Statics Dollar, PositionNFT accounts, global rewards, lending, flash loans, and canonical v4 liquidity.
For a plain-language introduction, see the value proposition
and worked examples. The repository also publishes an
LLM-oriented protocol index. For protocol invariants, accounting,
and lifecycle details, see Statics-Design.md, the
architecture guide, and the
integration guide. See the
current deployment record for a human-readable summary, and
the Robinhood testnet manifest
for the canonical machine-readable integration-beta state.
- Highlights
- Architecture at a Glance
- Repository Layout
- Prerequisites
- Setup
- Build
- Test
- Deploy
- Core Concepts
- Common Flows
- Configuration Reference
- Conventions & Contributing
- License
| Capability | Summary |
|---|---|
| Standalone Genesis | All 5,555 marketplace-compatible Genesis NFTs start in vault inventory and are mechanically paired with 180,000 STATICS each plus, after the immutable Genesis Epoch, a 1/5,555 share of a permanent native ETH reserve; STATICS backing stays exact and Diamond-independent while the reserve grows from protocol revenue and donations and can never be withdrawn. |
| Permanent STATICS/WETH market | Doppler Multicurve distributes the 800-million public allocation; fees earned by its launch positions route 5% to the Doppler/Airlock owner and 95% to permanent Statics fee ingress. |
| Unified integration address | StaticsDiamond is the ordinary user action surface, PositionNFT ERC-721, and custody address for basket and Dollar periphery assets. |
| Static baskets | Each permit-enabled StaticsBasketToken represents a creator-defined vector of up to 16 assets with fixed bundle amounts and action-size fee tiers. |
| Statics Dollar | StaticsDollarCoreDiamond manages volatile and pegged collateral profiles, senior issuance, Risk Shares, solvency, transitions, insurance, and recovery. |
| Shared PositionNFT | One transferable ERC-721 position can own Dollar legs, basket collateral, loans, and selected global rewards. |
| Global rewards | Positions stake the configured Statics token and select up to 64 reward assets; new selections cannot capture historical fees. |
| Self-backed lending | Basket collateral releases its proportional constituent vector at a basket-defined LTV, with independent loan tranches, extension, repayment, and permissionless expiry recovery. |
| Flash composition | Basket vectors or individual Diamond-held assets can be borrowed through dedicated typed callbacks while nested flash loans remain blocked. |
| Canonical v4 liquidity | Basket creators choose each constituent pool's static native LP fee, tick spacing, price, and seed while the mandatory Statics hook charges governed bilateral input/output fees. |
| Permissionless general pools | Anyone can create a Statics-hook pool between two compatible ERC-20s or native ETH and an ERC-20, gated by an independent creation fee and EIP-712 creator authorization, selecting the native LP fee, tick spacing, and initial price, with a fixed 500-bps perpetual creator share and no mandatory liquidity seed. |
| Managed protocol liquidity | Settled POL inventory funds PoolId-bound PositionManager NFT portfolios; strategy can manage explicit ranges but cannot redirect protocol principal, refunds, or NFTs. |
| Governed lifecycle | A shared timelock owns both Diamonds; guardians can restrict exposure while repayment, recovery, and exit paths remain available. |
┌────────────────────────────────────┐
ETH / WETH ─────▶│ StaticsDollarCoreDiamond │
pegged collateral ▶│ collateral + issuance + solvency │
│ insurance + transition + recovery │
└───────────────┬────────────────────┘
│
Statics Dollar + Risk Shares
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ StaticsDiamond (EIP-2535) │
│ user gateway + PositionNFT ERC-721 + shared custody │
│ │
│ ├─ Basket creation / mint / redemption / lifecycle │
│ ├─ Basket collateral / lending / repayment / recovery │
│ ├─ Global Statics staking + selected multi-asset rewards │
│ ├─ Dollar gateway + pairing-risk liquidity │
│ ├─ Basket-vector and single-asset flash loans │
│ └─ Canonical-pool configuration + liquidity-position rewards │
└──────────────────────────────┬─────────────────────────────────────┘
│
one pool per basket constituent
│
▼
Uniswap v4 PoolManager + PositionManager
│
StaticsSwapFeeHook + LiquidityManager
bilateral fees + permanent full-range POL
StaticsDiamond is the normal integration address, but the Dollar Core remains a separate custody and solvency boundary. Both Diamonds are owned by the same StaticsTimelock. Each basket has its own transferable ERC-20 token; module accounting and physical-token reservations remain isolated inside the Diamond.
statics/
├── src/
│ ├── diamond/ # Statics Diamond kernel and initialization
│ ├── facets/ # Basket, rewards, lending, flash, and liquidity facets
│ ├── position/ # Shared PositionNFT storage and ERC-721 facet
│ ├── dollar/
│ │ ├── core/ # Dollar Core facets, accounting, solvency, recovery
│ │ ├── periphery/ # Shared-Diamond Dollar gateway and staking facets
│ │ ├── interfaces/ # Dollar integration interfaces and types
│ │ └── testnet/ # Explicit public-testnet oracle fixtures
│ ├── liquidity/ # v4 hook, liquidity manager, and pool accounting
│ ├── genesis/ # Genesis vault, activation, Doppler ingress, and launch rewards
│ ├── metadata/ # Genesis artwork and PositionNFT logo metadata
│ ├── periphery/ # Typed flash-arbitrage receiver
│ ├── governance/ # Statics timelock
│ ├── tokens/ # Basket and Statics staking tokens
│ ├── testnet/ # Public-testnet faucet
│ ├── interfaces/ # User and integration interfaces
│ └── libraries/ # Shared storage, custody, fee, and math libraries
├── script/ # Deployment, upgrade, governance, and launch scripts
├── scripts/ # Operational and focused security helpers
├── test/
│ ├── basket/ # Basket lifecycle and custody flows
│ ├── dollar/ # Unit, integration, property, and fork coverage
│ ├── liquidity/ # v4, flash, POL, lending, and fork coverage
│ ├── rewards/ # Global and basket reward behavior
│ ├── invariant/ # Cross-module stateful invariants
│ └── deployment/ # Launcher, manifest, and ceremony proofs
├── sdk/ # TypeScript ABIs, decoders, builders, and chain bindings
├── deployments/ # Pinned dependency and public testnet manifests
├── docs/ # Architecture, integration, deployment, and ADRs
├── Statics-Design.md # Full protocol design document
├── SECURITY.md # Authority, custody, and liveness assumptions
├── foundry.toml # Compiler, optimizer, fuzz, and invariant profiles
└── remappings.txt
- Foundry (
forge,cast,anvil) - Node.js and npm for the TypeScript SDK
- Solidity
0.8.33for Statics production sources - Cancun-compatible EVM support; the v4
PositionManagerdependency uses its pinned Solidity0.8.26compiler profile
OpenZeppelin, Forge Standard Library, Uniswap v4, and the TypeScript SDK are pinned git submodules. Initialize the complete dependency tree after cloning:
git submodule update --init --recursive
npm ci --prefix sdkThe principal remappings are:
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/
@uniswap/v4-core/=lib/v4-periphery/lib/v4-core/
@uniswap/v4-periphery/=lib/v4-periphery/
forge-std/=lib/forge-std/src/
permit2/=lib/v4-periphery/lib/permit2/
Copy .env.example into an ignored environment file and populate only the values required for the intended local, fork, or deployment operation. Never commit broadcaster keys, mnemonics, RPC credentials, or populated environment files.
forge build
npm run build --prefix sdkStatics and its v4 dependencies are large. Do not run
forge build --force,forge build --contracts, orforge cleanduring normal iteration. Prefer incremental compilation through path-scoped tests.
Run focused paths while iterating:
# Basket lifecycle and measured custody
forge test --match-path test/basket/BasketLifecycle.t.sol -vv
# Statics Dollar gateway behavior
forge test --match-path test/dollar/unit/StaticsDollarGateway.t.sol -vv
# Canonical hook fee accounting
forge test --match-path test/liquidity/StaticsSwapFeeHook.t.sol -vv
# Standalone Genesis vault and Doppler launch rewards
forge test --match-path test/genesis/StaticsGenesisVault.t.sol -vv
forge test --match-path test/genesis/GenesisLaunchRewards.t.sol -vv
forge test --match-path test/deployment/DeployStaticsGenesis.t.sol -vv
# Shared PositionNFT behavior
forge test --match-path test/position/PositionNFT.t.sol -vv
# Full Genesis rewards, Position linkage, recovery, and governed handoff
forge test --match-path test/genesis/GenesisPositionIntegration.t.sol -vv
forge test --match-path test/deployment/ConfigureStaticsGenesis.t.sol -vv
# SDK surface
npm test --prefix sdkTest organization:
test/genesis/: standalone backing, issuance, metadata, v4 launch, fee, and invariant coverage.test/basket/,test/rewards/,test/position/: focused module and real-flow coverage.test/dollar/unit/andtest/dollar/integration/: Core/periphery state machines and launch-level flows.test/liquidity/: canonical pools, hook accounting, POL, lending composition, and flash behavior.test/invariant/andtest/dollar/properties/: stateful invariants and fuzz properties.test/deployment/: complete launcher, selector, manifest, timelock, and genesis-ceremony proofs.test/**/fork/: environment-gated checks against pinned external chain state.
The default profile uses 1,000 fuzz runs and 256 invariant runs at depth 50. The security profile enables fail-on-revert invariants with 128 runs at depth 64.
Robinhood mainnet fork tests read ROBINHOOD_MAINNET; testnet fork tests read
ROBINHOOD_TESTNET or ROBINHOOD_TESTNET_RPC_URL. A missing RPC causes
environment-gated tests to skip unless the matching REQUIRE_* flag is
enabled.
The standalone Genesis release has a current-network integration proof for the official Robinhood Doppler modules:
ROBINHOOD_MAINNET="$ROBINHOOD_MAINNET" \
REQUIRE_DOPPLER_FORK_PROOF=true \
forge test \
--match-path test/genesis/fork/DopplerGenesisLaunchFork.t.sol \
-vvThis proof calls the official Airlock creation path, validates all configured modules, creates the four-curve pool, proves the exact 5%/95% beneficiary shares, executes a v4 swap, harvests the resulting launch-position fees, and checks the token allocation, fee ingress, activation consumer, vault, Genesis reward, and treasury-revenue wiring. A missing RPC skips its corresponding network; an executed pass is separate evidence from the default skipped path. The required-proof flag turns either missing RPC into a failure for release verification.
Run the focused deployed-router proof with:
ROBINHOOD_MAINNET="$ROBINHOOD_MAINNET" \
forge test \
--match-path test/liquidity/fork/RobinhoodStaticsLiquidityFork.t.sol \
-vvThis path exercises Robinhood's deployed Quoter, Universal Router, Permit2, and hooked canonical pools. Treat an executed pass separately from local-only coverage or an environment-gated skip.
A fresh standalone Genesis replica can use a separate ownerless faucet that dispenses 200,000 STATICS per wallet every 24 hours. The funding command quotes an exact-output purchase from that replica's Doppler pool, permits at most 1% input slippage, refuses to spend more than 0.012 testnet ETH, and funds exactly one initial claim. Anyone may refill the faucet later, including from released Treasury vesting.
export STATICS_GENESIS_TESTNET_ARTIFACT=artifacts/genesis-testnet/<run>/genesis.json
export ROBINHOOD_TESTNET_RPC_URL=...
export PRIVATE_KEY=...
scripts/deploy-genesis-testnet-faucet.sh --broadcast
export STATICS_GENESIS_FAUCET_ADDRESS=0x...
scripts/deploy-genesis-testnet-faucet.sh --check- Use unit harnesses for narrow branches, storage checks, and otherwise-unreachable edges.
- Use real approvals, transfers, mints, redemptions, borrows, repayments, extensions, recoveries, flash loans, and governance calls for value-moving lifecycles.
- Use fuzz and invariant suites to broaden coverage, not replace real-flow proof.
- Keep synthetic state shortcuts narrow and document why the corresponding state is impractical to reach economically.
- Every code change must include behavior-focused regression coverage.
The standalone Genesis launcher is
script/DeployStaticsGenesis.s.sol:DeployStaticsGenesis. It commits an explicit
Prepare -> Launch -> Finalize ceremony. Prepare deploys only the permanent fee
receiver and immutable treasury vesting contract. Launch is one zero-value,
canonical Airlock.create() transaction that creates the one-billion-STATICS
token and live six-curve market with 800 million STATICS of inventory. Finalize
installs the activation registry, vault, Statics Operators collection, and
temporary launch distributor; accounts for exactly 99.9 million STATICS of Vault
backing; and starts immutable vesting for the 100.1-million-STATICS principal.
It does not deploy or require the Statics Diamonds.
Robinhood runPrepare() and runLaunch() remain compile-time locked until a
follow-up decision pins the approved launch-configuration hash. Production
operators Prepare through the normal RPC, simulate the exact committed Launch
without --broadcast, sign and inspect its artifact calldata locally, submit
that raw transaction directly to Robinhood's sequencer, then Finalize through
the normal RPC:
forge script script/DeployStaticsGenesis.s.sol:DeployStaticsGenesis \
--sig "runPrepare()" --rpc-url "$RPC_URL" --broadcast -vv
forge script script/DeployStaticsGenesis.s.sol:DeployStaticsGenesis \
--sig "runLaunch()" --rpc-url "$TRUSTED_SIMULATION_RPC" -vv
# Sign and submit the artifact's exact Airlock calldata as documented below.
forge script script/DeployStaticsGenesis.s.sol:DeployStaticsGenesis \
--sig "runFinalize()" --rpc-url "$RPC_URL" --broadcast -vvThe reviewed deployment manifest and transaction records provide the canonical release evidence for an already completed launch.
The staged production entry point is
script/DeployStaticsPhaseOne.s.sol:DeployStaticsPhaseOne. It deploys one
StaticsTimelock, the 32-facet and 226-selector StaticsDiamond, separate public and
permissioned swap hooks, and a default venue-controller factory. It requires a nonzero general-pool
creation fee at deployment, enabling fee-paid public creation, while
accepting the PositionNFT fee as a deployment input. The exact-0.8.26
permissioned router, non-transferable position manager, and owner-claims
companion are deployed separately before both hooks and all trusted periphery
are installed with the public liquidity manager and POL operator configuration by the deployment
signer before the Diamond is handed to the governance Safe. At least one initial public pool is
created before the Safe later transfers ownership to the timelock.
Phase 1 includes arbitrary Statics-hooked ERC-20 pairs, protocol fee routing, custody-constrained managed POL portfolios, PositionNFT accounts, and global STATICS staking with per-position reward opt-ins. Public-pool PositionNFT range gauges expose five fixed reward slots. Slot 0 is reserved for weekly protocol STATICS incentives, while slots 1 through 4 remain independently and permissionlessly funded by creators, partners, and communities. Each direct slot may split future funding between active-range LPs and PoolId allocators at a creator-selected rate, with funder-side share and target-epoch protection. Stakers allocate raw staked STATICS to eligible public PoolIds for the next weekly epoch. A custody-backed reserve releases a governed percentage pro rata across every allocated PoolId without using Genesis or Operator multipliers. Pool shares activate lazily through ordinary pool activity or a permissionless checkpoint and expire after one extra weekly epoch. A Diamond-bound liquidity manager holds and mutates the underlying Uniswap v4 position NFTs. It also includes a separate permissioned market path with creator-operated controllers, approved traders and LPs, non-transferable LP NFTs, reward restrictions, and creator/timelock-agreed PoolId-local economics. Permissioned pools have no Statics POL. It excludes every basket, credit, flash-loan, Genesis-integration, Dollar, Morpho, and borrow-to-liquidity selector. The complete four-phase decision and authority model are recorded in the staged-launch ADR.
The canonical fresh full-stack entry point remains
script/DeployStatics.s.sol:DeployStatics. It remains a regression reference,
not the upgrade path for a live phased Diamond. The concrete Phase 2, 3, and 4
implementation/deployment entry points are runPhaseTwo(), runPhaseThree(),
and runPhaseFour() on script/DeployStaticsPhases.s.sol:DeployStaticsPhases.
They deploy each phase's contracts and emit the exact Safe-to-timelock schedule
and permissionless execute calldata.
All staged and fresh cuts are derived from
script/libraries/StaticsProtocolPlan.sol. The staged regression advances one
Diamond through every timelocked batch, then compares all 367 selector routes
and implementation runtime hashes, plus all 95 Dollar Core selector routes and
runtimes, with a fresh full deployment.
The launcher validates governance addresses, Dollar risk parameters, oracle bounds, sequencer requirements, WETH, chain-specific v4 dependencies, runtime code hashes, hook permissions, and immutable bindings. Its fresh-deployment architecture is:
Phase 1 StaticsDiamond: 29 facets, 189 selectors
Phase 2 StaticsDiamond: 41 facets, 282 selectors cumulative
Phase 3 StaticsDiamond: 46 facets, 340 selectors cumulative
Phase 4 StaticsDiamond: 51 facets, 367 selectors cumulative
Full StaticsDiamond: 51 facets, 367 selectors
StaticsDollarCoreDiamond: 11 facets, 95 selectors (Phase 3 onward)
Core.periphery == Core.positionNFT == StaticsDiamond
Core owner == Diamond owner == StaticsTimelock
For the Phase 1 launcher, Core.* does not exist and the Diamond alone is owned
by StaticsTimelock.
DeployLocalStaticsWithLiquidity deploys local WETH and oracle fixtures, a pegged development profile, real local v4 dependencies, the Statics hook, and the liquidity manager:
anvil # separate terminal
PRIVATE_KEY="$ANVIL_PRIVATE_KEY" forge script \
script/dollar/DeployLocalStaticsWithLiquidity.s.sol:DeployLocalStaticsWithLiquidity \
--sig 'runLocalWithLiquidity()' \
--rpc-url http://127.0.0.1:8545 \
--broadcast \
-vvUse an ephemeral Anvil key only. Local fixtures and addresses are not production deployment evidence.
To reproduce the realistic standalone launch-liquidity lifecycle against the deployed Robinhood contracts, start a pinned fork in a separate terminal:
anvil \
--fork-url "${ROBINHOOD_MAINNET:?set private Robinhood RPC}" \
--fork-block-number 56184871 \
--chain-id 4663 \
--host 127.0.0.1 \
--port 8545Then run the checked-in fork regression against Anvil:
ROBINHOOD_MAINNET=http://127.0.0.1:8545 \
ROBINHOOD_FORK_LATEST=true \
REQUIRE_ROBINHOOD_FORK=true \
forge test \
--match-path test/liquidity/fork/RobinhoodRealisticLaunchLiquidityFork.t.sol \
-vvThe regression initializes the supplied STATICS/NVDA ratio, proves a $10,000 single-sided STATICS seed transfers zero NVDA, adds two independently owned concentrated positions, reconfigures bilateral hook fees and their receiver, executes approximately $100,000 of two-way input notional, removes 10% of only the launch position, and verifies another swap still succeeds. The receiver accrues PoolManager ERC-6909 claims for each charged currency; neither the hook nor the receiver needs raw counterasset inventory for the first converting swap.
Each registered launch pool has a designated launch operator. The bound
PositionManager must initialize it at the registered price, positions may then
be minted normally, and swaps remain disabled until either that operator or
hook governance calls activatePool. Activation is permanent and does not
restrict later PositionManager NFT additions, removals, transfers, or burns.
The Safe holding the hook owner's existing timelock proposer role may register
new pools immediately. Later changes to a registered pool's bilateral hook fees
or the shared fee receiver remain owner-only and execute through the timelock.
The deployment artifact contains only stable deployment and pool configuration. Generate expiring PositionManager calldata immediately before execution:
STATICS_LAUNCH_LIQUIDITY_ARTIFACT=artifacts/launch-liquidity/robinhood-4663.json \
STATICS_LAUNCH_POSITION_ARTIFACT=artifacts/launch-liquidity/robinhood-4663-position.json \
STATICS_LAUNCH_POSITION_DEADLINE="$FRESH_UNIX_TIMESTAMP" \
forge script \
script/PrepareStaticsLaunchPosition.s.sol:PrepareStaticsLaunchPosition \
--rpc-url "$ROBINHOOD_MAINNET"The prepared artifact includes atomic initialize-and-mint calldata, a mint-only
fallback if the exact-price initialization was already completed, and separate
activation calldata. To convert accrued claims to underlying tokens, the claim
owner authorizes the deployed StaticsLaunchFeeClaimRedeemer in PoolManager
and calls redeem; the helper burns the claims and sends the underlying to the
chosen recipient without retaining custody.
For repeated PoolKey launches, three funding modes, amount-based liquidity sizing, additional position mints at the current pool price, and existing-NFT management calldata, follow the launch-liquidity tooling guide.
Robinhood testnet is chain 46630. The repository records the current
integration beta in deployment.md, with canonical
machine-readable state in
deployments/robinhood-testnet-46630-statics.json.
For a disposable rehearsal baseline that mirrors the standalone mainnet Genesis launch without deploying either Diamond, use the repeatable replica command. It deploys fresh pinned Doppler modules and a fresh Genesis environment on every invocation while reusing Robinhood testnet's verified PoolManager and WETH:
PRIVATE_KEY="$PRIVATE_KEY" \
ROBINHOOD_TESTNET_RPC_URL="$ROBINHOOD_TESTNET_RPC_URL" \
STATICS_GENESIS_EPOCH_END="$FUTURE_UNIX_TIMESTAMP" \
scripts/deploy-genesis-testnet-replica.sh --broadcastGovernance, treasury, Doppler's 5% fee recipient, and integrator default to the
broadcaster and may be overridden with STATICS_GENESIS_GOVERNANCE,
STATICS_GENESIS_TREASURY, DOPPLER_FEE_RECIPIENT, and
STATICS_DOPPLER_INTEGRATOR. Each run writes its addresses and pool ID under
the ignored artifacts/genesis-testnet/ directory. The command refuses to run
if the canonical launch sources differ from mainnet commit 43018f1 or if the
testnet chain dependencies no longer match their checked-in runtime hashes.
Robinhood testnet also has one shared Morpho Blue deployment for repeatable Statics lending rehearsals. Unlike the disposable Genesis replica, the Morpho singleton and its AdaptiveCurveIRM are deployed once and reused; each future Basket/USDstx rehearsal creates a separate immutable market on that shared infrastructure.
PRIVATE_KEY="$PRIVATE_KEY" \
ROBINHOOD_TESTNET_RPC_URL="$ROBINHOOD_TESTNET_RPC_URL" \
scripts/deploy-morpho-testnet.sh --broadcast
ROBINHOOD_TESTNET_RPC_URL="$ROBINHOOD_TESTNET_RPC_URL" \
scripts/deploy-morpho-testnet.sh --checkThe command pins the Morpho Blue and AdaptiveCurveIRM sources and exact
Robinhood mainnet compiler profile, deploys through the canonical CREATE2
factory, enables the production IRM and LLTV set, and refuses a different
chain, owner, dependency revision, compiler configuration, or runtime hash.
After the first deployment, --broadcast performs the same read-only manifest
validation as --check and sends no transactions. The shared addresses and
live evidence are recorded in
deployments/robinhood-testnet-46630-morpho.json.
No oracle or Morpho market is created by this infrastructure command.
The release sequence is intentionally explicit:
- Deploy and verify the fixed-supply Statics staking token, or use the token from the standalone Genesis release.
- Deploy and verify the testnet ETH/USD, sequencer-uptime, and USDG oracle fixtures.
- Set the confirmed staking-token and oracle addresses in the ignored release environment.
- Simulate, inspect, then broadcast and verify the canonical Statics launcher.
- Schedule and execute the timelocked canonical-liquidity installation.
- Configure the pegged Mock USDG profile.
- Schedule and execute the owner-funded genesis basket launch.
- Link the standalone Genesis deployment through the split-governance handoff.
- Deploy the two adjustable testnet Morpho oracles, create both markets, then schedule and execute
ConfigureStaticsMorpho. - Mint USDstx through the pegged profile and seed both markets with
runSeedLiquidity(). - Deploy and fully fund the six-asset public rehearsal faucet.
- Verify both Diamond manifests, ownership, selector routing, immutable bindings, pool state, fee configuration, faucet inventory, and deployment runtime hashes.
The faucet command consumes the recorded rehearsal addresses, prepares 100 complete USDG, USDstx, STATICS, TSLA, PLTR, and AMD bundles through the real testnet token paths, and refuses to deploy until every non-mintable asset is available:
STATICS_REHEARSAL_MANIFEST=deployments/robinhood-testnet-46630-rehearsal-YYYYMMDDTHHMMSSZ.json \
PRIVATE_KEY="$PRIVATE_KEY" \
ROBINHOOD_TESTNET_RPC_URL="$ROBINHOOD_TESTNET_RPC_URL" \
scripts/deploy-rehearsal-faucet.sh --broadcast
STATICS_REHEARSAL_MANIFEST=deployments/robinhood-testnet-46630-rehearsal-YYYYMMDDTHHMMSSZ.json \
STATICS_FAUCET_ADDRESS="$STATICS_FAUCET_ADDRESS" \
ROBINHOOD_TESTNET_RPC_URL="$ROBINHOOD_TESTNET_RPC_URL" \
scripts/deploy-rehearsal-faucet.sh --checkEach wallet may claim once per day. A bundle contains 5,000 USDG, 5,000 USDstx, 1,000 STATICS, and 0.001 of each stock fixture.
Focused deployment proofs:
forge test --match-path test/deployment/DeployStaticsPhaseOne.t.sol -vv
forge test --match-path test/deployment/ConfigureStaticsPhaseOneLiquidity.t.sol -vv
forge test --match-path test/deployment/DeployStatics.t.sol -vv
forge test --match-path test/deployment/RobinhoodDeploymentConfig.t.sol -vv
forge test --match-path test/deployment/DeployStaticsGenesis.t.sol -vv
forge test --match-path test/deployment/LaunchGenesisBasket.t.sol -vv
forge test --match-path test/deployment/ConfigureStaticsMorpho.t.sol -vv
forge test --match-path test/testnet/TestnetMorphoOracle.t.sol -vvThe pinned read-only testnet dependency check is:
ROBINHOOD_TESTNET_RPC_URL="$ROBINHOOD_TESTNET_RPC_URL" \
forge test \
--match-path test/liquidity/fork/RobinhoodTestnetV4DeploymentFork.t.sol \
-vvThe approved Phase 1 public fees are 0.01 ETH per pool, 0.001 ETH per new PositionNFT, and 0.025 ETH for managed-POL activation. Deploy with a zero pool creation fee so only the deployment owner can create the four launch pools. The launch script enables the 0.01 ETH public fee after all four are verified:
export POOL_CREATION_FEE_AMOUNT=0
export POSITION_CREATION_FEE_AMOUNT=1000000000000000
export STATICS_POL_ACTIVATION_FEE=25000000000000000The Phase 1 mainnet scripts reject different values. The Genesis governance Safe is both the timelock proposer and the Phase 1 emergency guardian, so there is no separate guardian veto signer. The deployment command is:
export MULTISIG=0x603A8A2f22ac1d61E9c932A4F6Fa23170CEcb9Ff
export GUARDIAN="$MULTISIG"
forge script script/DeployStaticsPhaseOne.s.sol:DeployStaticsPhaseOne \
--rpc-url "$ROBINHOOD_MAINNET" \
--chain-id 4663 \
--broadcast \
--legacy \
--slow \
-vvDeploy the exact-0.8.26 permissioned periphery after the Diamond and hooks, and record the three emitted addresses and runtime hashes:
forge script \
script/DeployStaticsPermissionedPeriphery.s.sol:DeployStaticsPermissionedPeriphery \
--rpc-url "$ROBINHOOD_MAINNET" \
--chain-id 4663 \
--broadcast \
-vvNo transaction is performed by this repository change. Simulate and inspect each exact deployment before any separately authorized broadcast.
The Phase 1 deployment temporarily gives Diamond ownership to the deployment
signer. After the exact-0.8.26 permissioned periphery is deployed, set
STATICS_TIMELOCK_ADDRESS to the address emitted by the Phase 1 deployment.
The same deployment signer executes the nine installation/configuration calls
and retains Diamond ownership for launch pool creation:
Set STATICS_REVENUE_MAINTENANCE_TIP_BPS=100 and
STATICS_POL_ACTIVATION_FEE=25000000000000000 for deployment finalization.
The tip is 1% of the settled Treasury share. Simulate and inspect the complete
transaction sequence before broadcasting:
forge script \
script/ConfigureStaticsPhaseOneLiquidity.s.sol:ConfigureStaticsPhaseOneLiquidity \
--sig "runFinalizeDeployment()" \
--rpc-url "$ROBINHOOD_MAINNET" \
--chain-id 4663 \
-vv
# After inspecting the simulation, use the same deployment signer to broadcast.
forge script \
script/ConfigureStaticsPhaseOneLiquidity.s.sol:ConfigureStaticsPhaseOneLiquidity \
--sig "runFinalizeDeployment()" \
--rpc-url "$ROBINHOOD_MAINNET" \
--chain-id 4663 \
--broadcast \
--legacy \
--slow \
-vvVerify the Diamond owner is still the deployment signer, the pool creation fee is zero, and the nine deployment settings are installed. Use the pinned mainnet tick spacings and supply reviewed raw-token opening square-root prices:
| Pool | Tick spacing | LP fee | Hook in | Hook out |
|---|---|---|---|---|
| Native ETH/USDG | 1 | 50 pips (0.005%) | 25 pips (0.0025%) | 25 pips (0.0025%) |
| STATICS/USDG | 10 | 200 pips (0.02%) | 1,400 pips (0.14%) | 1,400 pips (0.14%) |
| STATICS/NVDA | 200 | 10,000 pips (1%) | 2,500 pips (0.25%) | 2,500 pips (0.25%) |
| NVDA/USDG | 1 | 50 pips (0.005%) | 25 pips (0.0025%) | 25 pips (0.0025%) |
Set STATICS_LAUNCH_USDG_ADDRESS=0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168
and STATICS_LAUNCH_NVDA_ADDRESS=0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC.
The entry point pins the Genesis governance Safe and checks USDG/NVDA runtime
hashes, symbols, and decimals before broadcasting. The NVDA pin was observed
through the configured private Robinhood Mainnet RPC at block 85395888; it is
an on-chain binding check, not an issuer attestation.
The script defaults each STATICS_LAUNCH_<PAIR>_TICK_SPACING to the table value
and rejects a different value on mainnet. Supply
STATICS_LAUNCH_<PAIR>_SQRT_PRICE_X96 for each <PAIR>: ETH_USDG,
STATICS_USDG, STATICS_NVDA, or NVDA_USDG. The price is
sqrt(tokenB raw units / tokenA raw units) times 2^96; USDG uses 6 decimals.
The script requires all four prices and validates the fee schedule and pool state.
Simulate it first, then broadcast using the same deployment signer:
forge script script/LaunchStaticsPhaseOnePools.s.sol:LaunchStaticsPhaseOnePools \
--sig "run()" --rpc-url "$ROBINHOOD_MAINNET" --chain-id 4663 -vv
forge script script/LaunchStaticsPhaseOnePools.s.sol:LaunchStaticsPhaseOnePools \
--sig "run()" --rpc-url "$ROBINHOOD_MAINNET" --chain-id 4663 \
--broadcast --legacy --slow -vvPool creation occurs at zero fee while the deployer remains owner. The script then sets the public fee to 0.01 ETH and transfers ownership to the governance Safe. Record its four PoolIds. These transactions initialize pools but do not provide liquidity. Complete any other owner-only launch setup from the Safe before the final timelock handoff.
Prepare the final Safe call:
forge script \
script/ConfigureStaticsPhaseOneLiquidity.s.sol:ConfigureStaticsPhaseOneLiquidity \
--sig "runPrepareHandoff()" \
--rpc-url "$ROBINHOOD_MAINNET" \
-vvThe handoff preparation verifies the installed configuration, final pool fee, timelock roles,
and delay before returning the Safe's
transferOwnership(timelock) call. Execute it from the Safe and verify the
Diamond owner is the timelock. Preparation refuses a mismatched Diamond runtime, selector manifest,
selector-to-facet route, compiled facet runtime, active deployment phase,
initialized guardian, treasury, staking token, fee, reserve-release setting,
ERC-165 interface set, dependency runtime, immutable binding, hook flag, or
pre-existing installation state. It does not call or reconfigure any deployed
Genesis contract.
Prepare later phases from the exact preceding phase with:
forge script script/DeployStaticsPhases.s.sol:DeployStaticsPhases \
--sig "runPhaseTwo()" --rpc-url "$ROBINHOOD_MAINNET" --chain-id 4663 -vv
forge script script/DeployStaticsPhases.s.sol:DeployStaticsPhases \
--sig "runPhaseThree()" --rpc-url "$ROBINHOOD_MAINNET" --chain-id 4663 -vv
forge script script/DeployStaticsPhases.s.sol:DeployStaticsPhases \
--sig "runPhaseFour()" --rpc-url "$ROBINHOOD_MAINNET" --chain-id 4663 -vvAdd --broadcast only after explicit authorization and review of the preceding
phase, dependency runtimes, deployed addresses, and emitted timelock calldata.
Phase 2's Genesis handoff remains separate and operates against the existing
Genesis deployment; it does not redeploy or transfer those contracts.
The later full-stack deployment command is:
forge script script/DeployStatics.s.sol:DeployStatics \
--rpc-url "$ROBINHOOD_TESTNET_RPC_URL" \
--chain-id 46630 \
--broadcast \
--verify \
--verifier blockscout \
--verifier-url "$ROBINHOOD_TESTNET_VERIFIER_URL" \
--retries 20 \
--delay 5 \
-vvDo not treat a successful broadcast as complete release evidence. Verify every standalone contract and facet, preserve transaction receipts outside version control, and update the reviewed deployment manifest.
A BasketToken represents a fixed constituent vector. Minting deposits the configured bundle plus the selected flat fee; redemption burns BasketTokens and returns the same vector less the selected fee. Statics is deliberately not ERC-4626: historical fees do not change a basket conversion rate, and new minters do not purchase accrued yield.
Basket creators choose the immutable assets, bundle amounts, action-size fee tiers, flash fee, lending fees, LTV, recovery penalty, and loan duration. Assets remain permissionless and are not endorsed by inclusion.
StaticsDiamond is the ERC-721 PositionNFT contract. A position owns all attached basket collateral, Dollar series legs, reward selections, and loans. User Uniswap v4 LP NFTs remain in the selected recipient's wallet and are not PositionNFT legs. ERC-721 transfer moves authority over the complete economic position. A position cannot close while any module leg remains active.
New PositionNFT creation charges the exact configured native fee; existing positions can be reused without paying again. Module entry points attach the first leg atomically so receiver callbacks cannot leave an empty initializing position.
A Genesis NFT can be linked to exactly one PositionNFT when both have the same actual owner. The link moves neither NFT into custody. It applies the Genesis activation multiplier only to the Position's global STATICS reward weight and locks owner-changing transfers of both NFTs until voluntary unlinking or credit recovery clears the relationship. Recovery leaves the PositionNFT and every unrelated ledger item with its owner and removes only the Genesis leg and boost.
Every valid PositionNFT has fully onchain Base64 JSON and a stable Base64 SVG showing the Statics logo and Position ID. The image deliberately excludes live financial state. Generative SVG identity belongs to the scarce Genesis collection, where metadata can also reflect the NFT's future activation tier.
Users stake the configured Statics ERC-20 in a PositionNFT and opt into selected reward assets. Each asset indexes rewards only across positions that selected it. Eligibility begins after the configured delay, so a new selection cannot capture historical fees. Unsupported or temporarily ineligible fee shares fall through to the governed accounting destination rather than remaining unbooked.
Raw staked STATICS remains principal. Reward indexes use effective weight,
floor(raw stake * rewardMultiplierBps / 10,000). Every multiplier change
settles the old interval first and preserves pending-stake maturity.
After the governed Genesis handoff, StaticsDiamond becomes the permanent
StaticsFeeReceiver distributor and activation consumer. Registered Genesis
NFTs earn direct STATICS and WETH rewards independently of Position linkage.
Registration stays with the token across transfers, activation resets to Tier
0, and rewards earned before transfer crystallize to the prior owner.
Liquidity providers may keep ordinary PositionManager NFTs entirely outside Statics and earn the native Uniswap v4 LP fee through standard Uniswap accounting. Public protocol pools also support an opt-in managed path: a user can bind one concentrated-liquidity NFT per PoolId to a transferable Statics PositionNFT, with the immutable liquidity manager holding the underlying NFT and the Diamond accounting for separately funded range rewards. Native fees remain ordinary PositionManager fees and are not duplicated by the range gauge.
Each range gauge has five reward slots. Protocol STATICS occupies slot 0 and cannot be funded through the direct funding function. Slots 1 through 4 retain ordinary permissionless direct funding, including a separate directly funded STATICS stream. For each direct slot, the pool creator may direct 0% through 100% of future deposits to PositionNFTs that allocate to that PoolId. Funders pin the expected split and target epoch, LP and allocator custody remain separate, and funded allocator rewards target the next epoch without a protocol winner cutoff. Allocator claims follow PositionNFT ownership, expire after 26 weeks, and route ineligible, unclaimed, or rounding amounts to treasury. PositionNFT owners may allocate no more than their actual raw staked STATICS across at most 16 eligible public PoolIds. Allocation changes take effect in the next Monday-aligned epoch, and allocated stake must be explicitly deallocated before it can be unstaked. Every scheduled PoolId weight receives a pro-rata share of that epoch's reserve-backed budget. Permissioned venues are not eligible. A decommissioned or reward-restricted PoolId remains in the denominator as an abstention, and its unusable share recycles rather than increasing another pool's reward. Unemitted slot-0 rewards recycle into the reserve instead of becoming a perpetual pool entitlement.
Basket lending locks deposited BasketTokens and releases the proportional constituent vector at the basket's configured LTV, capped by the immutable 95% protocol ceiling. Independent tranches preserve separate maturities. Repayment restores the exact stored principal; extension charges each outstanding constituent; permissionless recovery becomes available only after maturity and grace.
Each basket has one canonical BasketToken/constituent Uniswap v4 pool per asset. The creator selects each pool's static native LP fee (0…999,999 pips), tick spacing, initial price, and paired-asset seed. StaticsSwapFeeHook separately charges governed fees on both input and output, then allocates them across managed POL, deposited BasketTokens, global Statics stakers, a fixed 500-bps creator share, and treasury.
POL inventory is settled permissionlessly from PoolManager claims into a PoolId-specific Diamond custody account. An authorized operator may open, increase, decrease, harvest, and close explicit positions through the liquidity manager, but every principal and NFT recipient is fixed to protocol custody. Native LP fees earned by POL route to treasury instead of compounding into principal. General pools start with POL disabled, and the would-be share routes to treasury without creating dormant inventory until the creator pays the exact governed activation fee. The hook-fee default is 500 pips (5 BPS) on each leg. Basket pools inherit the live default. A general-pool creator may select an initial rate as low as 10 pips on each leg, including rates below the default, provided both legs total at most 20,000 pips (200 BPS). Selecting the exact default stores no override; any other selection stores both legs as a fixed PoolId override. Governance may change the global default, replace a PoolId override, or clear an override back to the current default. Creators have no post-creation fee setter. Fee allocation remains governed by two global profiles (basket and general); the fixed creator share sits outside those profiles and the configurable shares always total 9,500 bps.
Beyond basket canonical pools, anyone can create a general pool, a Statics-hook Uniswap v4 pool between two compatible ERC-20s or native ETH and an ERC-20 with no basket association, once permissionless creation is enabled. createPool (preceded by a deterministic quotePool) lets the creator select a static native LP fee below 100%, valid tick spacing, initial price, and an initial bilateral hook-fee rate subject to the governed per-leg floor and combined ceiling; Statics fixes the installed hook. Creation is gated by an independent poolCreationFeeAmount that doubles as the permissionless switch: zero means only the Diamond owner may create (disabled), while a nonzero fee requires exact payment from every caller and forwards it to treasury.
Creator attribution uses EIP-712 authorization version 5 (domain "Statics Protocol Pools") validated for EOA and ERC-1271 signers, binding the PoolId, normalized price, both initial hook-fee legs, managed-POL activation choice, creator, an unordered nonce, and a deadline. PoolId commits to the pair, native LP fee, tick spacing, and hook. When permissionless creation is enabled, a direct creator needs no signature; relayed authorization does not bind msg.sender, so front-running cannot steal creator identity, and unused nonces can be cancelled with invalidatePoolCreationNonce. General pools require no mandatory liquidity seed. Managed POL is disabled by default, routes its would-be share to treasury without accumulating dormant inventory, and can be permanently activated by the creator through an exact governed native fee. Activation enables only future funding. An authorized operator may manage any number of explicit PoolId-bound positions but cannot redirect principal, refunds, or NFTs. A different native LP fee or tick spacing creates a distinct PoolId; price or hook fee alone does not. The immutable creator earns a fixed 500-bps perpetual share, claimed pull-based through claimCreatorRevenue. General pools never gain basket backing, collateral, or lending status, and a pool's price is never a Statics solvency input. Owner-only decommissioning is staged: begin stops swaps and the gauge, explicit bounded transactions close POL positions, and finalization requires none remain. Accrued creator credits and user LP principal are preserved. General pools carry no privacy guarantees: the immutable creator address, creation events, nonces, every swap and LP action, and every revenue claim are permanently public and linkable onchain, so use a fresh creator address per pool where identity separation matters.
Volatile profiles accept collateral such as WETH and mint equal senior Statics Dollar plus series-scoped Risk Shares. The Core governs price bands, coverage, insurance, transitions, recovery, oracle revision, and debt ceilings. Recombining equal senior and junior claims returns proportional collateral.
Pegged profiles mint only Statics Dollar, create no Risk Shares, and charge independent collateral-denominated mint and redemption fees. Any fungible Statics Dollar can redeem against available proportional profile capacity, subject to global health and recovery gates.
Baskets transition through Active, Quarantined, and ExitOnly. Quarantine blocks new exposure immediately while preserving repayment, recovery, and exit paths. ExitOnly disables new risk in the installed facets but remains a governed software state because the Diamond is upgradeable.
Every module maintains isolated logical reservations while LibCustody enforces global physical backing. Transfers use observed balance deltas and caller-provided bounds. Fee-on-transfer behavior can be measured, but rebases, external burns, deceptive balance implementations, blocklists, pauses, and token callbacks remain constituent risks.
These examples are illustrative. Read the live interfaces and docs/integration.md for complete structs, approvals, return values, and failure conditions.
Create a PositionNFT and stake Statics
address[] memory rewardAssets = new address[](2);
rewardAssets[0] = usdg;
rewardAssets[1] = basketToken;
uint256 creationFee = positionFees.positionCreationFee();
IERC20(staticsToken).approve(staticsDiamond, 100e18);
uint256 positionId = globalRewards.createAndStake{value: creationFee}(
100e18,
msg.sender,
rewardAssets
);Mint and redeem a static basket
uint256 shares = 10e18;
uint256[] memory maximumAmountsIn = basket.quoteMint(basketId, shares);
for (uint256 i; i < assets.length; ++i) {
IERC20(assets[i]).approve(staticsDiamond, maximumAmountsIn[i]);
}
basket.mint(basketId, shares, msg.sender, maximumAmountsIn);
IERC20(basketToken).approve(staticsDiamond, shares);
uint256[] memory minimumAmountsOut = basket.quoteRedeem(basketId, shares);
basket.redeem(basketId, shares, msg.sender, minimumAmountsOut);Deposit basket collateral and borrow constituents
IERC20(basketToken).approve(staticsDiamond, collateralShares);
basketCollateral.depositBasketCollateral(positionId, basketId, collateralShares);
(uint256 loanId, uint256[] memory principals) = lending.borrow(
positionId,
basketId,
collateralShares,
msg.sender
);
// Approve the exact stored principal for each constituent before repayment.
lending.repay(loanId);Mint Statics Dollar from native ETH
(uint256 seriesId, uint256 dollarOut, uint256 riskSharesOut) = dollarGateway.depositETH{value: 1 ether}(
msg.sender,
msg.sender,
minimumDollarOut,
minimumRiskSharesOut
);Borrow a basket constituent vector atomically
(address[] memory assets, uint256[] memory amounts, uint256[] memory fees) =
flashLender.quoteFlashLoan(basketId, shares);
flashLender.flashLoan(basketId, shares, address(receiver), routeData);
// receiver.onStaticsFlashLoan(...) must return
// keccak256("IStaticsFlashBorrower.onStaticsFlashLoan") and restore principal + fees.
// A dedicated single-asset loan uses all physical balance held by the Diamond.
uint256 amount = flashLender.maxFlashLoan(asset);
uint256 fee = flashLender.quoteFlashLoanAsset(asset, amount);
flashLender.flashLoanAsset(asset, amount, address(assetReceiver), routeData);
// assetReceiver.onStaticsFlashLoanAsset(...) must return the dedicated callback
// hash and approve the Diamond to collect amount + fee.Create a permissionless general pool
IStaticsProtocolPools.CreatePoolParams memory params = IStaticsProtocolPools.CreatePoolParams({
tokenA: tokenA,
tokenB: tokenB,
lpFee: 3_000,
tickSpacing: 60,
sqrtPriceBPerAX96: initialSqrtPriceBPerAX96,
initialFeeRate: IStaticsProtocolPools.PoolSwapFeeRate({
inputFeePips: 500,
outputFeePips: 500
}),
creator: msg.sender,
activateManagedPol: false,
nonce: nonce,
deadline: block.timestamp + 1 hours
});
// Deterministic preview: sorted PoolKey, PoolId, normalized price, fee, and EIP-712 digest.
IStaticsProtocolPools.GeneralPoolQuote memory quote = pools.quotePool(params);
// A direct creator (creator == msg.sender) passes empty authorization and consumes no nonce.
PoolId poolId = pools.createPool{value: quote.creationFee}(params, "");
// Later, the immutable creator pulls accrued revenue.
pools.claimCreatorRevenue(tokenA, msg.sender, minReceived);Deployment reads protocol parameters from environment variables. Selected keys from .env.example:
| Variable | Meaning |
|---|---|
PRIVATE_KEY |
Local broadcaster key; never commit a populated value |
MULTISIG |
Initial timelock proposer and governance authority |
GUARDIAN |
Phase 1 staking/liquidity emergency guardian and later module guardian |
TREASURY |
Shared protocol treasury |
STAKING_TOKEN |
Statics ERC-20 used as the global reward denominator |
WEEKLY_GAUGE_RELEASE_BPS |
Initial weekly release from the available protocol gauge reserve; defaults to 400 bps and cannot exceed 1,000 bps |
BASKET_CREATION_FEE_AMOUNT |
Exact native fee opening permissionless basket creation; zero permits owner-only genesis |
POSITION_CREATION_FEE_AMOUNT |
Exact native fee for each new PositionNFT; Phase 1 mainnet launch requires 0.001 ETH |
POOL_CREATION_FEE_AMOUNT |
Initial general-pool creation fee; Phase 1 deploys at zero for owner-only launch creation, then enables 0.01 ETH before Safe ownership |
STATICS_POL_OPERATOR |
Operational address permitted to manage explicit protocol-owned liquidity positions without withdrawal authority |
STATICS_POL_ACTIVATION_FEE |
Exact native Treasury fee a general-pool creator pays to permanently enable future managed-POL funding; Phase 1 mainnet launch requires 0.025 ETH |
STATICS_GENESIS_CONTRACT_URI |
Optional local-fork override; production uses the launcher's onchain ERC-7572 collection metadata URI |
STATICS_GENESIS_RESERVE_SHARE_BPS |
Governed share of harvested WETH routed into the permanent Genesis native reserve |
STATICS_GENESIS_CREDIT_ORIGINATION_FEE |
Ratified flat native Genesis secured-credit origination fee |
STATICS_GENESIS_CREDIT_EXTENSION_FEE |
Ratified flat native Genesis secured-credit extension fee |
STATICS_GENESIS_RECOVERY_CALLER_SHARE_BPS |
Ratified caller share of the fixed recovery residual; must be between 1 and 9,999 bps |
STATICS_GENESIS_EPOCH_END |
Reviewed absolute Unix timestamp for the immutable Genesis Epoch end and launch hash |
WETH_ADDRESS |
Verified WETH for the selected chain |
ETH_USD_FEED |
Verified Chainlink-compatible ETH/USD feed |
SEQUENCER_UPTIME_FEED |
Verified target-chain sequencer uptime feed |
SEQUENCER_GRACE_PERIOD |
Required recovery interval after sequencer restoration |
STATICS_DOLLAR_COLLATERAL_RATIO_BPS |
Initial volatile-profile collateral ratio |
STATICS_DOLLAR_PRICE_BAND_BPS |
Initial volatile-profile transition band |
STATICS_DOLLAR_DEBT_CEILING |
Initial volatile-profile issuance ceiling |
STATICS_DOLLAR_RISK_URI |
ERC-1155 metadata URI for Risk Share series |
STATICS_DOLLAR_BASE_BPS |
Initial share of Dollar fees routed to the base reward path; defaults to 7,000 bps |
STATICS_DOLLAR_INSURANCE_BPS |
Initial share of Dollar fees routed to insurance; defaults to 3,000 bps and must sum with base to 10,000 |
STATICS_DOLLAR_REDEMPTION_FEE_BPS |
Initial pairing-vault redemption fee; defaults to 50 bps |
STATICS_DOLLAR_REDEMPTION_SUPPLIER_SHARE_BPS |
Initial supplier share of pairing-vault redemption fees; defaults to 8,000 bps |
STATICS_DIAMOND_ADDRESS |
Existing Diamond used by post-deployment ceremonies |
STATICS_DIAMOND_RUNTIME_CODE_HASH |
Exact runtime hash of the deployed Diamond, including its immutable native sender binding |
STATICS_POOL_MANAGER_ADDRESS |
Existing v4 PoolManager already bound to the Phase 1 hook |
STATICS_POSITION_MANAGER_ADDRESS |
Existing v4 PositionManager bound to the Phase 1 liquidity manager |
STATICS_PERMIT2_ADDRESS |
Existing Permit2 bound to the Phase 1 liquidity manager |
STATICS_SWAP_FEE_HOOK_ADDRESS |
Deployed canonical swap-fee hook |
STATICS_SWAP_FEE_HOOK_RUNTIME_CODE_HASH |
Exact runtime hash of the deployed canonical swap-fee hook; required by installation |
STATICS_PERMISSIONED_SWAP_FEE_HOOK_ADDRESS |
Deployed separate permissioned exact-input output-fee hook |
STATICS_PERMISSIONED_SWAP_FEE_HOOK_RUNTIME_CODE_HASH |
Exact runtime hash of the permissioned hook |
STATICS_PERMISSIONED_ROUTER_ADDRESS |
Exact-input trusted router for permissioned pools |
STATICS_PERMISSIONED_ROUTER_RUNTIME_CODE_HASH |
Exact runtime hash of the permissioned router |
STATICS_PERMISSIONED_POSITION_MANAGER_ADDRESS |
Non-transferable approved-LP v4 Position Manager |
STATICS_PERMISSIONED_POSITION_MANAGER_RUNTIME_CODE_HASH |
Exact runtime hash of the permissioned Position Manager |
STATICS_PERMISSIONED_POSITION_CLAIMS_RUNTIME_CODE_HASH |
Exact runtime hash of the companion claim-backed unwind proceeds contract |
STATICS_LIQUIDITY_MANAGER_ADDRESS |
Phase 1 v4 liquidity manager deployed by the launcher and installed through the liquidity ceremony |
STATICS_LIQUIDITY_MANAGER_RUNTIME_CODE_HASH |
Exact runtime hash required by Phase 1 installation and later-phase provenance checks |
STATICS_REVENUE_MAINTENANCE_TIP_BPS |
Permissionless revenue-settlement tip paid from the settled treasury share; default 100 BPS |
STATICS_PROTOCOL_POL_OPERATOR |
Optional strategy operator authorized to manage custody-constrained protocol POL positions |
STATICS_POL_ACTIVATION_FEE |
Exact native fee a general-pool creator pays to activate prospective managed POL funding |
STATICS_LIQUIDITY_TIMELOCK_SALT |
Unique salt binding the liquidity-installation batch |
STATICS_PHASE_TWO_TIMELOCK_SALT |
Unique salt binding the basket/credit/flash activation batch |
STATICS_PHASE_THREE_TIMELOCK_SALT |
Unique salt binding the Dollar activation and core-finalization batch |
STATICS_PHASE_FOUR_TIMELOCK_SALT |
Unique salt binding the Morpho selector activation batch |
STATICS_GENESIS_BASKET_CONFIG |
Reviewed owner-funded genesis basket JSON |
STATICS_GENESIS_TIMELOCK_SALT |
Unique salt binding genesis approvals and launch |
STATICS_MORPHO_ADDRESS |
Reusable chain-local Morpho Blue deployment |
STATICS_MORPHO_IRM_ADDRESS |
Enabled AdaptiveCurveIRM used by rehearsal markets |
STATICS_MORPHO_LLTV |
Enabled Morpho LLTV shared by the rehearsal markets |
STATICS_MORPHO_SYNC_BOUNTY_BPS |
Share of forfeited rewards paid to the first successful synchronizer |
STATICS_MORPHO_TIMELOCK_SALT |
Unique salt binding Morpho initialization and both market registrations |
STATICS_MORPHO_LIQUIDITY_PER_MARKET |
USDstx minted through the real pegged profile and supplied to each market |
TESTNET_MORPHO_STATICS_PRICE |
Initial owner-published STATICS price in Morpho scale |
TESTNET_MORPHO_BASKET_PRICE |
Initial owner-published Basket price in Morpho scale |
ROBINHOOD_MAINNET |
Robinhood mainnet fork RPC; defaults to https://rpc.mainnet.chain.robinhood.com and may be overridden |
ROBINHOOD_TESTNET_RPC_URL |
Robinhood testnet RPC for simulation and authorized broadcast |
ROBINHOOD_TESTNET_VERIFIER_URL |
Blockscout verification endpoint |
Chain-specific v4 addresses and runtime hashes live in deployments/robinhood-chain-4663.json and deployments/robinhood-chain-testnet-46630.json. Solidity deployment code selects the matching manifest by block.chainid and rejects unsupported networks.
Runtime protocol state is available through the Diamond loupe, basket, position, rewards, liquidity, and Dollar view interfaces. Treat deployed state and the reviewed release manifest as authoritative over historical planning documents.
- Project name: use Statics in contracts, interfaces, events, documentation, deployments, SDKs, and commits.
- Solidity guidance: follow the security and testing guidance in
SECURITY.mdandverification/README.mdwhen changing Solidity. - Build discipline: avoid full clean rebuilds; use incremental compilation and
forge test --match-path …. - Test fidelity: prove value-moving behavior with real flows; use fuzz and invariant tests to broaden coverage.
- Harness resilience: prefer
uint256external helper parameters with explicit bounds checks and internal narrowing casts in broad test harnesses. - SDK changes: run
npm test --prefix sdkandnpm run build --prefix sdkwhen changing TypeScript bindings or builders. - Commits: use Conventional Commits, present tense, a title no longer than 72 characters, and a bulleted explanatory body.
Statics is licensed under the Business Source License 1.1 (BUSL-1.1). See LICENSE for the authoritative licensor, Additional Use Grant, Change Date, and Change License terms. Third-party submodules remain governed by their own licenses.
BUSL-1.1 is a source-available compromise, not an Open Source license. Before the Change Date, the grant lets you copy, modify, create derivative works, redistribute, and make non-production use of the Licensed Work; production use requires a commercial license from the Licensor unless an Additional Use Grant applies (currently "None"). On the earlier of the Change Date (2030-07-18) or the fourth anniversary of a version's first public distribution, that version relicenses to the Change License (MIT). This balances open review, auditing, and experimentation against protecting production commercialization during the initial period; publishing the source, ADRs, and this LLM-oriented index does not waive the production-use restriction.