0

This is probably a simple problem to fix, but it is very frustrating.

I am developing in Solidity using Remix 0.5.10.

I have a loan contract that collects funds from borrowers. I now want to collect those funds and pass them through to the portfolio which owns those loans. The code is as follows:

        function passThrough() payable public
        {
        address(portfolio).transfer(address(this).balance);
        }

The error I get is:

**Gas Estimation Fail**
Gas estimation errored with the following message (see below). 
The transaction execution will likely fail. Do you want to force sending?
Internal JSON-RPC error.

If I do press Send Anyway, I get the following error:

enter image description here

I would have thought that gas will just be taken from the amount sent correct? Or do I need to reduce the amount snet by the estimated amount of gas explicitly?

@Ismael: Regarding your question, yes Portfolio is a contract and it has a fallback function which is as follows:

function () payable external {
    // fallback function to receive funds
    received = msg.value;
    availableFunds += received;
    } // function () payable external {

After trying Ismael's suggestion, I have changed the call as follows:

    address(portfolio).call.gas(100000).value(address(this).balance);

I also tried:

    address(portfolio).call.value(address(this).balance).gas(100000)("");

Neither worked. They do not throw up an error, however, for some reason the funds are not transferred. Now I am really confused. I understand the point about not enough gas, but with that solved and the transaction completing succesfully, why is the value not also sent? I did check to make sure that there was a balance to send, by the way!

I really appreciate your feedback. Thanks.

Philip Rutovitz
  • 525
  • 4
  • 25
  • Is portfolio a contract? Does it have defined the fallback function? – Ismael Jul 19 '19 at 03:30
  • Yes. Please see above. I added the Portfolio fallback function. – Philip Rutovitz Jul 20 '19 at 13:59
  • For security transfer only send 2300 gas to execute the fallback, if your fallback modify the contract's state it will fail. See here how to send more gas https://ethereum.stackexchange.com/questions/2876/how-does-one-contract-send-ether-to-another-contract-with-more-than-2300-gas – Ismael Jul 20 '19 at 17:39
  • Thanks. That makes sense. I will try to increase the amount of gas, but to how much? 200000 as in the example you mention? How do I work that out? – Philip Rutovitz Jul 20 '19 at 18:05
  • You can call portfolio's fallback from remix and you will get gas usage. Web3 has an api call estimateGas to measure such thing if you cannot use remix functionality or you want to do it yourself. – Ismael Jul 20 '19 at 19:22
  • @Ismael - thanks for the tips. However, I edited the question above. Even though I changed my trasnfer statement to a call and specified the amount of gas, it does not actually transfer the ether. The transaction goes through and is confirmed without error. Any idea what could be happening? – Philip Rutovitz Jul 22 '19 at 06:44

3 Answers3

1

I don't know why your contract is failing but the following snippet works in remix. I've changed to use gasleft() instead of hardcoding a default value.

pragma solidity >=0.4.22 <0.6.0;

contract Back {
    uint availableFunds;

    event Received(uint);

    function () external payable {
        uint received = msg.value;
        availableFunds += received;
        emit Received(received);
    }

    function total() public view returns (uint) {
        return address(this).balance;
    }
}


contract Front {
    Back public back;

    event Created(address);
    event Received(uint);

    constructor() public {
        back = new Back();
        emit Created(address(back));
    }

    function () external payable {
        emit Received(msg.value);
    }

    function forward() public payable {
        address(back).call.value(address(this).balance).gas(gasleft())("");
    }

    function total() public view returns (uint) {
        return address(this).balance;
    }
}
Ismael
  • 30,570
  • 21
  • 53
  • 96
  • Thank-you so much Ismael. I tried using your gasleft() solution but could ot get it to work. I did solve it though - please see my answer. Thanks again! – Philip Rutovitz Aug 03 '19 at 09:51
1

So I finally figured it out. Thanks to all of you for your contributions! I really appreciate it. I figured out a really simple solution that works well and requires less gas.

I added a function receiveFunds to the Portfolio contract:

function receiveFunds() public payable {
    // function to receive funds
    received = msg.value;
    availableFunds += received;
} // function receiveFunds() public payable {

Then in the Loan contract I used the following call:

function passThrough() payable public
    {
    // Passthrough funds
    portfolio.receiveFunds.value(address(this).balance)();
    }

This worked perfectly. The remaining question is why this works whereas the call function did not. I would be very interested in any ideas why!

Thanks again to everyone who helped!

Philip Rutovitz
  • 525
  • 4
  • 25
0

I think It's only warning from Remix IDE due to it cannot perform estimated gas properly because EVM don't know what is in address of portfolio. If it's smart contract then the gas used will be difference because smart contract can have fallback function to do other things also.

enter image description here

You still can force send the tnx by clicking on Send Transaction button.

Tony Dang
  • 2,151
  • 2
  • 9
  • 16