A fully on-chain perpetuals exchange deployed on Polkadot Hub Testnet.
Mock Chainlink price feeds ยท Binance live prices ยท CCIP cross-chain margin ยท 50ร leverage.
๐ Live App ย ยทย ๐ป Source Code ย ยทย ๐ Docs ย ยทย ๐ฐ Get Testnet PAS
Short.Demo.mp4
| Problem With Existing Protocols | Nexus Solution |
|---|---|
| Oracle manipulation via thin markets | MockAggregatorV3 with per-asset heartbeat staleness guards |
| Liquidity fragmented across chains | CCIP cross-chain margin relay with nonce replay protection |
| Custodial bridges introduce counterparty risk | All collateral lives in PerpsVault.sol โ non-custodial, on-chain |
| LP inflation attacks on first deposit | MINIMUM_LIQUIDITY = 1000 shares permanently burned on genesis deposit |
| Dust sweep / precision drain | scaledAmount % DECIMALS_SCALAR != 0 enforced on every withdrawal |
| Stale oracle prices | Binance WebSocket drives live PnL; entry price saved locally at trade execution |
- ๐๏ธ Architecture
- โ Deployed Contracts
- ๐งฉ Contract Reference
- ๐ป Frontend Stack
- ๐งช Test Suite & Coverage
- ๐ ๏ธ Local Setup
- ๐ Security Model
Five isolated protocol layers. A failure in cross-chain routing cannot affect vault solvency. The oracle layer is fully stateless with zero write access to core contracts.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ USER / DAPP โ
โ RainbowKit ยท Wagmi v2 ยท Viem ยท Next.js 15 App Router โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ TRADING ENGINE โ
โ PositionManager.sol ยท PnLCalculator.sol ยท LiquidationEngineโ
โ Market & limit orders ยท Isolated/Cross margin ยท Batch keepers โ
โโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโ
โ โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโ โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโ
โ VAULT LAYER โ โ ORACLE LAYER โ
โ PerpsVault.sol โ โ PriceOracle.sol โ
โ 18-dec precision โ โ MockAggregatorV3 (BTC+ETH) โ
โ LP share system โ โ Heartbeat staleness guard โ
โ settleTrade / PnL โ โ Binance WS live prices โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CROSS-CHAIN LAYER (CCIP) โ
โ CrossChainRouter.sol โโ encodes & sends trade requests โ
โ MessageReceiver.sol โโ decodes, deduplicates nonce, executes โ
โ Source chain + sender whitelist ยท try/catch pipeline safety โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
1. No off-chain trust โ Price discovery, execution, liquidation, settlement โ all fully on-chain.
2. 18-decimal precision throughout โ DECIMALS_SCALAR = 10^(18 - tokenDecimals) normalizes USDC (6 dec) to 1e18 internally.
3. Vault solvency is an invariant โ 128 runs ร 50 calls = 6,400 randomized state mutations, zero reverts.
4. Isolated margin by default โ Cross-margin mode uses _calculateGlobalPnL iterating all active positions.
All contracts deployed on Polkadot Hub Testnet (Chain ID: 420420417).
Explorer: blockscout-passet-hub.parity-testnet.parity.io
RPC: services.polkadothub-rpc.com/testnet
| Contract | Address |
|---|---|
| PositionManager | 0xd16150d0B2a04ECb1Aa09f840556347D5251fB53 |
| PerpsVault | 0x9495fE47049a7aFe8180E9e8Aee743D533c67173 |
| LiquidationEngine | 0x01721d6502547faFD3049BE60b1485B12407f58B |
| PriceOracle | 0x7C002F51B8D4F06275D43cFD1F15EcbFE7A52803 |
| PriceKeeper | 0x481EC593F7bD9aB4219a0d0A185C16F2687871C2 |
| Asset | Address | Notes |
|---|---|---|
| MockUSDC | 0xDFdb18430C5C5C1EB4F9Abd69a78952f9BC3Afab |
6-decimal collateral |
| MockWETH | 0xE3579516aeB339A4a8624beadaE256619E77F61E |
Test asset |
| MockWBTC | 0x20e9D3Ef17753EC0a0349eA7e26c8B8fd2B1A119 |
Test asset |
| ETH Feed | 0xCbE91D0b302d4eD146eE0CFfbe0d23E93e655d94 |
MockAggregatorV3 |
| BTC Feed | 0xf3878A726cF855EDF11C8aCbA38bEBd817fa9F23 |
MockAggregatorV3 |
| Contract | Address |
|---|---|
| CrossChainRouter | 0x8768d7470681a81caeA781285c9478dFDD7312e9 |
| MessageReceiver | 0xdcd169ca4Ab081C1B926Dc56430ADa8fE1E10A64 |
nexus-polka-perps/
โโโ src/
โ โโโ core/
โ โ โโโ PositionManager.sol # Trading engine: market/limit/liquidate/cross-chain
โ โ โโโ PerpsVault.sol # Collateral & LP vault (18-dec precision)
โ โ โโโ LiquidationEngine.sol # Keeper-compatible batch liquidator
โ โโโ math/
โ โ โโโ PnLCalculator.sol # Pure library: PnL, liquidation health, overflow guards
โ โโโ oracles/
โ โ โโโ PriceOracle.sol # MockAggregatorV3 wrapper + heartbeat staleness
โ โโโ mocks/
โ โ โโโ MockAggregatorV3.sol # Chainlink-compatible mock feed
โ โ โโโ PriceKeeper.sol # Permissioned price updater (60s cooldown)
โ โ โโโ MockUSDC.sol
โ โ โโโ MockWBTC.sol
โ โ โโโ MockWETH.sol
โ โโโ cross-chain/
โ โ โโโ CrossChainRouter.sol # CCIP message sender + fee estimation
โ โ โโโ MessageReceiver.sol # CCIP receiver + nonce dedup + try/catch execution
โ โโโ account-abstraction/
โ โ โโโ SmartAccount.sol # ERC-4337: EIP-712 signing, nonce, batch execution
โ โ โโโ AccountFactory.sol # CREATE2 deterministic EIP-1167 clone factory
โ โ โโโ NexusPaymaster.sol # Verifying paymaster, chain-ID bound
โ โโโ interfaces/
โ โ โโโ IPerpsCore.sol
โ โ โโโ IPriceOracle.sol
โ โ โโโ ICrossChain.sol
โ โ โโโ IEntryPoint.sol
โ โโโ errors/
โ โโโ PerpsErrors.sol # Centralized custom error library
โโโ web3-app/
โโโ src/
โโโ app/
โ โโโ trade/page.tsx # Trading interface (Binance WS + lightweight-charts)
โ โโโ vaults/page.tsx # LP vault interface
โ โโโ portfolio/page.tsx # Position dashboard
โ โโโ docs/page.tsx # Protocol documentation
โโโ hooks/
โ โโโ useVaultOperations.ts
โ โโโ useLPOperations.ts
โ โโโ useVaultStats.ts
โ โโโ usePortfolioData.ts
โโโ constants/
โโโ contracts.ts # All deployed addresses + ABIs
โโโ abis/ # Auto-generated ABI JSON files
Full position lifecycle: open โ update โ close โ liquidate.
- Market Orders โ
openPosition()validates oracle price, locks collateral in vault, stores position at current mock Chainlink price - Limit Orders โ
placeLimitOrder()locks collateral optimistically. Keeper callsexecuteLimitOrder()when price condition met - Cross-Chain Trades โ
executeCrossChainTrade()gated byonlyCrossChainReceiver - Liquidations โ Isolated mode uses
PnLCalculator.isLiquidatable(). Cross-margin computestotalEquity = vaultCollateral + globalPnL
Single contract holding all trader collateral and LP liquidity.
- Dual accounting โ
traderCollateral(free) andlockedCollateral(in positions) tracked separately - LP Shares โ First deposit burns
MINIMUM_LIQUIDITY = 1000permanently preventing inflation attacks settleTrade()โ Atomically unlocks collateral โ adjuststotalLiquidityfor PnL โ credits payout to trader- Dust prevention โ
withdraw()enforcesscaledAmount % DECIMALS_SCALAR == 0
Pure Solidity library, zero state.
positionSize = (collateral ร leverage) / 1e18
PnL = (priceDelta ร positionSize) / entryPrice
isLiquidatable = equity โค maintenanceMargin
= (collateral + PnL) โค (collateral ร liquidationThresholdBps / 10000)
Next.js 15 App Router with zero backend dependency for read operations.
| Layer | Technology |
|---|---|
| Framework | Next.js 15 (TypeScript, App Router) |
| Blockchain | Wagmi v2 + Viem |
| Wallet UI | RainbowKit (MetaMask, Bitget, OKX) |
| Queries | TanStack Query v5 |
| Charts | lightweight-charts (Binance REST API klines) |
| Live Prices | Binance WebSocket (wss://stream.binance.com) |
| Styling | Tailwind CSS + Framer Motion |
| Network | Polkadot Hub Testnet (Chain ID: 420420417) |
- Live PnL โ Binance WebSocket prices drive real-time P&L display independent of on-chain oracle
- Entry Price โ Saved locally at trade execution time, survives page refresh
- Position Polling โ 2s refetch interval, aggressive retry after open/close
- Lightweight Charts โ Fast candlestick chart via Binance REST API klines
forge test # 95 tests, ~3s
forge coverage # coverage report
forge test -vvv # verbose with tracesInvariant Tests (128 runs ร 50 calls = 6,400 state mutations, 0 reverts):
โญโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโโฎ
โ Contract โ Selector โ Calls โ Reverts โ Discards โ
โโโโโโโโโโโโโโโโโโโโโโโชโโโโโโโโโโโโโโโโโโโโโชโโโโโโโโชโโโโโโโโโโชโโโโโโโโโโโก
โ PositionHandler โ changeOraclePrice โ 1,541 โ 0 โ 0 โ
โ PositionHandler โ createTrader โ 1,603 โ 0 โ 1 โ
โ PositionHandler โ openRandomPosition โ 1,659 โ 0 โ 0 โ
โ PositionHandler โ tryLiquidation โ 1,598 โ 0 โ 0 โ
โฐโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโฏ
invariant_VaultIsSolventโtotalLiquidity โฅ 0holds across all mutationsinvariant_InternalAccountingConsistentโ internal balances matchASSET.balanceOf(vault)invariant_MaxActiveAssetsRespectedโ no trader exceedsmaxActiveAssets
- Foundry (forge, cast, anvil)
- Node.js โฅ 18
git clone https://github.com/NexTechArchitect/nexus-polka-perps.git
cd nexus-polka-perps
# Install Foundry dependencies
forge install
# Run full test suite (95 tests)
forge test -vv
# Deploy to Polkadot Hub Testnet
cp .env.example .env
# Fill: PRIVATE_KEY
forge script script/deploy/01_DeployMocks.s.sol --rpc-url polkadot-testnet --broadcast --legacy
forge script script/deploy/02_DeployOracle.s.sol --rpc-url polkadot-testnet --broadcast --legacy
forge script script/deploy/03_DeployVault.s.sol --rpc-url polkadot-testnet --broadcast --legacy
forge script script/deploy/04_DeployCore.s.sol --rpc-url polkadot-testnet --broadcast --legacy
forge script script/deploy/05_DeployCCIP.s.sol --rpc-url polkadot-testnet --broadcast --legacycd web3-app
npm install --legacy-peer-deps
npm run dev
# โ http://localhost:3000[rpc_endpoints]
polkadot-testnet = "https://services.polkadothub-rpc.com/testnet"
[etherscan]
polkadot-testnet = { key = "no-key", url = "https://blockscout-passet-hub.parity-testnet.parity.io/api" }| Token | Faucet |
|---|---|
| PAS (gas) | faucet.polkadot.io |
| USDC (collateral) | Mint via MockUSDC.mint() or ask deployer |
| Attack Vector | Mitigation |
|---|---|
| Oracle price manipulation | MockAggregatorV3 + block.timestamp - updatedAt > heartbeat staleness revert |
| Reentrancy | ReentrancyGuard on all vault state-changing functions |
| LP share inflation attack | MINIMUM_LIQUIDITY = 1000 permanently burned on genesis deposit |
| Dust sweep / precision drain | scaledAmount % DECIMALS_SCALAR != 0 reverts on withdrawal |
| Cross-chain replay | Per-trader nonce map in MessageReceiver |
| Unauthorized cross-chain calls | onlyCrossChainReceiver + source chain whitelist + sender whitelist |
| Over-withdrawal during active position | lockedCollateral tracking prevents withdrawing margin from open positions |
| Keeper reward rug pull | rescueTokens() blocks PROTOCOL_ASSET from owner withdrawal |
| CCIP pipeline blocking | try/catch in _ccipReceive โ failed trades emit TradeFailed, never block pipeline |
โ ๏ธ No formal external security audit has been conducted. Deployed on Polkadot Hub testnet with testnet assets only. Do not use with real funds.
Nexus Perps runs exclusively on Polkadot Hub Testnet (Chain ID: 420420417). All assets are testnet tokens with zero real-world value. Get PAS gas tokens from faucet.polkadot.io. This is not financial advice.