Skip to content

Commit 90fc63c

Browse files
committed
test: maximum number of beneficiaries
1 parent 503ae97 commit 90fc63c

4 files changed

Lines changed: 57 additions & 1 deletion

File tree

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,18 @@ $ forge --help
6666
$ anvil --help
6767
$ cast --help
6868
```
69+
70+
### Maximum number of beneficiaries
71+
72+
The list of beneficiaries is determined at the moment of deploying the smart contract [VestingParams.sol](./src/tokenDistribution/vesting/VestingParams.sol) in the constructor. Therefore, it is important to understand the maximum number of beneficiaries that can be set in this way without exceeding the block gas limit.
73+
74+
As of 2025, the block gas limit in the Ethereum network is 36 million. In the Arbitrum network, it is significantly higher, but according to the documentation, the practical working limit is 32 million.
75+
76+
To determine the actual gas consumption, you can refer to the load test [MaxBeneficiaries.t.sol](./test/tokenDistribution/vesting/loadTests/MaxBeneficiaries.t.sol). Run the test with gas profiling using `forge test -vvv --mt test_deploy_moreBeneficiaries --gas-report`.
77+
78+
The resulting table shows that for 401 beneficiaries, `19_448_973` gas will be consumed, which is optimal and will occupy approximately half of the block gas limit in Ethereum.
79+
80+
![](./images/maxBeneficiariesLimit.png)
81+
82+
Important! For deployment on other networks, it is necessary to check the documentation and review the block and transaction gas limits.
83+

images/maxBeneficiariesLimit.png

86.3 KB
Loading

src/tokenDistribution/vesting/VestingParams.sol

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ contract VestingParams is IVestingParams {
2727
Beneficiary[] memory teamBeneficiaries,
2828
Beneficiary[] memory liquidityBeneficiaries
2929
) {
30-
// TODO: протестировать сколько можно запихать бенефициаров
3130
_validateAndStoreBeneficiaries(VestingType.TEAM, teamBeneficiaries, TEAM_TOTAL_AMOUNT);
3231
_validateAndStoreBeneficiaries(VestingType.LIQUIDITY, liquidityBeneficiaries, LIQUIDITY_TOTAL_AMOUNT);
3332
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity 0.8.28;
3+
4+
import {Test, console} from "forge-std/Test.sol";
5+
6+
import {VestingParams, IVestingParams} from "src/tokenDistribution/vesting/VestingParams.sol";
7+
import {Beneficiary, VestingType, Schedule} from "src/tokenDistribution/utils/Common.sol";
8+
9+
contract MaxBeneficiariesTest is Test {
10+
VestingParams vestingParams;
11+
12+
/// @dev Deployment cost of 401 beneficiaries is equal 19_448_973 (≈ half a block gas limit)
13+
/// Checked with the command:
14+
/// `forge test -vvv --mt test_deploy_moreBeneficiaries --gas-report`
15+
function test_maxBeneficiaries() external {
16+
// Stage 0. Create liquidity beneficiaries
17+
uint256 liquidityTotalAmount = 287_500_000e18; // equal vestingParams.LIQUIDITY_TOTAL_AMOUNT()
18+
Beneficiary[] memory liquidityBeneficiaries = new Beneficiary[](1); // min number of beneficiary
19+
liquidityBeneficiaries[0] = Beneficiary({
20+
account: makeAddr("liquidityBeneficiary"),
21+
amount: liquidityTotalAmount
22+
});
23+
24+
// Stage 1. Create team beneficiary. Simulate 400 beneficiaries
25+
uint256 teamBeneficiariesCount = 400;
26+
uint256 teamTotalAmount = 100_000_000e18; // equal vestingParams.TEAM_TOTAL_AMOUNT()
27+
28+
Beneficiary[] memory teamBeneficiaries = new Beneficiary[](teamBeneficiariesCount);
29+
30+
for (uint256 i = 0; i < teamBeneficiariesCount; i++) {
31+
teamBeneficiaries[i] = Beneficiary({
32+
account: vm.addr(uint256(keccak256(abi.encodePacked("OneOfBeneficiary", i)))),
33+
amount: teamTotalAmount / teamBeneficiariesCount
34+
});
35+
}
36+
37+
// Stage 2. Deploy VestingParams
38+
vestingParams = new VestingParams(teamBeneficiaries, liquidityBeneficiaries);
39+
40+
assertEq(vestingParams.getBeneficiaries(VestingType.TEAM).length, teamBeneficiariesCount);
41+
}
42+
}

0 commit comments

Comments
 (0)