in _executeTransaction
there is particular code block, which is using call
method to send ether to target. However zksync era do not support passing native ether as of now.
In _executeTransaction
function, when to != DEPLOYER_SYSTEM_CONTRACT
, it call the target with provided eth value
and data like how it's done on ethereum. As we can see highlighted code below.
However call
is not same as it works on ethereum
. As per ZksyncEra Docs ,
There is no native support for Ether transfers within the call function.
Ether transfers are managed by a special system contract called MsgValueSimulator.
MsgValueSimulator receives the address of the callee and the Ether amount, performs the necessary balance changes, and then calls the callee.
call
is handledWhen using call(gas(), target, value, in, insize, out, outsize)
, the EVM will allocate memory up to out + outsize
regardless of the actual size of - the returned data (returndatasize).
This allocation happens before the call is made.
If outsize is non-zero, the memory growth occurs immediately.
zkSync Era performs memory allocation for return data only after the call ends.
Instead of pre-allocating memory, zkSync Era copies the return data with additional checks to ensure that out + outsize
does not exceed returndatasize
.
This means msize()
(memory size) differs between zkSync Era and EVM during the call, and zkSync Era might not trigger a panic in scenarios where EVM would, due to the difference in memory growth timing.
Unexpected behaviour of call on zksync could lead to failed txs, eth loss etc.
Manual Review
update the code as shown below to fix the issue.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.