06 — On-chain Architecture
Status: not deployed. These contracts are written and tested but are not live on any network. Mainnet deployment is gated behind an external audit of the exact bytecode. Everything below describes designed behaviour.
Not an offer or investment advice. $DRPXBT is a utility token that gates access to the platform. Staking distributes a share of variable, non-guaranteed platform revenue and may be zero; nothing here promises a return.
Network: Base. Token: $DRPXBT, an existing external ERC-20 at
0xFA3946432C6A76eDFF377D9bbFB81ca3FfC05874.
The contracts never mint. They lock, stake, route and burn a token that already exists — which removes an entire class of supply-side risk and makes the trust story simple.
Contract graph
flowchart TB
U([User]) -->|lock| TL[HunterTierLock]
U -->|stake| ST[HunterStaking]
U -->|subscribe| SU[HunterSubscription]
TL -->|early-exit penalty| SP[HunterRevenueSplitter]
SU -->|proceeds| SP
SU -.->|DRPXBT burn share| DEAD[0x…dEaD]
OFF([Off-chain revenue<br/>API, x402, ACP]) -->|USDC| SP
SP -->|40%| BB[HunterBuyback]
SP -->|30% notifyRewardAmount| ST
SP -->|30%| TR[Treasury multisig]
BB -->|swap USDC→DRPXBT| DEX[Uniswap v3]
DEX --> DEAD
ST -->|USDC rewards| U
Contracts
HunterTierLock
Locks $DRPXBT for a committed duration in exchange for an access tier.
- One active lock per wallet; top-ups and extensions allowed, shortening is
not (
CannotShortenLock) — otherwise a user could claim a long-duration tier then immediately shorten. tierOf(user)walks the tier table descending and requires bothamount >= minAmountand committed duration(end - start) >= minDuration. A whale with a 30-day lock gets the 30-day tier, not the top tier.earlyExit()returns principal minuspenaltyBps(default 10%, hard-capped atMAX_PENALTY_BPS = 25%), penalty routed to the splitter.- Guards:
Ownable2Step,Pausable,ReentrancyGuard,SafeERC20.
HunterStaking
Synthetix-style staking. Rewards are a share of realised platform revenue rather than token emissions, and are therefore variable and not guaranteed — if the platform earns nothing, rewards are zero.
notifyRewardAmountis callable only byrewardsDistribution(the splitter) and pulls the reward in, so a notification can never promise tokens the contract does not hold.- A solvency guard rejects a rate the held balance cannot sustain
(
RewardTooHigh). rewardRateisPRECISION-scaled;rewardPerToken()divides bytotalSupplywithout re-multiplying — a subtle place where a stray1e18would silently corrupt every payout, so it carries a comment.
HunterSubscription
Monthly plans payable in USDC or discounted $DRPXBT.
subscribeDrpxbtburnsburnBpsof the payment (default 100%) and sends the remainder to the splitter.- Renewals extend from the current expiry when the plan is unchanged, and from
nowwhen switching plans, so users never lose paid time or accumulate it across different plans.
HunterRevenueSplitter
The single mouth of the funnel. Default split 40% buyback+burn / 30% staker
rewards / 30% treasury, governable via setSplit (must sum to 10,000 bps).
Defensive behaviours that matter in production:
- If buyback is unset, its share folds into treasury rather than reverting —
revenue never gets stuck because of a configuration gap.
- The staking share is only streamed when the incoming token is the staking
rewards token; otherwise it also folds into treasury. This is why DRPXBT
penalties don't jam the USDC reward stream.
- distribute() is permissionless — anyone can push revenue through, so the
team cannot silently withhold it.
HunterBuyback
Executes buybacks in bounded clips and burns the proceeds to 0x…dEaD.
- Per-execution size and interval limits are enforced on-chain, and every swap carries a slippage floor, so a compromised operational key cannot drain the treasury into a thin market. Exact parameters are set at deployment and readable from the contract.
- An owner-only recovery function exists for tokens sent to the contract by mistake.
Roles
| Role | Held by | Powers |
|---|---|---|
owner (all contracts) |
Treasury multisig | Tiers, plans, split ratios, pause, keeper set |
rewardsDistribution |
Splitter contract | Stream staking rewards |
| keeper | Ops key(s) | Execute bounded buyback clips |
| anyone | — | distribute(), all reads |
Ownership transfer uses Ownable2Step: the multisig must accept, so a typo
cannot brick a contract.
Deployment
Deployment is scripted (scripts/deploy.js, configured by environment) and
ends by handing ownership to the treasury multisig. Order matters: the splitter
must exist before the tier lock (which needs a penalty recipient) and before
staking (which needs a distributor). Remaining parameters — tiers, plans,
keeper and clip configuration — are set post-deploy by the owner.
Deployed addresses will be published here once the contracts are audited and live.
Testing and safety posture
19 tests cover tier derivation (including the amount-vs-duration interaction),
expiry, early-exit accounting, pro-rata reward streaming, split correctness for
both reward and non-reward tokens, subscription renewal/burn maths, and buyback
keeper/clip/slippage guards. Mocks (MockERC20, MockSwapRouter) keep the
suite hermetic.
Standing rule: no mainnet deployment without an external audit of the exact bytecode. Sepolia first, mainnet after, TierLock (lowest risk) before Subscription.