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.
Summary
ShieldedContract.read.<function>()accepts documentedvalueandgasoptions. For functions without shielded inputs, smart routing selects transparenteth_call, but the sync and async branches forward onlytoanddata. Explicit call context is silently replaced by provider defaults.Affected commit and files
Commit:
d99e46cdc2d7ec8c049452ba72127f0540582f53clients/py/src/seismic_web3/contract/shielded.py#L331-L375clients/py/src/seismic_web3/contract/shielded.py#L664-L708docs/gitbook/clients/python/contract/namespaces/read.md#L61-L69Expected behavior
A transparent smart read invoked with
value=9, gas=0should pass both explicit values in the transaction dictionary supplied toWeb3.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';gasis absent as well.Minimal local regressions
The audit file contains the equivalent async regression using
AsyncMock.Test command and observed output
Observed: both tests failed with
KeyError: 'value'. The explicitgas=0field was also absent.Root cause
The smart read signatures collect
valueandgas, 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 transparenteth.callrequest 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 tovalueandgas.Suggested fix direction
Include
valueandgasin the sync and async transparenteth_calltransaction dictionaries without truthiness filtering, and add paired regressions includinggas=0. Clarify the route-dependentsecurityAPI separately rather than forwarding it to a standard transparent call.