When staked, the owner of the NFT is still the user, but it is supposed to be the street contract for all the duration of the staking.
In fact, the street contract never receive the NFT since onERC721Received is never triggered since transferFrom() doesn't call the checkOnERC721Received, unlike safeTransferFrom(). Also stakes[tokenId] is set before transferFrom is called, and since transferFrom will not revert, the call is successful.
User can do whatever he wants with his NFT when he's staking as it is not technically in the street contract
Manual analysis
Use safeTransferFrom instead of transferFrom in the stake() function and modify stake so it looks like this:
function stake(uint256 tokenId) external {
oneShotContract.safeTransferFrom(msg.sender, address(this), tokenId);
stakes[tokenId] = Stake(block.timestamp, msg.sender);
emit Staked(msg.sender, tokenId, block.timestamp);
}
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.