0

I have 3 solidity contracts, main.sol, provider.sol and allowance.sol

Now from main.sol, I am calling a function "Transact", which calls another function "Transact" in provider.sol (there's a Transact function in main and one in provider).

I'm using remix ide. Now, from the deploy and run transactions tab, I call the Transact function of main.sol, it throws an error saying:

revert
    The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.

but when I call the Transact function of provider.sol directly, it runs without any errors! and the transfer of eth goes through!

Any idea why this is happening?

Here are both the transact functions for reference:

From main.sol

    function Transact(address _recipientAddress, uint256 _amount, address _behalfAddress) external payable {

        Receivers memory receiver = receivers[_behalfAddress];
        address providerAddress = receiver.ProviderAddress;
        address allowanceContractAddress = receiver.contractAddress;

        require(allowanceContractAddress != address(0), "Allowance contract not found");

        ProviderContract providerContractInstance = ProviderContract(payable(providerAddress));
        AllowanceContract allowanceContractInstance = AllowanceContract(allowanceContractAddress);

        allowanceContractInstance.Transact(_amount);

        // Call the Transact function of the ProviderContract to make the payment
        // THIS IS THE LINE THE ERROR IS COMING IN (FOUND IN DEBUGGING)
        providerContractInstance.Transact(_recipientAddress, _amount, _behalfAddress);
    }

From Provider.sol:

    function Transact(address _recipient, uint _amount, address _benefactorAddress) external payable {
        string memory behalfName = benefactors[_benefactorAddress];

        Transaction memory newTransaction = Transaction({
            amount: _amount,
            recipient: _recipient,
            timestamp: block.timestamp,
            behalf: behalfName
        });

        transactions.push(newTransaction);

        for (uint i = 0; i < allowances.length; i++) {
            if (allowances[i].walletAddress == _recipient) {
                allowances[i].allowanceSpent += _amount;
                break;
            }
        }

        address _recipientaddress = _recipient;

        bytes memory rand;
        (bool sent, bytes memory data) = payable(_recipientaddress).call{value: _amount}("");
        require(sent, "Failed to send Ether");
        rand = data;
    }

Please note that I am not sending any ether as value while calling the functions. I want the provider.sol contract to use it's own balance (Balance in the contract address) and I am making sure that the contract balance is sufficient. (As I mentioned, the functionality is working when I directly call provider.sol's Transact Function)

6
  • I've created this gist. Can you please confirm if this is the minimum reproducible code as per your problem ? Commented Apr 18 at 7:57
  • But using this gist's code, I was able to successfully execute the Transact() function of Main contract, provided that the Provider contract has sufficient ETH balance (i.e., >= _amount). Can you please confirm by trying on your end ? Commented Apr 18 at 7:58
  • @SYEDASADKAZMI I don't think this is the minimum reproducible code. Main is a contract that is deployed once, and it deploys a Provider contract everytime a provider is registered. Now, while calling the function, I have sufficient balance in the Provider contract, but not in the main contract. Does this have an effect? Maybe that is why the transaction goes through when I call it the provider function independently but not when I call it through the main function Commented Apr 18 at 20:01
  • Yeah, so the only thing that’s missing from that gist is the deployment of Provider contract whenever a provider is registered. Commented Apr 19 at 5:13
  • Rest, while testing, I funded the Provider contract, not the Main contract. And it worked fine. Commented Apr 19 at 5:15

1 Answer 1

0

I think the issue might be resolved by making the function you're calling non-payable Removing payable Keyword if you're not sending any value with it.

Also make sure Main contract have enough balance to cover the needs of that call.

1
  • Tried doing this, didn't work. Also for any kind of payment, to send value, don't you think the function needs to be payable? Commented Apr 18 at 19:53

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.