Skip to content

Commit 8ec9d23

Browse files
authored
chore(protocol-contracts): add staking tasks (#1397)
1 parent ae22adc commit 8ec9d23

36 files changed

+4241
-45
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
PRIVATE_KEY=
2+
ETHERSCAN_API_KEY=
3+
4+
# Mainnet
5+
MAINNET_RPC_URL=
6+
# Testnet
7+
SEPOLIA_RPC_URL=
8+
9+
# ----------------------------------------------------------------------------
10+
# ProtocolStaking deployment and configuration
11+
# ----------------------------------------------------------------------------
12+
# Address of the underlying staking ERC20
13+
ZAMA_TOKEN_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3
14+
15+
# Address of the governance DAO
16+
DAO_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 # accounts[1] (address)
17+
18+
# ----------------------------------------------------------------------------
19+
# Coprocessor
20+
# ----------------------------------------------------------------------------
21+
PROTOCOL_STAKING_COPRO_TOKEN_NAME=ProtocolStakingCoprocessors
22+
PROTOCOL_STAKING_COPRO_TOKEN_SYMBOL=stZAMAcoprocessors
23+
PROTOCOL_STAKING_COPRO_VERSION=1
24+
25+
# Cooldown period in seconds before unstaked tokens can be released
26+
PROTOCOL_STAKING_COPRO_COOLDOWN_PERIOD=604800 # 7 days
27+
28+
# Initial reward rate
29+
# Note: The reward rate is in tokens (using 18 decimals) per second
30+
PROTOCOL_STAKING_COPRO_REWARD_RATE=10000000000000000
31+
32+
# ----------------------------------------------------------------------------
33+
# KMS
34+
# ----------------------------------------------------------------------------
35+
PROTOCOL_STAKING_KMS_TOKEN_NAME=ProtocolStakingKMS
36+
PROTOCOL_STAKING_KMS_TOKEN_SYMBOL=stZAMAkms
37+
PROTOCOL_STAKING_KMS_VERSION=1
38+
39+
# Cooldown period in seconds before unstaked tokens can be released
40+
PROTOCOL_STAKING_KMS_COOLDOWN_PERIOD=604800 # 7 days
41+
42+
# Initial reward rate
43+
# Note: The reward rate is in tokens (using 18 decimals) per second
44+
PROTOCOL_STAKING_KMS_REWARD_RATE=10000000000000000
45+
46+
# ----------------------------------------------------------------------------
47+
# OperatorStaking deployment and configuration
48+
# ----------------------------------------------------------------------------
49+
# ----------------------------------------------------------------------------
50+
# Coprocessor
51+
# ----------------------------------------------------------------------------
52+
# The number of OperatorStaking for coprocessors must be equal to the number of addresses defined below
53+
NUM_OPERATOR_STAKING_COPRO=2
54+
55+
# OperatorStaking coprocessor 1
56+
OPERATOR_STAKING_COPRO_TOKEN_NAME_0="OperatorStakingCopro1"
57+
OPERATOR_STAKING_COPRO_TOKEN_SYMBOL_0="stZAMAcopro1"
58+
OPERATOR_STAKING_COPRO_OWNER_ADDRESS_0="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" # accounts[0] (address)
59+
60+
# Initial assets (in the smallest unit of $ZAMA, using 10^18 decimals) and receiver
61+
OPERATOR_STAKING_COPRO_INITIAL_DEPOSIT_ASSETS_0=100000000000000000000000
62+
OPERATOR_STAKING_COPRO_INITIAL_DEPOSIT_RECEIVER_0="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" # accounts[0] (address)
63+
64+
# OperatorRewarder coprocessor 1
65+
# Initial owner fee
66+
# Note: The owner fee is in basis points (in 1/100th of a percent, so 10000 = 100.00%)
67+
OPERATOR_REWARDER_COPRO_OWNER_FEE_0=2000
68+
69+
# OperatorStaking coprocessor 2
70+
OPERATOR_STAKING_COPRO_TOKEN_NAME_1="OperatorStakingCopro2"
71+
OPERATOR_STAKING_COPRO_TOKEN_SYMBOL_1="stZAMAcopro2"
72+
OPERATOR_STAKING_COPRO_OWNER_ADDRESS_1="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" # accounts[0] (address)
73+
74+
# Initial assets (in the smallest unit of $ZAMA, using 10^18 decimals) and receiver
75+
OPERATOR_STAKING_COPRO_INITIAL_DEPOSIT_ASSETS_1=250000000000000000000000
76+
OPERATOR_STAKING_COPRO_INITIAL_DEPOSIT_RECEIVER_1="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" # accounts[0] (address)
77+
78+
# OperatorRewarder coprocessor 2
79+
# Initial owner fee
80+
# Note: The owner fee is in basis points (in 1/100th of a percent, so 10000 = 100.00%)
81+
OPERATOR_REWARDER_COPRO_OWNER_FEE_1=1000
82+
83+
# ----------------------------------------------------------------------------
84+
# KMS
85+
# ----------------------------------------------------------------------------
86+
# The number of OperatorStaking for KMS must be equal to the number of addresses defined below
87+
NUM_OPERATOR_STAKING_KMS=3
88+
89+
# OperatorStaking KMS 1
90+
OPERATOR_STAKING_KMS_TOKEN_NAME_0="OperatorStakingKms1"
91+
OPERATOR_STAKING_KMS_TOKEN_SYMBOL_0="stZAMAkms1"
92+
OPERATOR_STAKING_KMS_OWNER_ADDRESS_0="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" # accounts[0] (address)
93+
94+
# Initial assets (in the smallest unit of $ZAMA, using 10^18 decimals) and receiver
95+
OPERATOR_STAKING_KMS_INITIAL_DEPOSIT_ASSETS_0=500000000000000000000000
96+
OPERATOR_STAKING_KMS_INITIAL_DEPOSIT_RECEIVER_0="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" # accounts[0] (address)
97+
98+
# OperatorRewarder KMS 1
99+
# Initial owner fee
100+
# Note: The owner fee is in basis points (in 1/100th of a percent, so 10000 = 100.00%)
101+
OPERATOR_REWARDER_KMS_OWNER_FEE_0=1500
102+
103+
# OperatorStaking KMS 2
104+
OPERATOR_STAKING_KMS_TOKEN_NAME_1="OperatorStakingKms2"
105+
OPERATOR_STAKING_KMS_TOKEN_SYMBOL_1="stZAMAkms2"
106+
OPERATOR_STAKING_KMS_OWNER_ADDRESS_1="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" # accounts[0] (address)
107+
108+
# Initial assets (in the smallest unit of $ZAMA, using 10^18 decimals) and receiver
109+
OPERATOR_STAKING_KMS_INITIAL_DEPOSIT_ASSETS_1=750000000000000000000000
110+
OPERATOR_STAKING_KMS_INITIAL_DEPOSIT_RECEIVER_1="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" # accounts[0] (address)
111+
112+
# OperatorRewarder KMS 2
113+
# Initial owner fee
114+
# Note: The owner fee is in basis points (in 1/100th of a percent, so 10000 = 100.00%)
115+
OPERATOR_REWARDER_KMS_OWNER_FEE_1=1000
116+
117+
# OperatorStaking KMS 3
118+
OPERATOR_STAKING_KMS_TOKEN_NAME_2="OperatorStakingKms3"
119+
OPERATOR_STAKING_KMS_TOKEN_SYMBOL_2="stZAMAkms3"
120+
OPERATOR_STAKING_KMS_OWNER_ADDRESS_2="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" # accounts[0] (address)
121+
122+
# Initial assets (in the smallest unit of $ZAMA, using 10^18 decimals) and receiver
123+
OPERATOR_STAKING_KMS_INITIAL_DEPOSIT_ASSETS_2=1000000000000000000000000
124+
OPERATOR_STAKING_KMS_INITIAL_DEPOSIT_RECEIVER_2="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" # accounts[0] (address)
125+
126+
# OperatorRewarder KMS 3
127+
# Initial owner fee
128+
# Note: The owner fee is in basis points (in 1/100th of a percent, so 10000 = 100.00%)
129+
OPERATOR_REWARDER_KMS_OWNER_FEE_2=500

protocol-contracts/staking/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ build/site
4242
# only used to package @openzeppelin/contracts
4343
contracts/build/
4444
contracts/README.md
45+
.openzeppelin
4546

4647
# temporary artifact from solidity-coverage
4748
allFiredEvents
@@ -56,6 +57,7 @@ contracts-exposed
5657
/cache
5758
/artifacts
5859
/types
60+
/deployments
5961

6062
# Foundry
6163
/out
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
include .env.example
2+
3+
ENV_PATH=.env.example
4+
5+
prettier:
6+
npx prettier . --write
7+
8+
compile:
9+
npx hardhat compile
10+
11+
clean:
12+
npx hardhat clean
13+
14+
get-accounts:
15+
DOTENV_CONFIG_PATH=$(ENV_PATH) npx hardhat get-accounts
16+
17+
# Define it as a phony target to avoid conflicts with the test directory
18+
.PHONY: test
19+
test: clean
20+
DOTENV_CONFIG_PATH=$(ENV_PATH) npx hardhat test --network hardhat $(if $(GREP),--grep '$(GREP)',)
21+
22+
test-tasks: clean
23+
DOTENV_CONFIG_PATH=$(ENV_PATH) npx hardhat test-tasks --network hardhat $(if $(GREP),--grep '$(GREP)',)
24+
25+
26+
# Conform to pre-commit checks
27+
conformance: prettier

protocol-contracts/staking/contracts/ProtocolStaking.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ interface IERC20Mintable is IERC20 {
1919

2020
/**
2121
* @dev Staking contract that distributes newly minted tokens to eligible accounts at a configurable flow rate.
22-
*
22+
*
2323
* NOTE: This staking contract does not support non-standard ERC-20 tokens such as fee-on-transfer or rebasing tokens.
2424
* @custom:security-contact security@zama.ai
2525
*/

protocol-contracts/staking/eslint.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import js from '@eslint/js';
21
import { includeIgnoreFile } from '@eslint/compat';
2+
import js from '@eslint/js';
33
import prettier from 'eslint-config-prettier';
44
import globals from 'globals';
55
import path from 'path';

protocol-contracts/staking/hardhat.config.ts

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,85 @@
1+
import './tasks/accounts';
2+
import './tasks/addEligibleAccount';
3+
import './tasks/deployment';
4+
import './tasks/deposit';
5+
import './tasks/ownership';
6+
import './tasks/setOwnerFee';
7+
import './tasks/setRewardRate';
8+
import './tasks/verify';
19
import '@nomicfoundation/hardhat-chai-matchers';
210
import '@nomicfoundation/hardhat-ethers';
11+
import '@nomicfoundation/hardhat-verify';
312
import '@openzeppelin/hardhat-upgrades';
413
import '@typechain/hardhat';
514
import dotenv from 'dotenv';
15+
import { existsSync } from 'fs';
16+
import 'hardhat-deploy';
617
import 'hardhat-exposed';
718
import 'hardhat-gas-reporter';
819
import 'hardhat-ignore-warnings';
9-
import { HardhatUserConfig } from 'hardhat/config';
20+
import { task, types } from 'hardhat/config';
21+
import { HardhatUserConfig, HttpNetworkAccountsUserConfig } from 'hardhat/types';
22+
import { resolve } from 'path';
1023
import 'solidity-coverage';
1124

12-
dotenv.config();
25+
// Get the environment configuration from .env file
26+
//
27+
// To make use of automatic environment setup:
28+
// - Duplicate .env.example file and name it .env
29+
// - Fill in the environment variables
30+
31+
// Set your preferred authentication method
32+
//
33+
// If you prefer using a mnemonic, set a MNEMONIC environment variable
34+
// to a valid mnemonic
35+
const MNEMONIC = process.env.MNEMONIC;
36+
37+
// If you prefer to be authenticated using a private key, set a PRIVATE_KEY environment variable
38+
const PRIVATE_KEY = process.env.PRIVATE_KEY;
39+
40+
const accounts: HttpNetworkAccountsUserConfig | undefined = MNEMONIC
41+
? { mnemonic: MNEMONIC }
42+
: PRIVATE_KEY
43+
? [PRIVATE_KEY]
44+
: undefined;
45+
46+
if (accounts == null) {
47+
console.warn(
48+
'Could not find MNEMONIC or PRIVATE_KEY environment variables. It will not be possible to execute transactions in your example.',
49+
);
50+
}
51+
52+
// Run the test suite for tasks with environment variables from `.env.example`
53+
task('test:tasks', 'Runs the test suite for tasks with environment variables from .env.example')
54+
.addOptionalParam('skipSetup', 'Set to true to skip setup tasks', false, types.boolean)
55+
.setAction(async (taskArgs, hre) => {
56+
// Load `.env.example`
57+
const envExamplePath = resolve(__dirname, '.env.example');
58+
if (existsSync(envExamplePath)) {
59+
dotenv.config({ path: envExamplePath, override: true });
60+
}
61+
62+
if (!taskArgs.skipSetup) {
63+
// Compile the contracts
64+
await hre.run('compile');
65+
66+
// Deploy mocked ERC20 Zama token
67+
await hre.run('task:deployERC20MockAndMintDeployer');
68+
69+
// Deploy all protocol staking contracts
70+
await hre.run('task:deployAllProtocolStakingContracts');
71+
72+
// Deploy all operator staking contracts
73+
await hre.run('task:deployAllOperatorStakingContracts');
74+
} else {
75+
console.log('Skipping contracts setup.');
76+
}
77+
await hre.run('test', ['test-tasks/**/*.test.ts']);
78+
});
1379

1480
const config: HardhatUserConfig = {
1581
solidity: {
16-
version: '0.8.29',
82+
version: '0.8.27',
1783
settings: {
1884
optimizer: {
1985
enabled: true,
@@ -22,6 +88,37 @@ const config: HardhatUserConfig = {
2288
evmVersion: 'cancun',
2389
},
2490
},
91+
networks: {
92+
mainnet: {
93+
url: process.env.MAINNET_RPC_URL || '',
94+
accounts,
95+
},
96+
testnet: {
97+
url: process.env.SEPOLIA_RPC_URL || '',
98+
accounts,
99+
},
100+
hardhat: {
101+
// Need this to avoid deployment issues in test
102+
saveDeployments: false,
103+
},
104+
},
105+
namedAccounts: {
106+
deployer: {
107+
default: 0, // wallet address of index[0], of the mnemonic in .env
108+
},
109+
alice: {
110+
default: 1, // wallet address of index[1], of the mnemonic in .env
111+
},
112+
bob: {
113+
default: 2, // wallet address of index[2], of the mnemonic in .env
114+
},
115+
charlie: {
116+
default: 3, // wallet address of index[3], of the mnemonic in .env
117+
},
118+
dave: {
119+
default: 4, // wallet address of index[4], of the mnemonic in .env
120+
},
121+
},
25122
gasReporter: {
26123
currency: 'USD',
27124
enabled: !!process.env.REPORT_GAS,
@@ -32,6 +129,9 @@ const config: HardhatUserConfig = {
32129
outDir: 'types',
33130
target: 'ethers-v6',
34131
},
132+
etherscan: {
133+
apiKey: process.env.ETHERSCAN_API_KEY!,
134+
},
35135
exposed: {
36136
imports: true,
37137
initializers: true,

0 commit comments

Comments
 (0)