Skip to content

Commit 03b8763

Browse files
committed
feat(ecdsa): add deployment infrastructure for beta staker consolidation
Add complete deployment workflow for Allowlist integration and operator weight migration with support for Ownable2StepUpgradeable pattern. Changes: - Add deployment script for WalletRegistry V2 upgrade with atomic initializeV2 execution via upgradeToAndCall pattern - Fix Allowlist deployment to defer ownership transfer until after weight initialization (prevents Ownable2Step pendingOwner issue) - Update weight initialization script to use actual contract owner and complete two-step ownership transfer to governance at end - Configure Sepolia and Mainnet named accounts for proper deployment authority (0x68ad60CC for Sepolia, 0x716089 for Mainnet deployer) - Add allowlist operator weights data with accumulated stakes from consolidated beta staker groups (1.3B total T vs 743M individual) - Add .env configuration infrastructure with template and gitignore rules to protect private keys Technical notes: - Script 17 uses upgradeToAndCall to atomically upgrade proxy and call initializeV2, preventing front-running window - Script 16 defers to actual contract owner() instead of assuming governance, fixing Ownable2StepUpgradeable compatibility - Beta staker weights accumulate all T stake from provider groups (e.g., P2P: 200M T from 6 operators vs 20M T from staying node) - Ownership transfer initiates at script end but requires governance to call acceptOwnership() to complete (two-step pattern) Files: - solidity/ecdsa/deploy/17_upgrade_wallet_registry_v2.ts (new) - solidity/ecdsa/deploy/15_deploy_allowlist.ts (ownership fix) - solidity/ecdsa/deploy/16_initialize_allowlist_weights.ts (owner fix) - solidity/ecdsa/deploy/data/allowlist-weights.json (new) - solidity/ecdsa/.env.example (new) - solidity/ecdsa/.gitignore (env protection) - solidity/ecdsa/hardhat.config.ts (named accounts)
1 parent 95cb2e6 commit 03b8763

File tree

7 files changed

+1184
-88
lines changed

7 files changed

+1184
-88
lines changed

solidity/ecdsa/.env.example

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# =============================================================================
2+
# Environment Configuration for keep-core/solidity/ecdsa
3+
# =============================================================================
4+
# Copy this file to .env and fill in your values.
5+
# NEVER commit .env files with private keys!
6+
# =============================================================================
7+
8+
# -----------------------------------------------------------------------------
9+
# RPC Endpoint (required for Sepolia and Mainnet)
10+
# -----------------------------------------------------------------------------
11+
# Use Alchemy, Infura, or another provider
12+
# Example: https://eth-sepolia.g.alchemy.com/v2/YOUR_API_KEY
13+
# Example: https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY
14+
CHAIN_API_URL=
15+
16+
# -----------------------------------------------------------------------------
17+
# Sepolia Configuration
18+
# -----------------------------------------------------------------------------
19+
# Comma-separated list of private keys (without 0x prefix)
20+
# The first key should correspond to: 0x68ad60CC5e8f3B7cC53beaB321cf0e6036962dBc
21+
ACCOUNTS_PRIVATE_KEYS=
22+
23+
# -----------------------------------------------------------------------------
24+
# Mainnet Configuration
25+
# -----------------------------------------------------------------------------
26+
# Single private key for the deployer account (without 0x prefix)
27+
# Should correspond to: 0x716089154304f22a2F9c8d2f8C45815183BF3532
28+
CONTRACT_OWNER_ACCOUNT_PRIVATE_KEY=
29+
30+
# -----------------------------------------------------------------------------
31+
# Contract Verification (optional but recommended)
32+
# -----------------------------------------------------------------------------
33+
# Get your API key from https://etherscan.io/myapikey
34+
ETHERSCAN_API_KEY=
35+
36+
# -----------------------------------------------------------------------------
37+
# Forking Configuration (optional, for local testing)
38+
# -----------------------------------------------------------------------------
39+
# URL for forking mainnet state (requires archive node access)
40+
# FORKING_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY
41+
# FORKING_BLOCK=
42+
43+
# -----------------------------------------------------------------------------
44+
# External Deployments (optional)
45+
# -----------------------------------------------------------------------------
46+
# Set to "true" to use external contract deployments
47+
# USE_EXTERNAL_DEPLOY=false

solidity/ecdsa/.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,13 @@ deployments/*
1313

1414
# OpenZeppelin
1515
.openzeppelin/unknown-*.json
16+
17+
# Environment variables (NEVER commit private keys!)
18+
.env
19+
.env.local
20+
.env.*.local
21+
.env.sepolia
22+
.env.mainnet
23+
24+
# Migration results (may contain sensitive info)
25+
migration-results.json

solidity/ecdsa/deploy/15_deploy_allowlist.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,27 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
2424
}
2525
)
2626

27-
// Transfer ownership to governance if specified and different from deployer
28-
if (governance && governance !== deployer) {
29-
await helpers.ownable.transferOwnership("Allowlist", governance, deployer)
30-
}
27+
// IMPORTANT: Do NOT transfer ownership here!
28+
// Allowlist uses Ownable2StepUpgradeable which requires two steps:
29+
// 1. transferOwnership(newOwner) - sets pendingOwner
30+
// 2. acceptOwnership() - new owner must call to complete transfer
31+
//
32+
// If we transfer here, script 16 would fail because:
33+
// - governance becomes pendingOwner (not owner)
34+
// - deployer is still the actual owner
35+
// - script 16 would try to use governance signer → onlyOwner fails
36+
//
37+
// Ownership transfer is handled at the END of script 16 after weights are set.
3138

3239
// Log deployment information
3340
console.log(`Allowlist deployed at: ${allowlist.address}`)
3441
console.log(
3542
`Allowlist proxy admin: ${proxyDeployment.receipt.contractAddress}`
3643
)
37-
console.log(`Allowlist owner: ${await allowlist.owner()}`)
44+
console.log(`Allowlist owner: ${await allowlist.owner()} (deployer)`)
45+
if (governance && governance !== deployer) {
46+
console.log(`Ownership will be transferred to governance (${governance}) after weights initialization`)
47+
}
3848

3949
return true
4050
}

0 commit comments

Comments
 (0)