Please note, this content is no longer actively maintained.
The content of the SWC registry has not been thoroughly updated since 2020. It is known to be incomplete and may contain errors as well as crucial omissions.
For currently maintained guidance on known Smart Contract vulnerabilities written primarily as guidance for security reviewers, please see the EEA EthTrust Security Levels specification. As well as the latest release version, an Editor's draft is available, that represents the latest work of the group developing the specification.
General guidance for developers on what to consider to ensure security, that is currently maintained, is also available through the Smart Contract Security Verification Standard (SCSVS).
Title
Shadowing State Variables
Relationships
- CWE-710: Improper Adherence to Coding Standards
- EthTrust Security Levels:
- [Q] Implement as Documented
Description
Solidity allows for ambiguous naming of state variables when inheritance is used. Contract A
with a variable x
could inherit contract B
that also has a state variable x
defined. This would result in two separate versions of x
, one of them being accessed from contract A
and the other one from contract B
. In more complex contract systems this condition could go unnoticed and subsequently lead to security issues.
Shadowing state variables can also occur within a single contract when there are multiple definitions on the contract and function level.
Remediation
Review storage variable layouts for your contract systems carefully and remove any ambiguities. Always check for compiler warnings as they can flag the issue within a single contract.
References
- Issue on Solidity's Github - Shadowing of inherited state variables should be an error (override keyword)
- Issue on Solidity's Github - Warn about shadowing state variables
EthTrust Security Levels: - [Q] Implement as Documented
Samples
ShadowingInFunctions.sol
pragma solidity 0.4.24;
contract ShadowingInFunctions {
uint n = 2;
uint x = 3;
function test1() constant returns (uint n) {
return n; // Will return 0
}
function test2() constant returns (uint n) {
n = 1;
return n; // Will return 1
}
function test3() constant returns (uint x) {
uint n = 4;
return n+x; // Will return 4
}
}
TokenSale.sol
pragma solidity 0.4.24;
contract Tokensale {
uint hardcap = 10000 ether;
function Tokensale() {}
function fetchCap() public constant returns(uint) {
return hardcap;
}
}
contract Presale is Tokensale {
uint hardcap = 1000 ether;
function Presale() Tokensale() {}
}
TokenSale_fixed.sol
pragma solidity 0.4.25;
//We fix the problem by eliminating the declaration which overrides the prefered hardcap.
contract Tokensale {
uint public hardcap = 10000 ether;
function Tokensale() {}
function fetchCap() public constant returns(uint) {
return hardcap;
}
}
contract Presale is Tokensale {
//uint hardcap = 1000 ether;
//If the hardcap variables were both needed we would have to rename one to fix this.
function Presale() Tokensale() {
hardcap = 1000 ether; //We set the hardcap from the constructor for the Tokensale to be 1000 instead of 10000
}
}