Crowdsale Contract - TypeError: Overriding function changes state mutability from "view" to "nonpayable"

Hi everyone,

So I’m having an issue with generating a crowdsale contract with the following requirements:

  • Hard Capped
  • Individually Capped (minimum/maximum per address)
  • Timed
  • Distribution only after sale ends or determined by date

So far, I’m pretty stuck in implementing individual minimum/maximum caps. I’m just trying to create a crowdsale contract, of which I’d transfer the tokens to the crowdsale contract and the crowdsale would own those tokens to use. I’m not looking to deploy an ERC20 token at the same time like most tutorials show.

:computer: Environment
OpenZeppeling 2.5.0
Truffle v5.2.4 (core: 5.2.4)

:memo:Details

Compiling the below contract results in the following error, of which I’m failing to understand how to get around.

Compiling your contracts...
===========================
√ Fetching solc version list from solc-bin. Attempt #1
> Compiling .\contracts\MyCrowdsale.sol
√ Fetching solc version list from solc-bin. Attempt #1

/C/Users/laptop/crypto/MY CROWDSALE/contracts/MyCrowdsale.sol:38:5: TypeError: Overriding function changes state mutability from "view" to "nonpayable".
    function _preValidatePurchase(
    ^ (Relevant source part starts here and spans across multiple lines).
@openzeppelin/contracts/crowdsale/validation/TimedCrowdsale.sol:82:5: Overridden function is here:
    function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal onlyWhileOpen view {
    ^ (Relevant source part starts here and spans across multiple lines).
,/C/Users/laptop/crypto/MY CROWDSALE/contracts/MyCrowdsale.sol:38:5: TypeError: Overriding function changes state mutability from "view" to "nonpayable".
    function _preValidatePurchase(
    ^ (Relevant source part starts here and spans across multiple lines).
@openzeppelin/contracts/crowdsale/validation/CappedCrowdsale.sol:44:5: Overridden function is here:
    function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
    ^ (Relevant source part starts here and spans across multiple lines).
,/C/Users/laptop/crypto/MY CROWDSALE/contracts/MyCrowdsale.sol:38:5: TypeError: Overriding function changes state mutability from "view" to "nonpayable".
    function _preValidatePurchase(
    ^ (Relevant source part starts here and spans across multiple lines).
@openzeppelin/contracts/crowdsale/Crowdsale.sol:139:5: Overridden function is here:
    function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
    ^ (Relevant source part starts here and spans across multiple lines).
,/C/Users/laptop/crypto/MY CROWDSALE/contracts/MyCrowdsale.sol:30:9: TypeError: Referenced declaration is neither modifier nor base class.   
        IndividuallyCappedCrowdsale()
        ^---------------------------^

Compilation failed. See above.
Truffle v5.2.4 (core: 5.2.4)
Node v15.11.0

:1234: Code to reproduce

pragma solidity ^0.5.0;

import "@openzeppelin/contracts/crowdsale/Crowdsale.sol";

import "@openzeppelin/contracts/crowdsale/validation/CappedCrowdsale.sol";

import "@openzeppelin/contracts/crowdsale/validation/TimedCrowdsale.sol";

import "@openzeppelin/contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol";

import "@openzeppelin/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol";

contract OS_PRESALE is Crowdsale, CappedCrowdsale, TimedCrowdsale {

  uint256 public investorMinCap = 10000000000000000000;

  uint256 public investorHardCap = 30000000000000000000;

       mapping(address => uint256) public _contributions;

        constructor(

        uint256 rate,            // rate, in TKNbits

        address payable wallet,  // wallet to send Ether

        IERC20 token,            // the token

        uint256 cap,             // total cap, in wei

        uint256 openingTime,     // opening time in unix epoch seconds

        uint256 closingTime      // closing time in unix epoch seconds

    )

        

        CappedCrowdsale(cap)

        TimedCrowdsale(openingTime, closingTime)

        Crowdsale(rate, wallet, token)

        IndividuallyCappedCrowdsale()

        public

    {

        // nice, we just created a crowdsale that's only open

        // for a certain amount of time

        // and stops accepting contributions once it reaches `cap`

    }

    function _preValidatePurchase(

    address _beneficiary,

    uint256 _weiAmount

  )

    internal

  {

    super._preValidatePurchase(_beneficiary, _weiAmount);

    uint256 _existingContribution = _contributions[_beneficiary];

    uint256 _newContribution = _existingContribution.add(_weiAmount);

    require(_newContribution >= investorMinCap && _newContribution <= investorHardCap);

  _contributions[_beneficiary] = _newContribution;   

  }

}
1 Like

Hi @Fursty,

Welcome to the community :wave:

The compiler gives TypeError: Overriding function changes state mutability from "view" to "nonpayable". for _preValidatePurchase.

This is a view function so you can’t change state, the purpose is to pre validate the purchase…

https://docs.openzeppelin.com/contracts/2.x/api/crowdsale#Crowdsale-_preValidatePurchase-address-uint256-

If you want to change state then you can do by overriding:
https://docs.openzeppelin.com/contracts/2.x/api/crowdsale#Crowdsale-_updatePurchasingState-address-uint256-