@@ -17,18 +17,34 @@ contract StakingRewardsV2 is RewardsDistributionRecipient, ReentrancyGuard {
17
17
18
18
/* ========== STATE VARIABLES ========== */
19
19
20
+ /// @notice Token to be distributed to stakers
20
21
IERC20 public rewardsToken;
22
+
23
+ /// @notice Token to be staked in the contract
21
24
IERC20 public stakingToken;
25
+
26
+ /// @notice Timestamp at which the staking rewards end
22
27
uint256 public periodFinish = 0 ;
28
+
29
+ /// @notice Number of tokens rewarded per unit time
23
30
uint256 public rewardRate = 0 ;
31
+
32
+ /// @notice Duration for which rewards are applied
24
33
uint256 public rewardsDuration;
34
+
25
35
uint256 public lastUpdateTime;
26
36
uint256 public rewardPerTokenStored;
27
37
28
38
mapping (address => uint256 ) public userRewardPerTokenPaid;
39
+
40
+ /// @notice Accumulated number of `rewardsToken` per address remaining to be claimed.
41
+ /// Once a staker claims the rewards, it is reset to 0.
29
42
mapping (address => uint256 ) public rewards;
30
43
44
+ /// @notice Total number of staked tokens
31
45
uint256 private _totalSupply;
46
+
47
+ /// @notice Number of staked tokens per address
32
48
mapping (address => uint256 ) private _balances;
33
49
34
50
/* ========== CONSTRUCTOR ========== */
@@ -47,14 +63,21 @@ contract StakingRewardsV2 is RewardsDistributionRecipient, ReentrancyGuard {
47
63
48
64
/* ========== VIEWS ========== */
49
65
66
+ // Number of total staked tokens
50
67
function totalSupply () external view returns (uint256 ) {
51
68
return _totalSupply;
52
69
}
53
70
71
+ /**
72
+ * @notice Get the number of tokens staked by the `account`
73
+ * @param account The address of the account to get the balance of
74
+ * @return The number of tokens staked
75
+ */
54
76
function balanceOf (address account ) external view returns (uint256 ) {
55
77
return _balances[account];
56
78
}
57
79
80
+ /// @return last time when the reward was applied.
58
81
function lastTimeRewardApplicable () public view returns (uint256 ) {
59
82
return Math.min (block .timestamp , periodFinish);
60
83
}
@@ -69,16 +92,21 @@ contract StakingRewardsV2 is RewardsDistributionRecipient, ReentrancyGuard {
69
92
);
70
93
}
71
94
95
+ /**
96
+ * @notice Accumulated number of `rewardsToken` remaining to be claimed by `address`.
97
+ */
72
98
function earned (address account ) public view returns (uint256 ) {
73
99
return _balances[account].mul (rewardPerToken ().sub (userRewardPerTokenPaid[account])).div (1e18 ).add (rewards[account]);
74
100
}
75
101
102
+ /// @notice Get the number of rewardsToken to be rewarded for `rewardsDuration`
76
103
function getRewardForDuration () external view returns (uint256 ) {
77
104
return rewardRate.mul (rewardsDuration);
78
105
}
79
106
80
107
/* ========== MUTATIVE FUNCTIONS ========== */
81
108
109
+ /// @notice Transfer `amount` of stakingToken from `msg.sender` to this contract for staking
82
110
function stake (uint256 amount ) external nonReentrant updateReward (msg .sender ) {
83
111
require (amount > 0 , "Cannot stake 0 " );
84
112
_totalSupply = _totalSupply.add (amount);
@@ -87,6 +115,7 @@ contract StakingRewardsV2 is RewardsDistributionRecipient, ReentrancyGuard {
87
115
emit Staked (msg .sender , amount);
88
116
}
89
117
118
+ /// @notice Unstake `amount` number of staked tokens by `msg.sender`
90
119
function withdraw (uint256 amount ) public nonReentrant updateReward (msg .sender ) {
91
120
require (amount > 0 , "Cannot withdraw 0 " );
92
121
_totalSupply = _totalSupply.sub (amount);
@@ -95,6 +124,7 @@ contract StakingRewardsV2 is RewardsDistributionRecipient, ReentrancyGuard {
95
124
emit Withdrawn (msg .sender , amount);
96
125
}
97
126
127
+ /// @notice Transfer the staking rewards from contract to `msg.sender`
98
128
function getReward () public nonReentrant updateReward (msg .sender ) {
99
129
uint256 reward = rewards[msg .sender ];
100
130
if (reward > 0 ) {
@@ -104,13 +134,22 @@ contract StakingRewardsV2 is RewardsDistributionRecipient, ReentrancyGuard {
104
134
}
105
135
}
106
136
137
+ /// @notice Unstake all the staked tokens by `msg.sender` and claim the rewards
107
138
function exit () external {
108
139
withdraw (_balances[msg .sender ]);
109
140
getReward ();
110
141
}
111
142
112
143
/* ========== RESTRICTED FUNCTIONS ========== */
113
144
145
+ /**
146
+ * @notice Update the number of `rewardsToken` to be rewarded to stakers.
147
+ The updated reward is only applicable from the next block.
148
+ If the staking period is over, ie, if the current block occurs at or after
149
+ `periodFinish` has passed, a fresh reward period starts with
150
+ duration=`rewardsDuration`.
151
+ * @param reward number of `rewardsToken` to to be rewarded from now on.
152
+ */
114
153
function notifyRewardAmount (uint256 reward ) external override onlyRewardsDistribution updateReward (address (0 )) {
115
154
if (block .timestamp >= periodFinish) {
116
155
rewardRate = reward.div (rewardsDuration);
@@ -134,6 +173,7 @@ contract StakingRewardsV2 is RewardsDistributionRecipient, ReentrancyGuard {
134
173
135
174
/* ========== MODIFIERS ========== */
136
175
176
+ /// @notice Update rewards for an address along with bookkeeping variables
137
177
modifier updateReward (address account ) {
138
178
rewardPerTokenStored = rewardPerToken ();
139
179
lastUpdateTime = lastTimeRewardApplicable ();
0 commit comments