Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: medium
Invalid

A user cannot easily know which NFTs he has in staking

Summary

In the stake() function, the stake information is stored in a mapping as tokenId => Stake. This allows retrieving the stake through the tokenId, but does not inform a user what his NFTs are in staking.

The stake() function emits an event, but this information is not very practical for this case.

Impact

A user could forget which NFTs he has in staking, and the dapp would have no easy way to tell him.

Tools Used

Foundry, Manual review

Recommendations

The Streets contract can be modified to use a mapping user => stakes, so the dapp can easily inform the user which NFTs he has in staking:

contract Streets is IERC721Receiver {
// Struct to hold staking information
struct Stake {
uint256 startTime;
- address owner;
+ uint256 tokenId;
}
- mapping(uint256 tokenId => Stake stake) public stakes;
+ mapping(address user => Stake[] stakes) public userStakes;
// ERC721 token contract
IOneShot public oneShotContract;
Credibility public credContract;
// Event declarations
event Staked(address indexed owner, uint256 tokenId, uint256 startTime);
event Unstaked(address indexed owner, uint256 tokenId, uint256 stakedDuration);
constructor(address _oneShotContract, address _credibilityContract) {
oneShotContract = IOneShot(_oneShotContract);
credContract = Credibility(_credibilityContract);
}
// Stake tokens by transferring them to this contract
function stake(uint256 tokenId) external returns(uint256 index) {
- stakes[tokenId] = Stake(block.timestamp, msg.sender);
+ index = userStakes[msg.sender].length;
+ userStakes[msg.sender].push(Stake(tokenId, block.timestamp));
emit Staked(msg.sender, tokenId, block.timestamp);
oneShotContract.transferFrom(msg.sender, address(this), tokenId);
}
// Unstake tokens by transferring them back to their owner
// @param Index of the stake in the userStakes array
function unstake(uint256 index) external {
- require(stakes[tokenId].owner == msg.sender, "Not the token owner");
- uint256 stakedDuration = block.timestamp - stakes[tokenId].startTime;
+ require(index < userStakes[msg.sender].length, "Index out of bounds");
+ // Access the stake using the provided index
+ Stake memory stakeInfo = userStakes[msg.sender][index];
+ uint256 tokenId = stakeInfo.tokenId; // Retrieve tokenId from the stake information
+ uint256 stakedDuration = block.timestamp - stakeInfo.startTime;
+ uint256 daysStaked = stakedDuration / 1 days;
+ // Remove the stake from the array by swapping it with the last element and then popping it off
+ userStakes[msg.sender][index] = userStakes[msg.sender][userStakes[msg.sender].length - 1];
+ userStakes[msg.sender].pop();
+ // Continue with the logic to update stats and return the token
...
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.