Unrestricted Pool Creation Leads to Reward Starvation Beyond First 21 Pools
registerNewPool allows unbounded pool registration, but rewardDistribution only iterates the first MAX_POOL_NUMBER (21) active pools. Pools registered beyond that index never receive rewards regardless of their stake.
Description
The registerNewPool() function in the MATToken contract allows the StakingPoolFactory to register new staking pools without enforcing any cap or upper bound on the number of pools:
function registerNewPool(address pool, address payer) public {require(msg.sender == MatchConfig(config).poolFactory(), "Only pool factory");_transfer(payer, pool, MIN_POOL_SELFSTAKE);_pools.push(pool);}
While this function does correctly restrict access to only the pool factory, it does not restrict the number of pools that can be added to the _pools array. As a result, users can continually deploy and register new pools via mintPool() in the StakingPoolFactory contract, leading to an unbounded growth in the pool list.
However, in the rewardDistribution() function, rewards are only distributed to the first 21 active pools:
StakingPool[MAX_POOL_NUMBER] memory activePools;...if (poolIndex == MAX_POOL_NUMBER) break;
Here, MAX_POOL_NUMBER is a hard-coded constant (uint256 public constant MAX_POOL_NUMBER = 21), and only the first 21 active pools in _pools are selected for reward distribution. Any pool registered beyond this limit, regardless of its stake or activity, will never receive staking rewards.
Impact
This leads to:
- Reward starvation for later pools.
- Unfair economic advantage for early pool creators.
- Potential for griefing or DoS-like behavior where actors flood the system with dummy pools to prevent others from entering the top 21.
This contradicts principles of fairness and decentralization, and severely limits protocol scalability.
Recommendation
Several options or design adjustments are available to address this issue. It is recommended to rethink the current reward distribution model to ensure that all active pools receive rewards fairly, not just the first 21.
- Avoid relying on a fixed-size array and static cap (
MAX_POOL_NUMBER) in the reward distribution logic. - The current push-based pattern, where the token contract actively mints and distributes to pools, is simple but does not scale well and is prone to fairness issues.

