Skip to content

Commit 3d04ee7

Browse files
Staking updates (#294)
* more efficient way of storing state for Staking contracts * [M-1] Block gas limit can be exceeded during setTimeUnit() and setRewardsPerUnit() when staker count grows * [C-1] Contract admins can lock staked tokens in the contract * [M-1] revised fix for Staking1155 * [H-1] TokenStake.sol rewards can be over- or under-awarded when the staking and reward tokens have different decimals * [M-2] ERC721 and ERC1155 tokens safe-transferred directly to contract will be locked and unrecoverable * [C-1] revised fix for large rewardsPerUnitTime * [L-1] Incorrect ERC165 implementation for NFTStake and EditionStake * [Q-2] Normalize support for ERC2771 trusted forwarder * [Q-3] Reentrancy init called twice * [Q-5] unitTime and rewardsPerUnitTime setter functions don’t check for new input data * [Q-6] getStakeInfo should be marked as external * [G-1] Halt array iteration after staker removed during withdraw() * [G-2] Loop reading from storage array length * [Q-7] Missing reward balance information * [M-3] TokenStake.sol: Double entry-point ERC20 tokens could be drained from the staking contract * [H-2] TokenStake.sol: Tokens with a tax on transfer will account for inaccurate amounts * virtual functions for bases * docs * v3.2.9 Co-authored-by: Krishang <krishang@thirdweb.com>
1 parent 3014c2c commit 3d04ee7

36 files changed

+2853
-938
lines changed

contracts/base/Staking1155Base.sol

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,16 @@ contract Staking1155Base is ContractMetadata, Multicall, Ownable, Staking1155 {
4343
address _rewardToken
4444
) Staking1155(_edition) {
4545
_setupOwner(msg.sender);
46-
_setDefaultTimeUnit(_defaultTimeUnit);
47-
_setDefaultRewardsPerUnitTime(_defaultRewardsPerUnitTime);
46+
_setDefaultStakingCondition(_defaultTimeUnit, _defaultRewardsPerUnitTime);
4847

4948
rewardToken = _rewardToken;
5049
}
5150

51+
/// @notice View total rewards available in the staking contract.
52+
function getRewardTokenBalance() external view virtual override returns (uint256 _rewardsAvailableInContract) {
53+
return IERC20(rewardToken).balanceOf(address(this));
54+
}
55+
5256
/*//////////////////////////////////////////////////////////////
5357
Minting logic
5458
//////////////////////////////////////////////////////////////*/
@@ -79,7 +83,7 @@ contract Staking1155Base is ContractMetadata, Multicall, Ownable, Staking1155 {
7983
//////////////////////////////////////////////////////////////*/
8084

8185
/// @dev Returns whether staking restrictions can be set in given execution context.
82-
function _canSetStakeConditions() internal view override returns (bool) {
86+
function _canSetStakeConditions() internal view virtual override returns (bool) {
8387
return msg.sender == owner();
8488
}
8589

contracts/base/Staking20Base.sol

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import "../extension/Ownable.sol";
77
import "../extension/Staking20.sol";
88

99
import "../eip/interface/IERC20.sol";
10+
import "../eip/interface/IERC20Metadata.sol";
1011

1112
/**
1213
* note: This is a Beta release.
@@ -42,15 +43,19 @@ contract Staking20Base is ContractMetadata, Multicall, Ownable, Staking20 {
4243
uint256 _rewardRatioDenominator,
4344
address _stakingToken,
4445
address _rewardToken
45-
) Staking20(_stakingToken) {
46+
) Staking20(_stakingToken, IERC20Metadata(_stakingToken).decimals(), IERC20Metadata(_rewardToken).decimals()) {
4647
_setupOwner(msg.sender);
47-
_setTimeUnit(_timeUnit);
48-
_setRewardRatio(_rewardRatioNumerator, _rewardRatioDenominator);
48+
_setStakingCondition(_timeUnit, _rewardRatioNumerator, _rewardRatioDenominator);
4949

5050
require(_rewardToken != _stakingToken, "Reward Token and Staking Token can't be same.");
5151
rewardToken = _rewardToken;
5252
}
5353

54+
/// @notice View total rewards available in the staking contract.
55+
function getRewardTokenBalance() external view virtual override returns (uint256 _rewardsAvailableInContract) {
56+
return IERC20(rewardToken).balanceOf(address(this));
57+
}
58+
5459
/*//////////////////////////////////////////////////////////////
5560
Minting logic
5661
//////////////////////////////////////////////////////////////*/
@@ -81,7 +86,7 @@ contract Staking20Base is ContractMetadata, Multicall, Ownable, Staking20 {
8186
//////////////////////////////////////////////////////////////*/
8287

8388
/// @dev Returns whether staking restrictions can be set in given execution context.
84-
function _canSetStakeConditions() internal view override returns (bool) {
89+
function _canSetStakeConditions() internal view virtual override returns (bool) {
8590
return msg.sender == owner();
8691
}
8792

contracts/base/Staking721Base.sol

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,22 @@ contract Staking721Base is ContractMetadata, Multicall, Ownable, Staking721 {
3737
address public rewardToken;
3838

3939
constructor(
40-
uint256 _timeUnit,
41-
uint256 _rewardsPerUnitTime,
40+
uint128 _timeUnit,
41+
uint128 _rewardsPerUnitTime,
4242
address _nftCollection,
4343
address _rewardToken
4444
) Staking721(_nftCollection) {
4545
_setupOwner(msg.sender);
46-
_setTimeUnit(_timeUnit);
47-
_setRewardsPerUnitTime(_rewardsPerUnitTime);
46+
_setStakingCondition(_timeUnit, _rewardsPerUnitTime);
4847

4948
rewardToken = _rewardToken;
5049
}
5150

51+
/// @notice View total rewards available in the staking contract.
52+
function getRewardTokenBalance() external view virtual override returns (uint256 _rewardsAvailableInContract) {
53+
return IERC20(rewardToken).balanceOf(address(this));
54+
}
55+
5256
/*//////////////////////////////////////////////////////////////
5357
Minting logic
5458
//////////////////////////////////////////////////////////////*/
@@ -79,7 +83,7 @@ contract Staking721Base is ContractMetadata, Multicall, Ownable, Staking721 {
7983
//////////////////////////////////////////////////////////////*/
8084

8185
/// @dev Returns whether staking restrictions can be set in given execution context.
82-
function _canSetStakeConditions() internal view override returns (bool) {
86+
function _canSetStakeConditions() internal view virtual override returns (bool) {
8387
return msg.sender == owner();
8488
}
8589

0 commit comments

Comments
 (0)