1

When I call the function fun inside the contract D, I expect the Logs to be "D.foo" -> "C.foo" -> "A.foo" -> "B.foo" -> "A.foo". However, the actual logs are "D.foo" -> "C.foo" -> "B.foo" -> "A.foo".

Why is the function fun inside the contract A only called once when the function fun both inside the contracts B and C calls it?

I am guessing Solidity follows the order of inheritance and goes one level up only when all the contracts from the same level have been called.

event Log(string message);

contract A {
    function fun() public virtual {
        emit Log("A.foo");
    }
}   

contract B is A {
    function fun() public  virtual override {
        emit Log("B.foo");
        super.fun();
    }
}

contract C is A {
    function fun() public virtual override {
        emit Log("C.foo");
        super.fun();
    }
}

contract D is B, C {
    function fun() public override(B, C) {
        emit Log("D.foo");
        super.fun();
    }
}
1
  • I think bases who shared a common ancestor, share the same memory, they enumerate the inheritance graph in super, and not evaluate the actual structure of each inherited class
    – johnny 5
    Commented Apr 29 at 15:53

1 Answer 1

0

That's due to the fact that Solidity follows C3 linearization algorithm. This algorithm determines the order in which base contracts are called to ensure that each contract is called only once, preserving the order of inheritance.

It is explained in-depth in this article.

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.