Shadowing Reserved Keyword
Overview
- Severity: Low
- Confidence: Medium
- Affected Versions: < 0.5.0
What is the Shadowing Reserved Keyword vulnerability?
The Solidity language specifies a number of reserved keywords that may be added as functionality to the language in the future. If contracts use these keywords today, they risk compilation failure or logical inconsistency with potential updates to the language in the future. While newer versions of the Solidity compiler restrict usage of these keywords, older versions do not, so if using a vulnerable version, the keywords should be carefully avoided.
Further reading: Solidity Documentation: Reserved Keywords
Technical example of vulnerable code
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.4.0;
contract OwnableMutable {
event ChangedVar(string changedVarName);
address public owner;
// Other management state variables would go here
modifier mutable(string varName) {
_;
emit ChangedVar(varName);
}
constructor() public {
owner = msg.sender;
}
function updateOwner(address _newOwner) public mutable("owner") {
require(msg.sender == owner, "Only the current owner can assign a new owner");
owner = _newOwner;
}
// Additional functionality omitted for brevity
}
In the example above, contract OwnableMutable
represents an ownership pattern contract with additional functionality to log when key state variables are changed by functions. The modifier that it uses for this purpose, mutable()
, uses a name that is now a reserved keyword in the Solidity language. As such, new contracts will be unable to integrate successfully with this pattern as written.
Technical example of how to fix the vulnerability
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.4.0;
contract OwnableMutableUpdated {
event ChangedVar(string changedVarName);
address public owner;
// Other management state variables would go here
modifier mutatesVar(string varName) {
_;
emit ChangedVar(varName);
}
constructor() public {
owner = msg.sender;
}
function updateOwner(address _newOwner) public mutatesVar("owner") {
require(msg.sender == owner, "Only the current owner can assign a new owner");
owner = _newOwner;
}
// Additional functionality omitted for brevity
}
In the revised example above, contract OwnableMutableUpdated
has renamed the modifier for tracking changed state variables to not collide with the mutable
reserved keyword.