0

I am building an approval contract in Remix and have been stuck on this issue.

When I try to transfer wei using address.transfer(value), it throws an error. I have marked it in the code below.

Maybe the error is related to the struct Request declared in the constructor because remix debugger ends there when .transfer() fails, I couldn't find an explaination though.

pragma solidity ^0.4.17;

 contract Campaign {
     struct Request {
         string description;
         uint32 value;
         address recipient;
         bool complete;
         uint approvalCount;
         mapping(address => bool) approvals;
     }

     Request[] public requests;
     address public manager;
     uint32 public minimumContribution;
    //  tutorial uses 'approvers' not 'contributors'
     mapping(address => bool) public contributors;
     uint32 public contributorCount;

     modifier restricted {
         require(msg.sender == manager );
        _;
     }


     constructor(uint32 minimum) public {
         manager = msg.sender;
         minimumContribution = minimum;
     }

     function contribute() public payable{
         require(msg.value > minimumContribution);

         contributors[msg.sender] = true; // because contributor is 
         contributorCount++;
     }

     function createRequest(string description, uint32 value, address recipient) 
        public restricted {
         Request memory newRequest = Request({
            description: description, 
            value: value, 
            recipient: recipient, 
            complete: false,
            approvalCount: 0
         });

         requests.push(newRequest);
     }

     function approveRequest(uint16 index) public {
         Request storage r = requests[index];

         // make sure the address has contributed, but has not approved this one yet
         require(contributors[msg.sender]); 
         require(!r.approvals[msg.sender]);

         r.approvals[msg.sender] = true;
         r.approvalCount++;
     }

     function finalizeRequest(uint16 index) public restricted {
         Request storage r = requests[index];

         // make sure more than 50% of contributors approved this request
         require(r.approvalCount > (contributorCount / 2));
         //make sure that this request has not been completed before
         require(!r.complete);

         // FAILS ON THIS LINE. Remix debugger goes through this line then ends on line 3 of the contract, in the constructor function. 
         r.recipient.transfer(r.value);


         // mark this request as completed
         r.complete = true;
     }

 }

Note the after failing on .transfer(), the debugger jumps up to the constructor function, where struct Request {...} is created. (is this where the problem lies?)

I thought it could be the function .transfer() was being called in, so I attempted to isolate the transfer by calling it in a separate function, but it stilled failed the same way.

Not sure if it helps but the address I input ( the address inaddress.transfer() ) is copied from one of the spare addresses that remix creates in javascriptVM.

  • 1
    If you comment out the line r.recipient.transfer(r.value), does the function succeed? If so, my guess would be that r.value is greater than the contract's balance. – user19510 Jun 2 '18 at 5:16
  • 1
    Perhaps try r.recipient.transfer(address(this).balance); to confirm. – user19510 Jun 2 '18 at 5:17
  • You are right @smarx. It passes when using address(this).balance. – Finn Rothacker Jun 3 '18 at 6:47
  • I will add another require(); ensuring that that r.value is less than the contract balance. – Finn Rothacker Jun 3 '18 at 6:49
0

The amount of wei specified by r.value was more than is held in the contract. I added a line to my contract to make sure contract contains enough money:

require(address(this).balance > r.value);

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.