1+ // SPDX-License-Identifier: UNLICENSED
2+ pragma solidity 0.8.28 ;
3+
4+ import {Test, console} from "forge-std/Test.sol " ;
5+ import {IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol " ;
6+
7+ import {MetaTokenDistributor, IMetaTokenDistributor} from "src/tokenDistribution/MetaTokenDistributor.sol " ;
8+ import {VestingParams} from "src/tokenDistribution/vesting/VestingParams.sol " ;
9+ import {Beneficiary, VestingType, Schedule} from "src/tokenDistribution/utils/Common.sol " ;
10+
11+ contract MetaTokenDistributorTest is Test {
12+ uint256 public constant MONTH = 30 days ;
13+ uint64 public vestingStartTime;
14+
15+ VestingParams vestingParams;
16+ MetaTokenDistributor distributor;
17+
18+ address teamBeneficiary1;
19+ address teamBeneficiary2;
20+ address liquidityBeneficiary;
21+
22+ function setUp () external {
23+ vestingStartTime = uint64 (block .timestamp + MONTH);
24+ (Beneficiary[] memory teamBeneficiaries , Beneficiary[] memory liquidityBeneficiaries )
25+ = _generateBeneficiaries ();
26+
27+ vestingParams = new VestingParams (teamBeneficiaries, liquidityBeneficiaries);
28+ distributor = new MetaTokenDistributor (address (vestingParams), vestingStartTime);
29+ }
30+
31+ // region - Deploy -
32+
33+ function test_deploy () external view {
34+ assertEq (distributor.getVestingParamsAddress (), address (vestingParams));
35+ assertEq (distributor.getVestingStartTime (), vestingStartTime);
36+
37+ assertNotEq (distributor.getMETAAddress (), address (0 ));
38+ }
39+
40+ function test_deploy_revertIfInvalidVestingStartTime (uint64 invalidVestingStartTime ) external {
41+ // simulate timestamp
42+ vm.warp (1000 );
43+
44+ vm.assume (invalidVestingStartTime < block .timestamp );
45+
46+ vm.expectRevert (IMetaTokenDistributor.InvalidVestingStartTime.selector );
47+
48+ distributor = new MetaTokenDistributor (address (vestingParams), invalidVestingStartTime);
49+ }
50+
51+ function test_deploy_revertIfZeroAddress () external {
52+
53+ vm.expectRevert (IMetaTokenDistributor.ZeroAddress.selector );
54+
55+ distributor = new MetaTokenDistributor (address (0 ), vestingStartTime);
56+ }
57+
58+ function test_deploy_emitMetaTokenDeployed () external {
59+ vm.expectEmit (true , true , true , false ); // data is not checking
60+ emit IMetaTokenDistributor.MetaTokenDeployed (address (0 ));
61+
62+ distributor = new MetaTokenDistributor (address (vestingParams), vestingStartTime);
63+ }
64+
65+ // endregion
66+
67+ // region - Start vesting -
68+
69+ function test_startVesting () external {
70+ vm.warp (vestingStartTime);
71+ IERC20 META = IERC20 (distributor.getMETAAddress ());
72+
73+ address vesting = distributor.startVesting (VestingType.TEAM);
74+
75+ assertEq (META.balanceOf (vesting), vestingParams.TEAM_TOTAL_AMOUNT ());
76+ assertEq (META.balanceOf (address (distributor)), META.totalSupply () - vestingParams.TEAM_TOTAL_AMOUNT ());
77+ assertNotEq (vesting, address (0 ));
78+ assertNotEq (distributor.getVestingAddress (VestingType.TEAM), address (0 ));
79+ }
80+
81+ function test_startVesting_emitVestingStarted () external {
82+ vm.warp (vestingStartTime);
83+
84+ // data is not checking
85+ vm.expectEmit (true , true , true , false );
86+ emit IMetaTokenDistributor.VestingStarted (address (0 ));
87+
88+ distributor.startVesting (VestingType.TEAM);
89+ }
90+
91+ function test_startVesting_revertIfVestingHasAlreadyStarted () external {
92+ vm.warp (vestingStartTime);
93+
94+ distributor.startVesting (VestingType.TEAM);
95+
96+ vm.expectRevert (IMetaTokenDistributor.VestingHasAlreadyStarted.selector );
97+
98+ distributor.startVesting (VestingType.TEAM);
99+ }
100+
101+ function test_startVesting_revertIfVestingStartTimeHasNotArrived (uint64 invalidVestingStartTime ) external {
102+ vm.assume (invalidVestingStartTime < vestingStartTime);
103+
104+ vm.expectRevert (IMetaTokenDistributor.VestingStartTimeHasNotArrived.selector );
105+
106+ distributor.startVesting (VestingType.TEAM);
107+ }
108+
109+ // endregion
110+
111+ // region - Service functions -
112+
113+ function _generateBeneficiaries () private returns (Beneficiary[] memory teamBeneficiaries , Beneficiary[] memory liquidityBeneficiaries ) {
114+ teamBeneficiary1 = makeAddr ("teamBeneficiary1 " );
115+ teamBeneficiary2 = makeAddr ("teamBeneficiary2 " );
116+ liquidityBeneficiary = makeAddr ("liquidityBeneficiary " );
117+
118+ teamBeneficiaries = new Beneficiary [](2 );
119+ teamBeneficiaries[0 ] = Beneficiary ({
120+ account: teamBeneficiary1,
121+ amount: 60_000_000e18
122+ });
123+ teamBeneficiaries[1 ] = Beneficiary ({
124+ account: teamBeneficiary2,
125+ amount: 40_000_000e18
126+ });
127+
128+ liquidityBeneficiaries = new Beneficiary [](1 );
129+ liquidityBeneficiaries[0 ] = Beneficiary ({
130+ account: liquidityBeneficiary,
131+ amount: 287_500_000e18
132+ });
133+ }
134+
135+ // endregion
136+ }
0 commit comments