Hardcoded Non-Essential Parameters
id: LS02L
title: Hardcoded Non-Essential Parameters
baseSeverity: L
category: maintainability
language: solidity
blockchain: [ethereum]
impact: Inflexible protocol configuration and upgrade overhead
status: draft
complexity: low
attack_vector: internal
mitigation_difficulty: easy
versions: [">=0.4.0", "<latest"]
cwe: CWE-611
swc: SWC-131
๐ Description
- Hardcoded non-essential parameters refers to values (such as fees, durations, limits, and addresses) that are written directly into the smart contract code instead of being stored in state variables or constructor-initialized. While not an immediate security threat, this practice:
- Reduces flexibility and upgradability
- Requires redeployment for any configuration change,
- Makes the contract more prone to technical debt and governance friction.
- These parameters often include:
- Fee percentages
- Cooldown durations
- Token or treasury addresses
- Reward multipliers
- Admin configurations
๐จ Vulnerable Code
contract HardcodedConfig {
function getFee() public pure returns (uint256) {
return 500; // โ Hardcoded 5% (basis points)
}
function cooldownPeriod() public pure returns (uint256) {
return 86400; // โ Hardcoded 1-day delay
}
}
๐งช Exploit Scenario
Step-by-step impact:
- Protocol deploys with a hardcoded getFee() value of 5%.
- Market conditions change, and the team decides to reduce it to 3%.
- Since the value is hardcoded, a new contract deployment is required.
- This causes upgrade delays, user confusion, or inconsistent frontend behavior.
Assumptions:
- The value is not mission-critical (e.g., not part of immutable trust assumptions).
- Governance or owner wants to change the value post-deployment.
โ Fixed Code
contract Configurable {
uint256 public fee; // in basis points
address public owner;
event FeeUpdated(uint256 newFee);
constructor(uint256 initialFee) {
fee = initialFee;
owner = msg.sender;
}
function setFee(uint256 newFee) external {
require(msg.sender == owner, "Unauthorized");
require(newFee <= 1000, "Too high"); // max 10%
fee = newFee;
emit FeeUpdated(newFee);
}
function getFee() public view returns (uint256) {
return fee;
}
}
๐งญ Contextual Severity
- context: "Default"
severity: L
reasoning: "Inflexibility introduces governance or UX issues but not security-critical."
- context: "Protocols with dynamic tokenomics"
severity: M
reasoning: "Hardcoded variables may lead to economic inefficiencies over time."
- context: "Upgradable governance-enabled contract"
severity: I
reasoning: "Issue is irrelevant if parameters are modifiable via governance."
๐ก๏ธ Prevention
Primary Defenses
- Use state variables for all configurable parameters.
- Initialize parameters via the constructor or an initializer.
- Restrict updates using onlyOwner, onlyGovernance, or AccessControl.
Additional Safeguards
- Emit events on config changes to ensure observability.
- Document acceptable ranges and constraints for each configurable value.
- In upgradable contracts, prefer UUPS pattern with secure admin control.
Detection Methods
- Slither: hardcoded-constant, fixed-parameter, immutable-config detectors.
- Manual audit to identify return
in pure/view functions with constants. - Use grep or AST tools to find magic numbers or hardcoded literals.
๐ฐ๏ธ Historical Exploits
- Name: Compound Interest Rate Hardcoding
- Date: 2020
- Loss: No direct financial loss
- Post-mortem: Link to post-mortem
๐ Further Reading
- SWC-131: Presence of Unused or Hardcoded Code
- Solidity Docs โ Constants vs Variables
- OpenZeppelin โ Upgradeable Patterns
โ Vulnerability Report
id: LS02L
title: Hardcoded Non-Essential Parameters
severity: L
score:
impact: 2
exploitability: 0
reachability: 5
complexity: 1
detectability: 5
finalScore: 2.1
๐ Justifications & Analysis
- Impact: Limits operational flexibility and causes protocol downtime during config changes.
- Exploitability: Not an attack vector on its own.
- Reachability: Common in early-stage and boilerplate contracts.
- Complexity: Simple to fix โ requires moving constants to variables.
- Detectability: High โ Slither and manual reviews can easily identify hardcoded logic.