The ARU protocol is three immutable contracts plus off-chain infrastructure. Everything is on Arbitrum. Everything written in Solidity 0.8.24. Everything uses OpenZeppelin primitives.
┌───────────────┐ mint rights ┌──────────────────────────────┐
│ ARU │◀─────────────────────│ ARUSubscriptionManager (v2) │
│ (ERC-20 + │ │ per-request flow │
│ Permit) │ │ AP-bound pricing │
└───────────────┘ └──────────────────────────────┘
▲ │
│ mint rights (fallback) │ approveSubscription / approveRedemption
│ ▼
┌──────────────────────────────┐ ┌───────────┐
│ ARUMintRedeemManager (v1) │ │ MANAGER_ │
│ epoch-batched (fallback) │ │ ADMIN │
└──────────────────────────────┘ │ multisig │
│ (3-of-5 │
│ + Auto- │
│ Signer) │
└───────────┘
┌───────────────────────┐
│ ARUPriceOracle │ AggregatorV3-compatible NAV feed; consumers only
│ (read-only) │ (not gating primary market)
└───────────────────────┘
isMinter[address] mapping, not a single slotowner rolePer-request subscription/redemption manager.
AP-side:
requestSubscription(usdcAmount, maxPricePerARU) → bytes32 idrequestRedemption(aruAmount, minPricePerARU) → bytes32 idcancelSubscription(id) / cancelRedemption(id) — any time before fulfillmentAdmin-side:
approveSubscription(id, pricePerARU) — must respect AP's max boundapproveRedemption(id, pricePerARU) — must respect AP's min boundaddAP / removeAP — AP registrypauseSubscriptions / pauseRedemptions / freezesetTreasuryAddress / setMinimumMintAmount / setMinimumRedeemAmount / setRequestTTLPermissionless keeper-side:
cancelExpiredSubscription(id) / cancelExpiredRedemption(id) — after 48h TTLCustody properties:
The original epoch-batched design. It has been removed from the codebase (commit 1153227) and is not part of the audited production system — the Nethermind NM-0902 audit covered the per-request contracts only. Its review history is retained in Audit History for the audit trail.
Chainlink-compatible NAV feed. Fed by Redstone relayer. Two read functions:
latestRoundData() — drop-in Chainlink compat, returns stale data silentlylatestRoundDataStrict() — reverts PriceStale when older than stalenessThresholdNot used for gating primary market mint/redeem (that would be an availability single point of failure). Used only by downstream DeFi integrators consuming ARU as a price reference.
| Role | Contract | Holder | Purpose |
|---|---|---|---|
owner |
ARU | Cold multisig (2-of-3) | Add/remove minters, transfer ownership (all 48h timelocked) |
isMinter |
ARU | v1 Manager + v2 Manager | Ability to call aru.mint and aru.burn |
MANAGER_ADMIN |
v1 + v2 managers | Operational multisig (3-of-5 w/ AutoSigner) | Approvals, AP registry, pause/freeze, config |
DEFAULT_ADMIN_ROLE |
v1 + v2 managers | Same as MANAGER_ADMIN | OZ AccessControl default (role management) |
ADMIN_ROLE |
Oracle | Oracle admin multisig | Safety parameter tuning |
PRICE_UPDATER |
Oracle | Redstone relayer hot key | setPrice calls subject to rate-of-change + interval guards |
AP → requestSubscription(amount, maxPrice)
↓ USDC: AP → ARUSubscriptionManager (escrow)
↓ Request struct stored, SubscriptionRequested event
Multisig (later, within 48h SLA) → approveSubscription(id, price ≤ maxPrice)
↓ ARU: minted to AP via aru.mint(...)
↓ USDC: ARUSubscriptionManager → treasury
↓ SubscriptionApproved event
Or: AP → cancelSubscription(id) [anytime before approval]
↓ USDC: ARUSubscriptionManager → AP
↓ SubscriptionCancelled event (byExpiry=false)
Or: anyone → cancelExpiredSubscription(id) [after TTL]
↓ USDC: ARUSubscriptionManager → AP
↓ SubscriptionCancelled event (byExpiry=true)
AP → requestRedemption(aruAmount, minPrice)
↓ ARU: AP → ARUSubscriptionManager (escrow, not burned)
↓ Request struct stored, RedemptionRequested event
Multisig (later, within 48h SLA) → approveRedemption(id, price ≥ minPrice)
↓ USDC: treasury → AP via safeTransferFrom
↓ ARU: burned by contract (aru.burn)
↓ RedemptionApproved event
Or: AP → cancelRedemption(id) [anytime before approval]
↓ ARU: ARUSubscriptionManager → AP (intact, not burned)
↓ RedemptionCancelled event
Or: anyone → cancelExpiredRedemption(id) [after TTL]
↓ ARU: ARUSubscriptionManager → AP
↓ RedemptionCancelled event (byExpiry=true)
Three off-chain components support the on-chain contracts:
One of the five MANAGER_ADMIN signers. Evaluates proposed approval transactions against NAV tolerance and refuses signatures outside policy. See Auto-Signer.
Pushes NAV updates to ARUPriceOracle.setPrice. Subject to:
maxPriceChangeBps (default 300 bps) — rate-of-change guardminUpdateInterval (default 1h) — frequency floorstalenessThreshold / 2Indexes all contract events for the frontend dashboard and oncall alerts. Computes:
No subgraph contract dependency — all state is derivable from events + standard ERC-20 views.
The protocol maintains these invariants at all times:
aru.totalSupply() × NAV == treasury_value + escrowed_ARU × NAV (100% backing)usdc.balanceOf(subscription_manager) == sum(unfulfilled_subscriptions[*].amount)IERC20(aru).balanceOf(subscription_manager) == sum(unfulfilled_redemptions[*].amount)MAX_OPEN_REQUESTS_PER_AP (50)Observable on-chain; covered by Foundry invariant tests. See Invariant Tests.
All contracts inherit from well-audited OpenZeppelin primitives:
AccessControlEnumerable — role management with enumerationReentrancyGuard — on all state-mutating externalsSafeERC20 — defensive ERC-20 transfersERC20 + ERC20Burnable + ERC20Permit — token baseNo custom base libraries. No proxy patterns. No delegatecall. Minimal external dependency surface.