F-2025-0014·incorrect-accounting

Missing stakers Counter Decrement in Ownership Transfer Leads to Inaccurate Staker Accounting

Fixedliquid-stakinglststaking-poolsgithub.com/matchain/contracts
TL;DR

_transferOwnership consolidates a new owner's stake into selfStake but never decrements the stakers counter, so the stakers metric overstates the true number of unique stakers.

Severity
LOW
Impact
LOW
Likelihood
MEDIUM
Method
MManual review
CAT.
Complexity
LOW
Exploitability
LOW
02Section · Description

Description

When ownership of a StakingPool is transferred to an address that already has a stake in the pool, the contract correctly consolidates the new owner's regular stake into the selfStake variable and zeros out their entry in the stakes mapping. However, the contract fails to decrement the stakers counter, which tracks the number of unique addresses with active stakes.

This occurs in the _transferOwnership function:

solidity
function _transferOwnership(address newOwner) internal virtual override {
address oldOwner = owner();
if (oldOwner == newOwner) return;
ownershipNFT.transferFrom(oldOwner, newOwner, uint160(address(this)));
if (stakes[newOwner] > 0) {
selfStake += stakes[newOwner];
stakes[newOwner] = 0;
// Missing: stakers--;
}
emit OwnershipTransferred(oldOwner, newOwner);
}

While the comment in the contract indicates that the stakers variable is "for information only," maintaining accurate protocol metrics is important for transparency and governance decisions. Additionally, if the protocol ever begins to rely on this counter for any functionality, the inaccuracy could lead to unexpected behavior.

03Section · Impact

Impact

The stakers counter overstates the true number of stakers after each ownership transfer where the new owner already had a regular stake. Off-chain analytics and any future logic depending on this metric becomes unreliable.

04Section · Recommendation

Recommendation

Decrement the stakers counter when consolidating a new owner's stake:

solidity
if (stakes[newOwner] > 0) {
selfStake += stakes[newOwner];
stakes[newOwner] = 0;
stakers--; // Add this line
}
F-2025-0014

oog
zealynx

Smart Contract Security Digest

Monthly exploit breakdowns, audit checklists, and DeFi security research — straight to your inbox

© 2026 Zealynx