Trying to understand how inheritance and super works


Let's say I have a contract that inherits from both ERC20Pausable and ERC20Capped, which both override _update.
How can I ensure in my _update override that both parents _update function is being called.
If I just call super._update, will that ensure both are going to be called and what if the order matters?

Thank you for advance.

1 Like

In Solidity, when dealing with multiple inheritance where more than one parent contract overrides the same function, it's important to explicitly manage the order in which these overridden functions are called. This is particularly relevant for your scenario, where you have a contract inheriting from both ERC20Pausable and ERC20Capped, and both of these parent contracts override the _update function.

When you use super._update() in your contract, Solidity attempts to call the most derived function in the inheritance hierarchy that is to the right of the current contract. This means if you have not explicitly specified the order of inheritance, only one of the parent contract's _update functions might be called, not both. The order in which contracts are listed in the inheritance list matters significantly.

Here's a general approach to ensure both parent functions are called, and you can control the order:

  1. Explicit Inheritance Order: In Solidity, the order of inheritance is from right to left. You need to specify the parent contracts in the order you want them to be called, considering the rightmost parent gets priority.
contract MyContract is ERC20Capped, ERC20Pausable {
    // Your contract code here

In this example, ERC20Pausable is more to the right, so if you call super._update(), it will call ERC20Pausable._update() first. But, this alone doesn't ensure ERC20Capped._update() is also called.

  1. Explicitly Call Parent Functions: Instead of relying on super, explicitly call the parent functions by their contract names. This way, you have full control over which function is called and in what order.
function _update() internal override(ERC20Capped, ERC20Pausable) {
    // Your additional logic here

By explicitly calling each parent's _update function, you ensure that both functions are called, and you control the order in which they are executed. Remember, this approach requires that you understand the implications of the order in which these functions are called, as it can affect the behavior of your contract.

It's also crucial to declare your function with the override keyword and specify all the parent contracts that have the _update function you're overriding. This makes your intent explicit and helps with readability and maintainability of your code.

1 Like