-
Notifications
You must be signed in to change notification settings - Fork 573
Staking Contract & Interface #268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slither found more than 10 potential problems in the proposed changes. Check the Files changed tab for more details.
function _stake(uint256[] calldata _tokenIds) internal virtual { | ||
uint256 len = _tokenIds.length; | ||
require(len != 0, "Staking 0 tokens"); | ||
|
||
if (stakers[msg.sender].amountStaked > 0) { | ||
_updateUnclaimedRewardsForStaker(msg.sender); | ||
} else { | ||
stakersArray.push(msg.sender); | ||
stakers[msg.sender].timeOfLastUpdate = block.timestamp; | ||
} | ||
for (uint256 i = 0; i < len; ++i) { | ||
require(IERC721(nftCollection).ownerOf(_tokenIds[i]) == msg.sender, "Not owner"); | ||
IERC721(nftCollection).transferFrom(msg.sender, address(this), _tokenIds[i]); | ||
stakerAddress[_tokenIds[i]] = msg.sender; | ||
} | ||
stakers[msg.sender].amountStaked += len; | ||
|
||
emit TokensStaked(msg.sender, _tokenIds); | ||
} |
Check warning
Code scanning / Slither
Reentrancy vulnerabilities
function _stake(uint256[] calldata _tokenIds) internal virtual { | ||
uint256 len = _tokenIds.length; | ||
require(len != 0, "Staking 0 tokens"); | ||
|
||
if (stakers[msg.sender].amountStaked > 0) { | ||
_updateUnclaimedRewardsForStaker(msg.sender); | ||
} else { | ||
stakersArray.push(msg.sender); | ||
stakers[msg.sender].timeOfLastUpdate = block.timestamp; | ||
} | ||
for (uint256 i = 0; i < len; ++i) { | ||
require(IERC721(nftCollection).ownerOf(_tokenIds[i]) == msg.sender, "Not owner"); | ||
IERC721(nftCollection).transferFrom(msg.sender, address(this), _tokenIds[i]); | ||
stakerAddress[_tokenIds[i]] = msg.sender; | ||
} | ||
stakers[msg.sender].amountStaked += len; | ||
|
||
emit TokensStaked(msg.sender, _tokenIds); | ||
} |
Check warning
Code scanning / Slither
Reentrancy vulnerabilities
function _stake(uint256[] calldata _tokenIds) internal virtual { | ||
uint256 len = _tokenIds.length; | ||
require(len != 0, "Staking 0 tokens"); | ||
|
||
if (stakers[msg.sender].amountStaked > 0) { | ||
_updateUnclaimedRewardsForStaker(msg.sender); | ||
} else { | ||
stakersArray.push(msg.sender); | ||
stakers[msg.sender].timeOfLastUpdate = block.timestamp; | ||
} | ||
for (uint256 i = 0; i < len; ++i) { | ||
require(IERC721(nftCollection).ownerOf(_tokenIds[i]) == msg.sender, "Not owner"); | ||
IERC721(nftCollection).transferFrom(msg.sender, address(this), _tokenIds[i]); | ||
stakerAddress[_tokenIds[i]] = msg.sender; | ||
} | ||
stakers[msg.sender].amountStaked += len; | ||
|
||
emit TokensStaked(msg.sender, _tokenIds); | ||
} |
Check notice
Code scanning / Slither
Reentrancy vulnerabilities
function _stake(uint256[] calldata _tokenIds) internal virtual { | ||
uint256 len = _tokenIds.length; | ||
require(len != 0, "Staking 0 tokens"); | ||
|
||
if (stakers[msg.sender].amountStaked > 0) { | ||
_updateUnclaimedRewardsForStaker(msg.sender); | ||
} else { | ||
stakersArray.push(msg.sender); | ||
stakers[msg.sender].timeOfLastUpdate = block.timestamp; | ||
} | ||
for (uint256 i = 0; i < len; ++i) { | ||
require(IERC721(nftCollection).ownerOf(_tokenIds[i]) == msg.sender, "Not owner"); | ||
IERC721(nftCollection).transferFrom(msg.sender, address(this), _tokenIds[i]); | ||
stakerAddress[_tokenIds[i]] = msg.sender; | ||
} | ||
stakers[msg.sender].amountStaked += len; | ||
|
||
emit TokensStaked(msg.sender, _tokenIds); | ||
} |
Check notice
Code scanning / Slither
Reentrancy vulnerabilities
function _stake(uint256[] calldata _tokenIds) internal virtual { | ||
uint256 len = _tokenIds.length; | ||
require(len != 0, "Staking 0 tokens"); | ||
|
||
if (stakers[msg.sender].amountStaked > 0) { | ||
_updateUnclaimedRewardsForStaker(msg.sender); | ||
} else { | ||
stakersArray.push(msg.sender); | ||
stakers[msg.sender].timeOfLastUpdate = block.timestamp; | ||
} | ||
for (uint256 i = 0; i < len; ++i) { | ||
require(IERC721(nftCollection).ownerOf(_tokenIds[i]) == msg.sender, "Not owner"); | ||
IERC721(nftCollection).transferFrom(msg.sender, address(this), _tokenIds[i]); | ||
stakerAddress[_tokenIds[i]] = msg.sender; | ||
} | ||
stakers[msg.sender].amountStaked += len; | ||
|
||
emit TokensStaked(msg.sender, _tokenIds); | ||
} |
Check notice
Code scanning / Slither
Reentrancy vulnerabilities
function _stake(uint256[] calldata _tokenIds) internal virtual { | ||
uint256 len = _tokenIds.length; | ||
require(len != 0, "Staking 0 tokens"); | ||
|
||
if (stakers[msg.sender].amountStaked > 0) { | ||
_updateUnclaimedRewardsForStaker(msg.sender); | ||
} else { | ||
stakersArray.push(msg.sender); | ||
stakers[msg.sender].timeOfLastUpdate = block.timestamp; | ||
} | ||
for (uint256 i = 0; i < len; ++i) { | ||
require(IERC721(nftCollection).ownerOf(_tokenIds[i]) == msg.sender, "Not owner"); | ||
IERC721(nftCollection).transferFrom(msg.sender, address(this), _tokenIds[i]); | ||
stakerAddress[_tokenIds[i]] = msg.sender; | ||
} | ||
stakers[msg.sender].amountStaked += len; | ||
|
||
emit TokensStaked(msg.sender, _tokenIds); | ||
} |
Check notice
Code scanning / Slither
Reentrancy vulnerabilities
contract NFTStake is | ||
Initializable, | ||
ContractMetadata, | ||
PermissionsEnumerable, | ||
ERC2771ContextUpgradeable, | ||
MulticallUpgradeable, | ||
IERC721ReceiverUpgradeable, | ||
Staking721Upgradeable | ||
{ | ||
bytes32 private constant MODULE_TYPE = bytes32("NFTStake"); | ||
uint256 private constant VERSION = 1; | ||
|
||
/// @dev ERC20 Reward Token address. See {_mintRewards} below. | ||
address public rewardToken; | ||
|
||
constructor() initializer {} | ||
|
||
/// @dev Initiliazes the contract, like a constructor. | ||
function initialize( | ||
address _defaultAdmin, | ||
string memory _contractURI, | ||
address[] memory _trustedForwarders, | ||
address _rewardToken, | ||
address _nftCollection, | ||
uint256 _timeUnit, | ||
uint256 _rewardsPerUnitTime | ||
) external initializer { | ||
__ReentrancyGuard_init(); | ||
__ERC2771Context_init_unchained(_trustedForwarders); | ||
|
||
rewardToken = _rewardToken; | ||
__Staking721_init(_nftCollection); | ||
_setTimeUnit(_timeUnit); | ||
_setRewardsPerUnitTime(_rewardsPerUnitTime); | ||
|
||
_setupContractURI(_contractURI); | ||
|
||
_setupRole(DEFAULT_ADMIN_ROLE, _defaultAdmin); | ||
} | ||
|
||
/// @dev Returns the module type of the contract. | ||
function contractType() external pure virtual returns (bytes32) { | ||
return MODULE_TYPE; | ||
} | ||
|
||
/// @dev Returns the version of the contract. | ||
function contractVersion() external pure virtual returns (uint8) { | ||
return uint8(VERSION); | ||
} | ||
|
||
/*/////////////////////////////////////////////////////////////// | ||
ERC 165 / 721 logic | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
function onERC721Received( | ||
address, | ||
address, | ||
uint256, | ||
bytes calldata | ||
) external pure override returns (bytes4) { | ||
return this.onERC721Received.selector; | ||
} | ||
|
||
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { | ||
return interfaceId == type(IERC721ReceiverUpgradeable).interfaceId; | ||
} | ||
|
||
/*/////////////////////////////////////////////////////////////// | ||
Transfer Staking Rewards | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
function _mintRewards(address _staker, uint256 _rewards) internal override { | ||
CurrencyTransferLib.transferCurrency(rewardToken, address(this), _staker, _rewards); | ||
} | ||
|
||
/*/////////////////////////////////////////////////////////////// | ||
Internal functions | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
/// @dev Returns whether staking related restrictions can be set in the given execution context. | ||
function _canSetStakeConditions() internal view override returns (bool) { | ||
return hasRole(DEFAULT_ADMIN_ROLE, _msgSender()); | ||
} | ||
|
||
/// @dev Checks whether contract metadata can be set in the given execution context. | ||
function _canSetContractURI() internal view override returns (bool) { | ||
return hasRole(DEFAULT_ADMIN_ROLE, _msgSender()); | ||
} | ||
|
||
/*/////////////////////////////////////////////////////////////// | ||
Miscellaneous | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
function _msgSender() internal view virtual override returns (address sender) { | ||
return ERC2771ContextUpgradeable._msgSender(); | ||
} | ||
|
||
function _msgData() internal view virtual override returns (bytes calldata) { | ||
return ERC2771ContextUpgradeable._msgData(); | ||
} | ||
} |
Check warning
Code scanning / Slither
Missing inheritance
No description provided.