1. Purpose of this document
This summary is written for smart contract auditors and security reviewers. It describes the intended split of the NBES monolith into multiple contracts to:
- Satisfy EIP-170 (24,576-byte deployment limit).
- Separate fund-moving logic from governance / emergency logic.
- Define trust boundaries, audit scopes, and in-scope attack surfaces per contract.
Auditors should treat v2.16 / v2.16.1 monolith as the historical implementation baseline and this document as the target architecture for v2.16.2+ unless otherwise stated in the engagement letter.
2. Executive summary
| Item | Detail |
| Current monolith size | ~33,955 bytes (optimizer runs=1, viaIR) |
| EIP-170 limit | 24,576 bytes |
| Shortfall | ~9,379 bytes (~27.6%) — not deployable as single contract |
| Proposed fix | Split into Core (token + trading), Admin (governance), View (read-only), Rescue (optional) |
| Proxy note | EIP-1167 / UUPS does not exempt implementation from 24 KB at its address |
Audit implication: Two engagement scopes are possible:
- Scope A: Monolith v2.16 / v2.16.1 only (as deployed or attempted on Sepolia).
- Scope B: Split architecture v2.16.2+ — Core invariants + Admin→Core privilege model + optional Rescue hook.
3. System diagram (logical)
┌─────────────────┐
Traders/Holders │ NexumRiseCore │ ← NBES token address (ERC-20)
───────────►│ ETH + NBES │ buyNBES / sellNBES / transfer
└────────┬────────┘
│ onlyAdmin / onlyRescue
┌──────────────┼──────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Admin │ │ Rescue │ │ View │
│ timelocks │ │ (optional) │ │ eth_call │
│ dual-sig │ │ 30d claim │ │ no ETH │
└────────────┘ └────────────┘ └────────────┘
4. Contract inventory
| Contract | Holds ETH | Mutates NBES supply | In-scope for fund safety |
| NexumRiseCore | Yes | Yes | Primary — Critical |
| NexumRiseAdmin | No | No (calls Core) | Secondary — High (privilege escalation) |
| NexumRiseRescue | No | Via Core hook | Tertiary — High (if enabled) |
| NexumRiseView | No | No | Out of fund scope (read-only) |
5. Audit scope by contract
5.1 NexumRiseCore — CRITICAL PATH
Must verify:
| Area | Functions / logic | Risk class |
| Pricing | _computeBasePrice, Chainlink read/fallback, volume weights, buy vs sell SOL handling | Oracle manipulation, stale data |
| Trading | buyNBES, sellNBES | Reserve drain, slippage, reentrancy |
| Reserves | Main reserve = balance - investmentReserve; premium cap; sell spread in floor check | Insolvency, accounting desync |
| Liquidity trap | getReserveHealth (internal), exit window, max sell, circuit breaker | Bank run, griefing on triggerCircuitBreaker |
| ETH protection | Inline in getSellPrice / sellNBES | Stale reference, unfair sell price |
| L1 burn | _transfer fee-on-transfer, floor at MIN_SUPPLY | Supply invariant, founder lock |
| L3 milestones | executeMilestone (Admin-gated) | Price threshold, floor breach |
| ETH transfer | _safeTransferETH | Return bomb (mitigated via assembly + check) |
| Access | onlyAdmin, onlyRescue, onlyOwner | Privilege escalation from Admin/Rescue |
| Direct ETH | receive() reverts | Forced ETH via selfdestruct (documented) |
Explicitly out of Core (moved to Admin): 39× propose/execute/cancel governance externals, dual-sig approval flows, migration.
5.2 NexumRiseAdmin — GOVERNANCE & EMERGENCY
| Area | Risk class |
| Timelock enforcement (24h / 48h / 60d) | Bypass, timestamp manipulation (N/A on-chain) |
| Dual-sig (owner + trustedSigner) | Single-party execution, signer collusion |
| Volume commit-reveal | Hash mismatch, front-running reveal |
| Feed update (48h + 14d signer override) | Malicious feed addresses |
| Investment reserve withdraw | Timelock bypass → Core.withdrawInvestmentReserve |
| Investment emergency (48h) | Drain investment reserve |
| Main reserve emergency (60d) | Total ETH drain — document as extreme trust assumption |
trustedSigner lifecycle | Owner = signer collapse |
All Core.set* calls | Only callable after Admin checks; no direct user path |
Not in Admin: Pricing math, buyNBES/sellNBES execution.
5.3 NexumRiseRescue — OPTIONAL
| Area | Risk class |
| Dual-sig initiation | Unauthorized rescue |
| Snapshot / hold period | Gaming lastBalanceIncrease |
claimRescueETH → Core.rescuePayout | Double claim, ETH insolvency, NBES burn correctness |
| Interaction with circuit breaker / sells | Race during active rescue |
5.4 NexumRiseView — INFORMATIONAL
- No state changes, no ETH.
- Verify it cannot be used to trick users (phishing address risk is operational, not contract).
- Incorrect display math is off-chain risk only.
6. Trust model (auditor checklist)
| # | Invariant | Enforced by |
| T1 | Only Core moves ETH to users on sell (except Admin/Rescue hooks) | Core sellNBES, _safeTransferETH |
| T2 | investmentReserve only increases on spread/revenue/redirect; decreases on premium payout & approved withdraw | Core accounting |
| T3 | Admin cannot mint NBES or bypass burn floor without Core logic | No mint function; milestone/manual burn via Core |
| T4 | admin address on Core is immutable or one-time set by owner | Constructor / setAdmin once |
| T5 | trustedSigner cannot become owner on Core | transferOwnership guard |
| T6 | Users never call Admin for normal trade | Operational |
| T7 | View contract has zero write access | No non-view functions |
Key trust assumption: Compromised Admin or malicious owner can drain reserves via emergency paths after timelock/dual-sig — by design (governance trust). Auditors should flag whether timelocks are sufficient for token holder expectations.
7. Cross-contract API (Core surface for Admin/Rescue)
Admin-only setters (representative — full list in ARCHITECTURE.md):
| Core function | Called by | Effect |
setVolumes | Admin | Formula weights |
setFeeds | Admin | Oracle addresses |
setSpreadBps | Admin | Buy/sell spread |
setReserveMultiplier | Admin | Premium formula |
setBurnFee / setBurnEnabled | Admin | L1 burn |
setEthProtectionEnabled | Admin | Sell protection toggle |
setETHReference | Admin | 24h ETH reference |
withdrawInvestmentReserve | Admin | Investment ring-fence |
drainInvestmentReserve / drainAllETH | Admin | Emergency only |
executeMilestone | Admin | L3 burn from contract balance |
resetCircuitBreaker | Admin | After cooldown |
rescuePayout | Rescue | Burn NBES + ETH to holder |
Primary audit question: Can any address other than admin / rescue invoke these? Can Admin be swapped without holder notice?
8. State ownership (summary)
| Storage domain | Contract |
_balances, _totalSupply, allowances | Core |
| Feeds, volumes, lastKnown prices, spreads, multiplier, protection flags | Core (Admin writes) |
| Circuit breaker, exit window, investmentReserve | Core |
All pending* timelock fields | Admin |
rescueSnapshot, rescueEthClaim | Rescue |
trustedSigner | Admin (recommended) |
9. Events (indexing guidance)
| Contract | Event families |
| Core | Transfer, Buy, Sell, TokensBurned, SpreadCollected, CircuitBreaker*, SellLimitHit, OracleStale |
| Admin | *Proposed/*Executed/*Cancelled, Volume*, Feed*, Emergency*, TrustedSigner* |
| Rescue | RescueInitiated, RescueClaimed |
Auditors: confirm no sensitive ops lack events on Core.
10. Known monolith issues relevant to split
| Issue | Monolith (v2.16.1) | Split mitigation |
| Bytecode > 24 KB | Yes (~34 KB) | Core target 18–22 KB |
transferOwnership in Ownable referenced trustedSigner | Compile fix in v2.16.1 (override on Core) | Keep override on Core only |
| Migration moves investment only | Documented | Defer to Admin v3 |
Permissionless triggerCircuitBreaker | By design | Stays on Core |
11. Out of scope (typical engagement)
- Frontend / MetaMask phishing
- Chainlink liveness and off-chain feed compromise
- Legal / securities classification
- Economic model (formula fairness to holders)
- Centralization of owner/signer keys (operational)
12. Recommended audit workplan
| Phase | Deliverable |
| 1 | Review Core: buyNBES, sellNBES, pricing, reserves, reentrancy |
| 2 | Review Admin→Core: every onlyAdmin path, timelocks, dual-sig |
| 3 | Review optional Rescue→Core: rescuePayout |
| 4 | Integration: deploy script wiring, admin/rescue immutability |
| 5 | Compare monolith v2.16 behavior parity (regression matrix) |
13. File references
| File | Role |
NexumRise_NBES_v2_16.sol | Audited monolith baseline (Sepolia) |
NexumRise_NBES_v2_16_1.sol | Lean monolith + custom errors |
NexumRiseCore.sol · NexumRiseAdmin.sol · NexumRiseView_v2_16_2.sol · NexumRiseRescue.sol | v2.16.2 split deployables |
NexumRiseView_v2_16_1.sol | Read-only companion (earlier) |
ARCHITECTURE.md | Full architecture specification |
NexumRise_NBES_Architecture_Summary.pdf | This summary (PDF) |
14. Module → contract quick reference
| Module | Contract |
| ERC-20 + L1 burn | Core |
| buy / sell + pricing | Core |
| Circuit breaker + exit limits | Core |
| Milestone burn (effect) | Core ← Admin |
| Oracle/volume storage | Core ← Admin writes |
| Timelocks + dual-sig | Admin |
| Emergencies + withdraw | Admin → Core |
| Trusted signer | Admin |
| Holder rescue | Rescue → Core (optional) |
| Migration | Admin (defer) |
| Dashboard | View |
| Shared constants | NexumRiseConstants |
15. Implementation recommendations
Consolidates implementation notes with architecture review. Required for v2.16.2, not optional.
15.1 A — One-time setAdmin handshake
| Step | Action |
| 1 | Deploy Core with admin = address(0) |
| 2 | Deploy Admin with core = CoreAddress |
| 3 | Core owner calls setAdmin(AdminAddress) once |
| 4 | Verify adminInitialized == true on-chain |
| 5 | Transfer Core owner to multisig (do not renounce until onlyOwner functions are scoped) |
function setAdmin(address _admin) external onlyOwner {
if (adminInitialized) revert NBESAdminAlreadySet();
if (_admin == address(0)) revert NBESZeroAddress();
admin = _admin;
adminInitialized = true;
}
Audit focus: Can setAdmin be called twice? Can non-owner set admin? Is Admin address correct before any trading?
Caveat: Renouncing Core ownership breaks seedReserve, depositRevenue, and one-time setRescue unless moved to Admin.
15.2 B — NexumRiseConstants.sol
Single import for INITIAL_SUPPLY, MIN_SUPPLY, staleness windows, FEE_DENOM, tier %, timelocks, volume bounds — used by Core, Admin, View, Rescue.
Audit focus: No mismatched constants between contracts (especially View vs Core pricing display).
15.3 C — onlyAdmin / onlyRescue on all Core setters
| Must be gated | Example |
onlyAdmin | setVolumes, setFeeds, setSpreadBps, executeMilestone, emergencies |
onlyRescue | rescuePayout |
Primary audit question: Can any EOA call Core setters directly and bypass Admin timelocks? Use custom errors (NBESNotAdmin, NBESNotRescue) per v2.16.1.
15.4 D — Phased deployment
| Phase | Contracts | Audit scope |
| 1 Sepolia | Core + View | Pricing, buy/sell, breaker; owner shortcuts OK |
| 2 Mainnet | + Admin | Full timelock + dual-sig → Core paths |
| 3 Optional | + Rescue | rescuePayout hook only if deployed |
Before mainnet: Monolith v2.16 behavior parity matrix (regression tests).
15.5 Owner vs Admin vs Rescue
| Role | Location | Post-launch capability |
Core owner | Multisig | Seed, deposit, one-time wiring, ownership |
Core admin | Admin contract | All parameter setters after governance |
Core rescue | Rescue contract | Holder rescue payout hook only |
trustedSigner | Admin only | Dual-sig approvals (not Core owner) |
15.6 Launch checklist
- Core + Admin + View (+ optional Rescue) compile under EIP-170
setAdmin one-time + adminInitialized
- All Core setters have
onlyAdmin or onlyRescue
NexumRiseConstants.sol imported everywhere
- Parity tests vs v2.16 monolith
- Emergency paths documented for holders
Disclaimer: This document describes intended architecture. Auditors should confirm commit hashes and deployed addresses in the audit engagement scope. Sepolia v2.16.2 addresses are linked from the
main site footer.