Salty Bone Skunk
High
Lack of similar data types in NounsAuctionHouseV2::createBid()
and NounsAuctionHouseV3::createBid()
will permanently break the auction bidding functionality for all users when block.timestamp
exceeds the maximum value of uint40
(approximately 34 years)
The lack of similar data types in the function createBid()
in NounsAuctionHouseV3.sol and in NounsAuctionHouseV2.sol will cause the require statement
require(block.timestamp < _auction.endTime, 'Auction expired');
to permanently fail when block.timestamp
is legitimately greater than _auction.endTime
. This is due to a type mismatch between block.timestamp
(which is always uint256
) and the auction's endTime (which is defined as a uint40
), causing all bid attempts to revert when the timestamp exceeds the maximum value of uint40
which is ~34 years.
_auction.endTime
in INounsAuctionHouseV3.sol
and in INounsAuctionHouseV2.sol
is a uint40
digit meant to indicate the time that an auction is scheduled to end. Each NFT auction ends at a different time, i.e noun 1's auction ended at a different time that noun 30's auction. block.timestamp
will always be a uint256
digit.
For that matter, _auction.endTime
has to be adjusted for every new Noun NFT to reflect the time when that NFT auction will end. It will reach a time in the future when block.timestamp
will be greater than _auction.endTime
as block.timestamp
increases with every new block added to the blockchain. Consider an NFT in the future whose _auction.endTime
is type(uint40).max
and the block.timestamp
is type(uint40).max + 100
. The problem is that the require statement in #L155 in NounsAuctionHouseV3.sol
and also in #L139 in NounsAuctionHouseV2.sol
will fail cause block.timestamp
will be greater than _auction.endTime
.
require(block.timestamp < _auction.endTime, 'Auction expired');
This means the contract breaks for every single person as no one can create a bid and consequently no bids can be settled rendering the protocol useless for everyone.
No response
- The ethereum blockchain has progressed to a block timestamp greater than
type(uint40).max
, i.e ~34 years.
- Wait for ethereum's blockchain timestamp to exceed
type(uint40).max
which is approximately 34 years. - Attempt to create a bid by calling
NounsAuctionHouseV2::createBid()
orNounsAuctionHouseV3::createBid()
for an NFT whose scheduled time to end istype(uint40.max)
. - The transaction will consistently revert due to timestamp comparison, i.e
require(block.timestamp < _auction.endTime, 'Auction expired');
will always fail.
- Complete denial of service for the Nouns DAO auction mechanism.
- Permanent inability to create auctions.
- The protocol becomes unusable for everyone.
- Breaks the One Noun, Every Day, Forever mantra of the Nouns DAO as NFT bidding creation will stop after
type(uint40).max
(approximately 34 years).
No response
- Change
_auction.endTime
to use auint256
data type, i.e change to the following in INounsAuctionHouseV2.sol and in INounsAuctionHouseV3.sol
struct AuctionV2 {
// ID for the Noun (ERC721 token ID)
uint96 nounId;
// ID of the client that facilitated the latest bid, used for client rewards
uint32 clientId;
// The current highest bid amount
uint128 amount;
// The time that the auction started
uint40 startTime;
// The time that the auction is scheduled to end
uint256 endTime; /// @audit-tag change from uint40 to uint256
// The address of the current highest bid
address payable bidder;
// Whether or not the auction has been settled
bool settled;
}
- Or constrain
block.timestamp
to auint40
in the require statement, i.e
require(uint40(block.timestamp) < _auction.endTime, 'Auction expired');