-
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.
* test initialize * test mintTo * test setContractURI * test setPlatformFeeInfo * test setPrimarySaleRecipient * test verify * test mintWithSignature * test other functions
- Loading branch information
1 parent
e06a324
commit 1ad2caa
Showing
16 changed files
with
1,435 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,233 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import "../../utils/BaseTest.sol"; | ||
|
||
import { TWProxy } from "contracts/infra/TWProxy.sol"; | ||
|
||
contract MyTokenERC20 is TokenERC20 { | ||
function eip712NameHash() external view returns (bytes32) { | ||
return _EIP712NameHash(); | ||
} | ||
|
||
function eip712VersionHash() external view returns (bytes32) { | ||
return _EIP712VersionHash(); | ||
} | ||
} | ||
|
||
contract TokenERC20Test_Initialize is BaseTest { | ||
address public implementation; | ||
address public proxy; | ||
|
||
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); | ||
|
||
function setUp() public override { | ||
super.setUp(); | ||
|
||
// Deploy implementation. | ||
implementation = address(new MyTokenERC20()); | ||
|
||
// Deploy proxy pointing to implementaion. | ||
vm.prank(deployer); | ||
proxy = address( | ||
new TWProxy( | ||
implementation, | ||
abi.encodeCall( | ||
TokenERC20.initialize, | ||
( | ||
deployer, | ||
NAME, | ||
SYMBOL, | ||
CONTRACT_URI, | ||
forwarders(), | ||
saleRecipient, | ||
platformFeeRecipient, | ||
platformFeeBps | ||
) | ||
) | ||
) | ||
); | ||
} | ||
|
||
function test_initialize_initializingImplementation() public { | ||
vm.expectRevert("Initializable: contract is already initialized"); | ||
TokenERC20(implementation).initialize( | ||
deployer, | ||
NAME, | ||
SYMBOL, | ||
CONTRACT_URI, | ||
forwarders(), | ||
saleRecipient, | ||
platformFeeRecipient, | ||
platformFeeBps | ||
); | ||
} | ||
|
||
modifier whenNotImplementation() { | ||
_; | ||
} | ||
|
||
function test_initialize_proxyAlreadyInitialized() public whenNotImplementation { | ||
vm.expectRevert("Initializable: contract is already initialized"); | ||
MyTokenERC20(proxy).initialize( | ||
deployer, | ||
NAME, | ||
SYMBOL, | ||
CONTRACT_URI, | ||
forwarders(), | ||
saleRecipient, | ||
platformFeeRecipient, | ||
platformFeeBps | ||
); | ||
} | ||
|
||
modifier whenProxyNotInitialized() { | ||
proxy = address(new TWProxy(implementation, "")); | ||
_; | ||
} | ||
|
||
function test_initialize_exceedsMaxBps() public whenNotImplementation whenProxyNotInitialized { | ||
vm.expectRevert("exceeds MAX_BPS"); | ||
MyTokenERC20(proxy).initialize( | ||
deployer, | ||
NAME, | ||
SYMBOL, | ||
CONTRACT_URI, | ||
forwarders(), | ||
saleRecipient, | ||
platformFeeRecipient, | ||
uint128(MAX_BPS) + 1 // platformFeeBps greater than MAX_BPS | ||
); | ||
} | ||
|
||
modifier whenPlatformFeeBpsWithinMaxBps() { | ||
_; | ||
} | ||
|
||
function test_initialize() public whenNotImplementation whenProxyNotInitialized whenPlatformFeeBpsWithinMaxBps { | ||
MyTokenERC20(proxy).initialize( | ||
deployer, | ||
NAME, | ||
SYMBOL, | ||
CONTRACT_URI, | ||
forwarders(), | ||
saleRecipient, | ||
platformFeeRecipient, | ||
platformFeeBps | ||
); | ||
|
||
// check state | ||
MyTokenERC20 tokenContract = MyTokenERC20(proxy); | ||
|
||
assertEq(tokenContract.eip712NameHash(), keccak256(bytes(NAME))); | ||
assertEq(tokenContract.eip712VersionHash(), keccak256(bytes("1"))); | ||
|
||
address[] memory _trustedForwarders = forwarders(); | ||
for (uint256 i = 0; i < _trustedForwarders.length; i++) { | ||
assertTrue(tokenContract.isTrustedForwarder(_trustedForwarders[i])); | ||
} | ||
|
||
assertEq(tokenContract.name(), NAME); | ||
assertEq(tokenContract.symbol(), SYMBOL); | ||
assertEq(tokenContract.contractURI(), CONTRACT_URI); | ||
|
||
(address _platformFeeRecipient, uint16 _platformFeeBps) = tokenContract.getPlatformFeeInfo(); | ||
assertEq(_platformFeeBps, platformFeeBps); | ||
assertEq(_platformFeeRecipient, platformFeeRecipient); | ||
|
||
assertEq(tokenContract.primarySaleRecipient(), saleRecipient); | ||
|
||
assertTrue(tokenContract.hasRole(bytes32(0x00), deployer)); | ||
assertTrue(tokenContract.hasRole(keccak256("TRANSFER_ROLE"), deployer)); | ||
assertTrue(tokenContract.hasRole(keccak256("TRANSFER_ROLE"), address(0))); | ||
assertTrue(tokenContract.hasRole(keccak256("MINTER_ROLE"), deployer)); | ||
} | ||
|
||
function test_initialize_event_RoleGranted_DefaultAdmin() | ||
public | ||
whenNotImplementation | ||
whenProxyNotInitialized | ||
whenPlatformFeeBpsWithinMaxBps | ||
{ | ||
bytes32 _defaultAdminRole = bytes32(0x00); | ||
vm.prank(deployer); | ||
vm.expectEmit(true, true, true, false); | ||
emit RoleGranted(_defaultAdminRole, deployer, deployer); | ||
MyTokenERC20(proxy).initialize( | ||
deployer, | ||
NAME, | ||
SYMBOL, | ||
CONTRACT_URI, | ||
forwarders(), | ||
saleRecipient, | ||
platformFeeRecipient, | ||
platformFeeBps | ||
); | ||
} | ||
|
||
function test_initialize_event_RoleGranted_MinterRole() | ||
public | ||
whenNotImplementation | ||
whenProxyNotInitialized | ||
whenPlatformFeeBpsWithinMaxBps | ||
{ | ||
bytes32 _minterRole = keccak256("MINTER_ROLE"); | ||
vm.prank(deployer); | ||
vm.expectEmit(true, true, true, false); | ||
emit RoleGranted(_minterRole, deployer, deployer); | ||
MyTokenERC20(proxy).initialize( | ||
deployer, | ||
NAME, | ||
SYMBOL, | ||
CONTRACT_URI, | ||
forwarders(), | ||
saleRecipient, | ||
platformFeeRecipient, | ||
platformFeeBps | ||
); | ||
} | ||
|
||
function test_initialize_event_RoleGranted_TransferRole() | ||
public | ||
whenNotImplementation | ||
whenProxyNotInitialized | ||
whenPlatformFeeBpsWithinMaxBps | ||
{ | ||
bytes32 _transferRole = keccak256("TRANSFER_ROLE"); | ||
vm.prank(deployer); | ||
vm.expectEmit(true, true, true, false); | ||
emit RoleGranted(_transferRole, deployer, deployer); | ||
MyTokenERC20(proxy).initialize( | ||
deployer, | ||
NAME, | ||
SYMBOL, | ||
CONTRACT_URI, | ||
forwarders(), | ||
saleRecipient, | ||
platformFeeRecipient, | ||
platformFeeBps | ||
); | ||
} | ||
|
||
function test_initialize_event_RoleGranted_TransferRole_AddressZero() | ||
public | ||
whenNotImplementation | ||
whenProxyNotInitialized | ||
whenPlatformFeeBpsWithinMaxBps | ||
{ | ||
bytes32 _transferRole = keccak256("TRANSFER_ROLE"); | ||
vm.prank(deployer); | ||
vm.expectEmit(true, true, true, false); | ||
emit RoleGranted(_transferRole, address(0), deployer); | ||
MyTokenERC20(proxy).initialize( | ||
deployer, | ||
NAME, | ||
SYMBOL, | ||
CONTRACT_URI, | ||
forwarders(), | ||
saleRecipient, | ||
platformFeeRecipient, | ||
platformFeeBps | ||
); | ||
} | ||
} |
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,34 @@ | ||
initialize( | ||
address _defaultAdmin, | ||
string memory _name, | ||
string memory _symbol, | ||
string memory _contractURI, | ||
address[] memory _trustedForwarders, | ||
address _primarySaleRecipient, | ||
address _platformFeeRecipient | ||
uint256 _platformFeeBps, | ||
) | ||
├── when initializing the implementation contract (not proxy) | ||
│ └── it should revert ✅ | ||
└── when it is a proxy to the implementation | ||
└── when it is already initialized | ||
│ └── it should revert ✅ | ||
└── when it is not initialized | ||
└── when platformFeeBps is greater than MAX_BPS | ||
│ └── it should revert ✅ | ||
└── when platformFeeBps is less than or equal to MAX_BPS | ||
└── it should correctly set EIP712 name hash and version hash ✅ | ||
└── it should set trustedForwarder mapping to true for all addresses in `_trustedForwarders` ✅ | ||
└── it should set _name and _symbol to `_name` and `_symbol` param values respectively ✅ | ||
└── it should set contractURI to `_contractURI` param value ✅ | ||
└── it should set platformFeeRecipient and platformFeeBps as `_platformFeeRecipient` and `_platformFeeBps` respectively ✅ | ||
└── it should set primary sale recipient as `_saleRecipient` param value ✅ | ||
└── it should grant 0x00 (DEFAULT_ADMIN_ROLE) to `_defaultAdmin` address ✅ | ||
└── it should emit RoleGranted event ✅ | ||
└── it should grant MINTER_ROLE to `_defaultAdmin` address ✅ | ||
└── it should emit RoleGranted event ✅ | ||
└── it should grant TRANSFER_ROLE to `_defaultAdmin` address ✅ | ||
└── it should emit RoleGranted event ✅ | ||
└── it should grant TRANSFER_ROLE to address(0) ✅ | ||
└── it should emit RoleGranted event ✅ | ||
|
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,81 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import "../../utils/BaseTest.sol"; | ||
|
||
import { TWProxy } from "contracts/infra/TWProxy.sol"; | ||
|
||
contract MyTokenERC20 is TokenERC20 {} | ||
|
||
contract TokenERC20Test_MintTo is BaseTest { | ||
address public implementation; | ||
address public proxy; | ||
address public caller; | ||
address public recipient; | ||
uint256 public amount; | ||
|
||
MyTokenERC20 internal tokenContract; | ||
|
||
event TokensMinted(address indexed mintedTo, uint256 quantityMinted); | ||
|
||
function setUp() public override { | ||
super.setUp(); | ||
|
||
// Deploy implementation. | ||
implementation = address(new MyTokenERC20()); | ||
caller = getActor(1); | ||
recipient = getActor(2); | ||
|
||
// Deploy proxy pointing to implementaion. | ||
vm.prank(deployer); | ||
proxy = address( | ||
new TWProxy( | ||
implementation, | ||
abi.encodeCall( | ||
TokenERC20.initialize, | ||
( | ||
deployer, | ||
NAME, | ||
SYMBOL, | ||
CONTRACT_URI, | ||
forwarders(), | ||
saleRecipient, | ||
platformFeeRecipient, | ||
platformFeeBps | ||
) | ||
) | ||
) | ||
); | ||
|
||
tokenContract = MyTokenERC20(proxy); | ||
amount = 100; | ||
} | ||
|
||
function test_mintTo_notMinterRole() public { | ||
vm.prank(caller); | ||
vm.expectRevert("not minter."); | ||
tokenContract.mintTo(recipient, amount); | ||
} | ||
|
||
modifier whenMinterRole() { | ||
vm.prank(deployer); | ||
tokenContract.grantRole(keccak256("MINTER_ROLE"), caller); | ||
_; | ||
} | ||
|
||
function test_mintTo() public whenMinterRole { | ||
// mint | ||
vm.prank(caller); | ||
tokenContract.mintTo(recipient, amount); | ||
|
||
// check state after | ||
assertEq(tokenContract.balanceOf(recipient), amount); | ||
} | ||
|
||
function test_mintTo_TokensMintedEvent() public whenMinterRole { | ||
vm.prank(caller); | ||
vm.expectEmit(true, false, false, true); | ||
emit TokensMinted(recipient, amount); | ||
tokenContract.mintTo(recipient, amount); | ||
} | ||
} |
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,7 @@ | ||
mintTo(address to, uint256 amount) | ||
├── when caller doesn't have MINTER_ROLE | ||
│ └── it should revert ✅ | ||
└── when caller has MINTER_ROLE | ||
└── it should mint `amount` to `to` ✅ | ||
└── it should emit TokensMinted event ✅ | ||
|
Oops, something went wrong.