> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://www.getfoundry.sh/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

## State variable read via `this`

**Severity**: `Gas`
**ID**: `var-read-using-this`

### What it does

Reports calls through `this` to the contract's own public variable getters and `view`
or `pure` functions, including inherited functions.

Read state directly where possible: use `foo` instead of `this.foo()`, or `m[k]` instead
of `this.m(k)`. Check that the replacement preserves the getter's return value and any
intentional external-call behavior.

### Why is this bad?

Each `this.X(...)` call compiles to a `STATICCALL` to the contract's own address. That costs a
fixed amount of gas, plus the encoding/decoding of arguments and return data, in addition to the
storage read itself. Reading the variable directly skips the call entirely.

### Example

```solidity
contract C {
    uint256 public counter;
    mapping(uint256 => address) public owners;

    function readDirect() external view returns (uint256, address) {
        // Each `this.X` performs an unnecessary STATICCALL.
        return (this.counter(), this.owners(0));
    }
}
```

Use instead:

```solidity
contract C {
    uint256 public counter;
    mapping(uint256 => address) public owners;

    function readDirect() external view returns (uint256, address) {
        // Direct storage reads — no external call.
        return (counter, owners[0]);
    }
}
```

For `external view`/`pure` functions, calling them via `this` from inside the contract is the
only in-contract syntax that resolves; the recommended fix is to extract the body into an
`internal` helper that both the `external` entry point and the local caller invoke.
