wNNS is an ERC20 token on Ethereum that represents native NNS (996-Coin) 1:1. Deposit your NNS into the treasury wallet, and wNNS is minted to your EVM address. Redeem it anytime to get your NNS back.
# Compile contracts
forge build
# Run all 54 tests
forge test
# Deploy staking contract (update config.js with resulting address)
forge script script/DeployStaking.s.sol:DeployStaking \
--rpc-url sepolia --broadcast --verify -vvvv
# Open frontend (no build step needed)
open frontend/index.htmlNNS lives on its own blockchain — it can't be used on Uniswap, PancakeSwap, Aave, or any other EVM dApp. wNNS bridges that gap:
- Trade NNS on any EVM DEX — Uniswap, PancakeSwap, 1inch, etc.
- Use NNS in DeFi — lending, yield farming, liquidity pools
- Stake wNNS — earn rewards from protocol fees
- Self-custodial — you always hold the keys to your assets
- Fully redeemable — burn wNNS to get native NNS back at any time
User → Bridge/Swap/Stake Web App (frontend/index.html)
│
├── WNNSToken (ERC20, 8 decimals)
├── WNNSVault (bridge mint/redeem with oracle)
├── WNNSStaking (stake wNNS → earn rewards)
└── Uniswap V3 Pool (buy/sell wNNS with ETH)
| Contract | Purpose | Sepolia Address |
|---|---|---|
WNNSToken |
ERC20 + ERC20Permit, 8 decimals | 0xda420ea70493767D6697aeb9A6062a01F19136C5 |
WNNSVault |
Bridge vault (mint/burn with oracle) | 0xA5e774BF559C50b2EFe11e5e8708F805f6F644A0 |
WNNSStaking |
Staking rewards (Synthetix pattern) | TBD — deploy required |
An off-chain TypeScript service (oracle/) polls the NNS chain via Bitcoin
JSON-RPC, detects deposits, and calls submitMint() on the vault. It also
listens for RedeemRequested events and fulfills them by sending NNS and
calling confirmRedeem().
Vanilla HTML/JS single-page app with 4 tabs:
- Bridge — Deposit NNS instructions + redeem wNNS → NNS
- Swap — Buy/sell wNNS with ETH via Uniswap V3 router
- Stake — Stake wNNS, claim rewards
- Portfolio — Balances, pending redemptions, activity
No build step — deploy by uploading frontend/ to any static host.
| Property | Value |
|---|---|
| Name | Wrapped NNS |
| Symbol | wNNS |
| Decimals | 8 (matches NNS precision) |
| Standard | ERC20 + ERC20Permit |
| Supply | Uncapped — equals NNS locked in treasury |
| Mint fee | 0.1% (configurable 0–1%) |
| Redeem fee | 0.1% (configurable 0–1%) |
wNNS_EVM/
├── contracts/ # Solidity contracts
│ ├── WNNSToken.sol # ERC20 token
│ ├── WNNSVault.sol # Bridge vault
│ ├── WNNSStaking.sol # Staking rewards
│ └── interfaces/ # Solidity interfaces
├── test/ # Foundry tests (54 total)
│ ├── WNNSToken.t.sol # Token tests (14)
│ ├── WNNSVault.t.sol # Vault tests (20)
│ └── WNNSStaking.t.sol # Staking tests (20)
├── script/ # Deployment scripts
│ ├── Deploy.s.sol # Token + vault deploy
│ ├── DeployStaking.s.sol # Staking deploy
│ └── Upgrade.s.sol # Upgrade implementations
├── oracle/ # Off-chain oracle service
│ └── src/ # TypeScript source
├── frontend/ # Bridge UI (no build step)
│ ├── index.html
│ └── src/ # JS modules + CSS
├── docs/ # Documentation
│ ├── ARCHITECTURE.md # Full system architecture
│ ├── HANDOFF.md # Agent handoff instructions
│ ├── frontend.md # Frontend developer guide
│ ├── implementation_plan.md # Original project plan
│ ├── tokenomics.md # Token economics
│ ├── security.md # Security model
│ ├── deployment.md # Deployment commands
│ ├── mainnet_deployment_guide.md # Mainnet checklist
│ ├── sepolia_testing_walkthrough.md
│ ├── operations_manual.md # Day-to-day operations
│ └── cast_commands.md # cast CLI reference
└── foundry.toml # Build config
# Prerequisites
forge --version # Foundry (nightly)
node --version # Node.js v20+
# Build contracts
forge build # Compile all Solidity
# Run tests
forge test # 54 tests, all passing
# Deploy to Sepolia
# 1. Set env vars:
export PRIVATE_KEY=0x...
export ORACLE_ADDRESS=0x...
export SEPOLIA_RPC_URL=https://rpc.sepolia.org
export ETHERSCAN_API_KEY=...
# 2. Deploy token + vault:
forge script script/Deploy.s.sol:Deploy --rpc-url sepolia --broadcast --verify -vvvv
# 3. Deploy staking:
export STAKING_TOKEN=<token_proxy_address>
export REWARDS_TOKEN=<token_proxy_address>
forge script script/DeployStaking.s.sol:DeployStaking --rpc-url sepolia --broadcast --verify -vvvv
# Run oracle (requires NNS node):
cd oracle && npm install && npm run dev- 1:1 backed — For every wNNS minted, 1 NNS is locked in the treasury wallet
- Mint caps — Per-transaction (100k wNNS) and daily (1M wNNS) limits
- Oracle guard — Oracle can only mint, not withdraw; rotateable by owner
- Pausable — Emergency circuit breaker on vault
- Reentrancy guard — All state-changing functions protected
- Ownable2Step — Ownership transfer requires explicit acceptance
- UPPS upgradeable — Bug fixes possible without token migration
- Full Architecture
- Agent Handoff Instructions
- Tokenomics
- Security Model
- Frontend Guide
- Mainnet Deployment Guide
- Oracle Service
MIT