@@ -31,11 +31,11 @@ contract StakeSablierNFT is Adminable, ERC721Holder, ISablierLockupRecipient {
31
31
ERRORS
32
32
//////////////////////////////////////////////////////////////////////////*/
33
33
34
- error AlreadyStaking (address account , uint256 tokenId );
35
- error DifferentStreamingAsset (uint256 tokenId , IERC20 rewardToken );
34
+ error AlreadyStaking (address account , uint256 streamId );
35
+ error DifferentStreamingToken (uint256 streamId , IERC20 rewardToken );
36
36
error ProvidedRewardTooHigh ();
37
37
error StakingAlreadyActive ();
38
- error UnauthorizedCaller (address account , uint256 tokenId );
38
+ error UnauthorizedCaller (address account , uint256 streamId );
39
39
error ZeroAddress (address account );
40
40
error ZeroAmount ();
41
41
error ZeroDuration ();
@@ -47,8 +47,8 @@ contract StakeSablierNFT is Adminable, ERC721Holder, ISablierLockupRecipient {
47
47
event RewardAdded (uint256 reward );
48
48
event RewardDurationUpdated (uint256 newDuration );
49
49
event RewardPaid (address indexed user , uint256 reward );
50
- event Staked (address indexed user , uint256 tokenId );
51
- event Unstaked (address indexed user , uint256 tokenId );
50
+ event Staked (address indexed user , uint256 streamId );
51
+ event Unstaked (address indexed user , uint256 streamId );
52
52
53
53
/*//////////////////////////////////////////////////////////////////////////
54
54
USER-FACING STATE
@@ -57,7 +57,7 @@ contract StakeSablierNFT is Adminable, ERC721Holder, ISablierLockupRecipient {
57
57
/// @dev The last time when rewards were updated.
58
58
uint256 public lastUpdateTime;
59
59
60
- /// @dev This should be your own ERC20 token in which the staking rewards will be distributed.
60
+ /// @dev This should be your own ERC-20 token in which the staking rewards will be distributed.
61
61
IERC20 public rewardERC20Token;
62
62
63
63
/// @dev Total rewards to be distributed per second.
@@ -74,23 +74,23 @@ contract StakeSablierNFT is Adminable, ERC721Holder, ISablierLockupRecipient {
74
74
/// - If you used Lockup Dynamic, you should use the LockupDynamic contract address.
75
75
ISablierV2Lockup public sablierLockup;
76
76
77
- /// @dev The owner of the streams mapped by tokenId .
78
- mapping (uint256 tokenId = > address account ) public stakedAssets ;
77
+ /// @dev The owners of the streams mapped by stream IDs .
78
+ mapping (uint256 streamId = > address account ) public stakedUsers ;
79
79
80
- /// @dev The staked token ID mapped by each account .
81
- mapping (address account = > uint256 tokenId ) public stakedTokenId ;
80
+ /// @dev The staked stream IDs mapped by user addresses .
81
+ mapping (address account = > uint256 streamId ) public stakedStreams ;
82
82
83
83
/// @dev The timestamp when the staking ends.
84
84
uint256 public stakingEndTime;
85
85
86
- /// @dev The total amount of ERC20 tokens staked through Sablier NFTs.
86
+ /// @dev The total amount of ERC-20 tokens staked through Sablier NFTs.
87
87
uint256 public totalERC20StakedSupply;
88
88
89
89
/// @dev Keeps track of the total rewards distributed divided by total staked supply.
90
90
uint256 public totalRewardPaidPerERC20Token;
91
91
92
- /// @dev The rewards paid to each account per ERC20 token mapped by the account.
93
- mapping (address account = > uint256 paidAmount ) public userRewardPerERC20Token;
92
+ /// @dev The rewards paid to each account per ERC-20 token mapped by the account.
93
+ mapping (address account = > uint256 reward ) public userRewardPerERC20Token;
94
94
95
95
/*//////////////////////////////////////////////////////////////////////////
96
96
MODIFIERS
@@ -111,8 +111,8 @@ contract StakeSablierNFT is Adminable, ERC721Holder, ISablierLockupRecipient {
111
111
//////////////////////////////////////////////////////////////////////////*/
112
112
113
113
/// @param initialAdmin The address of the initial contract admin.
114
- /// @param rewardERC20Token_ The address of the ERC20 token used for rewards.
115
- /// @param sablierLockup_ The address of the ERC721 Contract.
114
+ /// @param rewardERC20Token_ The address of the ERC-20 token used for rewards.
115
+ /// @param sablierLockup_ The address of the ERC-721 Contract.
116
116
constructor (address initialAdmin , IERC20 rewardERC20Token_ , ISablierV2Lockup sablierLockup_ ) {
117
117
admin = initialAdmin;
118
118
rewardERC20Token = rewardERC20Token_;
@@ -127,13 +127,12 @@ contract StakeSablierNFT is Adminable, ERC721Holder, ISablierLockupRecipient {
127
127
/// @param account The address of the account to calculate available rewards for.
128
128
/// @return earned The amount available as rewards for the account.
129
129
function calculateUserRewards (address account ) public view returns (uint256 earned ) {
130
- if (stakedTokenId [account] == 0 ) {
130
+ if (stakedStreams [account] == 0 ) {
131
131
return rewards[account];
132
132
}
133
133
134
- uint256 amountInStream = _getAmountInStream (stakedTokenId [account]);
134
+ uint256 amountInStream = _getAmountInStream (stakedStreams [account]);
135
135
uint256 userRewardPerERC20Token_ = userRewardPerERC20Token[account];
136
-
137
136
uint256 rewardsSinceLastTime = (amountInStream * (rewardPaidPerERC20Token () - userRewardPerERC20Token_)) / 1e18 ;
138
137
139
138
return rewardsSinceLastTime + rewards[account];
@@ -144,10 +143,10 @@ contract StakeSablierNFT is Adminable, ERC721Holder, ISablierLockupRecipient {
144
143
return block .timestamp < stakingEndTime ? block .timestamp : stakingEndTime;
145
144
}
146
145
147
- /// @notice Calculates the total rewards distributed per ERC20 token.
148
- /// @dev This is called by `updateReward` which also update the value of `totalRewardPaidPerERC20Token`.
146
+ /// @notice Calculates the total rewards distributed per ERC-20 token.
147
+ /// @dev This is called by `updateReward`, which also updates the value of `totalRewardPaidPerERC20Token`.
149
148
function rewardPaidPerERC20Token () public view returns (uint256 ) {
150
- // If the total staked supply is zero or staking has ended, return the stored value of reward per ERC20 .
149
+ // If the total staked supply is zero or staking has ended, return the stored value of reward per ERC-20 .
151
150
if (totalERC20StakedSupply == 0 || block .timestamp >= stakingEndTime) {
152
151
return totalRewardPaidPerERC20Token;
153
152
}
@@ -190,10 +189,10 @@ contract StakeSablierNFT is Adminable, ERC721Holder, ISablierLockupRecipient {
190
189
uint128 /* recipientAmount */
191
190
)
192
191
external
193
- updateReward (stakedAssets [streamId])
192
+ updateReward (stakedUsers [streamId])
194
193
returns (bytes4 selector )
195
194
{
196
- // Check: the caller is the lockup contract.
195
+ // Check: the caller is the Lockup contract.
197
196
if (msg .sender != address (sablierLockup)) {
198
197
revert UnauthorizedCaller (msg .sender , streamId);
199
198
}
@@ -214,15 +213,15 @@ contract StakeSablierNFT is Adminable, ERC721Holder, ISablierLockupRecipient {
214
213
uint128 amount
215
214
)
216
215
external
217
- updateReward (stakedAssets [streamId])
216
+ updateReward (stakedUsers [streamId])
218
217
returns (bytes4 selector )
219
218
{
220
- // Check: the caller is the lockup contract
219
+ // Check: the caller is the Lockup contract
221
220
if (msg .sender != address (sablierLockup)) {
222
221
revert UnauthorizedCaller (msg .sender , streamId);
223
222
}
224
223
225
- address staker = stakedAssets [streamId];
224
+ address staker = stakedUsers [streamId];
226
225
227
226
// Check: the staker is not the zero address.
228
227
if (staker == address (0 )) {
@@ -240,46 +239,46 @@ contract StakeSablierNFT is Adminable, ERC721Holder, ISablierLockupRecipient {
240
239
241
240
/// @notice Stake a Sablier NFT with specified base asset.
242
241
/// @dev The `msg.sender` must approve the staking contract to spend the Sablier NFT before calling this function.
243
- /// One user can only stake one NFT at a time.
244
- /// @param tokenId The tokenId of the Sablier NFT to be staked.
245
- function stake (uint256 tokenId ) external updateReward (msg .sender ) {
242
+ /// One user can only stake one NFT at a time.
243
+ /// @param streamId The stream ID of the Sablier NFT to be staked.
244
+ function stake (uint256 streamId ) external updateReward (msg .sender ) {
246
245
// Check: the Sablier NFT is streaming the staking asset.
247
- if (sablierLockup.getAsset (tokenId ) != rewardERC20Token) {
248
- revert DifferentStreamingAsset (tokenId , rewardERC20Token);
246
+ if (sablierLockup.getAsset (streamId ) != rewardERC20Token) {
247
+ revert DifferentStreamingToken (streamId , rewardERC20Token);
249
248
}
250
249
251
250
// Check: the user is not already staking.
252
- if (stakedTokenId [msg .sender ] != 0 ) {
253
- revert AlreadyStaking (msg .sender , stakedTokenId [msg .sender ]);
251
+ if (stakedStreams [msg .sender ] != 0 ) {
252
+ revert AlreadyStaking (msg .sender , stakedStreams [msg .sender ]);
254
253
}
255
254
256
255
// Effect: store the owner of the Sablier NFT.
257
- stakedAssets[tokenId ] = msg .sender ;
256
+ stakedUsers[streamId ] = msg .sender ;
258
257
259
- // Effect: Store the new tokenId against the user address .
260
- stakedTokenId [msg .sender ] = tokenId ;
258
+ // Effect: store the stream ID .
259
+ stakedStreams [msg .sender ] = streamId ;
261
260
262
261
// Effect: update the total staked amount.
263
- totalERC20StakedSupply += _getAmountInStream (tokenId );
262
+ totalERC20StakedSupply += _getAmountInStream (streamId );
264
263
265
264
// Interaction: transfer NFT to the staking contract.
266
- sablierLockup.safeTransferFrom ({ from: msg .sender , to: address (this ), tokenId: tokenId });
265
+ sablierLockup.safeTransferFrom ({ from: msg .sender , to: address (this ), tokenId: streamId });
267
266
268
- emit Staked (msg .sender , tokenId );
267
+ emit Staked (msg .sender , streamId );
269
268
}
270
269
271
270
/// @notice Unstaking a Sablier NFT will transfer the NFT back to the `msg.sender`.
272
- /// @param tokenId The tokenId of the Sablier NFT to be unstaked.
273
- function unstake (uint256 tokenId ) public updateReward (msg .sender ) {
271
+ /// @param streamId The stream ID of the Sablier NFT to be unstaked.
272
+ function unstake (uint256 streamId ) public updateReward (msg .sender ) {
274
273
// Check: the caller is the stored owner of the NFT.
275
- if (stakedAssets[tokenId ] != msg .sender ) {
276
- revert UnauthorizedCaller (msg .sender , tokenId );
274
+ if (stakedUsers[streamId ] != msg .sender ) {
275
+ revert UnauthorizedCaller (msg .sender , streamId );
277
276
}
278
277
279
278
// Effect: update the total staked amount.
280
- totalERC20StakedSupply -= _getAmountInStream (tokenId );
279
+ totalERC20StakedSupply -= _getAmountInStream (streamId );
281
280
282
- _unstake (tokenId, msg .sender );
281
+ _unstake ({ streamId: streamId, account: msg .sender } );
283
282
}
284
283
285
284
/*//////////////////////////////////////////////////////////////////////////
@@ -288,35 +287,35 @@ contract StakeSablierNFT is Adminable, ERC721Holder, ISablierLockupRecipient {
288
287
289
288
/// @notice Determine the amount available in the stream.
290
289
/// @dev The following function determines the amounts of tokens in a stream irrespective of its cancelable status.
291
- function _getAmountInStream (uint256 tokenId ) private view returns (uint256 amount ) {
290
+ function _getAmountInStream (uint256 streamId ) private view returns (uint256 amount ) {
292
291
// The tokens in the stream = amount deposited - amount withdrawn - amount refunded.
293
- return sablierLockup.getDepositedAmount (tokenId ) - sablierLockup.getWithdrawnAmount (tokenId )
294
- - sablierLockup.getRefundedAmount (tokenId );
292
+ return sablierLockup.getDepositedAmount (streamId ) - sablierLockup.getWithdrawnAmount (streamId )
293
+ - sablierLockup.getRefundedAmount (streamId );
295
294
}
296
295
297
- function _unstake (uint256 tokenId , address account ) private {
296
+ function _unstake (uint256 streamId , address account ) private {
298
297
// Check: account is not zero.
299
298
if (account == address (0 )) {
300
299
revert ZeroAddress (account);
301
300
}
302
301
303
- // Effect: delete the owner of the staked token from the storage .
304
- delete stakedAssets[tokenId ];
302
+ // Effect: delete the owner of the staked stream .
303
+ delete stakedUsers[streamId ];
305
304
306
- // Effect: delete the `tokenId` from the user storage .
307
- delete stakedTokenId [account];
305
+ // Effect: delete the Sablier NFT .
306
+ delete stakedStreams [account];
308
307
309
308
// Interaction: transfer stream back to user.
310
- sablierLockup.safeTransferFrom (address (this ), account, tokenId);
309
+ sablierLockup.safeTransferFrom ({ from: address (this ), to: account, tokenId: streamId } );
311
310
312
- emit Unstaked (account, tokenId );
311
+ emit Unstaked (account, streamId );
313
312
}
314
313
315
314
/*//////////////////////////////////////////////////////////////////////////
316
315
ADMIN FUNCTIONS
317
316
//////////////////////////////////////////////////////////////////////////*/
318
317
319
- /// @notice Start a Staking period and set the amount of ERC20 tokens to be distributed as rewards in said period.
318
+ /// @notice Start a Staking period and set the amount of ERC-20 tokens to be distributed as rewards in said period.
320
319
/// @dev The Staking Contract have to already own enough Rewards Tokens to distribute all the rewards, so make sure
321
320
/// to send all the tokens to the contract before calling this function.
322
321
/// @param rewardAmount The amount of Reward Tokens to be distributed.
0 commit comments