Accessing function/event/error selector defined in parent interface through a child interface
- Dominant language
- C++
- Stars
- 25.7k
- Forks
- 6.2k
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 29
Description
## Abstract
Consider the the following code
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface A {
function a() external;
}
interface B is A {
function b() external;
}
contract test {
bytes4 public selectorFromA = A.a.selector;
bytes4 public selectorFromB = B.a.selector;
}
```
By inheritance `B is A`, the function `a()` it part of both interfaces, and should be implemented by contract implementing either `A` or `B`. However, the compiler fails to identify `a()` as a member of `B`, and the declaration of `selectorFromB` is seen as invalid.
```
TypeError: Member "a" not found or not visible after argument-dependent lookup in type(contract B).
--> tester.sol:14:35:
|
14 | bytes4 public selectorFromB = B.a.selector;
| ^^^
```
This should be supported
## Motivation
Beyond this simple exemple, we can consider the case of `ISafe`
```
import {ISafe} from "@safe-global/safe-smart-account/contracts/interfaces/ISafe.sol";
```
It is composed of many "module" interfaces, such as `IOwnerManager`. It would be great to be able to refer to function inside `ISafe` without having to load, and refer to the actual module that hold them.
I would like to be able to do
```solidity
import {ISafe} from "@safe-global/safe-smart-account/contracts/interfaces/ISafe.sol";
//...
abi.encodeCall(ISafe.swapOwner, ...);
```
and not have to do
```solidity
import {ISafe, IOwnerManager} from "@safe-global/safe-smart-account/interfaces/ISafe.sol";
(or)
import {IOwnerManager} from "@safe-global/safe-smart-account/interfaces/IOwnerManager.sol";
// ...
abi.encodeCall(IOwnerManager.swapOwner, ...);
```
## Specification
When resolving function, event or errors from a contract (or interface) for getting their selector, support the items declared both the contract (or interface) and the one declared in its parents. Currently, items declared in parents are not available.
## Backwards Compatibility
In our example above, if `A` and `B` declare functions with the same name and different argument, the ambiguity will cause a resolution issue that does not exist today. While it is breaking, I don't think this is a bad change. There is an ambiguity, and it should be mentioned to the user that the name actually cary two (or more) functions with the same name.
Contributor guide
Research direction
Start by reproducing the provided A/B Solidity example and trace how member resolution handles selectorFromB. Check inherited function, event, and error selectors, including the specified ambiguity case; done when selectors can be accessed through child interfaces and ambiguous names produce a clear resolution error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- solidity
- Domain
- blockchain, compilers
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100