1

I have a situation where my contract (C) inherits from two other contracts (A and B). Both of these base contracts have a function with the same name and parameters but different return types. Here's a simplified version of what I have:

contract A {
    function func(address a) internal view returns (uint64) {
        // Implementation returns a uint64 value
    }
}

contract B {
    function func(address a) internal view virtual returns (uint88) {
        // Implementation returns a uint88 value
    }
}

contract C is A, B {
    function func(address a) internal view override(A, B) returns (uint88) {
        // Intended to override and call B's version of func
        super.func(a);
    }
}

In contract C, I'm trying to override the func function and specifically call the version from contract B using super.func(a). However, the Solidity compiler is giving me an error:

TypeError: Overriding function return types differ.

How to handle this scenario?

2 Answers 2

0

Unfortunately, function return type mismatch is not allowed by design in Solidity (as in many languages, too).

There's no way you can override this function and make it work without making both parent contracts implement the same return type.

That has already been discussed in detail here: https://github.com/ethereum/solidity/issues/13390


That is because Solidity doesn't treat distinct return types as a type of function overloading, so it will just throw an error, assuming it's a mismatch (= mistake).


The best solutions here would be the following:

  • 1st case: remove the code related to the func method in either one of the parent contracts (A or B). Logically, you do not need both of them simultaneously, do you? That is because only one of them can be called with the super.func(a) expression in the child contract.
  • 2nd case: give the func in contract A a name different from the name of func in contract B; => then you can override the only parent function with the signature func in the child contract C (for example, the func that is in the parent contract B), and you can get the value from contract A's funcA (basically the same function, you can just prefix it to assign it a distinct signature) just like super.funcA(a), if you need it, and use it in the child contract func override (for example, for some kind of calculations, etc.)

You can confirm that it's the desired behavior here in this "test" example: https://github.com/ethereum/solidity/blob/7676ab1014b9fe6bd4314cb648ef790933992e7f/test/libsolidity/syntaxTests/nameAndTypeResolution/181_override_changes_return_types.sol#L5

Hopefully, that makes things more clear for you.


***** Make sure that if you go with the Solution №2, the funcA should not be virtual.

-1

The error occurred because in Solidity, when overriding a function, the return type must match exactly with the return type of the base function being overridden.

The func from contract A returns uint64 types values, but other from contract B returns uint88. So you need to match two types of returned values.

contract A {
    function func(address a) internal view virtual returns (uint64) {
        // Implementation returns a uint64 value
    }
}

contract B {
    function func(address a) internal view virtual returns (uint88) {
        // Implementation returns a uint88 value
    }
}

contract C is A, B {
     function func(address a) internal view override(A,B) returns (uint88) {
        // Intended to override and call B's version of func
        return B.func(a));
    }
}
1
  • Syntax errors and the answer is not completely correct.
    – DevCrypto
    Mar 5 at 12:03

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.