Solidity – How to Override Inherited Contracts with Same Method Name but Different Signatures

compilationcontract-developmentsolidity

I'm inheriting 2 abstract contracts having the same function name but slightly different signature.

These are the 2 base contracts:

abstract contract Base1 {
    function foo() internal view virtual returns (address) {
        return msg.sender;
    }
}

abstract contract Base2 {
    function foo() internal override virtual view returns (address payable ret) {
         return msg.sender;
    } 
}

My contract inherits from both of them and attempts to override the foo() method. Here, I will get an error because their signature is slightly different:

contract MyContract is Base1, Base2 {
    // This is going to have an error DeclarationError: Function with same name and parameter types defined twice.
    function foo() internal view override(Base1, Base2) returns (address payable) {
         return msg.sender;
    }
}

The above overriding will throw this error when compiled:

DeclarationError: Function with same name and parameter types defined twice.

How do I override in such a case where the inherited contracts from external packages that I don't have control over have the same methods in them but slightly different signatures?

Best Answer

It's not possible by design because address and address payable are different types and one is not implicitly convertible to the other (on purpose).

But it's easy to deal with. Just make your function return address as well and have the caller convert it to address payable.

The other functions that are out of your control and already call foo() are expecting a non-payable address so it's not a problem if they treat your address as such.

And your own functions that know they are dealing with your own contract and that it actually returns a payable address can convert the value to address payable. Alternatively you could add a helper that returns address payable just for them.