This guide covers deploying to Base Sepolia testnet specifically. For general deployment information, see docs/DEPLOYMENT.md.
Two options:
- Ledger (recommended) — Hardware wallet for production-grade security
- Private Key — For CI/automated deployments
- Connect Ledger and open the Ethereum app
- Enable "Blind signing" in Settings
- Keep device connected and unlocked throughout deployment
Fund your Ledger address from the Base faucet: https://www.coinbase.com/faucets/base-ethereum-sepolia-faucet
Budget 0.05 ETH for deployment costs.
Create .env.sepolia in the repository root:
# Network
BASE_SEPOLIA_RPC_URL=https://sepolia.base.org
BASESCAN_API_KEY=your_basescan_api_key
# Protocol Configuration
ADMIN_MSIG=0xYourGnosisSafeAddress
INITIAL_TREASURY=0xYourTreasuryAddress
# Leave empty to deploy mock router (recommended for testing)
UNISWAP_V2_ROUTER=No private key needed for Ledger deployment.
bash scripts/deploy-sepolia.sh --ledger
# Or with specific address:
bash scripts/deploy-sepolia.sh --ledger --ledger-address 0xYourAddressApprove each transaction on the Ledger device.
bash scripts/verify-sepolia.shFor automated deployments without hardware wallet:
# Add to .env.sepolia
DEPLOYER_PRIVATE_KEY=your_private_key_herebash scripts/deploy-sepolia.sh --private-keySecurity: Remove DEPLOYER_PRIVATE_KEY from the file after deployment.
We deploy a mock Uniswap V2-compatible router for testing. This provides:
- Full control over bonding curve testing
- No external dependencies
- Consistent behavior with local development
AppModuleFactory exceeds the 24KB limit and is skipped on Base Sepolia. Core functionality still works:
- App launches work
- Bonding curves work
- Staking and rewards work
- Module deployment (InAppContent721, ContentStore, etc.) unavailable on testnet
This resolves automatically on Base Mainnet, which doesn't enforce the limit.
- Total deployment: ~15-20M gas
- At 1 gwei: ~0.015-0.02 ETH
- Recommended budget: 0.05 ETH
After deployment:
deployments/base-sepolia-deployment.json— Contract addressesbroadcast/Deploy.sol/84532/— Foundry broadcast logs
- All contracts deployed successfully
- All contracts verified on BaseScan
- Initial ELTA minted to multisig
- Multisig has admin roles
- Verification script passes
- Timelock permissions configured (see below)
- Vercel environment variables updated
- Private key removed from
.env.sepolia
The multisig must grant Governor permissions on the Timelock:
# Grant PROPOSER_ROLE to Governor
cast send $TIMELOCK_ADDRESS \
"grantRole(bytes32,address)" \
0xb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1 \
$GOVERNOR_ADDRESS \
--rpc-url $BASE_SEPOLIA_RPC_URL
# Grant EXECUTOR_ROLE to Governor
cast send $TIMELOCK_ADDRESS \
"grantRole(bytes32,address)" \
0xfd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783 \
$GOVERNOR_ADDRESS \
--rpc-url $BASE_SEPOLIA_RPC_URLOr use Gnosis Safe Transaction Builder.
Configure your frontend application with the deployed contract addresses.
See deployments/base-sepolia.json for all addresses.
Required contract addresses:
- ELTA token
- AppFactory
- AppModuleFactory
- RewardsDistributor
- AppRewardsDistributor
- VeELTA
- ElataPoints (XP)
See the frontend repository documentation for environment variable configuration.
- Verify RPC URL is accessible
- Check deployer has sufficient ETH
- Confirm all environment variables are set
- Ensure BaseScan API key is valid
- Wait 30 seconds after deployment before verifying
- Try manual verification on BaseScan
Expected for AppModuleFactory. It deploys successfully on L2s without the 24KB limit.
- Run end-to-end tests against testnet
- Send test ELTA from multisig to test wallets
- Launch a test app
- Verify bonding curve buys and sells work
- Test staking and reward claims
- Document any issues