Multiple Constructors
Overview
- Severity: High
- Confidence: High
- Affected Versions: 0.4.22
What is the Multiple Constructors vulnerability?
In version 0.4.22
of the Solidity compiler, constructors for smart contracts could be defined in both old-style notation (a function with the same name as the contract) and new-style notation (using the constructor()
keyword), in the same contract. This ambiguity could lead to unintended behavior as only one constructor would be executed.
Further reading: Solidity Version 0.4.23 Release Notes
Technical example of vulnerable code
// SPDX-License-Identifier: Unlicense
pragma solidity 0.4.22;
contract MultipleConstructors {
address owner;
constructor() public {
owner = address(0);
}
function MultipleConstructors() public {
owner = msg.sender;
}
function withdraw() public {
require(owner == msg.sender);
msg.sender.transfer(this.balance);
}
// additional smart contract logic
}
In the above example, contract MultipleConstructors
initializes a state variable owner
through two different constructors, which will set the value to different addresses. Additional logic of the contract is predicated on the value of the owner
variable, so depending on which constructor is executed, the contract may not behave as intended.
Technical example of how to fix the vulnerability
// SPDX-License-Identifier: Unlicense
pragma solidity 0.4.23;
contract MultipleConstructors {
address owner;
constructor() public {
owner = msg.sender;
}
function withdraw() public {
require(owner == msg.sender);
msg.sender.transfer(this.balance);
}
// additional smart contract logic
}
In the corrected code example, only the new-style constructor scheme with the special constructor
keyword is used, and a newer version of the compiler not affected by this vulnerability is specified in the pragma.