Root + Impact
Description
The placeBid function should emit events that accurately reflect the current bid being placed, including the correct bidder address and bid amount. This ensures external systems and users can reliably track auction state through event logs.
The specific issue is that the event emission contains incorrect parameter data, potentially showing previous bidder information or incorrect bid amounts instead of the actual current bid details.
function placeBid(uint256 tokenId) external payable {
emit NewBid(tokenId, previousBidder, previousAmount);
}
Risk
Likelihood:
-
Occurs every time a bid is placed through the contract
-
No special conditions required - triggered by normal contract usage
-
Affects all bid transactions automatically
Impact:
-
External systems receive incorrect auction state data
-
User interfaces display wrong bid information
-
Analytics platforms report inaccurate auction metrics
-
Reduces transparency and trust in the platform
Proof of Concept
This test demonstrates how the event emission issue affects data accuracy:
Setup: We create a valid auction with a listed NFT
Action: User2 places a bid of 1.5 ETH
Verification: We check that the emitted event contains the correct bidder (user2) and amount (1.5 ETH)
Issue: The test will fail if the event contains incorrect data, proving the vulnerability exists
The test specifically validates:
-
Token ID matches the auction
-
Bidder address matches the actual caller
-
Bid amount matches the actual value sent
pragma solidity ^0.8.19;
import {Test} from "forge-std/Test.sol";
import {BidBeastsNFTMarketPlace} from "../src/BidBeastsNFTMarketPlace.sol";
import {BidBeasts_NFT_ERC721} from "../src/BidBeasts_NFT_ERC721.sol";
contract EventAccuracyTest is Test {
BidBeastsNFTMarketPlace marketplace;
BidBeasts_NFT_ERC721 nft;
address user1 = makeAddr("user1");
address user2 = makeAddr("user2");
event NewBid(uint256 indexed tokenId, address indexed bidder, uint256 amount);
function setUp() public {
nft = new BidBeasts_NFT_ERC721();
marketplace = new BidBeastsNFTMarketPlace(address(nft));
nft.mint(user1, 1);
vm.prank(user1);
nft.approve(address(marketplace), 1);
vm.prank(user1);
marketplace.listNFT(1, 1 ether, 2 ether);
}
function testEventAccuracy() public {
uint256 expectedAmount = 1.5 ether;
vm.recordLogs();
vm.prank(user2);
vm.deal(user2, expectedAmount);
marketplace.placeBid{value: expectedAmount}(1);
Vm.Log[] memory entries = vm.getRecordedLogs();
(uint256 tokenId, address bidder, uint256 amount) = abi.decode(
entries[0].data,
(uint256, address, uint256)
);
assertEq(tokenId, 1, "Wrong token ID");
assertEq(bidder, user2, "Wrong bidder address");
assertEq(amount, expectedAmount, "Wrong bid amount");
}
}
Recommended Mitigation
// In placeBid function
function placeBid(uint256 tokenId) external payable {
// ... existing validation logic ...
- emit NewBid(tokenId, previousBidder, previousAmount);
+ emit NewBid(tokenId, msg.sender, msg.value);
// Additional event for transparency
+ emit BidPlaced(tokenId, msg.sender, msg.value, block.timestamp);
}
Or for more comprehensive tracking:
// Enhanced event emission
function placeBid(uint256 tokenId) external payable {
// ... validation logic ...
- emit NewBid(tokenId, someAddress, someAmount);
+ emit BidPlaced(
+ tokenId,
+ msg.sender,
+ msg.value,
+ block.timestamp,
+ auction.highestBid
+ );
}