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 |
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.