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.
A user could forget which NFTs he has in staking, and the dapp would have no easy way to tell him.
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
...