Skip to content

Commit

Permalink
Merge pull request #94 from ourzora/test_bid_forking_mainnet
Browse files Browse the repository at this point in the history
Test bid forking mainnet
  • Loading branch information
tbtstl authored Dec 17, 2022
2 parents 0973df0 + 0a4bb7e commit d97dc4b
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 5 deletions.
24 changes: 20 additions & 4 deletions src/auction/Auction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,14 @@ contract Auction is IAuction, VersionedContract, UUPS, Ownable, ReentrancyGuard,
/// @param _tokenId The ERC-721 token id
function createBid(uint256 _tokenId) external payable nonReentrant {
// Ensure the bid is for the current token
if (auction.tokenId != _tokenId) revert INVALID_TOKEN_ID();
if (auction.tokenId != _tokenId) {
revert INVALID_TOKEN_ID();
}

// Ensure the auction is still active
if (block.timestamp >= auction.endTime) revert AUCTION_OVER();
if (block.timestamp >= auction.endTime) {
revert AUCTION_OVER();
}

// Cache the amount of ETH attached
uint256 msgValue = msg.value;
Expand Down Expand Up @@ -136,7 +140,9 @@ contract Auction is IAuction, VersionedContract, UUPS, Ownable, ReentrancyGuard,
// If this is the first bid:
if (lastHighestBidder == address(0)) {
// Ensure the bid meets the reserve price
if (msgValue < settings.reservePrice) revert RESERVE_PRICE_NOT_MET();
if (msgValue < settings.reservePrice) {
revert RESERVE_PRICE_NOT_MET();
}

// Else this is a subsequent bid:
} else {
Expand All @@ -150,7 +156,13 @@ contract Auction is IAuction, VersionedContract, UUPS, Ownable, ReentrancyGuard,
}

// Ensure the incoming bid meets the minimum
if (msgValue < minBid || minBid == lastHighestBid) revert MINIMUM_BID_NOT_MET();
if (msgValue < minBid) {
revert MINIMUM_BID_NOT_MET();
}
// Ensure that the second bid is not also zero
if (minBid == 0 && msgValue == 0 && lastHighestBidder != address(0)) {
revert MINIMUM_BID_NOT_MET();
}

// Refund the previous bidder
_handleOutgoingTransfer(lastHighestBidder, lastHighestBid);
Expand Down Expand Up @@ -345,6 +357,10 @@ contract Auction is IAuction, VersionedContract, UUPS, Ownable, ReentrancyGuard,
/// @notice Updates the minimum bid increment of each subsequent bid
/// @param _percentage The new percentage
function setMinimumBidIncrement(uint256 _percentage) external onlyOwner whenPaused {
if (_percentage == 0) {
revert MIN_BID_INCREMENT_1_PERCENT();
}

settings.minBidIncrement = SafeCast.toUint8(_percentage);

emit MinBidIncrementPercentageUpdated(_percentage);
Expand Down
3 changes: 3 additions & 0 deletions src/auction/IAuction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ interface IAuction is IUUPS, IOwnable, IPausable {
/// @dev Reverts if a bid does not meet the minimum bid
error MINIMUM_BID_NOT_MET();

/// @dev Error for when the bid increment is set to 0.
error MIN_BID_INCREMENT_1_PERCENT();

/// @dev Reverts if the contract does not have enough ETH
error INSOLVENT();

Expand Down
64 changes: 63 additions & 1 deletion test/Auction.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { NounsBuilderTest } from "./utils/NounsBuilderTest.sol";
import { MockERC721 } from "./utils/mocks/MockERC721.sol";
import { MockImpl } from "./utils/mocks/MockImpl.sol";
import { MockPartialTokenImpl } from "./utils/mocks/MockPartialTokenImpl.sol";

import { IAuction } from "../src/auction/IAuction.sol";

contract AuctionTest is NounsBuilderTest {
MockImpl internal mockImpl;
Expand Down Expand Up @@ -73,6 +73,68 @@ contract AuctionTest is NounsBuilderTest {
auction.unpause();
}

function test_ZeroBidIncrementNotAllowed() public {
deployMock();

vm.prank(founder);
vm.expectRevert(IAuction.MIN_BID_INCREMENT_1_PERCENT.selector);
auction.setMinimumBidIncrement(0);
}

function test_CreateMultipleBidsAfterZero(uint256 _amount) public {
deployMock();
vm.assume(_amount > 0 && _amount <= bidder1.balance);

vm.startPrank(founder);
// Set minimum possible bid increment
auction.setMinimumBidIncrement(1);
auction.setReservePrice(0);

auction.unpause();
vm.stopPrank();

vm.prank(bidder1);

// 0 value bid placed
auction.createBid{value: 0}(2);

(, uint256 highestBidOriginal, address highestBidderOriginal, , , ) = auction.auction();
assertEq(highestBidOriginal, 0);
assertEq(highestBidderOriginal, bidder1);

uint256 bidder2BalanceBefore = bidder2.balance;

vm.prank(bidder2);
auction.createBid{ value: _amount }(2);

(, uint256 highestBid, address highestBidder, , , ) = auction.auction();
assertEq(highestBid, _amount);
assertEq(highestBidder, bidder2);
assertEq(bidder2BalanceBefore - bidder2.balance, _amount);
}

function test_NoTwoZeroValueBids() public {
deployMock();

// Set minimum possible bid increment
vm.startPrank(founder);
auction.setMinimumBidIncrement(1);
auction.setReservePrice(0);
vm.stopPrank();

vm.prank(founder);
auction.unpause();

// 0 value bid placed
vm.prank(bidder1);
auction.createBid{value: 0}(2);

// another 0 value bid should not be able to be
vm.prank(bidder2);
vm.expectRevert(IAuction.MINIMUM_BID_NOT_MET.selector);
auction.createBid{value: 0}(2);
}

function test_CreateBid(uint256 _amount) public {
deployMock();

Expand Down
47 changes: 47 additions & 0 deletions test/forking/TestBid.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import { Test } from "forge-std/Test.sol";
import { Treasury } from "../../src/governance/treasury/Treasury.sol";
import { Auction } from "../../src/auction/Auction.sol";
import { IAuction } from "../../src/auction/IAuction.sol";
import { Token } from "../../src/token/Token.sol";
import { Governor } from "../../src/governance/governor/Governor.sol";
import { IManager } from "../../src/manager/IManager.sol";
import { Manager } from "../../src/manager/Manager.sol";
import { UUPS } from "../../src/lib/proxy/UUPS.sol";

contract TestBidError is Test {
Manager internal immutable manager = Manager(0xd310A3041dFcF14Def5ccBc508668974b5da7174);
Token internal immutable token = Token(0x8983eC4B57dbebe8944Af8d4F9D3adBAfEA5b9f1);

function setUp() public {
uint256 mainnetFork = vm.createFork(vm.envString("ETH_RPC_MAINNET"));
vm.selectFork(mainnetFork);
vm.rollFork(16200201);
}

function testBidIssue() public {
(address metadata, address auction, address treasury, address governor) = manager.getAddresses(address(token));
address bidder1 = address(0xb1dd331);
vm.deal(bidder1, 2 ether);

vm.expectRevert(IAuction.MINIMUM_BID_NOT_MET.selector);
vm.prank(bidder1);
Auction(auction).createBid{ value: 0.1 ether }(2);

// test new impl
address newAuctionImpl = address(new Auction(address(manager), address(0)));
address auctionImpl = manager.auctionImpl();
// Update bytecode for debugging
vm.etch(auctionImpl, newAuctionImpl.code);

vm.prank(bidder1);
Auction(auction).createBid{ value: 0.10 ether }(2);

vm.warp(100);

vm.prank(bidder1);
Auction(auction).createBid{ value: 0.30 ether }(2);
}
}

0 comments on commit d97dc4b

Please sign in to comment.