• YouTube Channel
  • System Status
  • VS Code Extension
  • No Parameter Validation in Constructor

    Overview

    What is the No Parameter Validation in Constructor vulnerability?

    In Solidity, constructor functions for smart contracts can be created with parameters, which are typically used to initialize some aspect of the contract's state. If the values passed to parameters in a constructor are not validated, it is possible that the contract might be deployed in an incorrect or undesirable state.

    Further reading: Solidity Documentation: Constructors

    Technical example of vulnerable code

      // SPDX-License-Identifier: Unlicense
      pragma solidity ^0.8.0;
    
      contract Crowdfunding {
          address public owner;
          uint256 public goal;
          uint256 public totalFundsRaised;
    
          event ContributionReceived(address contributor, uint256 amount);
          event GoalReached(uint256 totalFundsRaised);
    
          constructor(uint256 _goal) {
              owner = msg.sender;
              goal = _goal;
          }
    
          function contribute() external payable {
              require(msg.value > 0, "Contribution must be greater than 0");
              totalFundsRaised += msg.value;
              emit ContributionReceived(msg.sender, msg.value);
    
              if (totalFundsRaised >= goal) {
                  emit GoalReached(totalFundsRaised);
              }
          }
    
          // Functionality to withdraw funds, check goal status, etc., omitted for brevity.
      }
    
    

    In the example above, contract Crowdfunding uses a constructor that accepts a value for parameter _goal, which is used to determine when the crowdfunding exercise succeeds. However, there is no check made on the value of the parameter inside of the constructor, meaning it could be passed as a nonsensical (or harmful) value; for example, if it were inadvertently specified as zero, much of the contract functionality might fail to work.

    Technical example of how to fix the vulnerability

      // SPDX-License-Identifier: Unlicense
      pragma solidity ^0.8.0;
    
      contract CrowdfundingUpdated {
          address public owner;
          uint256 public goal;
          uint256 public totalFundsRaised;
    
          event ContributionReceived(address contributor, uint256 amount);
          event GoalReached(uint256 totalFundsRaised);
    
          constructor(uint256 _goal) {
              require (_goal > 100, "Goal must be greater than 100");
              owner = msg.sender;
              goal = _goal;
          }
    
          function contribute() external payable {
              require(msg.value > 0, "Contribution must be greater than 0");
              totalFundsRaised += msg.value;
              emit ContributionReceived(msg.sender, msg.value);
    
              if (totalFundsRaised >= goal) {
                  emit GoalReached(totalFundsRaised);
              }
          }
    
          // Functionality to withdraw funds, check goal status, etc., omitted for brevity.
      }
    
    

    In the revised example above, contract CrowdfundingUpdated imposes a check on the _goal parameter in the constructor using a require() condition, specifying a minimal goal for the crowdfunding. While exact values to specify for the parameter check will be application-dependent, specifying some check rather than none can help avoid situations where a contract is deployed in an undesired state.