Lack of Input Validation in initiateNeuroEmissionMultiplierUpdate Function #332
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Vulnerability Summary
The initiateNeuroEmissionMultiplierUpdate function in the ParanetNeuroIncentivesPool contract lacks input validation for the newMultiplier parameter. This oversight allows for the setting of unintended or malicious multiplier values, which can disrupt the reward distribution mechanism and potentially lead to financial exploitation.
Vulnerable Code
https://github.com/OriginTrail/dkg-evm-module/blob/main/contracts/paranets/ParanetNeuroIncentivesPool.sol
function initiateNeuroEmissionMultiplierUpdate(uint256 newMultiplier) external onlyVotersRegistrar {
if (!neuroEmissionMultipliers[neuroEmissionMultipliers.length - 1].finalized) {
neuroEmissionMultipliers[neuroEmissionMultipliers.length - 1].multiplier = newMultiplier;
neuroEmissionMultipliers[neuroEmissionMultipliers.length - 1].timestamp =
block.timestamp +
neuroEmissionMultiplierUpdateDelay;
} else {
neuroEmissionMultipliers.push(
ParanetLib.NeuroEmissionMultiplier({
multiplier: newMultiplier,
timestamp: block.timestamp + neuroEmissionMultiplierUpdateDelay,
finalized: false
})
);
}
}
Detailed Description
The initiateNeuroEmissionMultiplierUpdate function is responsible for updating the neuroEmissionMultiplier, which determines how much NEURO is released per TRAC spent. However, the function does not validate the newMultiplier input. This lack of validation can lead to several issues:
Unintended Multiplier Values: Without constraints, the multiplier can be set to zero, negative, or excessively large values, disrupting the reward distribution logic.
Operational Disruption: An incorrect multiplier can lead to either no rewards being distributed or excessive rewards being given out, affecting the contract's operational integrity.
Potential Exploits: A malicious actor with the appropriate permissions could set the multiplier to a value that disproportionately benefits them, leading to financial exploitation.
Lack of Constraints: The absence of sanity checks on the multiplier value means there is no safeguard against human error or malicious input.
Impact
Financial Loss: Incorrect multiplier values can lead to financial discrepancies, either by overpaying or underpaying rewards.
Operational Disruption: The reward distribution mechanism can be severely affected, leading to loss of trust and potential contract failure.
Exploitation Risk: Malicious actors could exploit the lack of validation to manipulate the reward system for personal gain.
Severity
Critical: The lack of input validation for a core parameter that affects reward distribution is a critical vulnerability. It can lead to significant financial loss and operational disruption if exploited.
Proof of Concept (PoC) Using Foundry's Forge
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../src/ParanetNeuroIncentivesPool.sol"; // Adjust the import path as necessary
contract ParanetNeuroIncentivesPoolTest is Test {
ParanetNeuroIncentivesPool pool;
}
Recommended Fix
To address the issue, implement input validation in the initiateNeuroEmissionMultiplierUpdate function to ensure the newMultiplier is within a reasonable and predefined range. Here's a suggested fix:
function initiateNeuroEmissionMultiplierUpdate(uint256 newMultiplier) external onlyVotersRegistrar {
require(newMultiplier > 0, "Multiplier must be greater than zero");
require(newMultiplier <= MAX_MULTIPLIER, "Multiplier exceeds maximum allowed value");
}
In this fix, MAX_MULTIPLIER should be defined as a constant that represents the maximum reasonable value for the multiplier.