@@ -250,13 +250,14 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
250250 if evm .depth > int (params .CallCreateDepth ) {
251251 return nil , gas , ErrDepth
252252 }
253- // Fail if we're trying to transfer more than the available balance
254- if ! value .IsZero () && ! evm .Context .CanTransfer (evm .StateDB , caller , value ) {
253+ syscall := isSystemCall (caller )
254+
255+ // Fail if we're trying to transfer more than the available balance.
256+ if ! syscall && ! value .IsZero () && ! evm .Context .CanTransfer (evm .StateDB , caller , value ) {
255257 return nil , gas , ErrInsufficientBalance
256258 }
257259 snapshot := evm .StateDB .Snapshot ()
258260 p , isPrecompile := evm .precompile (addr )
259-
260261 if ! evm .StateDB .Exist (addr ) {
261262 if ! isPrecompile && evm .chainRules .IsEIP4762 && ! isSystemCall (caller ) {
262263 // Add proof of absence to witness
@@ -280,8 +281,11 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
280281 }
281282 evm .StateDB .CreateAccount (addr )
282283 }
283- evm .Context .Transfer (evm .StateDB , caller , addr , value )
284-
284+ // Perform the value transfer in non-syscall mode. This is essential for zero-value
285+ // transfers to ensure the clearing mechanism is applied.
286+ if ! syscall {
287+ evm .Context .Transfer (evm .StateDB , caller , addr , value )
288+ }
285289 if isPrecompile {
286290 ret , gas , err = RunPrecompiledContract (p , input , gas , evm .Config .Tracer )
287291 } else {
@@ -307,7 +311,6 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
307311 if evm .Config .Tracer != nil && evm .Config .Tracer .OnGasChange != nil {
308312 evm .Config .Tracer .OnGasChange (gas , 0 , tracing .GasChangeCallFailedExecution )
309313 }
310-
311314 gas = 0
312315 }
313316 // TODO: consider clearing up unused snapshots:
0 commit comments