/ test / CommunityTokenDeployer.t.sol
CommunityTokenDeployer.t.sol
  1  // SPDX-License-Identifier: UNLICENSED
  2  pragma solidity ^0.8.17;
  3  
  4  import { Test } from "forge-std/Test.sol";
  5  import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
  6  import { DeployContracts } from "../script/DeployContracts.s.sol";
  7  import { DeploymentConfig } from "../script/DeploymentConfig.s.sol";
  8  import { BaseTokenFactory } from "../contracts/factories/BaseTokenFactory.sol";
  9  import { OwnerToken } from "../contracts/tokens/OwnerToken.sol";
 10  import { MasterToken } from "../contracts/tokens/MasterToken.sol";
 11  import { CommunityOwnerTokenRegistry } from "../contracts/CommunityOwnerTokenRegistry.sol";
 12  import { CommunityTokenDeployer } from "../contracts/CommunityTokenDeployer.sol";
 13  
 14  contract CommunityTokenDeployerTest is Test {
 15      DeploymentConfig internal deploymentConfig;
 16  
 17      CommunityTokenDeployer internal tokenDeployer;
 18      CommunityOwnerTokenRegistry internal tokenRegistry;
 19  
 20      address internal deployer;
 21  
 22      address internal immutable owner = makeAddr("owner");
 23  
 24      address internal communityAddress;
 25      uint256 internal communityKey;
 26  
 27      function setUp() public virtual {
 28          DeployContracts deployment = new DeployContracts();
 29          (tokenDeployer, tokenRegistry,,, deploymentConfig) = deployment.run();
 30          deployer = deploymentConfig.deployer();
 31          (communityAddress, communityKey) = makeAddrAndKey("community");
 32      }
 33  
 34      function test_Deployment() public {
 35          assertEq(tokenDeployer.deploymentRegistry(), address(tokenRegistry));
 36          assertEq(tokenDeployer.owner(), deployer);
 37      }
 38  
 39      function _getOwnerTokenConfig() internal view returns (CommunityTokenDeployer.TokenConfig memory, bytes memory) {
 40          (
 41              string memory ownerTokenName,
 42              string memory ownerTokenSymbol,
 43              string memory ownerTokenBaseURI,
 44              bytes memory signerPublicKey
 45          ) = deploymentConfig.ownerTokenConfig();
 46  
 47          CommunityTokenDeployer.TokenConfig memory ownerTokenConfig =
 48              CommunityTokenDeployer.TokenConfig(ownerTokenName, ownerTokenSymbol, ownerTokenBaseURI);
 49          return (ownerTokenConfig, signerPublicKey);
 50      }
 51  
 52      function _getMasterTokenConfig() internal view returns (CommunityTokenDeployer.TokenConfig memory) {
 53          (string memory masterTokenName, string memory masterTokenSymbol, string memory masterTokenBaseURI,) =
 54              deploymentConfig.masterTokenConfig();
 55  
 56          CommunityTokenDeployer.TokenConfig memory masterTokenConfig =
 57              CommunityTokenDeployer.TokenConfig(masterTokenName, masterTokenSymbol, masterTokenBaseURI);
 58          return masterTokenConfig;
 59      }
 60  
 61      function _createDeploymentSignature(
 62          uint256 _signerKey,
 63          address _signer,
 64          address _deployer
 65      )
 66          internal
 67          view
 68          returns (CommunityTokenDeployer.DeploymentSignature memory)
 69      {
 70          bytes32 digest = ECDSA.toTypedDataHash(
 71              tokenDeployer.DOMAIN_SEPARATOR(),
 72              keccak256(abi.encode(tokenDeployer.DEPLOYMENT_SIGNATURE_TYPEHASH(), _signer, _deployer))
 73          );
 74          (uint8 v, bytes32 r, bytes32 s) = vm.sign(_signerKey, digest);
 75          return CommunityTokenDeployer.DeploymentSignature(_signer, _deployer, v, r, s);
 76      }
 77  }
 78  
 79  contract SetDeploymentRegistryAddressTest is CommunityTokenDeployerTest {
 80      event DeploymentRegistryAddressChange(address indexed);
 81  
 82      function setUp() public virtual override {
 83          CommunityTokenDeployerTest.setUp();
 84      }
 85  
 86      function test_RevertWhen_SenderIsNotOwner() public {
 87          vm.expectRevert(bytes("Ownable: caller is not the owner"));
 88          tokenDeployer.setDeploymentRegistryAddress(makeAddr("someAddress"));
 89      }
 90  
 91      function test_RevertWhen_InvalidDeploymentRegistryAddress() public {
 92          vm.prank(deployer);
 93          vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidDeploymentRegistryAddress.selector);
 94          tokenDeployer.setDeploymentRegistryAddress(address(0));
 95      }
 96  
 97      function test_SetDeploymentRegistryAddress() public {
 98          address newAddress = makeAddr("newAddress");
 99          vm.prank(deployer);
100          vm.expectEmit(true, true, true, true);
101          emit DeploymentRegistryAddressChange(newAddress);
102          tokenDeployer.setDeploymentRegistryAddress(newAddress);
103  
104          assertEq(tokenDeployer.deploymentRegistry(), newAddress);
105      }
106  }
107  
108  contract SetOwnerTokenFactoryAddressTest is CommunityTokenDeployerTest {
109      event OwnerTokenFactoryAddressChange(address indexed);
110  
111      function setUp() public virtual override {
112          CommunityTokenDeployerTest.setUp();
113      }
114  
115      function test_RevertWhen_SenderIsNotOwner() public {
116          vm.expectRevert(bytes("Ownable: caller is not the owner"));
117          tokenDeployer.setOwnerTokenFactoryAddress(makeAddr("someAddress"));
118      }
119  
120      function test_RevertWhen_InvalidTokenFactoryAddress() public {
121          vm.prank(deployer);
122          vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidTokenFactoryAddress.selector);
123          tokenDeployer.setOwnerTokenFactoryAddress(address(0));
124      }
125  
126      function test_SetOwnerTokenFactoryAddress() public {
127          address newAddress = makeAddr("newAddress");
128          vm.prank(deployer);
129          vm.expectEmit(true, true, true, true);
130          emit OwnerTokenFactoryAddressChange(newAddress);
131          tokenDeployer.setOwnerTokenFactoryAddress(newAddress);
132  
133          assertEq(tokenDeployer.ownerTokenFactory(), newAddress);
134      }
135  }
136  
137  contract SetMasterTokenFactoryAddressTest is CommunityTokenDeployerTest {
138      event MasterTokenFactoryAddressChange(address indexed);
139  
140      function setUp() public virtual override {
141          CommunityTokenDeployerTest.setUp();
142      }
143  
144      function test_RevertWhen_SenderIsNotOwner() public {
145          vm.expectRevert(bytes("Ownable: caller is not the owner"));
146          tokenDeployer.setMasterTokenFactoryAddress(makeAddr("someAddress"));
147      }
148  
149      function test_RevertWhen_InvalidTokenFactoryAddress() public {
150          vm.prank(deployer);
151          vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidTokenFactoryAddress.selector);
152          tokenDeployer.setMasterTokenFactoryAddress(address(0));
153      }
154  
155      function test_SetOwnerTokenFactoryAddress() public {
156          address newAddress = makeAddr("newAddress");
157          vm.prank(deployer);
158          vm.expectEmit(true, true, true, true);
159          emit MasterTokenFactoryAddressChange(newAddress);
160          tokenDeployer.setMasterTokenFactoryAddress(newAddress);
161  
162          assertEq(tokenDeployer.masterTokenFactory(), newAddress);
163      }
164  }
165  
166  contract DeployTest is CommunityTokenDeployerTest {
167      function setUp() public virtual override {
168          CommunityTokenDeployerTest.setUp();
169      }
170  
171      function test_RevertWhen_InvalidDeployerAddress() public {
172          (CommunityTokenDeployer.TokenConfig memory ownerTokenConfig, bytes memory signerPublicKey) =
173              _getOwnerTokenConfig();
174          CommunityTokenDeployer.TokenConfig memory masterTokenConfig = _getMasterTokenConfig();
175          CommunityTokenDeployer.DeploymentSignature memory signature =
176              _createDeploymentSignature(communityKey, communityAddress, makeAddr("someone else"));
177          vm.prank(owner);
178          vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidDeployerAddress.selector);
179          tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
180      }
181  
182      function test_RevertWhen_InvalidDeploymentSignature() public {
183          (CommunityTokenDeployer.TokenConfig memory ownerTokenConfig, bytes memory signerPublicKey) =
184              _getOwnerTokenConfig();
185          CommunityTokenDeployer.TokenConfig memory masterTokenConfig = _getMasterTokenConfig();
186          CommunityTokenDeployer.DeploymentSignature memory signature =
187              _createDeploymentSignature(communityKey, makeAddr("invalid address"), owner);
188          vm.prank(owner);
189          vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidDeploymentSignature.selector);
190          tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
191      }
192  
193      function test_RevertWhen_InvalidTokenMetadata() public {
194          (, bytes memory signerPublicKey) = _getOwnerTokenConfig();
195          CommunityTokenDeployer.TokenConfig memory ownerTokenConfig = CommunityTokenDeployer.TokenConfig("", "", "");
196          CommunityTokenDeployer.TokenConfig memory masterTokenConfig = CommunityTokenDeployer.TokenConfig("", "", "");
197          CommunityTokenDeployer.DeploymentSignature memory signature =
198              _createDeploymentSignature(communityKey, communityAddress, owner);
199  
200          vm.prank(owner);
201          vm.expectRevert(BaseTokenFactory.BaseTokenFactory_InvalidTokenMetadata.selector);
202          tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
203  
204          // fill `masterTokenConfig` with data
205          masterTokenConfig = _getMasterTokenConfig();
206  
207          vm.prank(owner);
208          vm.expectRevert(BaseTokenFactory.BaseTokenFactory_InvalidTokenMetadata.selector);
209          tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
210  
211          // fill `ownerTokenConfig` with data and reset `masterTokenConfig`
212          (ownerTokenConfig,) = _getOwnerTokenConfig();
213          masterTokenConfig = CommunityTokenDeployer.TokenConfig("", "", "");
214  
215          vm.prank(owner);
216          vm.expectRevert(BaseTokenFactory.BaseTokenFactory_InvalidTokenMetadata.selector);
217          tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
218      }
219  
220      function test_RevertWhen_InvalidSignerPublicKey() public {
221          (CommunityTokenDeployer.TokenConfig memory ownerTokenConfig,) = _getOwnerTokenConfig();
222          CommunityTokenDeployer.TokenConfig memory masterTokenConfig = _getMasterTokenConfig();
223          CommunityTokenDeployer.DeploymentSignature memory signature =
224              _createDeploymentSignature(communityKey, communityAddress, owner);
225  
226          vm.prank(owner);
227          vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidSignerKeyOrCommunityAddress.selector);
228          tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, bytes(""));
229      }
230  
231      function test_RevertWhen_InvalidCommunityAddress() public {
232          (CommunityTokenDeployer.TokenConfig memory ownerTokenConfig, bytes memory signerPublicKey) =
233              _getOwnerTokenConfig();
234          CommunityTokenDeployer.TokenConfig memory masterTokenConfig = _getMasterTokenConfig();
235          CommunityTokenDeployer.DeploymentSignature memory signature =
236              _createDeploymentSignature(communityKey, address(0), owner);
237  
238          vm.prank(owner);
239          vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidSignerKeyOrCommunityAddress.selector);
240          tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
241      }
242  
243      function test_RevertWhen_AlreadyDeployed() public {
244          (CommunityTokenDeployer.TokenConfig memory ownerTokenConfig, bytes memory signerPublicKey) =
245              _getOwnerTokenConfig();
246          CommunityTokenDeployer.TokenConfig memory masterTokenConfig = _getMasterTokenConfig();
247          CommunityTokenDeployer.DeploymentSignature memory signature =
248              _createDeploymentSignature(communityKey, communityAddress, owner);
249  
250          vm.startPrank(owner);
251          tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
252  
253          vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_AlreadyDeployed.selector);
254          tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
255      }
256  
257      function test_Deploy() public {
258          (CommunityTokenDeployer.TokenConfig memory ownerTokenConfig, bytes memory signerPublicKey) =
259              _getOwnerTokenConfig();
260          CommunityTokenDeployer.TokenConfig memory masterTokenConfig = _getMasterTokenConfig();
261          CommunityTokenDeployer.DeploymentSignature memory signature =
262              _createDeploymentSignature(communityKey, communityAddress, owner);
263  
264          vm.prank(owner);
265          (address ownerTokenAddress, address masterTokenAddress) =
266              tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
267  
268          assertEq(ownerTokenAddress, tokenRegistry.getEntry(communityAddress));
269          assertEq(OwnerToken(ownerTokenAddress).balanceOf(owner), 1);
270  
271          MasterToken masterToken = MasterToken(masterTokenAddress);
272  
273          assertEq(masterToken.ownerToken(), ownerTokenAddress);
274          assertEq(masterToken.balanceOf(owner), 0);
275          assertEq(masterToken.remoteBurnable(), true);
276          assertEq(masterToken.transferable(), false);
277      }
278  }