argotorg / argotorg/solidity

super can dispatch a pure/view function to a state-modifying implementation

Open
#16,930 0 comments 0 reactions 1 assignee Claimed by @msooseth View on GitHub
bug :bug:
Dominant language
C++
Stars
25.7k
Forks
6.2k
Avg merge
2d 19h
Merged PRs (30d)
29

Description

A `super.f()` call is type-checked against the candidate set of the contract
that lexically contains it, but resolved at code generation time over the
linearization of the most derived contract. Those are two different contract
lists, and state mutability is not among the properties re-checked during
resolution.

The result is that a function declared `pure` can execute an `SSTORE`. The
compiler reports no error and no warning, and the ABI still advertises the
function as `pure`.

## Reproducer

```solidity
contract A {
function f() public pure virtual returns (uint256) { return 1; }
}

contract X {
uint256 public s;
function f() public virtual returns (uint256) { s = 5; return 100; }
}

contract B is A {
function f() public pure virtual override returns (uint256) { return super.f(); }
}

contract D is A, X, B {
function f() public pure override(A, X, B) returns (uint256) { return super.f(); }
}
```

Compiles without an issue. Deploying `D` and calling it gives:

```
f() -> 100 // X.f ran, not A.f
s() -> 5 // a pure function wrote storage
```

`solc --abi` reports `"stateMutability": "pure"` for `D.f`.

With `view` instead of `pure` throughout, the same construction produces a
contract that cannot be used at all from a static context, since `view` is the
half of the guarantee the EVM enforces:

```solidity
contract Caller {
D d = new D();
function g() public view returns (uint256) { return d.f(); }
}
```

`D.f` is declared `view`, so the call compiles to `STATICCALL`, the `super`
chain lands on the storage-writing `X.f`, and `g()` reverts. Every external
view call to `D.f()` fails.

## Expected behaviour

A compile-time error on the joining contract.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.