You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Zellic finding 3.13 (Low). Warnings 10306/10307 are best-effort developer safety nets flagging msg.value/msg.data stored into a shielded type. Two gaps weaken them:
Tuple member/index targets. The tuple branch of visit(Assignment) called checkMsgValueToShielded only when the LHS component was an Identifier, so (s.priv, x) = (suint256(msg.value), 0) (MemberAccess) and (arr[0], x) = ... (IndexAccess) were silent.
Helper-call launder.checkMsgValueToShielded recursed only through TypeConversion nodes, so secret = wrap(msg.value) (a real call whose param is public uint256) was silent — and the call-site check does not fire either because it only triggers on a shielded parameter.
Fix
Drop the Identifier-only gate in the tuple branch; fire for every component whose resolved type is shielded (checkMsgValueToShielded self-guards on target type).
In checkMsgValueToShielded, additionally recurse into a real call's positional arguments whose parameter is public. Shielded-parameter arguments are still covered by the call-site check, so no double warning.
Guard against TupleType targets (nested-tuple LHS components): TupleType::containsShieldedType() is unimplemented, and those components are decomposed/checked individually anyway.
Tests
msg_value_tuple_shielded_target.sol (10306 x3: member, index, identifier) and msg_value_helper_launder.sol (10306 x3: launder, direct, shielded-param). Full syntax suite passes; no regressions. Warning-only, no codegen change.
With ssolc --evm-version mercury --bin, the positional call emits 10306, while the named call compiles without that warning.
The helper recursion in checkMsgValueToShielded is currently gated by funcCall->names().empty(). The general function-call checker already maps named arguments back to parameter positions, so a narrow follow-up could preserve the same public-parameter rule while applying it to both call forms.
Would a focused PR covering the named form, the existing positional behavior, and the no-double-warning shielded-parameter case be useful here?
Activity
Osraka commentedon Aug 25, 2026
Follow-up after #371 landed via #398: current
seismic(e0eb91ec8) still misses the named-argument form of the helper-launder case.Minimal reproducer:
With
ssolc --evm-version mercury --bin, the positional call emits 10306, while the named call compiles without that warning.The helper recursion in
checkMsgValueToShieldedis currently gated byfuncCall->names().empty(). The general function-call checker already maps named arguments back to parameter positions, so a narrow follow-up could preserve the same public-parameter rule while applying it to both call forms.Would a focused PR covering the named form, the existing positional behavior, and the no-double-warning shielded-parameter case be useful here?