Skip to content

Conversation

kumaryash90
Copy link
Member

No description provided.

@kumaryash90 kumaryash90 changed the title [WIP Don't Merge] Staking Contract [WIP Don't Merge] Staking Contract & Interface Oct 26, 2022
Copy link

@github-advanced-security github-advanced-security bot left a 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.

@kumaryash90 kumaryash90 changed the title [WIP Don't Merge] Staking Contract & Interface Staking Contract & Interface Nov 14, 2022
Comment on lines +136 to +154
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

Reentrancy in Staking721._stake(uint256[]) (contracts/extension/Staking721.sol#136-154): External calls: - IERC721(nftCollection).transferFrom(msg.sender,address(this),_tokenIds[i]) (contracts/extension/Staking721.sol#148) State variables written after the call(s): - stakers[msg.sender].amountStaked += len (contracts/extension/Staking721.sol#151)
Comment on lines +138 to +156
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

Reentrancy in Staking721Upgradeable._stake(uint256[]) (contracts/extension/Staking721Upgradeable.sol#138-156): External calls: - IERC721(nftCollection).transferFrom(msg.sender,address(this),_tokenIds[i]) (contracts/extension/Staking721Upgradeable.sol#150) State variables written after the call(s): - stakers[msg.sender].amountStaked += len (contracts/extension/Staking721Upgradeable.sol#153)
Comment on lines +136 to +154
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

Reentrancy in Staking721._stake(uint256[]) (contracts/extension/Staking721.sol#136-154): External calls: - IERC721(nftCollection).transferFrom(msg.sender,address(this),_tokenIds[i]) (contracts/extension/Staking721.sol#148) State variables written after the call(s): - stakerAddress[_tokenIds[i]] = msg.sender (contracts/extension/Staking721.sol#149)
Comment on lines +138 to +156
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

Reentrancy in Staking721Upgradeable._stake(uint256[]) (contracts/extension/Staking721Upgradeable.sol#138-156): External calls: - IERC721(nftCollection).transferFrom(msg.sender,address(this),_tokenIds[i]) (contracts/extension/Staking721Upgradeable.sol#150) State variables written after the call(s): - stakerAddress[_tokenIds[i]] = msg.sender (contracts/extension/Staking721Upgradeable.sol#151)
Comment on lines +136 to +154
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

Reentrancy in Staking721._stake(uint256[]) (contracts/extension/Staking721.sol#136-154): External calls: - IERC721(nftCollection).transferFrom(msg.sender,address(this),_tokenIds[i]) (contracts/extension/Staking721.sol#148) Event emitted after the call(s): - TokensStaked(msg.sender,_tokenIds) (contracts/extension/Staking721.sol#153)
Comment on lines +138 to +156
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

Reentrancy in Staking721Upgradeable._stake(uint256[]) (contracts/extension/Staking721Upgradeable.sol#138-156): External calls: - IERC721(nftCollection).transferFrom(msg.sender,address(this),_tokenIds[i]) (contracts/extension/Staking721Upgradeable.sol#150) Event emitted after the call(s): - TokensStaked(msg.sender,_tokenIds) (contracts/extension/Staking721Upgradeable.sol#155)
Comment on lines +29 to +129
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

NFTStake (contracts/staking/NFTStake.sol#29-129) should inherit from IThirdwebContract (contracts/interfaces/IThirdwebContract.sol#4-19)
@kumaryash90 kumaryash90 merged commit 4c03dfe into main Nov 14, 2022
@nkrishang nkrishang deleted the staking-contract branch December 26, 2022 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant