Skip to content

Commit 6d293ec

Browse files
authored
feat(protocol-contracts): add reward rate in protocol staking constructor (#1472)
1 parent 0baa6d6 commit 6d293ec

File tree

5 files changed

+64
-55
lines changed

5 files changed

+64
-55
lines changed

protocol-contracts/staking/contracts/ProtocolStaking.sol

Lines changed: 18 additions & 8 deletions
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 [email protected]
2525
*/
@@ -91,7 +91,8 @@ contract ProtocolStaking is AccessControlDefaultAdminRulesUpgradeable, ERC20Vote
9191
address governor,
9292
address upgrader,
9393
address manager,
94-
uint48 initialUnstakeCooldownPeriod
94+
uint48 initialUnstakeCooldownPeriod,
95+
uint256 initialRewardRate
9596
) public initializer {
9697
__AccessControlDefaultAdminRules_init(0, governor);
9798
_grantRole(UPGRADER_ROLE, upgrader);
@@ -101,6 +102,7 @@ contract ProtocolStaking is AccessControlDefaultAdminRulesUpgradeable, ERC20Vote
101102
__EIP712_init(name, version);
102103
_getProtocolStakingStorage()._stakingToken = stakingToken_;
103104
_setUnstakeCooldownPeriod(initialUnstakeCooldownPeriod);
105+
_setRewardRate(initialRewardRate);
104106
}
105107

106108
/**
@@ -173,12 +175,7 @@ contract ProtocolStaking is AccessControlDefaultAdminRulesUpgradeable, ERC20Vote
173175
* @param rewardRate_ The new reward rate in tokens per second.
174176
*/
175177
function setRewardRate(uint256 rewardRate_) public onlyRole(MANAGER_ROLE) {
176-
ProtocolStakingStorage storage $ = _getProtocolStakingStorage();
177-
$._lastUpdateReward = _historicalReward();
178-
$._lastUpdateTimestamp = Time.timestamp();
179-
$._rewardRate = rewardRate_;
180-
181-
emit RewardRateSet(rewardRate_);
178+
_setRewardRate(rewardRate_);
182179
}
183180

184181
/**
@@ -322,6 +319,19 @@ contract ProtocolStaking is AccessControlDefaultAdminRulesUpgradeable, ERC20Vote
322319
emit UnstakeCooldownPeriodSet(unstakeCooldownPeriod_);
323320
}
324321

322+
/**
323+
* @dev Sets the reward rate in tokens per second.
324+
* @param rewardRate_ The new reward rate in tokens per second.
325+
*/
326+
function _setRewardRate(uint256 rewardRate_) internal {
327+
ProtocolStakingStorage storage $ = _getProtocolStakingStorage();
328+
$._lastUpdateReward = _historicalReward();
329+
$._lastUpdateTimestamp = Time.timestamp();
330+
$._rewardRate = rewardRate_;
331+
332+
emit RewardRateSet(rewardRate_);
333+
}
334+
325335
function _updateRewards(address user, uint256 weightBefore, uint256 weightAfter) internal {
326336
ProtocolStakingStorage storage $ = _getProtocolStakingStorage();
327337
uint256 oldTotalWeight = $._totalEligibleStakedWeight;

protocol-contracts/staking/tasks/deployment/protocolStaking.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ async function deployProtocolStaking(
2020
symbol: string,
2121
version: string,
2222
cooldown: number,
23+
rewardRate: bigint,
2324
hre: HardhatRuntimeEnvironment,
2425
) {
2526
const { getNamedAccounts, ethers, deployments, upgrades, network } = hre;
@@ -39,7 +40,7 @@ async function deployProtocolStaking(
3940
const protocolStakingFactory = await ethers.getContractFactory(PROTOCOL_STAKING_CONTRACT_NAME, deployerSigner);
4041
const proxy = await upgrades.deployProxy(
4142
protocolStakingFactory,
42-
[tokenName, symbol, version, zamaTokenAddress, deployer, daoAddress, deployer, cooldown],
43+
[tokenName, symbol, version, zamaTokenAddress, deployer, daoAddress, deployer, cooldown, rewardRate],
4344
{ kind: 'uups', initializer: 'initialize' },
4445
);
4546
await proxy.waitForDeployment();
@@ -74,9 +75,10 @@ task('task:deployProtocolStakingCopro').setAction(async function (_, hre) {
7475
const coproTokenSymbol = getRequiredEnvVar('PROTOCOL_STAKING_COPRO_TOKEN_SYMBOL');
7576
const coproVersion = getRequiredEnvVar('PROTOCOL_STAKING_COPRO_VERSION');
7677
const coproCooldown = parseInt(getRequiredEnvVar('PROTOCOL_STAKING_COPRO_COOLDOWN_PERIOD'));
78+
const coproRewardRate = BigInt(parseInt(getRequiredEnvVar('PROTOCOL_STAKING_COPRO_REWARD_RATE')));
7779

7880
// Deploy the coprocessor protocol staking contract
79-
await deployProtocolStaking(coproTokenName, coproTokenSymbol, coproVersion, coproCooldown, hre);
81+
await deployProtocolStaking(coproTokenName, coproTokenSymbol, coproVersion, coproCooldown, coproRewardRate, hre);
8082
});
8183

8284
// Deploy the KMS ProtocolStaking contracts
@@ -90,9 +92,10 @@ task('task:deployProtocolStakingKMS').setAction(async function (_, hre) {
9092
const kmsTokenSymbol = getRequiredEnvVar('PROTOCOL_STAKING_KMS_TOKEN_SYMBOL');
9193
const kmsVersion = getRequiredEnvVar('PROTOCOL_STAKING_KMS_VERSION');
9294
const kmsCooldown = parseInt(getRequiredEnvVar('PROTOCOL_STAKING_KMS_COOLDOWN_PERIOD'));
95+
const kmsRewardRate = BigInt(parseInt(getRequiredEnvVar('PROTOCOL_STAKING_KMS_REWARD_RATE')));
9396

9497
// Deploy the KMS protocol staking contract
95-
await deployProtocolStaking(kmsTokenName, kmsTokenSymbol, kmsVersion, kmsCooldown, hre);
98+
await deployProtocolStaking(kmsTokenName, kmsTokenSymbol, kmsVersion, kmsCooldown, kmsRewardRate, hre);
9699
});
97100

98101
// Deploy the ProtocolStaking contracts

protocol-contracts/staking/test/OperatorRewarder.test.ts

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,19 @@ describe('OperatorRewarder', function () {
1212
const [staker1, staker2, admin, anyone, ...accounts] = await ethers.getSigners();
1313

1414
const token = await ethers.deployContract('$ERC20Mock', ['StakingToken', 'ST', 18]);
15-
const protocolStaking = await ethers
16-
.getContractFactory('ProtocolStakingSlashingMock')
17-
.then(factory =>
18-
upgrades.deployProxy(factory, [
19-
'StakedToken',
20-
'SST',
21-
'1',
22-
token.target,
23-
admin.address,
24-
admin.address,
25-
admin.address,
26-
60 /* 1 min */,
27-
]),
28-
);
15+
const protocolStaking = await ethers.getContractFactory('ProtocolStakingSlashingMock').then(factory =>
16+
upgrades.deployProxy(factory, [
17+
'StakedToken',
18+
'SST',
19+
'1',
20+
token.target,
21+
admin.address,
22+
admin.address,
23+
admin.address,
24+
60 /* 1 min */, // unstake cooldown period
25+
ethers.parseEther('0.5'), // reward rate
26+
]),
27+
);
2928
const operatorStaking = await ethers.deployContract('$OperatorStaking', [
3029
'OPStake',
3130
'OP',
@@ -43,7 +42,6 @@ describe('OperatorRewarder', function () {
4342
);
4443

4544
await protocolStaking.connect(admin).addEligibleAccount(operatorStaking);
46-
await protocolStaking.connect(admin).setRewardRate(ethers.parseEther('0.5'));
4745

4846
Object.assign(this, { staker1, staker2, admin, anyone, accounts, token, operatorStaking, protocolStaking, mock });
4947
});

protocol-contracts/staking/test/OperatorStaking.test.ts

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,19 @@ describe('OperatorStaking', function () {
1111
const [staker1, staker2, admin, ...accounts] = await ethers.getSigners();
1212

1313
const token = await ethers.deployContract('$ERC20Mock', ['StakingToken', 'ST', 18]);
14-
const protocolStaking = await ethers
15-
.getContractFactory('ProtocolStakingSlashingMock')
16-
.then(factory =>
17-
upgrades.deployProxy(factory, [
18-
'StakedToken',
19-
'SST',
20-
'1',
21-
token.target,
22-
admin.address,
23-
admin.address,
24-
admin.address,
25-
60 /* 1 min */,
26-
]),
27-
);
14+
const protocolStaking = await ethers.getContractFactory('ProtocolStakingSlashingMock').then(factory =>
15+
upgrades.deployProxy(factory, [
16+
'StakedToken',
17+
'SST',
18+
'1',
19+
token.target,
20+
admin.address,
21+
admin.address,
22+
admin.address,
23+
60 /* 1 min */, // unstake cooldown period
24+
0n, // reward rate
25+
]),
26+
);
2827
const mock = await ethers.deployContract('$OperatorStaking', ['OPStake', 'OP', protocolStaking, admin.address]);
2928

3029
await Promise.all(

protocol-contracts/staking/test/ProtocolStaking.test.ts

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { anyValue } from '@nomicfoundation/hardhat-chai-matchers/withArgs';
2-
import { mine, time } from '@nomicfoundation/hardhat-network-helpers';
2+
import { time } from '@nomicfoundation/hardhat-network-helpers';
33
import { expect } from 'chai';
44
import { ethers, upgrades } from 'hardhat';
55

@@ -12,20 +12,19 @@ describe('Protocol Staking', function () {
1212
beforeEach(async function () {
1313
const [staker1, staker2, admin, upgrader, manager, anyone, ...accounts] = await ethers.getSigners();
1414
const token = await ethers.deployContract('$ERC20Mock', ['StakingToken', 'ST', 18]);
15-
const mock = await ethers
16-
.getContractFactory('ProtocolStaking')
17-
.then(factory =>
18-
upgrades.deployProxy(factory, [
19-
'StakedToken',
20-
'SST',
21-
'1',
22-
token.target,
23-
admin.address,
24-
upgrader.address,
25-
manager.address,
26-
1,
27-
]),
28-
);
15+
const mock = await ethers.getContractFactory('ProtocolStaking').then(factory =>
16+
upgrades.deployProxy(factory, [
17+
'StakedToken',
18+
'SST',
19+
'1',
20+
token.target,
21+
admin.address,
22+
upgrader.address,
23+
manager.address,
24+
1, // unstake cooldown period
25+
0n, // reward rate
26+
]),
27+
);
2928

3029
await Promise.all(
3130
[staker1, staker2].flatMap(account => [

0 commit comments

Comments
 (0)