Skip to content

Commit

Permalink
Add mint with affiliate incentive tests and fix verify plaform fees
Browse files Browse the repository at this point in the history
  • Loading branch information
Vectorized committed Nov 6, 2023
1 parent 7a75bab commit 2e1143a
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 123 deletions.
2 changes: 1 addition & 1 deletion contracts/modules/SuperMinterV1_1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,7 @@ contract SuperMinterV1_1 is ISuperMinterV1_1, EIP712 {
c.perTxFlat > MAX_PLATFORM_PER_TX_FLAT_FEE,
c.perMintFlat > MAX_PLATFORM_PER_MINT_FLAT_FEE,
c.perMintBPS > MAX_PLATFORM_PER_MINT_FEE_BPS,
incentiveSum > c.perTxFlat
incentiveSum > c.perMintFlat
)
) revert InvalidPlatformFeeConfig();
}
Expand Down
245 changes: 123 additions & 122 deletions tests/modules/SuperMinterV1_1.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -757,128 +757,129 @@ contract SuperMinterV1_1Tests is TestConfigV2 {
}
}

// function testMintWithAffiliateFlatFees(uint256) public {
// SuperMinterV1_1Constants memory smc = _superMinterConstants();
// address[] memory feeRecipients = _twoRandomUniqueAddresses();

// // Create a tier 1 mint schedule, without any affiliate root.
// ISuperMinterV1_1.MintCreation memory c;
// c.maxMintable = type(uint32).max;
// c.platform = _randomNonZeroAddress();
// c.edition = address(edition);
// c.tier = 1;
// c.price = uint96(_bound(_random(), 0, type(uint96).max));
// c.affiliateFeeBPS = uint16(_bound(_random(), 0, smc.MAX_AFFILIATE_FEE_BPS));
// c.startTime = 0;
// c.endTime = uint32(block.timestamp + 1000);
// c.maxMintablePerAccount = type(uint32).max;
// assertEq(sm.createEditionMint(c), 0);

// // Set the tier 1 platform fee config.
// ISuperMinterV1_1.PlatformFeeConfig memory pfc;
// pfc.affiliatePerMintFlat = uint96(_bound(_random(), 0, smc.MAX_PLATFORM_PER_MINT_FLAT_FEE));
// pfc.perTxFlat = uint96(_bound(_random(), 0, smc.MAX_PLATFORM_PER_TX_FLAT_FEE));
// pfc.perMintFlat = uint96(_bound(_random(), 0, smc.MAX_PLATFORM_PER_MINT_FLAT_FEE));
// pfc.perMintBPS = uint16(_bound(_random(), 0, smc.MAX_PLATFORM_PER_MINT_FEE_BPS));
// pfc.active = true;
// vm.prank(c.platform);
// sm.setPlatformFeeConfig(1, pfc);

// // Prepare the MintTo struct witha a random quantity.
// ISuperMinterV1_1.MintTo memory p;
// p.edition = address(edition);
// p.tier = 1;
// p.scheduleNum = 0;
// p.to = address(this);
// p.quantity = uint32(_bound(_random(), 0, type(uint32).max));

// ISuperMinterV1_1.TotalPriceAndFees memory tpaf;
// tpaf = sm.totalPriceAndFees(address(edition), 1, 0, p.quantity);
// assertEq(tpaf.affiliateFlatFee, pfc.affiliatePerMintFlat * p.quantity);
// assertEq(tpaf.affiliateFee, tpaf.affiliateFlatFee + tpaf.affiliateBPSFee);

// // Use a lower, non-zero quantity for mint testing.
// p.quantity = uint32(_bound(_random(), 1, 8));
// tpaf = sm.totalPriceAndFees(address(edition), 1, 0, p.quantity);
// assertEq(tpaf.affiliateFlatFee, pfc.affiliatePerMintFlat * p.quantity);
// assertEq(tpaf.affiliateFee, tpaf.affiliateFlatFee + tpaf.affiliateBPSFee);

// // Just to ensure we have enough ETH to mint.
// vm.deal(address(this), type(uint192).max);

// // Test the affiliated path.
// if (_random() % 2 == 0) {
// p.affiliate = _randomNonZeroAddress();

// vm.expectEmit(true, true, true, true);
// ISuperMinterV1_1.MintedLogData memory l;
// l.quantity = p.quantity;
// l.fromTokenId = 1;
// l.affiliate = p.affiliate;
// l.affiliated = true;
// l.requiredEtherValue = tpaf.total;
// l.unitPrice = tpaf.unitPrice;
// l.platformFee = tpaf.platformFee;
// l.platformFlatFee = tpaf.platformFlatFee;
// l.affiliateFee = tpaf.affiliateFee;
// l.affiliateFlatFee = tpaf.affiliateFlatFee;
// emit Minted(address(edition), 1, 0, address(this), l, 0);

// sm.mintTo{ value: tpaf.total }(p);
// assertEq(sm.platformFeesAccrued(c.platform), tpaf.platformFee);
// assertEq(sm.affiliateFeesAccrued(p.affiliate), tpaf.affiliateFee);
// assertEq(address(sm).balance, tpaf.affiliateFee + tpaf.platformFee);
// assertEq(address(edition).balance, (tpaf.total - tpaf.platformFee - tpaf.affiliateFee));

// // Perform the withdrawals and check if the balances tally.
// vm.prank(c.platform);
// sm.setPlatformFeeAddress(feeRecipients[0]);
// assertEq(sm.platformFeeAddress(c.platform), feeRecipients[0]);

// uint256 balanceBefore = address(p.affiliate).balance;
// sm.withdrawForAffiliate(p.affiliate);
// assertEq(address(p.affiliate).balance, balanceBefore + tpaf.affiliateFee);
// assertEq(address(sm).balance, tpaf.platformFee);

// balanceBefore = address(feeRecipients[0]).balance;
// sm.withdrawForPlatform(c.platform);
// assertEq(address(feeRecipients[0]).balance, balanceBefore + tpaf.platformFee);
// assertEq(sm.platformFeeAddress(c.platform), feeRecipients[0]);
// assertEq(address(sm).balance, 0);
// } else {
// p.affiliate = address(0);

// vm.expectEmit(true, true, true, true);
// ISuperMinterV1_1.MintedLogData memory l;
// l.quantity = p.quantity;
// l.fromTokenId = 1;
// l.affiliate = address(0);
// l.affiliated = false;
// l.requiredEtherValue = tpaf.total;
// l.unitPrice = tpaf.unitPrice;
// l.platformFee = tpaf.platformFee + tpaf.affiliateFlatFee;
// l.platformFlatFee = tpaf.platformFlatFee + tpaf.affiliateFlatFee;
// l.affiliateFee = 0;
// l.affiliateFlatFee = 0;
// emit Minted(address(edition), 1, 0, address(this), l, 0);
// sm.mintTo{ value: tpaf.total }(p);

// assertEq(sm.platformFeesAccrued(c.platform), tpaf.affiliateFlatFee + tpaf.platformFee);
// assertEq(address(sm).balance, tpaf.affiliateFlatFee + tpaf.platformFee);
// assertEq(address(edition).balance, (tpaf.total - tpaf.platformFee - tpaf.affiliateFlatFee));

// // Perform the withdrawals and check if the balances tally.
// vm.prank(c.platform);
// sm.setPlatformFeeAddress(feeRecipients[0]);
// assertEq(sm.platformFeeAddress(c.platform), feeRecipients[0]);

// uint256 balanceBefore = address(feeRecipients[0]).balance;
// sm.withdrawForPlatform(c.platform);
// assertEq(address(feeRecipients[0]).balance, balanceBefore + tpaf.affiliateFlatFee + tpaf.platformFee);
// assertEq(sm.platformFeeAddress(c.platform), feeRecipients[0]);
// assertEq(address(sm).balance, 0);
// }
// }
function testMintWithAffiliateIncentive(uint256) public {
SuperMinterV1_1Constants memory smc = _superMinterConstants();
address[] memory feeRecipients = _twoRandomUniqueAddresses();

// Create a tier 1 mint schedule, without any affiliate root.
ISuperMinterV1_1.MintCreation memory c;
c.maxMintable = type(uint32).max;
c.platform = _randomNonZeroAddress();
c.edition = address(edition);
c.tier = 1;
c.price = uint96(_bound(_random(), 0, type(uint96).max));
c.affiliateFeeBPS = uint16(_bound(_random(), 0, smc.MAX_AFFILIATE_FEE_BPS));
c.startTime = 0;
c.endTime = uint32(block.timestamp + 1000);
c.maxMintablePerAccount = type(uint32).max;
assertEq(sm.createEditionMint(c), 0);

// Set the tier 1 platform fee config.
ISuperMinterV1_1.PlatformFeeConfig memory pfc;

pfc.perTxFlat = uint96(_bound(_random(), 0, smc.MAX_PLATFORM_PER_TX_FLAT_FEE));
pfc.perMintFlat = uint96(_bound(_random(), 0, smc.MAX_PLATFORM_PER_MINT_FLAT_FEE));
pfc.perMintBPS = uint16(_bound(_random(), 0, smc.MAX_PLATFORM_PER_MINT_FEE_BPS));
pfc.affiliateIncentive = uint96(_bound(_random(), 0, pfc.perMintFlat));
pfc.active = true;
vm.prank(c.platform);
sm.setPlatformFeeConfig(1, pfc);

// Prepare the MintTo struct witha a random quantity.
ISuperMinterV1_1.MintTo memory p;
p.edition = address(edition);
p.tier = 1;
p.scheduleNum = 0;
p.to = address(this);
p.quantity = uint32(_bound(_random(), 0, type(uint32).max));

ISuperMinterV1_1.TotalPriceAndFees memory tpaf;
tpaf = sm.totalPriceAndFees(address(edition), 1, 0, p.quantity);
assertEq(tpaf.affiliateIncentive, pfc.affiliateIncentive * uint256(p.quantity));

// Use a lower, non-zero quantity for mint testing.
p.quantity = uint32(_bound(_random(), 1, 8));
tpaf = sm.totalPriceAndFees(address(edition), 1, 0, p.quantity);
assertEq(tpaf.affiliateIncentive, pfc.affiliateIncentive * uint256(p.quantity));

// Just to ensure we have enough ETH to mint.
vm.deal(address(this), type(uint192).max);

// Test the affiliated path.
if (_random() % 2 == 0) {
p.affiliate = _randomNonZeroAddress();

vm.expectEmit(true, true, true, true);
ISuperMinterV1_1.MintedLogData memory l;
l.quantity = p.quantity;
l.fromTokenId = 1;
l.affiliate = p.affiliate;
l.affiliated = true;
l.requiredEtherValue = tpaf.total;
l.unitPrice = tpaf.unitPrice;
l.finalArtistFee = tpaf.total - tpaf.platformFee - tpaf.affiliateFee;
l.finalPlatformFee = tpaf.platformFee - tpaf.affiliateIncentive;
l.finalAffiliateFee = tpaf.affiliateFee + tpaf.affiliateIncentive;
l.finalFreeMintFee = 0;
l.finalFirstCollectorFee = 0;
emit Minted(address(edition), 1, 0, address(this), l, 0);

sm.mintTo{ value: tpaf.total }(p);
assertEq(sm.platformFeesAccrued(c.platform), l.finalPlatformFee);
assertEq(sm.affiliateFeesAccrued(p.affiliate), l.finalAffiliateFee);
assertEq(address(sm).balance, l.finalPlatformFee + l.finalAffiliateFee);
assertEq(address(edition).balance, l.finalArtistFee);

// Perform the withdrawals and check if the balances tally.
vm.prank(c.platform);
sm.setPlatformFeeAddress(feeRecipients[0]);
assertEq(sm.platformFeeAddress(c.platform), feeRecipients[0]);

uint256 balanceBefore = address(p.affiliate).balance;
sm.withdrawForAffiliate(p.affiliate);
assertEq(address(p.affiliate).balance, balanceBefore + l.finalAffiliateFee);
assertEq(address(sm).balance, l.finalPlatformFee);

balanceBefore = address(feeRecipients[0]).balance;
sm.withdrawForPlatform(c.platform);
assertEq(address(feeRecipients[0]).balance, balanceBefore + l.finalPlatformFee);
assertEq(sm.platformFeeAddress(c.platform), feeRecipients[0]);
assertEq(address(sm).balance, 0);
} else {
p.affiliate = address(0);

vm.expectEmit(true, true, true, true);
ISuperMinterV1_1.MintedLogData memory l;
l.quantity = p.quantity;
l.fromTokenId = 1;
l.affiliate = address(0);
l.affiliated = false;
l.requiredEtherValue = tpaf.total;
l.unitPrice = tpaf.unitPrice;
l.finalArtistFee = tpaf.total - tpaf.platformFee;
l.finalPlatformFee = tpaf.platformFee;
l.finalAffiliateFee = 0;
l.finalFreeMintFee = 0;
l.finalFirstCollectorFee = 0;
emit Minted(address(edition), 1, 0, address(this), l, 0);
sm.mintTo{ value: tpaf.total }(p);

assertEq(sm.platformFeesAccrued(c.platform), l.finalPlatformFee);
assertEq(address(sm).balance, l.finalPlatformFee);
assertEq(address(edition).balance, l.finalArtistFee);

// Perform the withdrawals and check if the balances tally.
vm.prank(c.platform);
sm.setPlatformFeeAddress(feeRecipients[0]);
assertEq(sm.platformFeeAddress(c.platform), feeRecipients[0]);

uint256 balanceBefore = address(feeRecipients[0]).balance;
sm.withdrawForPlatform(c.platform);
assertEq(address(feeRecipients[0]).balance, balanceBefore + l.finalPlatformFee);
assertEq(sm.platformFeeAddress(c.platform), feeRecipients[0]);
assertEq(address(sm).balance, 0);
}
}

function _checkTotalPriceAndFees(
ISuperMinterV1_1.TotalPriceAndFees memory tpaf,
Expand Down

0 comments on commit 2e1143a

Please sign in to comment.