@@ -263,12 +263,14 @@ func (cvm *CVM) Call(caller common.Address, addr common.Address, input []byte, g
263263 if cvm .depth > int (params .CallCreateDepth ) {
264264 return nil , gas , nil , ErrDepth
265265 }
266+ syscall := isSystemCall (caller )
266267 // Fail if we're trying to transfer more than the available balance
267- if value .Sign () != 0 && ! cvm .Context .CanTransfer (cvm .StateDB , caller , value ) {
268+ if ! syscall && value .Sign () != 0 && ! cvm .Context .CanTransfer (cvm .StateDB , caller , value ) {
268269 return nil , gas , nil , ErrInsufficientBalance
269270 }
270271 snapshot := cvm .StateDB .Snapshot ()
271272 p , isPrecompile := cvm .precompile (addr )
273+
272274 debug := cvm .Config ().Tracer != nil
273275
274276 if ! cvm .StateDB .Exist (addr ) {
@@ -287,7 +289,12 @@ func (cvm *CVM) Call(caller common.Address, addr common.Address, input []byte, g
287289 }
288290 cvm .StateDB .CreateAccount (addr )
289291 }
290- cvm .Context .Transfer (cvm .StateDB , caller , addr , value )
292+ // Perform the value transfer only in non-syscall mode.
293+ // Calling this is required even for zero-value transfers,
294+ // to ensure the state clearing mechanism is applied.
295+ if ! syscall {
296+ cvm .Context .Transfer (cvm .StateDB , caller , addr , value )
297+ }
291298
292299 // Capture the tracer start/end events in debug mode
293300 if debug {
0 commit comments