0

I'm having lint check warning in Remix for my smart contract in Solidity: addFeature(int128,uint256,bool,uint256,uint256,uint16,uint16,address) high: infinite. If the gas requirement of a function is higher than the block gas limit, it cannot be executed. Please avoid loops in your functions or actions that modify large areas of storage (this includes clearing or copying arrays in storage)

Feature is a struct with lot's of fields:

struct Feature {
    int128 key;
    uint256 goal;
    bool finishOnGoal;
    uint campaignStart; // timestamp
    uint campaignFinish; // timestamp

    PledgeType pledgeType; // enum
    FixedPledge fixedPledge; // description for enum value #1
    VariablePledge variablePledge; // description for enum value #2

    PrepaymentType prepaymentType; // enum
    FixedPrepayment fixedPrepayment; // description for enum value #1
    PercentPrepayment percentPrepayment; // description for enum value #2

    uint16 maxDevelopmentDelay; // days
    uint16 developmentDuration; // days

    ConfirmationType confirmationType; // enum
    UserConfirmation userConfirmation; // description for enum value #1

    address developer;
}

...

// featureKey => feature
mapping (int128 => Feature) features;

// featureKey => feature
mapping (int128 => FeatureData) data;

...

// common feature data
function addFeature(
    int128 key,
    uint256 goal,
    bool finishOnGoal,
    uint campaignStart,  // timestamp
    uint campaignFinish, // timestamp
    uint16 maxDevelopmentDelay,
    uint16 developmentDuration,
    address developer) public
    ownerOnly
    withState(key, State.NotSet)
{
    Feature memory feature;
    feature.key = key;
    feature.goal = goal;
    feature.finishOnGoal = finishOnGoal;
    feature.campaignStart = campaignStart;
    feature.campaignFinish = campaignFinish;
    feature.maxDevelopmentDelay = maxDevelopmentDelay;
    feature.developmentDuration = developmentDuration;
    feature.developer = developer;

    FeatureData memory featureData;
    featureData.state = State.Deployment;
    featureData.backers = new address[](0);
    featureData.raised = 0;
    featureData.prepaid = 0;

    features[key] = feature;
    data[key] = featureData;
}

Why do i have this warning? What can/should be changed to fix it (without loosing of functionality)? AFAIK there are neither loops nor arrays modifications here (maps only).

3
  • You haven't shared enough code to try to reproduce the warning, but I would have expected this to fail to compile... I'm not sure how a FeatureData in memory is supposed to be copied into storage due to the dynamically-sized backers array. Could you share enough code that it's possible to compile this?
    – user19510
    Commented Jun 14, 2018 at 8:33
  • though i don't really feel struct fields description is helpful here i've updated source code in the question
    – 4ntoine
    Commented Jun 14, 2018 at 8:53
  • This code still can't be compiled. I don't want to try to make up definitions of all the different types. Share some compilable source code that reproduces the problem. One way to do that would be to share all your code. Another (better!) way to do it would be to trim down the code until it's minimal but still reproduces the problem. E.g. delete most of the fields and see if you can still trigger the warning.
    – user19510
    Commented Jun 14, 2018 at 8:55

1 Answer 1

1

Here's a minimal contract that exhibits the problem:

pragma solidity ^0.4.24;

contract Test {
    mapping (uint128 => address[]) data;

    function addFeature() public {
        data[0] = new address[](0);
    }
}

You can verify that this is the issue you're having by getting rid of the address[] field from FeatureData and checking whether you still get an infinite gas estimate.

I believe the issue is that the static analysis isn't sophisticated enough to know that the array you're copying is always length 0. It just sees that an array needs to be copied from memory to storage and fails to make a good gas estimate.

That said, the simple code above has a roughly fixed gas cost, so the warning is safe to ignore. If you verify the same issue is causing the warning in your code, I believe it's safe for you to ignore too.

If you want to get rid of the warning, you could write this code instead. I suspect this is more gas efficient anyway:

FeatureData storage featureData = data[key];
featureData.state = State.Deployment;
featureData.backers.length = 0;
featureData.raised = 0;
featureData.prepaid = 0;
1
  • i believe "static analysis isn't sophisticated enough" is the answer and it's false positive in my case. @smarx thanks a lot for the purified code example
    – 4ntoine
    Commented Jun 14, 2018 at 10:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.