Skip to content

Commit

Permalink
update the logic of tax calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
zeckli committed Mar 15, 2024
1 parent 93e7aa5 commit b956a65
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 51 deletions.
96 changes: 49 additions & 47 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -9,54 +9,56 @@ ACLManagerTest:testGrantRole() (gas: 23547)
ACLManagerTest:testRenounceRole() (gas: 27841)
ACLManagerTest:testRoles() (gas: 15393)
ACLManagerTest:testTransferRole() (gas: 21528)
BillboardTest:testAddToWhitelist() (gas: 35114)
BillboardTest:testApproveAndTransfer() (gas: 162468)
BillboardTest:testCalculateTax() (gas: 21760)
BillboardTest:testCannnotWithdrawTaxIfSmallAmount(uint8) (runs: 256, μ: 519701, ~: 524563)
BillboardTest:testCannnotWithdrawTaxIfZero() (gas: 490384)
BillboardTest:testCannotAddToWhitelistByAttacker() (gas: 9037)
BillboardTest:testCannotApproveByAttacker() (gas: 130281)
BillboardTest:testCannotClearAuctionIfAuctionNotEnded() (gas: 700985)
BillboardTest:testCannotClearAuctionOnNewBoard() (gas: 136261)
BillboardTest:testCannotMintBoardByAttacker() (gas: 13321)
BillboardTest:testCannotPlaceBidByAttacker() (gas: 246293)
BillboardTest:testCannotPlaceBidTwice(uint96) (runs: 256, μ: 749802, ~: 754905)
BillboardTest:testCannotRemoveToWhitelistByAttacker() (gas: 9104)
BillboardTest:testCannotSafeTransferByAttacker() (gas: 127438)
BillboardTest:testCannotSetBoardProprtiesByAttacker() (gas: 157292)
BillboardTest:testCannotSetIsOpenedByAttacker() (gas: 8994)
BillboardTest:testCannotSetTaxRateByAttacker() (gas: 9006)
BillboardTest:testCannotTransferByOperator() (gas: 132771)
BillboardTest:testCannotTransferToZeroAddress() (gas: 128258)
BillboardTest:testAddToWhitelist() (gas: 35092)
BillboardTest:testApproveAndTransfer() (gas: 162514)
BillboardTest:testCalculateTax() (gas: 30107)
BillboardTest:testCannnotWithdrawTaxIfSmallAmount(uint8) (runs: 256, μ: 522933, ~: 527800)
BillboardTest:testCannnotWithdrawTaxIfZero() (gas: 492392)
BillboardTest:testCannotAddToWhitelistByAttacker() (gas: 9059)
BillboardTest:testCannotApproveByAttacker() (gas: 130326)
BillboardTest:testCannotClearAuctionIfAuctionNotEnded() (gas: 704554)
BillboardTest:testCannotClearAuctionOnNewBoard() (gas: 136218)
BillboardTest:testCannotMintBoardByAttacker() (gas: 13366)
BillboardTest:testCannotPlaceBidByAttacker() (gas: 249507)
BillboardTest:testCannotPlaceBidTwice(uint96) (runs: 256, μ: 754445, ~: 759484)
BillboardTest:testCannotRemoveToWhitelistByAttacker() (gas: 9083)
BillboardTest:testCannotSafeTransferByAttacker() (gas: 127483)
BillboardTest:testCannotSetBlocksPerDayByAttacker() (gas: 9075)
BillboardTest:testCannotSetBoardProprtiesByAttacker() (gas: 157250)
BillboardTest:testCannotSetIsOpenedByAttacker() (gas: 9050)
BillboardTest:testCannotSetTaxRateByAttacker() (gas: 8984)
BillboardTest:testCannotTransferByOperator() (gas: 132749)
BillboardTest:testCannotTransferToZeroAddress() (gas: 128303)
BillboardTest:testCannotUpgradeRegistryByAttacker() (gas: 9128)
BillboardTest:testCannotWithBidTwice(uint96) (runs: 256, μ: 1079907, ~: 1079907)
BillboardTest:testCannotWithdrawBidIfAuctionNotCleared(uint96) (runs: 256, μ: 911089, ~: 911089)
BillboardTest:testCannotWithdrawBidIfAuctionNotEnded(uint96) (runs: 256, μ: 725782, ~: 725782)
BillboardTest:testCannotWithdrawBidIfNotFound() (gas: 428052)
BillboardTest:testCannotWithdrawBidIfWon(uint96) (runs: 256, μ: 834282, ~: 834282)
BillboardTest:testCannotWithdrawTaxByAttacker() (gas: 16687)
BillboardTest:testClearAuctionIfAuctionEnded(uint96) (runs: 256, μ: 837581, ~: 837581)
BillboardTest:testClearAuctionsIfAuctionEnded() (gas: 1379962)
BillboardTest:testGetBids(uint8,uint8,uint8) (runs: 256, μ: 4579559, ~: 2075259)
BillboardTest:testGetTokenURI() (gas: 154936)
BillboardTest:testMintBoard() (gas: 225541)
BillboardTest:testMintBoardByWhitelist() (gas: 154942)
BillboardTest:testMintBoardIfOpened() (gas: 145715)
BillboardTest:testPlaceBidByWhitelist() (gas: 579179)
BillboardTest:testPlaceBidIfAuctionEnded() (gas: 1090700)
BillboardTest:testPlaceBidOnNewBoard(uint96) (runs: 256, μ: 618810, ~: 635089)
BillboardTest:testPlaceBidWithHigherPrice(uint96) (runs: 256, μ: 904936, ~: 913254)
BillboardTest:testPlaceBidWithSamePrices(uint96) (runs: 256, μ: 908100, ~: 918050)
BillboardTest:testPlaceBidZeroPrice() (gas: 376947)
BillboardTest:testRemoveToWhitelist() (gas: 23188)
BillboardTest:testSafeTransferByOperator() (gas: 141193)
BillboardTest:testSetBoardProperties() (gas: 305972)
BillboardTest:testSetBoardPropertiesAfterTransfer() (gas: 335477)
BillboardTest:testSetIsOpened() (gas: 22661)
BillboardTest:testSetTaxRate() (gas: 22887)
BillboardTest:testUpgradeRegistry() (gas: 3132522)
BillboardTest:testWithdrawBid(uint96) (runs: 256, μ: 1081415, ~: 1081415)
BillboardTest:testWithdrawTax(uint96) (runs: 256, μ: 597714, ~: 597714)
BillboardTest:testCannotWithBidTwice(uint96) (runs: 256, μ: 1087298, ~: 1087298)
BillboardTest:testCannotWithdrawBidIfAuctionNotCleared(uint96) (runs: 256, μ: 918777, ~: 918777)
BillboardTest:testCannotWithdrawBidIfAuctionNotEnded(uint96) (runs: 256, μ: 731455, ~: 731455)
BillboardTest:testCannotWithdrawBidIfNotFound() (gas: 429903)
BillboardTest:testCannotWithdrawBidIfWon(uint96) (runs: 256, μ: 839993, ~: 839993)
BillboardTest:testCannotWithdrawTaxByAttacker() (gas: 16798)
BillboardTest:testClearAuctionIfAuctionEnded(uint96) (runs: 256, μ: 843359, ~: 843359)
BillboardTest:testClearAuctionsIfAuctionEnded() (gas: 1387506)
BillboardTest:testGetBids(uint8,uint8,uint8) (runs: 256, μ: 4632683, ~: 2095732)
BillboardTest:testGetTokenURI() (gas: 154915)
BillboardTest:testMintBoard() (gas: 225611)
BillboardTest:testMintBoardByWhitelist() (gas: 155010)
BillboardTest:testMintBoardIfOpened() (gas: 145783)
BillboardTest:testPlaceBidByWhitelist() (gas: 583159)
BillboardTest:testPlaceBidIfAuctionEnded() (gas: 1098489)
BillboardTest:testPlaceBidOnNewBoard(uint96) (runs: 256, μ: 623087, ~: 639135)
BillboardTest:testPlaceBidWithHigherPrice(uint96) (runs: 256, μ: 914975, ~: 922982)
BillboardTest:testPlaceBidWithSamePrices(uint96) (runs: 256, μ: 915600, ~: 925784)
BillboardTest:testPlaceBidZeroPrice() (gas: 378911)
BillboardTest:testRemoveToWhitelist() (gas: 23225)
BillboardTest:testSafeTransferByOperator() (gas: 141238)
BillboardTest:testSetBlocksPerDay() (gas: 23413)
BillboardTest:testSetBoardProperties() (gas: 305820)
BillboardTest:testSetBoardPropertiesAfterTransfer() (gas: 335288)
BillboardTest:testSetIsOpened() (gas: 22821)
BillboardTest:testSetTaxRate() (gas: 22910)
BillboardTest:testUpgradeRegistry() (gas: 3291749)
BillboardTest:testWithdrawBid(uint96) (runs: 256, μ: 1088963, ~: 1088963)
BillboardTest:testWithdrawTax(uint96) (runs: 256, μ: 601718, ~: 601718)
CurationTest:testCannotCurateERC20CurateZeroAmount() (gas: 12194)
CurationTest:testCannotCurateERC20EmptyURI() (gas: 15797)
CurationTest:testCannotCurateERC20IfNotApproval() (gas: 21624)
Expand Down
27 changes: 25 additions & 2 deletions src/Billboard/Billboard.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ contract Billboard is IBillboard {
address admin_,
uint256 taxRate_,
uint64 leaseTerm_,
uint64 blocksPerDay_,
string memory name_,
string memory symbol_
) {
Expand All @@ -33,7 +34,15 @@ contract Billboard is IBillboard {
}
// deploy operator and registry
else {
registry = new BillboardRegistry(token_, address(this), taxRate_, leaseTerm_, name_, symbol_);
registry = new BillboardRegistry(
token_,
address(this),
taxRate_,
leaseTerm_,
blocksPerDay_,
name_,
symbol_
);
}
}

Expand Down Expand Up @@ -336,7 +345,7 @@ contract Billboard is IBillboard {
}

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

/// @inheritdoc IBillboard
Expand Down Expand Up @@ -386,4 +395,18 @@ contract Billboard is IBillboard {
// emit BidWithdrawn
registry.emitBidWithdrawn(tokenId_, auctionId_, msg.sender, _bid.price, _bid.tax);
}

//////////////////////////////
/// Block
//////////////////////////////

/// @inheritdoc IBillboard
function getBlocksPerDay() external view returns (uint64 blocksPerDay) {
return registry.blocksPerDay();
}

/// @inheritdoc IBillboard
function setBlocksPerDay(uint64 blocksPerDay_) external isFromAdmin {
registry.setBlocksPerDay(blocksPerDay_);
}
}
14 changes: 14 additions & 0 deletions src/Billboard/BillboardRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ contract BillboardRegistry is IBillboardRegistry, ERC721 {
IERC20 public immutable token;
uint256 public taxRate;
uint64 public leaseTerm;
uint64 public blocksPerDay;

// tokenId => Board
mapping(uint256 => Board) public boards;
Expand All @@ -42,6 +43,7 @@ contract BillboardRegistry is IBillboardRegistry, ERC721 {
address operator_,
uint256 taxRate_,
uint64 leaseTerm_,
uint64 blocksPerDay_,
string memory name_,
string memory symbol_
) ERC721(name_, symbol_) {
Expand All @@ -52,6 +54,7 @@ contract BillboardRegistry is IBillboardRegistry, ERC721 {
operator = operator_;
taxRate = taxRate_;
leaseTerm = leaseTerm_;
blocksPerDay = blocksPerDay_;
}

//////////////////////////////
Expand Down Expand Up @@ -256,6 +259,17 @@ contract BillboardRegistry is IBillboardRegistry, ERC721 {
taxTreasury[owner_].withdrawn = withdrawn_;
}

//////////////////////////////
/// Block
//////////////////////////////

/// @inheritdoc IBillboardRegistry
function setBlocksPerDay(uint64 blocksPerDay_) external isFromOperator {
blocksPerDay = blocksPerDay_;

emit BlocksPerDayUpdated(blocksPerDay_);
}

//////////////////////////////
/// ERC721 Overrides
//////////////////////////////
Expand Down
18 changes: 18 additions & 0 deletions src/Billboard/IBillboard.sol
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,22 @@ interface IBillboard {
* @param auctionId_ Auction ID of a board.
*/
function withdrawBid(uint256 tokenId_, uint256 auctionId_) external;

//////////////////////////////
/// Block
//////////////////////////////

/**
* @notice Get the global block number per day.
*
* @return blocksPerDay Block number per day.
*/
function getBlocksPerDay() external view returns (uint64 blocksPerDay);

/**
* @notice Set the global block number per day.
*
* @param blocksPerDay_ Block number per day.
*/
function setBlocksPerDay(uint64 blocksPerDay_) external;
}
18 changes: 18 additions & 0 deletions src/Billboard/IBillboardRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ interface IBillboardRegistry is IERC721 {
*/
event TaxRateUpdated(uint256 taxRate);

/**
* @notice Global block number per day is updated.
*
* @param blocksPerDay New block number per day.
*/
event BlocksPerDayUpdated(uint64 blocksPerDay);

/**
* @notice Auction is created.
*
Expand Down Expand Up @@ -366,6 +373,17 @@ interface IBillboardRegistry is IERC721 {
*/
function setTaxTreasury(address owner_, uint256 accumulated_, uint256 withdrawn_) external;

//////////////////////////////
/// Block
//////////////////////////////

/**
* @notice Set the global block number per day.
*
* @param blocksPerDay_ Block number per day.
*/
function setBlocksPerDay(uint64 blocksPerDay_) external;

//////////////////////////////
/// Event emission
//////////////////////////////
Expand Down
26 changes: 25 additions & 1 deletion src/test/Billboard/BillboardTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ contract BillboardTest is BillboardTestBase {
ADMIN,
TAX_RATE,
LEASE_TERM,
BLOCKS_PER_DAY,
"Billboard2",
"BLBD2"
);
Expand Down Expand Up @@ -799,12 +800,14 @@ contract BillboardTest is BillboardTestBase {
function testCalculateTax() public {
uint256 _amount = 100;
uint256 _taxRate = 10; // 10% per lease term
uint64 _leaseTerm = registry.leaseTerm();
uint64 _blocksPerDay = registry.blocksPerDay();

vm.startPrank(ADMIN);
operator.setTaxRate(_taxRate);

uint256 _tax = operator.calculateTax(_amount);
assertEq(_tax, (_amount * _taxRate) / 100);
assertEq(_tax, (_amount * _taxRate * (_leaseTerm / _blocksPerDay)) / 100);
}

function testSetTaxRate() public {
Expand Down Expand Up @@ -1057,4 +1060,25 @@ contract BillboardTest is BillboardTestBase {
vm.expectRevert("Bid not found");
operator.withdrawBid(_tokenId, _nextAuctionId);
}

//////////////////////////////
/// Block
//////////////////////////////

function testSetBlocksPerDay() public {
vm.startPrank(ADMIN);

vm.expectEmit(true, true, true, true);
emit IBillboardRegistry.BlocksPerDayUpdated(200);

operator.setBlocksPerDay(200);
assertEq(operator.getBlocksPerDay(), 200);
}

function testCannotSetBlocksPerDayByAttacker() public {
vm.startPrank(ATTACKER);

vm.expectRevert("Admin");
operator.setBlocksPerDay(100);
}
}
12 changes: 11 additions & 1 deletion src/test/Billboard/BillboardTestBase.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ contract BillboardTestBase is Test {

uint256 constant TAX_RATE = 1; // 1% per lease term
uint64 constant LEASE_TERM = 100; // 100 blocks
uint64 constant BLOCKS_PER_DAY = 100; // 100 blocks per day

address constant ZERO_ADDRESS = address(0);
address constant FAKE_CONTRACT = address(1);
Expand All @@ -36,7 +37,16 @@ contract BillboardTestBase is Test {
usdt = new USDT(ADMIN, 0);

// deploy operator & registry
operator = new Billboard(address(usdt), payable(address(0)), ADMIN, TAX_RATE, LEASE_TERM, "Billboard", "BLBD");
operator = new Billboard(
address(usdt),
payable(address(0)),
ADMIN,
TAX_RATE,
LEASE_TERM,
BLOCKS_PER_DAY,
"Billboard",
"BLBD"
);
registry = operator.registry();
assertEq(operator.admin(), ADMIN);
assertEq(registry.operator(), address(operator));
Expand Down

0 comments on commit b956a65

Please sign in to comment.