Bid Beasts

First Flight #49
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: low
Likelihood: high
Invalid

Missing Critical Event Emissions When State Variables Change (Poor Observability + Reduced Off-chain Integration)

Missing Critical Event Emissions When State Variables Change (Poor Observability + Reduced Off-chain Integration)

Description

  • Events should be emitted whenever important state variables are modified to provide transparency and enable off-chain monitoring of contract activities.

  • The contract fails to emit events for several critical state changes including contract initialization, bid clearing, listing status updates, and failed credit withdrawals, making it difficult for external systems and users to track these important activities.

In src/BidBeastsNFTMarketPlace.sol:

contract BidBeastsNFTMarket is Ownable(msg.sender) {
//existing code
constructor(address _BidBeastsNFT) {
@> BBERC721 = BidBeasts(_BidBeastsNFT);//Line#57
}
//existing code
function listNFT(uint256 tokenId, uint256 _minPrice, uint256 _buyNowPrice) external{
//existing code
if (listing.buyNowPrice > 0 && msg.value >= listing.buyNowPrice) {
//existing code
@> bids[tokenId] = Bid(msg.sender, salePrice);//Line#124
@> listing.listed = false;//Line#125
//existing code
}
//existing code
}
//existing code
function _executeSale(uint256 tokenId) internal {
//existing code
@> listing.listed = false;//Line#210
@> delete bids[tokenId];//Line#211
//existing code
}
function withdrawAllFailedCredits(address _receiver) external {
//existing code
@> failedTransferCredits[msg.sender] = 0;//Line#242
//existing code
}
//existing code
}

Risk

Likelihood:

  • These state changes occur during normal contract operations - contract deployment, buy-now purchases, auction completions, and failed credit withdrawals.

  • Off-chain systems and dApps commonly rely on events to track contract state changes and update their interfaces accordingly.

Impact:

  • Reduced transparency and auditability of contract operations.

  • Difficulty for off-chain systems, indexers, and dApps to track important state changes.

Proof of Concept

The following code demonstrates the missing event emissions that prevent proper off-chain monitoring and integration:

contract BidBeastsNFTMarket is Ownable(msg.sender) {
//existing code
constructor(address _BidBeastsNFT) {
BBERC721 = BidBeasts(_BidBeastsNFT);//Line#57
// No event emitted - off-chain systems cannot detect contract initialization
}
//existing code
function listNFT(uint256 tokenId, uint256 _minPrice, uint256 _buyNowPrice) external{
//existing code
if (listing.buyNowPrice > 0 && msg.value >= listing.buyNowPrice) {
//existing code
bids[tokenId] = Bid(msg.sender, salePrice);//Line#124
// No event emitted - bid placement cannot be tracked
listing.listed = false;//Line#125
// No event emitted - NFT unlisting cannot be detected
//existing code
}
//existing code
}
//existing code
function _executeSale(uint256 tokenId) internal {
//existing code
listing.listed = false;//Line#210
// No event emitted - sale completion status change is invisible
delete bids[tokenId];//Line#211
// No event emitted - bid clearing cannot be monitored
//existing code
}
function withdrawAllFailedCredits(address _receiver) external {
//existing code
failedTransferCredits[msg.sender] = 0;//Line#242
// No event emitted - credit withdrawal cannot be tracked for accounting
//existing code
}
//existing code
}

Recommended Mitigation

Add appropriate event emissions for all critical state changes to improve transparency and enable proper off-chain integration.

contract BidBeastsNFTMarket is Ownable(msg.sender) {
//existing code
+ event BidBeastsContractSet(address indexed newContract);
+ event BidCleared(uint256 indexed tokenId);
+ event FailedCreditsWithdrawn(address indexed user, uint256 amount);
constructor(address _BidBeastsNFT) {
BBERC721 = BidBeasts(_BidBeastsNFT);//Line#57
+ emit BidBeastsContractSet(_BidBeastsNFT);
}
//existing code
function listNFT(uint256 tokenId, uint256 _minPrice, uint256 _buyNowPrice) external{
//existing code
if (listing.buyNowPrice > 0 && msg.value >= listing.buyNowPrice) {
//existing code
bids[tokenId] = Bid(msg.sender, salePrice);//Line#124
+ emit BidPlaced(tokenId, msg.sender, salePrice);
listing.listed = false;//Line#125
+ emit NftUnlisted(tokenId);
//existing code
}
//existing code
}
//existing code
function _executeSale(uint256 tokenId) internal {
//existing code
listing.listed = false;//Line#210
+ emit NftUnlisted(tokenId);
delete bids[tokenId];//Line#211
+ emit BidCleared(tokenId);
//existing code
}
function withdrawAllFailedCredits(address _receiver) external {
//existing code
failedTransferCredits[msg.sender] = 0;//Line#242
+ emit FailedCreditsWithdrawn(msg.sender, amount);
//existing code
}
//existing code
}
Updates

Lead Judging Commences

cryptoghost Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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