Below is my smart contract. Remix gives warnings on each of the following functions:

Gas requirement of function MedicalRecord.addNote(bytes32,bytes32) high: infinite.
Gas requirement of function Voting.allCandidates() high: infinite.
Gas requirement of function  Voting.indexOfCandidate(bytes32)  high: infinite.
Gas requirement of function Voting.transferBalance()  high: infinite.
Gas requirement of function Voting.voteForCandidate(bytes32,uint256) high: infinite. 

Here is smart contract code:

pragma solidity ^0.4.23;

contract Voting {
  bytes32[] public candidateList;
  uint public totalTokens;
  uint public balanceTokens;
  uint public tokenPrice;

  address public owner;

  struct voter {
    address voterAddress;
     uint tokensBought;
     uint[] tokensUsedPerCandidate;

  mapping(address => voter) public voterInfo;
  mapping(bytes32 => uint) public votesReceived;

  constructor(uint _totalTokens, uint _tokenPrice, bytes32[] 
    _candidateNames) public {
    totalTokens = _totalTokens;
    balanceTokens = _totalTokens;
    tokenPrice = _tokenPrice;
    candidateList = _candidateNames;
    owner = msg.sender;

  function transferBalance() public {

  function buy() payable public {
    uint tokensToBuy = msg.value / tokenPrice;
    require(tokensToBuy <= balanceTokens);
    voterInfo[msg.sender].voterAddress = msg.sender;
    voterInfo[msg.sender].tokensBought += tokensToBuy;
    balanceTokens -= tokensToBuy;

  function voteForCandidate(bytes32 candidate, uint tokens) public {
    // Check to make sure user has enough tokens to vote
    // Increment vote count for candidate
    // Update the voter struct tokensUsedPerCandidate for this voter

    uint availableTokens = voterInfo[msg.sender].tokensBought - 

    require(tokens <= availableTokens, "You don't have enough tokens");
    votesReceived[candidate] += tokens;

    if(voterInfo[msg.sender].tokensUsedPerCandidate.length == 0) {
      for(uint i=0; i<candidateList.length; i++) {

    uint index = indexOfCandidate(candidate);
    voterInfo[msg.sender].tokensUsedPerCandidate[index] += tokens;

  function indexOfCandidate(bytes32 candidate) view public returns(uint) 
    for(uint i=0; i<candidateList.length; i++) {
      if (candidateList[i] == candidate) {
        return i;
    return uint(-1);

  function totalTokensUsed(uint[] _tokensUsedPerCandidate) private pure 
  returns (uint) {
    uint totalUsedTokens = 0;
    for(uint i=0; i<_tokensUsedPerCandidate.length; i++) {
      totalUsedTokens += _tokensUsedPerCandidate[i];
    return totalUsedTokens;

  function voterDetails(address user) view public returns (uint, uint[]) 
    return (voterInfo[user].tokensBought, 

  function tokensSold() public view returns (uint) {
    return totalTokens - balanceTokens;

  function allCandidates() public view returns (bytes32[]) {
    return candidateList;

  function totalVotesFor(bytes32 candidate) public view returns (uint) {
    return votesReceived[candidate];

The contract is deployed on ropsten testnet, voteForCandidate fails during contract execution.


The warnings are because you have a variable-length array that you're returning or looping over. (For transferBalance, it's just because you're calling transfer, and there's no way for the compiler to know how much gas the recipient will use in their fallback function.)

You could make indexOfCandidate constant time by using a mapping. Otherwise, as long as you know there's some reasonable upper bound on the length of candidateList, you can ignore these warnings.

As to why voteForCandidate is failing, we'd need a lot more information to debug (like what the state of the contract is, what parameters you passed, etc.).

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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