-
Notifications
You must be signed in to change notification settings - Fork 522
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* create file structure * tree: initialize * tree: _beforeClaim * tree: _collectPriceOnClaim * tree: setMaxTotalSupply * clean * tree: _beforeClaim * test: initialize * test: _beforeClaim * test: collectPriceOnClaim * test: canSetFunctions * test: misc * test: setMaxTotalSupply * test: misc * test: misc * clean/lint * remove initialize harness and use TWProxy * clean/lint tests --------- Co-authored-by: Yash <72552910+kumaryash90@users.noreply.github.com> Co-authored-by: Joaquim Verges <joaquim.verges@gmail.com>
- Loading branch information
1 parent
a64ca6b
commit 9e5d693
Showing
12 changed files
with
906 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import { DropERC20 } from "contracts/prebuilts/drop/DropERC20.sol"; | ||
import { TWProxy } from "contracts/infra/TWProxy.sol"; | ||
|
||
// Test imports | ||
import "../../../utils/BaseTest.sol"; | ||
|
||
contract HarnessDropERC20BeforeClaim is DropERC20 { | ||
bytes private emptyBytes = bytes(""); | ||
|
||
function harness_beforeClaim(uint256 quantity, AllowlistProof calldata _proof) public view { | ||
_beforeClaim(address(0), quantity, address(0), 0, _proof, emptyBytes); | ||
} | ||
} | ||
|
||
contract DropERC20Test_beforeClaim is BaseTest { | ||
address public dropImp; | ||
HarnessDropERC20BeforeClaim public proxy; | ||
|
||
uint256 private mintQty; | ||
|
||
function setUp() public override { | ||
super.setUp(); | ||
|
||
bytes memory initializeData = abi.encodeCall( | ||
DropERC20.initialize, | ||
(deployer, NAME, SYMBOL, CONTRACT_URI, forwarders(), saleRecipient, platformFeeRecipient, platformFeeBps) | ||
); | ||
|
||
dropImp = address(new HarnessDropERC20BeforeClaim()); | ||
proxy = HarnessDropERC20BeforeClaim(address(new TWProxy(dropImp, initializeData))); | ||
} | ||
|
||
modifier setMaxTotalSupply() { | ||
vm.prank(deployer); | ||
proxy.setMaxTotalSupply(100); | ||
_; | ||
} | ||
|
||
modifier qtyExceedMaxTotalSupply() { | ||
mintQty = 101; | ||
_; | ||
} | ||
|
||
function test_revert_MaxSupplyExceeded() public setMaxTotalSupply qtyExceedMaxTotalSupply { | ||
DropERC20.AllowlistProof memory proof; | ||
vm.expectRevert("exceed max total supply."); | ||
proxy.harness_beforeClaim(mintQty, proof); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
function _beforeClaim( | ||
address, | ||
uint256 _quantity, | ||
address, | ||
uint256, | ||
AllowlistProof calldata, | ||
bytes memory | ||
) | ||
└── when maxTotalSupply does not equal to 0 and totalSupply() + _quantity is greater than _maxTotalSupply | ||
└── it should revert ✅ |
93 changes: 93 additions & 0 deletions
93
src/test/drop/drop-erc20/_canSetFunctions/_canSetFunctions.t.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import { DropERC20 } from "contracts/prebuilts/drop/DropERC20.sol"; | ||
import { TWProxy } from "contracts/infra/TWProxy.sol"; | ||
|
||
// Test imports | ||
import "../../../utils/BaseTest.sol"; | ||
|
||
contract HarnessDropERC20CanSet is DropERC20 { | ||
function canSetPlatformFeeInfo() external view returns (bool) { | ||
return _canSetPlatformFeeInfo(); | ||
} | ||
|
||
function canSetPrimarySaleRecipient() external view returns (bool) { | ||
return _canSetPrimarySaleRecipient(); | ||
} | ||
|
||
function canSetContractURI() external view returns (bool) { | ||
return _canSetContractURI(); | ||
} | ||
|
||
function canSetClaimConditions() external view returns (bool) { | ||
return _canSetClaimConditions(); | ||
} | ||
} | ||
|
||
contract DropERC20Test_canSet is BaseTest { | ||
address public dropImp; | ||
|
||
HarnessDropERC20CanSet public proxy; | ||
|
||
function setUp() public override { | ||
super.setUp(); | ||
|
||
bytes memory initializeData = abi.encodeCall( | ||
DropERC20.initialize, | ||
(deployer, NAME, SYMBOL, CONTRACT_URI, forwarders(), saleRecipient, platformFeeRecipient, platformFeeBps) | ||
); | ||
|
||
dropImp = address(new HarnessDropERC20CanSet()); | ||
proxy = HarnessDropERC20CanSet(address(new TWProxy(dropImp, initializeData))); | ||
} | ||
|
||
modifier callerHasDefaultAdminRole() { | ||
vm.startPrank(deployer); | ||
_; | ||
} | ||
|
||
modifier callerDoesNotHaveDefaultAdminRole() { | ||
_; | ||
} | ||
|
||
function test_canSetPlatformFee_returnTrue() public callerHasDefaultAdminRole { | ||
bool status = proxy.canSetPlatformFeeInfo(); | ||
assertEq(status, true); | ||
} | ||
|
||
function test_canSetPlatformFee_returnFalse() public callerDoesNotHaveDefaultAdminRole { | ||
bool status = proxy.canSetPlatformFeeInfo(); | ||
assertEq(status, false); | ||
} | ||
|
||
function test_canSetPrimarySaleRecipient_returnTrue() public callerHasDefaultAdminRole { | ||
bool status = proxy.canSetPrimarySaleRecipient(); | ||
assertEq(status, true); | ||
} | ||
|
||
function test_canSetPrimarySaleRecipient_returnFalse() public callerDoesNotHaveDefaultAdminRole { | ||
bool status = proxy.canSetPrimarySaleRecipient(); | ||
assertEq(status, false); | ||
} | ||
|
||
function test_canSetContractURI_returnTrue() public callerHasDefaultAdminRole { | ||
bool status = proxy.canSetContractURI(); | ||
assertEq(status, true); | ||
} | ||
|
||
function test_canSetContractURI_returnFalse() public callerDoesNotHaveDefaultAdminRole { | ||
bool status = proxy.canSetContractURI(); | ||
assertEq(status, false); | ||
} | ||
|
||
function test_canSetClaimConditions_returnTrue() public callerHasDefaultAdminRole { | ||
bool status = proxy.canSetClaimConditions(); | ||
assertEq(status, true); | ||
} | ||
|
||
function test_canSetClaimConditions_returnFalse() public callerDoesNotHaveDefaultAdminRole { | ||
bool status = proxy.canSetClaimConditions(); | ||
assertEq(status, false); | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/test/drop/drop-erc20/_canSetFunctions/_canSetFunctions.tree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
function _canSetPlatformFeeInfo() | ||
├── when caller has DEFAULT_ADMIN_ROLE | ||
│ └── it should return true ✅ | ||
└── when caller does not have DEFAULT_ADMIN_ROLE | ||
└── it should return false ✅ | ||
|
||
function _canSetPrimarySaleRecipient() | ||
├── when caller has DEFAULT_ADMIN_ROLE | ||
│ └── it should return true ✅ | ||
└── when caller does not have DEFAULT_ADMIN_ROLE | ||
└── it should return false ✅ | ||
|
||
function _canSetContractURI() | ||
├── when caller has DEFAULT_ADMIN_ROLE | ||
│ └── it should return true ✅ | ||
└── when caller does not have DEFAULT_ADMIN_ROLE | ||
└── it should return false ✅ | ||
|
||
function _canSetClaimConditions() | ||
├── when caller has DEFAULT_ADMIN_ROLE | ||
│ └── it should return true ✅ | ||
└── when caller does not have DEFAULT_ADMIN_ROLE | ||
└── it should return false ✅ |
209 changes: 209 additions & 0 deletions
209
src/test/drop/drop-erc20/_collectPriceOnClaim/_collectPriceOnClaim.t.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import { DropERC20 } from "contracts/prebuilts/drop/DropERC20.sol"; | ||
import { TWProxy } from "contracts/infra/TWProxy.sol"; | ||
|
||
// Test imports | ||
import "../../../utils/BaseTest.sol"; | ||
|
||
contract HarnessDropERC20CollectPriceOnClaim is DropERC20 { | ||
function harness_collectPrice( | ||
address _primarySaleRecipient, | ||
uint256 _quantityToClaim, | ||
address _currency, | ||
uint256 _pricePerToken | ||
) public payable { | ||
_collectPriceOnClaim(_primarySaleRecipient, _quantityToClaim, _currency, _pricePerToken); | ||
} | ||
} | ||
|
||
contract DropERC20Test_collectPrice is BaseTest { | ||
address public dropImp; | ||
HarnessDropERC20CollectPriceOnClaim public proxy; | ||
|
||
address private currency; | ||
address private primarySaleRecipient; | ||
uint256 private msgValue; | ||
uint256 private pricePerToken; | ||
|
||
function setUp() public override { | ||
super.setUp(); | ||
|
||
bytes memory initializeData = abi.encodeCall( | ||
DropERC20.initialize, | ||
(deployer, NAME, SYMBOL, CONTRACT_URI, forwarders(), saleRecipient, platformFeeRecipient, platformFeeBps) | ||
); | ||
|
||
dropImp = address(new HarnessDropERC20CollectPriceOnClaim()); | ||
proxy = HarnessDropERC20CollectPriceOnClaim(address(new TWProxy(dropImp, initializeData))); | ||
} | ||
|
||
modifier pricePerTokenZero() { | ||
_; | ||
} | ||
|
||
modifier pricePerTokenNotZero() { | ||
pricePerToken = 1 ether; | ||
_; | ||
} | ||
|
||
modifier msgValueZero() { | ||
_; | ||
} | ||
|
||
modifier msgValueNotZero() { | ||
msgValue = 1 ether; | ||
_; | ||
} | ||
|
||
modifier valuePriceMismatch() { | ||
msgValue = 1 ether; | ||
pricePerToken = 2 ether; | ||
_; | ||
} | ||
|
||
modifier primarySaleRecipientZeroAddress() { | ||
primarySaleRecipient = address(0); | ||
_; | ||
} | ||
|
||
modifier primarySaleRecipientNotZeroAddress() { | ||
primarySaleRecipient = address(0x0999); | ||
_; | ||
} | ||
|
||
modifier currencyNativeToken() { | ||
currency = NATIVE_TOKEN; | ||
_; | ||
} | ||
|
||
modifier currencyNotNativeToken() { | ||
currency = address(erc20); | ||
_; | ||
} | ||
|
||
function test_revert_pricePerTokenZeroMsgValueNotZero() public pricePerTokenZero msgValueNotZero { | ||
vm.expectRevert("!Value"); | ||
proxy.harness_collectPrice{ value: msgValue }(primarySaleRecipient, 1 ether, currency, pricePerToken); | ||
} | ||
|
||
function test_revert_nativeCurrencyTotalPriceZero() public pricePerTokenNotZero msgValueZero currencyNativeToken { | ||
vm.expectRevert("quantity too low"); | ||
proxy.harness_collectPrice{ value: msgValue }(primarySaleRecipient, 0, currency, pricePerToken); | ||
} | ||
|
||
function test_revert_nativeCurrencyValuePriceMismatch() public currencyNativeToken valuePriceMismatch { | ||
vm.expectRevert("Invalid msg value"); | ||
proxy.harness_collectPrice{ value: msgValue }(primarySaleRecipient, 1 ether, currency, pricePerToken); | ||
} | ||
|
||
function test_revert_erc20ValuePriceMismatch() public currencyNotNativeToken valuePriceMismatch { | ||
vm.expectRevert("Invalid msg value"); | ||
proxy.harness_collectPrice{ value: msgValue }(primarySaleRecipient, 1 ether, currency, pricePerToken); | ||
} | ||
|
||
function test_state_nativeCurrency() | ||
public | ||
currencyNativeToken | ||
pricePerTokenNotZero | ||
msgValueNotZero | ||
primarySaleRecipientNotZeroAddress | ||
{ | ||
(address platformFeeRecipient, uint16 platformFeeBps) = proxy.getPlatformFeeInfo(); | ||
uint256 beforeBalancePrimarySaleRecipient = address(primarySaleRecipient).balance; | ||
uint256 beforeBalancePlatformFeeRecipient = address(platformFeeRecipient).balance; | ||
|
||
proxy.harness_collectPrice{ value: msgValue }(primarySaleRecipient, 1 ether, currency, pricePerToken); | ||
|
||
uint256 afterBalancePrimarySaleRecipient = address(primarySaleRecipient).balance; | ||
uint256 afterBalancePlatformFeeRecipient = address(platformFeeRecipient).balance; | ||
|
||
uint256 platformFeeVal = (msgValue * platformFeeBps) / MAX_BPS; | ||
uint256 primarySaleRecipientVal = msgValue - platformFeeVal; | ||
|
||
assertEq(beforeBalancePrimarySaleRecipient + primarySaleRecipientVal, afterBalancePrimarySaleRecipient); | ||
assertEq(beforeBalancePlatformFeeRecipient + platformFeeVal, afterBalancePlatformFeeRecipient); | ||
} | ||
|
||
function test_revert_erc20_msgValueNotZero() | ||
public | ||
currencyNotNativeToken | ||
msgValueNotZero | ||
primarySaleRecipientNotZeroAddress | ||
{ | ||
vm.expectRevert("!Value"); | ||
proxy.harness_collectPrice{ value: msgValue }(primarySaleRecipient, msgValue, currency, pricePerToken); | ||
} | ||
|
||
function test_state_erc20() public currencyNotNativeToken pricePerTokenNotZero primarySaleRecipientNotZeroAddress { | ||
(address platformFeeRecipient, uint16 platformFeeBps) = proxy.getPlatformFeeInfo(); | ||
|
||
erc20.mint(address(this), pricePerToken); | ||
ERC20(erc20).approve(address(proxy), pricePerToken); | ||
uint256 beforeBalancePrimarySaleRecipient = erc20.balanceOf(primarySaleRecipient); | ||
uint256 beforeBalancePlatformFeeRecipient = erc20.balanceOf(platformFeeRecipient); | ||
|
||
proxy.harness_collectPrice(primarySaleRecipient, pricePerToken, currency, pricePerToken); | ||
|
||
uint256 afterBalancePrimarySaleRecipient = erc20.balanceOf(primarySaleRecipient); | ||
uint256 afterBalancePlatformFeeRecipient = erc20.balanceOf(platformFeeRecipient); | ||
|
||
uint256 platformFeeVal = (pricePerToken * platformFeeBps) / MAX_BPS; | ||
uint256 primarySaleRecipientVal = 1 ether - platformFeeVal; | ||
|
||
assertEq(beforeBalancePrimarySaleRecipient + primarySaleRecipientVal, afterBalancePrimarySaleRecipient); | ||
assertEq(beforeBalancePlatformFeeRecipient + platformFeeVal, afterBalancePlatformFeeRecipient); | ||
} | ||
|
||
function test_state_erc20StoredPrimarySaleRecipient() | ||
public | ||
currencyNotNativeToken | ||
pricePerTokenNotZero | ||
primarySaleRecipientZeroAddress | ||
{ | ||
(address platformFeeRecipient, uint16 platformFeeBps) = proxy.getPlatformFeeInfo(); | ||
address storedPrimarySaleRecipient = proxy.primarySaleRecipient(); | ||
|
||
erc20.mint(address(this), pricePerToken); | ||
ERC20(erc20).approve(address(proxy), pricePerToken); | ||
uint256 beforeBalancePrimarySaleRecipient = erc20.balanceOf(storedPrimarySaleRecipient); | ||
uint256 beforeBalancePlatformFeeRecipient = erc20.balanceOf(platformFeeRecipient); | ||
|
||
proxy.harness_collectPrice(primarySaleRecipient, pricePerToken, currency, pricePerToken); | ||
|
||
uint256 afterBalancePrimarySaleRecipient = erc20.balanceOf(storedPrimarySaleRecipient); | ||
uint256 afterBalancePlatformFeeRecipient = erc20.balanceOf(platformFeeRecipient); | ||
|
||
uint256 platformFeeVal = (pricePerToken * platformFeeBps) / MAX_BPS; | ||
uint256 primarySaleRecipientVal = 1 ether - platformFeeVal; | ||
|
||
assertEq(beforeBalancePrimarySaleRecipient + primarySaleRecipientVal, afterBalancePrimarySaleRecipient); | ||
assertEq(beforeBalancePlatformFeeRecipient + platformFeeVal, afterBalancePlatformFeeRecipient); | ||
} | ||
|
||
function test_state_nativeCurrencyStoredPrimarySaleRecipient() | ||
public | ||
currencyNativeToken | ||
pricePerTokenNotZero | ||
primarySaleRecipientZeroAddress | ||
msgValueNotZero | ||
{ | ||
(address platformFeeRecipient, uint16 platformFeeBps) = proxy.getPlatformFeeInfo(); | ||
address storedPrimarySaleRecipient = proxy.primarySaleRecipient(); | ||
|
||
uint256 beforeBalancePrimarySaleRecipient = address(storedPrimarySaleRecipient).balance; | ||
uint256 beforeBalancePlatformFeeRecipient = address(platformFeeRecipient).balance; | ||
|
||
proxy.harness_collectPrice{ value: msgValue }(primarySaleRecipient, 1 ether, currency, pricePerToken); | ||
|
||
uint256 afterBalancePrimarySaleRecipient = address(storedPrimarySaleRecipient).balance; | ||
uint256 afterBalancePlatformFeeRecipient = address(platformFeeRecipient).balance; | ||
|
||
uint256 platformFeeVal = (msgValue * platformFeeBps) / MAX_BPS; | ||
uint256 primarySaleRecipientVal = msgValue - platformFeeVal; | ||
|
||
assertEq(beforeBalancePrimarySaleRecipient + primarySaleRecipientVal, afterBalancePrimarySaleRecipient); | ||
assertEq(beforeBalancePlatformFeeRecipient + platformFeeVal, afterBalancePlatformFeeRecipient); | ||
} | ||
} |
Oops, something went wrong.