communities-contracts/test/CommunityTokenDeployer.t.sol

279 lines
12 KiB
Solidity

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import { Test } from "forge-std/Test.sol";
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import { DeployContracts } from "../script/DeployContracts.s.sol";
import { DeploymentConfig } from "../script/DeploymentConfig.s.sol";
import { BaseTokenFactory } from "../contracts/factories/BaseTokenFactory.sol";
import { OwnerToken } from "../contracts/tokens/OwnerToken.sol";
import { MasterToken } from "../contracts/tokens/MasterToken.sol";
import { CommunityOwnerTokenRegistry } from "../contracts/CommunityOwnerTokenRegistry.sol";
import { CommunityTokenDeployer } from "../contracts/CommunityTokenDeployer.sol";
contract CommunityTokenDeployerTest is Test {
DeploymentConfig internal deploymentConfig;
CommunityTokenDeployer internal tokenDeployer;
CommunityOwnerTokenRegistry internal tokenRegistry;
address internal deployer;
address internal immutable owner = makeAddr("owner");
address internal communityAddress;
uint256 internal communityKey;
function setUp() public virtual {
DeployContracts deployment = new DeployContracts();
(tokenDeployer, tokenRegistry,,, deploymentConfig) = deployment.run();
deployer = deploymentConfig.deployer();
(communityAddress, communityKey) = makeAddrAndKey("community");
}
function test_Deployment() public {
assertEq(tokenDeployer.deploymentRegistry(), address(tokenRegistry));
assertEq(tokenDeployer.owner(), deployer);
}
function _getOwnerTokenConfig() internal view returns (CommunityTokenDeployer.TokenConfig memory, bytes memory) {
(
string memory ownerTokenName,
string memory ownerTokenSymbol,
string memory ownerTokenBaseURI,
bytes memory signerPublicKey
) = deploymentConfig.ownerTokenConfig();
CommunityTokenDeployer.TokenConfig memory ownerTokenConfig =
CommunityTokenDeployer.TokenConfig(ownerTokenName, ownerTokenSymbol, ownerTokenBaseURI);
return (ownerTokenConfig, signerPublicKey);
}
function _getMasterTokenConfig() internal view returns (CommunityTokenDeployer.TokenConfig memory) {
(string memory masterTokenName, string memory masterTokenSymbol, string memory masterTokenBaseURI,) =
deploymentConfig.masterTokenConfig();
CommunityTokenDeployer.TokenConfig memory masterTokenConfig =
CommunityTokenDeployer.TokenConfig(masterTokenName, masterTokenSymbol, masterTokenBaseURI);
return masterTokenConfig;
}
function _createDeploymentSignature(
uint256 _signerKey,
address _signer,
address _deployer
)
internal
view
returns (CommunityTokenDeployer.DeploymentSignature memory)
{
bytes32 digest = ECDSA.toTypedDataHash(
tokenDeployer.DOMAIN_SEPARATOR(),
keccak256(abi.encode(tokenDeployer.DEPLOYMENT_SIGNATURE_TYPEHASH(), _signer, _deployer))
);
(uint8 v, bytes32 r, bytes32 s) = vm.sign(_signerKey, digest);
return CommunityTokenDeployer.DeploymentSignature(_signer, _deployer, v, r, s);
}
}
contract SetDeploymentRegistryAddressTest is CommunityTokenDeployerTest {
event DeploymentRegistryAddressChange(address indexed);
function setUp() public virtual override {
CommunityTokenDeployerTest.setUp();
}
function test_RevertWhen_SenderIsNotOwner() public {
vm.expectRevert(bytes("Ownable: caller is not the owner"));
tokenDeployer.setDeploymentRegistryAddress(makeAddr("someAddress"));
}
function test_RevertWhen_InvalidDeploymentRegistryAddress() public {
vm.prank(deployer);
vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidDeploymentRegistryAddress.selector);
tokenDeployer.setDeploymentRegistryAddress(address(0));
}
function test_SetDeploymentRegistryAddress() public {
address newAddress = makeAddr("newAddress");
vm.prank(deployer);
vm.expectEmit(true, true, true, true);
emit DeploymentRegistryAddressChange(newAddress);
tokenDeployer.setDeploymentRegistryAddress(newAddress);
assertEq(tokenDeployer.deploymentRegistry(), newAddress);
}
}
contract SetOwnerTokenFactoryAddressTest is CommunityTokenDeployerTest {
event OwnerTokenFactoryAddressChange(address indexed);
function setUp() public virtual override {
CommunityTokenDeployerTest.setUp();
}
function test_RevertWhen_SenderIsNotOwner() public {
vm.expectRevert(bytes("Ownable: caller is not the owner"));
tokenDeployer.setOwnerTokenFactoryAddress(makeAddr("someAddress"));
}
function test_RevertWhen_InvalidTokenFactoryAddress() public {
vm.prank(deployer);
vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidTokenFactoryAddress.selector);
tokenDeployer.setOwnerTokenFactoryAddress(address(0));
}
function test_SetOwnerTokenFactoryAddress() public {
address newAddress = makeAddr("newAddress");
vm.prank(deployer);
vm.expectEmit(true, true, true, true);
emit OwnerTokenFactoryAddressChange(newAddress);
tokenDeployer.setOwnerTokenFactoryAddress(newAddress);
assertEq(tokenDeployer.ownerTokenFactory(), newAddress);
}
}
contract SetMasterTokenFactoryAddressTest is CommunityTokenDeployerTest {
event MasterTokenFactoryAddressChange(address indexed);
function setUp() public virtual override {
CommunityTokenDeployerTest.setUp();
}
function test_RevertWhen_SenderIsNotOwner() public {
vm.expectRevert(bytes("Ownable: caller is not the owner"));
tokenDeployer.setMasterTokenFactoryAddress(makeAddr("someAddress"));
}
function test_RevertWhen_InvalidTokenFactoryAddress() public {
vm.prank(deployer);
vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidTokenFactoryAddress.selector);
tokenDeployer.setMasterTokenFactoryAddress(address(0));
}
function test_SetOwnerTokenFactoryAddress() public {
address newAddress = makeAddr("newAddress");
vm.prank(deployer);
vm.expectEmit(true, true, true, true);
emit MasterTokenFactoryAddressChange(newAddress);
tokenDeployer.setMasterTokenFactoryAddress(newAddress);
assertEq(tokenDeployer.masterTokenFactory(), newAddress);
}
}
contract DeployTest is CommunityTokenDeployerTest {
function setUp() public virtual override {
CommunityTokenDeployerTest.setUp();
}
function test_RevertWhen_InvalidDeployerAddress() public {
(CommunityTokenDeployer.TokenConfig memory ownerTokenConfig, bytes memory signerPublicKey) =
_getOwnerTokenConfig();
CommunityTokenDeployer.TokenConfig memory masterTokenConfig = _getMasterTokenConfig();
CommunityTokenDeployer.DeploymentSignature memory signature =
_createDeploymentSignature(communityKey, communityAddress, makeAddr("someone else"));
vm.prank(owner);
vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidDeployerAddress.selector);
tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
}
function test_RevertWhen_InvalidDeploymentSignature() public {
(CommunityTokenDeployer.TokenConfig memory ownerTokenConfig, bytes memory signerPublicKey) =
_getOwnerTokenConfig();
CommunityTokenDeployer.TokenConfig memory masterTokenConfig = _getMasterTokenConfig();
CommunityTokenDeployer.DeploymentSignature memory signature =
_createDeploymentSignature(communityKey, makeAddr("invalid address"), owner);
vm.prank(owner);
vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidDeploymentSignature.selector);
tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
}
function test_RevertWhen_InvalidTokenMetadata() public {
(, bytes memory signerPublicKey) = _getOwnerTokenConfig();
CommunityTokenDeployer.TokenConfig memory ownerTokenConfig = CommunityTokenDeployer.TokenConfig("", "", "");
CommunityTokenDeployer.TokenConfig memory masterTokenConfig = CommunityTokenDeployer.TokenConfig("", "", "");
CommunityTokenDeployer.DeploymentSignature memory signature =
_createDeploymentSignature(communityKey, communityAddress, owner);
vm.prank(owner);
vm.expectRevert(BaseTokenFactory.BaseTokenFactory_InvalidTokenMetadata.selector);
tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
// fill `masterTokenConfig` with data
masterTokenConfig = _getMasterTokenConfig();
vm.prank(owner);
vm.expectRevert(BaseTokenFactory.BaseTokenFactory_InvalidTokenMetadata.selector);
tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
// fill `ownerTokenConfig` with data and reset `masterTokenConfig`
(ownerTokenConfig,) = _getOwnerTokenConfig();
masterTokenConfig = CommunityTokenDeployer.TokenConfig("", "", "");
vm.prank(owner);
vm.expectRevert(BaseTokenFactory.BaseTokenFactory_InvalidTokenMetadata.selector);
tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
}
function test_RevertWhen_InvalidSignerPublicKey() public {
(CommunityTokenDeployer.TokenConfig memory ownerTokenConfig,) = _getOwnerTokenConfig();
CommunityTokenDeployer.TokenConfig memory masterTokenConfig = _getMasterTokenConfig();
CommunityTokenDeployer.DeploymentSignature memory signature =
_createDeploymentSignature(communityKey, communityAddress, owner);
vm.prank(owner);
vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidSignerKeyOrCommunityAddress.selector);
tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, bytes(""));
}
function test_RevertWhen_InvalidCommunityAddress() public {
(CommunityTokenDeployer.TokenConfig memory ownerTokenConfig, bytes memory signerPublicKey) =
_getOwnerTokenConfig();
CommunityTokenDeployer.TokenConfig memory masterTokenConfig = _getMasterTokenConfig();
CommunityTokenDeployer.DeploymentSignature memory signature =
_createDeploymentSignature(communityKey, address(0), owner);
vm.prank(owner);
vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_InvalidSignerKeyOrCommunityAddress.selector);
tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
}
function test_RevertWhen_AlreadyDeployed() public {
(CommunityTokenDeployer.TokenConfig memory ownerTokenConfig, bytes memory signerPublicKey) =
_getOwnerTokenConfig();
CommunityTokenDeployer.TokenConfig memory masterTokenConfig = _getMasterTokenConfig();
CommunityTokenDeployer.DeploymentSignature memory signature =
_createDeploymentSignature(communityKey, communityAddress, owner);
vm.startPrank(owner);
tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
vm.expectRevert(CommunityTokenDeployer.CommunityTokenDeployer_AlreadyDeployed.selector);
tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
}
function test_Deploy() public {
(CommunityTokenDeployer.TokenConfig memory ownerTokenConfig, bytes memory signerPublicKey) =
_getOwnerTokenConfig();
CommunityTokenDeployer.TokenConfig memory masterTokenConfig = _getMasterTokenConfig();
CommunityTokenDeployer.DeploymentSignature memory signature =
_createDeploymentSignature(communityKey, communityAddress, owner);
vm.prank(owner);
(address ownerTokenAddress, address masterTokenAddress) =
tokenDeployer.deploy(ownerTokenConfig, masterTokenConfig, signature, signerPublicKey);
assertEq(ownerTokenAddress, tokenRegistry.getEntry(communityAddress));
assertEq(OwnerToken(ownerTokenAddress).balanceOf(owner), 1);
MasterToken masterToken = MasterToken(masterTokenAddress);
assertEq(masterToken.ownerToken(), ownerTokenAddress);
assertEq(masterToken.balanceOf(owner), 0);
assertEq(masterToken.remoteBurnable(), true);
assertEq(masterToken.transferable(), false);
}
}