Security Model
Security architecture, access control, and anti-rug mechanisms in the LaunchRobin protocol.
Role-Based Access Control
| Role | Who | What They Can Do |
|---|---|---|
| DEFAULT_ADMIN_ROLE | Protocol owner (multisig) | Global pause, fee boundaries, adapter registration, UUPS upgrades, set core addresses |
| PLATFORM_OWNER_ROLE | Per-platform owner | Update fees (within bounds), set treasury, pause own platform, manage platform admins |
| PLATFORM_ADMIN_ROLE | Per-platform admin | Update branding only |
| TREASURY_MANAGER_ROLE | Per-platform treasury | Claim platform fees |
Platform roles are derived via keccak256(abi.encodePacked("ROLE_NAME", platformId)), making each platform's roles unique and non-overlapping.
Fee Safety Caps
| Parameter | Min | Max | Enforcement |
|---|---|---|---|
| Trading Fee | 25 bps (0.25%) | 500 bps (5%) | PlatformConfig._validateFees() |
| LP Fee Tier | — | 25000 (2.5%) | Must be 5000, 10000, or 25000 |
| Creator Share | — | 5000 bps (50%) | PlatformConfig._validateFees() |
The minimum trading fee (25 bps) ensures the protocol fee (0.25%) is always covered. Platform owners cannot set fees below this threshold.
Immutable Bonding Curves
When a platform owner updates fees or treasury, the platform's version counter increments. The Factory snapshots the current version into each new Launch contract at creation time. Active bonding curves use their snapshotted config — changing platform fees never affects existing launches. This prevents rug pulls where a platform owner changes fees retroactively.
Permanent Liquidity Lock
The UniswapV4Adapter has no LP withdraw function. Once a token graduates and liquidity is deployed to Uniswap v4, the LP positions are permanently locked. No one — not the creator, not the platform owner, not the protocol owner — can remove liquidity from graduated pools.
Fee Distribution
Every Trade:
Trade Amount
├── Net to curve
└── Fee
├── Protocol Fee (0.25% fixed) → protocolTreasury
└── Platform Fee (variable)
├── Creator Share (%) → creator
└── Platform Remainder → platformTreasuryFees are held in PlatformConfig accumulators (pull model). No ETH sits in bonding curves or individual tokens — it's all centralized in the auditable PlatformConfig contract.
Claim Restrictions
| Function | Who Can Call | Where Funds Go |
|---|---|---|
claimProtocolFees() | Anyone | protocolTreasury (fixed) |
claimPlatformFees(pid) | Platform treasury or owner | Platform treasury |
claimCreatorFees() | Anyone (self only) | msg.sender |
harvestDEXFees(token) | Anyone | Fee split: protocol → protocolTreasury, platform → platformTreasury, creator → creator |
Emergency Pause
- Global pause (
setGlobalPaused(true)) — stops all token creation and trading across all platforms. Protocol owner only. - Platform pause (
setPlatformPaused(platformId, true)) — stops creation and trading for a single platform. Platform owner only.
Pause only affects new transactions — existing positions and graduated pools are unaffected.
Reentrancy Protection
- Factory.createToken — protected by OpenZeppelin
nonReentrant - BondingCurve.buy / sell — protected by separate
nonReentrant(different contract) - Cross-contract calls (createToken → launch.buy) — safe because each contract has its own ReentrancyGuard storage slot
- ETH refunds use bare
.callwith no calldata, preventing fallback-based reentrancy
Configuration Versioning
Platform fees and treasury addresses are versioned. Each token launch records the config version at creation time. Fee changes increment the version. This means:
- Existing bonding curves are immutable regardless of config changes
- Platform owners cannot retroactively increase fees on active launches
- Creators know their token's economics are locked at deployment
UUPS Upgradeability
PlatformConfig, Factory, and Registry use UUPS proxies. Upgrades can only be performed by DEFAULT_ADMIN_ROLE. The _authorizeUpgrade function is overridden in each contract to enforce this. Upgrade keys should be held in a multisig wallet for production deployments.
Production Recommendations
Multisig for admin
Use a Gnosis Safe or similar for DEFAULT_ADMIN_ROLE
Separate treasuries
Don't use deployer key as protocolTreasury
External audit
Full audit of all contracts before mainnet
Monitor pause events
Alert on any pause/unpause events
Verify on Blockscout
Verify all contract source code
Rate limit the API
Add rate limiting for production indexer
Separate RPC providers
Indexer and frontend shouldn't share RPC endpoints