Skip to content

seismic-web3: smart transparent reads silently drop value and gas options #299

Description

@Kewe63

Summary

ShieldedContract.read.<function>() accepts documented value and gas options. For functions without shielded inputs, smart routing selects transparent eth_call, but the sync and async branches forward only to and data. Explicit call context is silently replaced by provider defaults.

Affected commit and files

Commit: d99e46cdc2d7ec8c049452ba72127f0540582f53

Expected behavior

A transparent smart read invoked with value=9, gas=0 should pass both explicit values in the transaction dictionary supplied to Web3.eth.call / AsyncWeb3.eth.call. A valid zero must not be treated as absent.

Actual behavior

Both branches send only:

{"to": self._address, "data": data}

The call itself returns, but inspection of the actual request raises KeyError: 'value'; gas is absent as well.

Minimal local regressions

def test_smart_transparent_read_forwards_value_and_gas() -> None:
    w3 = MagicMock()
    w3.eth.call.return_value = encode(["uint256"], [7])
    contract = ShieldedContract(w3, MagicMock(), MagicMock(), ADDRESS, ABI)

    assert contract.read.quote(value=9, gas=0) == 7
    request = w3.eth.call.call_args.args[0]
    assert request["value"] == 9
    assert request["gas"] == 0

The audit file contains the equivalent async regression using AsyncMock.

Test command and observed output

uv run pytest \
  tests/test_contract_audit_regressions.py::test_smart_transparent_read_forwards_value_and_gas \
  tests/test_contract_audit_regressions.py::test_async_smart_transparent_read_forwards_value_and_gas \
  -vv

Observed: both tests failed with KeyError: 'value'. The explicit gas=0 field was also absent.

Root cause

The smart read signatures collect value and gas, but each transparent branch constructs a new request containing only the address and calldata instead of forwarding those options.

User impact

Payable/view simulations and gas-constrained calls can execute under a different call context than requested without warning. Sync and async users see the same behavior.

Duplicate-check evidence

No issue, PR, discussion comment, or review comment reports this Python option loss. PR #144 introduced the branches. Open PR #296 also touches shielded.py, but only passes positional arguments into overload routing and decoding; it leaves both transparent eth.call request dictionaries unchanged. The TypeScript smart transparent path forwards the complete read parameters. PR #176 separately documents why Seismic-only security overrides should not be treated as transparent call options; this report is limited to value and gas.

Suggested fix direction

Include value and gas in the sync and async transparent eth_call transaction dictionaries without truthiness filtering, and add paired regressions including gas=0. Clarify the route-dependent security API separately rather than forwarding it to a standard transparent call.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions