From 213a7e160c28661de711283134b0dce8d6e6917a Mon Sep 17 00:00:00 2001 From: pragmaxim Date: Tue, 10 Feb 2026 12:54:00 +0100 Subject: [PATCH] zero existing erc20 balances --- db/rocksdb_ethereumtype.go | 10 ++++++++-- db/rocksdb_ethereumtype_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/db/rocksdb_ethereumtype.go b/db/rocksdb_ethereumtype.go index 2e0d8152..bb3ca82b 100644 --- a/db/rocksdb_ethereumtype.go +++ b/db/rocksdb_ethereumtype.go @@ -419,8 +419,14 @@ func addToContract(c *unpackedAddrContract, contractIndex int, index int32, cont } if transfer.Standard == bchain.FungibleToken { // Skip ERC20 balance aggregation; ensure a zero value is available for packing. - if c.Value.Value == nil && len(c.Value.Slice) == 0 { - c.Value.Value = big.NewInt(0) + if c.Value.Value == nil { // no decoded bigint yet; normalize before first use + if len(c.Value.Slice) != 0 { // packed value exists; drop it so we don't re-pack stale data + c.Value.Slice = nil + } + c.Value.Value = new(big.Int) // initialize zero value + } else if len(c.Value.Slice) != 0 || c.Value.Value.Sign() != 0 { // packed or non-zero decoded value present; force zero + c.Value.Slice = nil + c.Value.Value.SetUint64(0) } } else if transfer.Standard == bchain.NonFungibleToken { if index < 0 { diff --git a/db/rocksdb_ethereumtype_test.go b/db/rocksdb_ethereumtype_test.go index 8d279714..2057daa7 100644 --- a/db/rocksdb_ethereumtype_test.go +++ b/db/rocksdb_ethereumtype_test.go @@ -1435,6 +1435,39 @@ func Test_addToContracts(t *testing.T) { } } +func Test_addToContract_ERC20ZeroesExistingValue(t *testing.T) { + transfer := &bchain.TokenTransfer{ + Standard: bchain.FungibleToken, + Value: *big.NewInt(1), + } + + c := &unpackedAddrContract{ + Standard: bchain.FungibleToken, + Contract: makeTestAddrDesc(123), + Value: unpackedBigInt{Value: big.NewInt(123456)}, + } + addToContract(c, 0, 1, c.Contract, transfer, false) + if c.Value.Value == nil || c.Value.Value.Sign() != 0 { + t.Fatalf("expected ERC20 value to be zeroed, got %v", c.Value.Value) + } + if len(c.Value.Slice) != 0 { + t.Fatalf("expected ERC20 packed slice to be cleared, got %d bytes", len(c.Value.Slice)) + } + + c = &unpackedAddrContract{ + Standard: bchain.FungibleToken, + Contract: makeTestAddrDesc(124), + Value: unpackedBigInt{Slice: []byte{0x1, 0x2}}, + } + addToContract(c, 0, 1, c.Contract, transfer, false) + if c.Value.Value == nil || c.Value.Value.Sign() != 0 { + t.Fatalf("expected ERC20 value to be zeroed after slice, got %v", c.Value.Value) + } + if len(c.Value.Slice) != 0 { + t.Fatalf("expected ERC20 packed slice to be cleared, got %d bytes", len(c.Value.Slice)) + } +} + func Test_packUnpackBlockTx(t *testing.T) { parser := ethereumTestnetParser() tests := []struct {