Skip to content

Commit

Permalink
feat(billboard): change leaseTerm from block.timestamp to block.number
Browse files Browse the repository at this point in the history
  • Loading branch information
robertu7 committed Dec 5, 2023
1 parent 363c16b commit 4f4c923
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 79 deletions.
3 changes: 2 additions & 1 deletion .env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ THESPACE_INCENTIVES_ADDRESS=
THESPACE_INCENTIVES_TOKENS=
THESPACE_LP_ADDRESS=
THESPACE_LP_TOKENS=
BILLBOARD_REGISTRY_ADDRESS=0x0000000000000000000000000000000000000000
BILLBOARD_REGISTRY_ADDRESS=0x0000000000000000000000000000000000000000
BILLBOARD_LEASE_TERM=
1 change: 1 addition & 0 deletions .env.polygon-mainnet.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ THESPACE_INCENTIVES_TOKENS=
THESPACE_LP_ADDRESS=
THESPACE_LP_TOKENS=
BILLBOARD_REGISTRY_ADDRESS=0x0000000000000000000000000000000000000000
BILLBOARD_LEASE_TERM=
1 change: 1 addition & 0 deletions .env.polygon-mumbai.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ THESPACE_INCENTIVES_TOKENS=
THESPACE_LP_ADDRESS=
THESPACE_LP_TOKENS=
BILLBOARD_REGISTRY_ADDRESS=0x0000000000000000000000000000000000000000
BILLBOARD_LEASE_TERM=
48 changes: 24 additions & 24 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ ACLManagerTest:testRoles() (gas: 15393)
ACLManagerTest:testTransferRole() (gas: 21528)
BillboardTest:testAddToWhitelist() (gas: 35114)
BillboardTest:testApproveAndTransfer() (gas: 162512)
BillboardTest:testCalculateTax() (gas: 22822)
BillboardTest:testCannnotWithdrawTaxIfSmallAmount(uint8) (runs: 256, μ: 410878, ~: 424702)
BillboardTest:testCannnotWithdrawTaxIfZero() (gas: 377863)
BillboardTest:testCalculateTax() (gas: 21782)
BillboardTest:testCannnotWithdrawTaxIfSmallAmount(uint8) (runs: 256, μ: 418269, ~: 424925)
BillboardTest:testCannnotWithdrawTaxIfZero() (gas: 379035)
BillboardTest:testCannotAddToWhitelistByAttacker() (gas: 9037)
BillboardTest:testCannotApproveByAttacker() (gas: 130271)
BillboardTest:testCannotClearAuctionIfAuctionNotEnded() (gas: 578827)
BillboardTest:testCannotClearAuctionIfAuctionNotEnded() (gas: 579292)
BillboardTest:testCannotClearAuctionOnNewBoard() (gas: 136253)
BillboardTest:testCannotMintBoardByAttacker() (gas: 13321)
BillboardTest:testCannotPlaceBidByAttacker() (gas: 139222)
BillboardTest:testCannotPlaceBidTwice(uint96) (runs: 256, μ: 624744, ~: 630975)
BillboardTest:testCannotPlaceBidByAttacker() (gas: 138273)
BillboardTest:testCannotPlaceBidTwice(uint96) (runs: 256, μ: 623750, ~: 630370)
BillboardTest:testCannotRemoveToWhitelistByAttacker() (gas: 9104)
BillboardTest:testCannotSafeTransferByAttacker() (gas: 127438)
BillboardTest:testCannotSetBoardProprtiesByAttacker() (gas: 157292)
Expand All @@ -29,35 +29,35 @@ BillboardTest:testCannotSetTaxRateByAttacker() (gas: 9006)
BillboardTest:testCannotTransferByOperator() (gas: 132771)
BillboardTest:testCannotTransferToZeroAddress() (gas: 128258)
BillboardTest:testCannotUpgradeRegistryByAttacker() (gas: 9128)
BillboardTest:testCannotWithBidTwice(uint96) (runs: 256, μ: 903306, ~: 903306)
BillboardTest:testCannotWithdrawBidIfAuctionNotCleared(uint96) (runs: 256, μ: 743847, ~: 743847)
BillboardTest:testCannotWithdrawBidIfAuctionNotEnded(uint96) (runs: 256, μ: 619025, ~: 619025)
BillboardTest:testCannotWithdrawBidIfNotFound() (gas: 413160)
BillboardTest:testCannotWithdrawBidIfWon(uint96) (runs: 256, μ: 710721, ~: 710721)
BillboardTest:testCannotWithBidTwice(uint96) (runs: 256, μ: 901993, ~: 901993)
BillboardTest:testCannotWithdrawBidIfAuctionNotCleared(uint96) (runs: 256, μ: 742413, ~: 742413)
BillboardTest:testCannotWithdrawBidIfAuctionNotEnded(uint96) (runs: 256, μ: 618541, ~: 618541)
BillboardTest:testCannotWithdrawBidIfNotFound() (gas: 414332)
BillboardTest:testCannotWithdrawBidIfWon(uint96) (runs: 256, μ: 710358, ~: 710358)
BillboardTest:testCannotWithdrawTaxByAttacker() (gas: 16677)
BillboardTest:testClearAuctionIfAuctionEnded() (gas: 622677)
BillboardTest:testClearAuctionsIfAuctionEnded() (gas: 1156582)
BillboardTest:testGetBids(uint8,uint8,uint8) (runs: 256, μ: 2773780, ~: 1419565)
BillboardTest:testClearAuctionIfAuctionEnded() (gas: 623626)
BillboardTest:testClearAuctionsIfAuctionEnded() (gas: 1156359)
BillboardTest:testGetBids(uint8,uint8,uint8) (runs: 256, μ: 2878685, ~: 1412103)
BillboardTest:testGetTokenURI() (gas: 154980)
BillboardTest:testMintBoard() (gas: 225541)
BillboardTest:testMintBoardByWhitelist() (gas: 154942)
BillboardTest:testMintBoardIfOpened() (gas: 145715)
BillboardTest:testPlaceBidByWhitelist() (gas: 461423)
BillboardTest:testPlaceBidIfAuctionEnded() (gas: 906529)
BillboardTest:testPlaceBidOnNewBoard(uint96) (runs: 256, μ: 510724, ~: 520900)
BillboardTest:testPlaceBidWithHigherPrice(uint96) (runs: 256, μ: 739847, ~: 747077)
BillboardTest:testPlaceBidWithSamePrices(uint96) (runs: 256, μ: 738385, ~: 750061)
BillboardTest:testPlaceBidZeroPrice() (gas: 354275)
BillboardTest:testPlaceBidByWhitelist() (gas: 461646)
BillboardTest:testPlaceBidIfAuctionEnded() (gas: 905458)
BillboardTest:testPlaceBidOnNewBoard(uint96) (runs: 256, μ: 510257, ~: 521365)
BillboardTest:testPlaceBidWithHigherPrice(uint96) (runs: 256, μ: 736177, ~: 744573)
BillboardTest:testPlaceBidWithSamePrices(uint96) (runs: 256, μ: 735897, ~: 748506)
BillboardTest:testPlaceBidZeroPrice() (gas: 355447)
BillboardTest:testRemoveToWhitelist() (gas: 23207)
BillboardTest:testSafeTransferByOperator() (gas: 141237)
BillboardTest:testSetBoardProperties() (gas: 305883)
BillboardTest:testSetBoardPropertiesAfterTransfer() (gas: 335509)
BillboardTest:testSetIsOpened() (gas: 22661)
BillboardTest:testSetTaxRate() (gas: 22909)
BillboardTest:testSomethin() (gas: 1626769)
BillboardTest:testUpgradeRegistry() (gas: 2968149)
BillboardTest:testWithdrawBid(uint96) (runs: 256, μ: 904808, ~: 904808)
BillboardTest:testWithdrawTax(uint96) (runs: 256, μ: 500265, ~: 500265)
BillboardTest:testSomethin() (gas: 1624285)
BillboardTest:testUpgradeRegistry() (gas: 2935587)
BillboardTest:testWithdrawBid(uint96) (runs: 256, μ: 903495, ~: 903495)
BillboardTest:testWithdrawTax(uint96) (runs: 256, μ: 500488, ~: 500488)
CurationTest:testCannotCurateERC20CurateZeroAmount() (gas: 12194)
CurationTest:testCannotCurateERC20EmptyURI() (gas: 15797)
CurationTest:testCannotCurateERC20IfNotApproval() (gas: 21624)
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ deploy-curation: clean

## Billboard
deploy-billboard: clean
@forge create Billboard --rpc-url ${ETH_RPC_URL} --private-key ${DEPLOYER_PRIVATE_KEY} --constructor-args ${BILLBOARD_REGISTRY_ADDRESS} 1 "Billboard" "BLBD" --legacy --verify --etherscan-api-key ${ETHERSCAN_API_KEY}
@forge create Billboard --rpc-url ${ETH_RPC_URL} --private-key ${DEPLOYER_PRIVATE_KEY} --constructor-args ${BILLBOARD_REGISTRY_ADDRESS} 1 ${BILLBOARD_LEASE_TERM} "Billboard" "BLBD" --legacy --verify --etherscan-api-key ${ETHERSCAN_API_KEY}
26 changes: 16 additions & 10 deletions src/Billboard/Billboard.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ contract Billboard is IBillboard {
mapping(address => bool) public whitelist;
bool public isOpened = false;

constructor(address payable registry_, uint256 taxRate_, string memory name_, string memory symbol_) {
constructor(
address payable registry_,
uint256 taxRate_,
uint64 leaseTerm_,
string memory name_,
string memory symbol_
) {
admin = msg.sender;
whitelist[msg.sender] = true;

Expand All @@ -22,7 +28,7 @@ contract Billboard is IBillboard {
}
// deploy operator and registry
else {
registry = new BillboardRegistry(address(this), taxRate_, name_, symbol_);
registry = new BillboardRegistry(address(this), taxRate_, leaseTerm_, name_, symbol_);
}
}

Expand Down Expand Up @@ -145,7 +151,7 @@ contract Billboard is IBillboard {
IBillboardRegistry.Auction memory _nextAuction = registry.getAuction(tokenId_, _nextAuctionId);

// revert if auction is still running
require(block.timestamp >= _nextAuction.endAt, "Auction not ended");
require(block.number >= _nextAuction.endAt, "Auction not ended");

// reclaim ownership to board creator if no auction
address _prevOwner = registry.ownerOf(tokenId_);
Expand Down Expand Up @@ -196,7 +202,7 @@ contract Billboard is IBillboard {
registry.setBidWon(tokenId_, nextAuctionId_, _nextAuction.highestBidder, true);

// set auction lease
uint64 leaseStartAt = uint64(block.timestamp);
uint64 leaseStartAt = uint64(block.number);
uint64 leaseEndAt = uint64(leaseStartAt + registry.leaseTerm());
registry.setAuctionLease(tokenId_, nextAuctionId_, leaseStartAt, leaseEndAt);

Expand All @@ -216,17 +222,17 @@ contract Billboard is IBillboard {
// create new auction and new bid first,
// then clear auction and transfer ownership to the bidder immediately.
if (_nextAuction.startAt == 0) {
uint256 _auctionId = _newAuctionAndBid(tokenId_, amount_, uint64(block.timestamp));
uint256 _auctionId = _newAuctionAndBid(tokenId_, amount_, uint64(block.number));
_clearAuction(tokenId_, _board.creator, _auctionId);
return;
}

// if next auction is ended,
// clear auction first,
// then create new auction and new bid
if (block.timestamp >= _nextAuction.endAt) {
if (block.number >= _nextAuction.endAt) {
_clearAuction(tokenId_, _board.creator, _nextAuctionId);
_newAuctionAndBid(tokenId_, amount_, uint64(block.timestamp + registry.leaseTerm()));
_newAuctionAndBid(tokenId_, amount_, uint64(block.number + registry.leaseTerm()));
return;
}
// if next auction is not ended,
Expand All @@ -242,7 +248,7 @@ contract Billboard is IBillboard {
}

function _newAuctionAndBid(uint256 tokenId_, uint256 amount_, uint64 endAt_) private returns (uint256 auctionId) {
uint64 _startAt = uint64(block.timestamp);
uint64 _startAt = uint64(block.number);
uint256 _tax = calculateTax(amount_);

auctionId = registry.newAuction(tokenId_, _startAt, endAt_);
Expand Down Expand Up @@ -319,7 +325,7 @@ contract Billboard is IBillboard {
}

function calculateTax(uint256 amount_) public view returns (uint256 tax) {
tax = (amount_ * registry.taxRate() * registry.leaseTerm()) / 1 days / 100;
tax = (amount_ * registry.taxRate()) / 100;
}

/// @inheritdoc IBillboard
Expand All @@ -344,7 +350,7 @@ contract Billboard is IBillboard {
function withdrawBid(uint256 tokenId_, uint256 auctionId_) external {
// revert if auction is still running
IBillboardRegistry.Auction memory _auction = registry.getAuction(tokenId_, auctionId_);
require(block.timestamp >= _auction.endAt, "Auction not ended");
require(block.number >= _auction.endAt, "Auction not ended");

// revert if auction is not cleared
require(_auction.leaseEndAt != 0, "Auction not cleared");
Expand Down
8 changes: 5 additions & 3 deletions src/Billboard/BillboardRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ contract BillboardRegistry is IBillboardRegistry, ERC721 {
Counters.Counter public lastTokenId;

uint256 public taxRate;
uint64 public constant leaseTerm = 14 days;
uint64 public leaseTerm;

// tokenId => Board
mapping(uint256 => Board) public boards;
Expand All @@ -38,12 +38,14 @@ contract BillboardRegistry is IBillboardRegistry, ERC721 {
constructor(
address operator_,
uint256 taxRate_,
uint64 leaseTerm_,
string memory name_,
string memory symbol_
) ERC721(name_, symbol_) {
require(operator_ != address(0), "Zero address");
operator = operator_;
taxRate = taxRate_;
leaseTerm = leaseTerm_;
}

//////////////////////////////
Expand Down Expand Up @@ -186,7 +188,7 @@ contract BillboardRegistry is IBillboardRegistry, ERC721 {
uint256 price_,
uint256 tax_
) external isFromOperator {
Bid memory _bid = Bid({price: price_, tax: tax_, placedAt: block.timestamp, isWithdrawn: false, isWon: false});
Bid memory _bid = Bid({price: price_, tax: tax_, placedAt: block.number, isWithdrawn: false, isWon: false});

// add to auction bids
auctionBids[tokenId_][auctionId_][bidder_] = _bid;
Expand All @@ -197,7 +199,7 @@ contract BillboardRegistry is IBillboardRegistry, ERC721 {
// set auction highest bidder if no highest bidder or price is higher.
//
// Note: for same price, the first bidder will always be
// the highest bidder since the block.timestamp is always greater.
// the highest bidder since the block.number is always greater.
address highestBidder = boardAuctions[tokenId_][auctionId_].highestBidder;
Bid memory highestBid = auctionBids[tokenId_][auctionId_][highestBidder];
if (highestBidder == address(0) || price_ > highestBid.price) {
Expand Down
10 changes: 5 additions & 5 deletions src/Billboard/IBillboardRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -152,17 +152,17 @@ interface IBillboardRegistry is IERC721 {
}

struct Auction {
uint64 startAt; // timestamp
uint64 endAt; // timestamp
uint64 leaseStartAt; // timestamp
uint64 leaseEndAt; // timestamp
uint64 startAt; // block number
uint64 endAt; // block number
uint64 leaseStartAt; // block number
uint64 leaseEndAt; // block number
address highestBidder;
}

struct Bid {
uint256 price;
uint256 tax;
uint256 placedAt; // timestamp
uint256 placedAt; // block number
bool isWon;
bool isWithdrawn;
}
Expand Down
Loading

0 comments on commit 4f4c923

Please sign in to comment.