From 43306975f4d6dfc66f4c7f044f23ac1457346b9d Mon Sep 17 00:00:00 2001 From: Vectorized Date: Sun, 17 Dec 2023 23:12:05 +0000 Subject: [PATCH] Fix code and fuzz test --- contracts/modules/SuperMinterV2.sol | 26 ++++++++----------- .../modules/interfaces/ISuperMinterV2.sol | 4 +-- tests/modules/SuperMinterV2.t.sol | 25 +++++++++++++----- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/contracts/modules/SuperMinterV2.sol b/contracts/modules/SuperMinterV2.sol index d6da541a..8c126fed 100644 --- a/contracts/modules/SuperMinterV2.sol +++ b/contracts/modules/SuperMinterV2.sol @@ -347,7 +347,7 @@ contract SuperMinterV2 is ISuperMinterV2, EIP712 { l.finalArtistFee = f.finalArtistFee; l.finalPlatformFee = f.finalPlatformFee; l.finalAffiliateFee = f.finalAffiliateFee; - + // Platform and affilaite fees are accrued mappings // Artist earnings are directly forwarded to the nft contract in mint call below if (l.finalAffiliateFee != 0) { @@ -879,10 +879,7 @@ contract SuperMinterV2 is ISuperMinterV2, EIP712 { */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return - LibOps.or( - interfaceId == type(ISuperMinterV2).interfaceId, - interfaceId == this.supportsInterface.selector - ); + LibOps.or(interfaceId == type(ISuperMinterV2).interfaceId, interfaceId == this.supportsInterface.selector); } // ============================================================= @@ -959,7 +956,10 @@ contract SuperMinterV2 is ISuperMinterV2, EIP712 { function _validatePlatformFeeConfig(PlatformFeeConfig memory c) internal pure { if ( LibOps.or( - LibOps.or(c.platformTxFlatFee > MAX_PLATFORM_PER_TX_FLAT_FEE, c.platformMintBPSFee > MAX_PLATFORM_PER_MINT_FEE_BPS), + LibOps.or( + c.platformTxFlatFee > MAX_PLATFORM_PER_TX_FLAT_FEE, + c.platformMintBPSFee > MAX_PLATFORM_PER_MINT_FEE_BPS + ), LibOps.or( c.artistMintReward > MAX_PER_MINT_REWARD, c.affiliateMintReward > MAX_PER_MINT_REWARD, @@ -1178,24 +1178,20 @@ contract SuperMinterV2 is ISuperMinterV2, EIP712 { uint256 affiliateBPSFee = LibOps.rawMulDiv(f.subTotal, d.affiliateFeeBPS, BPS_DENOMINATOR); f.finalArtistFee -= affiliateBPSFee; f.finalAffiliateFee = affiliateBPSFee; - } else { - f.finalAffiliateFee = 0; } + if (c.platformMintBPSFee != 0) { uint256 platformBPSFee = LibOps.rawMulDiv(f.subTotal, c.platformMintBPSFee, BPS_DENOMINATOR); f.finalArtistFee -= platformBPSFee; f.finalPlatformFee = platformBPSFee; - } else { - f.finalPlatformFee = 0; } - // Protocol rewards are additive to unitPrice and paid by the buyer. // There are 2 sets of rewards, one for prices below thresholdPrice and one for prices above. if (unitPrice <= c.thresholdPrice) { f.finalArtistFee += c.artistMintReward * uint256(quantity); - f.finalPlatformFee = c.platformMintReward * uint256(quantity); - + f.finalPlatformFee += c.platformMintReward * uint256(quantity); + // The platform is the affiliate if no affiliate is provided if (hasValidAffiliate) { f.finalAffiliateFee += c.affiliateMintReward * uint256(quantity); @@ -1204,8 +1200,8 @@ contract SuperMinterV2 is ISuperMinterV2, EIP712 { } } else { f.finalArtistFee += c.thresholdArtistMintReward * uint256(quantity); - f.finalPlatformFee = c.thresholdPlatformMintReward * uint256(quantity); - + f.finalPlatformFee += c.thresholdPlatformMintReward * uint256(quantity); + // The platform is the affiliate if no affiliate is provided if (hasValidAffiliate) { f.finalAffiliateFee += c.thresholdAffiliateMintReward * uint256(quantity); diff --git a/contracts/modules/interfaces/ISuperMinterV2.sol b/contracts/modules/interfaces/ISuperMinterV2.sol index 4eca7595..55424d6a 100644 --- a/contracts/modules/interfaces/ISuperMinterV2.sol +++ b/contracts/modules/interfaces/ISuperMinterV2.sol @@ -116,7 +116,7 @@ interface ISuperMinterV2 is IERC165 { uint256 subTotal; // The price per token. uint256 unitPrice; - // The final artist fee (inclusive of `finalArtistReward`). + // The final artist fee (inclusive of `finalArtistReward`). uint256 finalArtistFee; // The total affiliate fee (inclusive of `finalAffiliateReward`). uint256 finalAffiliateFee; @@ -874,7 +874,7 @@ interface ISuperMinterV2 is IERC165 { * @param scheduleNum The edition-tier schedule number. * @param quantity How many tokens to mint. * @param signedPrice The signed price. - * @param hasValidAffiliate Whether there is a valid affiliate for the mint. + * @param hasValidAffiliate Whether there is a valid affiliate for the mint. * @return A struct containing the total price and fees. */ function totalPriceAndFeesWithSignedPrice( diff --git a/tests/modules/SuperMinterV2.t.sol b/tests/modules/SuperMinterV2.t.sol index 1be05055..a033af71 100644 --- a/tests/modules/SuperMinterV2.t.sol +++ b/tests/modules/SuperMinterV2.t.sol @@ -737,14 +737,25 @@ contract SuperMinterV2Tests is TestConfigV2_1 { ISuperMinterV2.MintedLogData memory l; ISuperMinterV2.TotalPriceAndFees memory tpaf; - + { + tpaf = sm.totalPriceAndFees(address(edition), c.tier, 0, p.quantity, _random() % 2 == 0); + assertEq(tpaf.subTotal, c.price * uint256(p.quantity)); + assertGt(tpaf.total + 1, tpaf.subTotal); + + // Use a lower, non-zero quantity for mint testing. + p.quantity = uint32(_bound(_random(), 1, 8)); + tpaf = sm.totalPriceAndFees(address(edition), c.tier, 0, p.quantity, _random() % 2 == 0); + assertEq(tpaf.subTotal, c.price * uint256(p.quantity)); + assertGt(tpaf.total + 1, tpaf.subTotal); + } + // Test the affiliated path. if (_random() % 2 == 0) { p.affiliate = _randomNonZeroAddress(); + tpaf = sm.totalPriceAndFees(address(edition), c.tier, 0, p.quantity, true); + vm.expectEmit(true, true, true, true); - - tpaf = sm.totalPriceAndFees(address(edition), 1, 0, p.quantity, true); l.quantity = p.quantity; l.fromTokenId = 1; @@ -756,13 +767,13 @@ contract SuperMinterV2Tests is TestConfigV2_1 { l.finalAffiliateFee = tpaf.finalAffiliateFee; l.finalPlatformFee = tpaf.finalPlatformFee; - emit Minted(address(edition), 1, 0, address(this), l, 0); + emit Minted(address(edition), c.tier, 0, address(this), l, 0); } else { p.affiliate = address(0); - vm.expectEmit(true, true, true, true); + tpaf = sm.totalPriceAndFees(address(edition), c.tier, 0, p.quantity, false); - tpaf = sm.totalPriceAndFees(address(edition), 1, 0, p.quantity, true); + vm.expectEmit(true, true, true, true); l.quantity = p.quantity; l.fromTokenId = 1; @@ -774,7 +785,7 @@ contract SuperMinterV2Tests is TestConfigV2_1 { l.finalAffiliateFee = 0; l.finalPlatformFee = tpaf.finalPlatformFee; - emit Minted(address(edition), 1, 0, address(this), l, 0); + emit Minted(address(edition), c.tier, 0, address(this), l, 0); } sm.mintTo{ value: tpaf.total }(p);