Repository: trustwallet/blockatlas
Pull request #1398 (2021-02-01 03:44:03)

[Vechain] Fix non gas token parsing
also fixes one bounce api typo

codecov[bot]: # [Codecov](https://codecov.io/gh/trustwallet/blockatlas/pull/1398?src=pr&el=h1) Report
> Merging [#1398](https://codecov.io/gh/trustwallet/blockatlas/pull/1398?src=pr&el=desc) (d290780) into [master](https://codecov.io/gh/trustwallet/blockatlas/commit/8dd3e775059bf3c9bb5978e7763657adb1113801?el=desc) (8dd3e77) will **decrease** coverage by `0%`.
> The diff coverage is `28%`.

[![Impacted file tree graph](https://codecov.io/gh/trustwallet/blockatlas/pull/1398/graphs/tree.svg?width=650&height=150&src=pr&token=jnrjoEQAqv)](https://codecov.io/gh/trustwallet/blockatlas/pull/1398?src=pr&el=tree)

```diff
@@          Coverage Diff           @@
##           master   #1398   +/-   ##
======================================
- Coverage      44%     44%   -1%     
======================================
  Files         147     147           
  Lines        4259    4280   +21     
======================================
- Hits         1892    1884    -8     
- Misses       2198    2223   +25     
- Partials      169     173    +4     
```


| [Impacted Files](https://codecov.io/gh/trustwallet/blockatlas/pull/1398?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [platform/ethereum/bounce/collection.go](https://codecov.io/gh/trustwallet/blockatlas/pull/1398/diff?src=pr&el=tree#diff-cGxhdGZvcm0vZXRoZXJldW0vYm91bmNlL2NvbGxlY3Rpb24uZ28=) | `25% <0%> (ø)` | |
| [platform/vechain/transaction.go](https://codecov.io/gh/trustwallet/blockatlas/pull/1398/diff?src=pr&el=tree#diff-cGxhdGZvcm0vdmVjaGFpbi90cmFuc2FjdGlvbi5nbw==) | `39% <30%> (-10%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/trustwallet/blockatlas/pull/1398?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/trustwallet/blockatlas/pull/1398?src=pr&el=footer). Last update [8dd3e77...d290780](https://codecov.io/gh/trustwallet/blockatlas/pull/1398?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/platform/ethereum/bounce/collection.go b/platform/ethereum/bounce/collection.go
index 6b6c450..db19252 100644
--- a/platform/ethereum/bounce/collection.go
+++ b/platform/ethereum/bounce/collection.go
@@ -92,11 +92,11 @@ func (c *Client) processCollectibles(collectibles []Collectible, coinIndex uint)
 		return types.CollectiblePage{}, nil
 	}
 	page := make(types.CollectiblePage, 0)
-	info, err := fetchTokenURI(collectibles[0].TokenURI)
-	if err != nil {
-		return nil, err
-	}
 	for _, c := range collectibles {
+		info, err := fetchTokenURI(c.TokenURI)
+		if err != nil {
+			return nil, err
+		}
 		normalized := normalizeCollectible(c, coinIndex, info)
 		page = append(page, normalized)
 	}
diff --git a/platform/vechain/transaction.go b/platform/vechain/transaction.go
index 2272bac..874a104 100644
--- a/platform/vechain/transaction.go
+++ b/platform/vechain/transaction.go
@@ -6,8 +6,10 @@ import (
 	"sync"
 
 	log "github.com/sirupsen/logrus"
+
 	"github.com/trustwallet/blockatlas/pkg/blockatlas"
 	"github.com/trustwallet/golibs/address"
+	"github.com/trustwallet/golibs/coin"
 	"github.com/trustwallet/golibs/numbers"
 	"github.com/trustwallet/golibs/types"
 )
@@ -72,7 +74,7 @@ func (p *Platform) getTransactionChannel(id string, txChan chan types.TxPage) er
 		return err
 	}
 
-	txs, err := p.NormalizeTokenTransaction(srcTx, receipt)
+	txs, err := NormalizeTokenTransaction(srcTx, receipt)
 	if err != nil {
 		return err
 	}
@@ -80,44 +82,14 @@ func (p *Platform) getTransactionChannel(id string, txChan chan types.TxPage) er
 	return nil
 }
 
-func (p *Platform) NormalizeTokenTransaction(srcTx Tx, receipt TxReceipt) (types.TxPage, error) {
-	txs := make(types.TxPage, 0)
-
-	fee, err := numbers.HexToDecimal(receipt.Paid)
-	if err != nil {
-		return txs, err
-	}
-
-	originSender, err := address.EIP55Checksum(blockatlas.GetValidParameter(srcTx.Origin, srcTx.Meta.TxOrigin))
-	if err != nil {
-		return txs, err
-	}
-
+func NormalizeTokenTransaction(srcTx Tx, receipt TxReceipt) (types.TxPage, error) {
+	// the only supported Token on VeChain is its Gas token
 	if receipt.Reverted {
-		var to string
-		if len(srcTx.Clauses) > 0 {
-			to = srcTx.Clauses[0].To
-			if checksumTo, err := address.EIP55Checksum(to); err == nil {
-				to = checksumTo
-			}
-		} else {
-			return txs, errors.New("NormalizeBlockTransaction: srcTx.Clauses not found: " + srcTx.Id)
-		}
-
-		txs = append(txs, types.Tx{
-			ID:     srcTx.Id,
-			Coin:   p.Coin().ID,
-			From:   originSender,
-			To:     to,
-			Fee:    types.Amount(fee),
-			Date:   srcTx.Meta.BlockTimestamp,
-			Type:   types.TxTokenTransfer,
-			Block:  srcTx.Meta.BlockNumber,
-			Status: types.StatusError,
-		})
-		return txs, nil
+		return normalizeRevertedTokenTransaction(srcTx, receipt)
 	}
 
+	txs := make(types.TxPage, 0)
+
 	if receipt.Outputs == nil || len(receipt.Outputs) == 0 {
 		return types.TxPage{}, errors.New("NormalizeBlockTransaction: receipt.Outputs not found: " + srcTx.Id)
 	}
@@ -126,7 +98,19 @@ func (p *Platform) NormalizeTokenTransaction(srcTx Tx, receipt TxReceipt) (types
 		if len(output.Events) == 0 || len(output.Events[0].Topics) < 3 {
 			continue
 		}
+
+		fee, err := numbers.HexToDecimal(receipt.Paid)
+		if err != nil {
+			return txs, err
+		}
+
+		originSender, err := address.EIP55Checksum(blockatlas.GetValidParameter(srcTx.Origin, srcTx.Meta.TxOrigin))
+		if err != nil {
+			return txs, err
+		}
+
 		event := output.Events[0]
+
 		value, err := numbers.HexToDecimal(event.Data)
 		if err != nil {
 			continue
@@ -137,6 +121,10 @@ func (p *Platform) NormalizeTokenTransaction(srcTx Tx, receipt TxReceipt) (types
 			continue
 		}
 
+		if originReceiver != gasTokenAddress {
+			continue
+		}
+
 		topicsTo, err := address.EIP55Checksum(getRecipientAddress(event.Topics[2]))
 		if err != nil {
 			continue
@@ -144,7 +132,7 @@ func (p *Platform) NormalizeTokenTransaction(srcTx Tx, receipt TxReceipt) (types
 
 		txs = append(txs, types.Tx{
 			ID:     srcTx.Id,
-			Coin:   p.Coin().ID,
+			Coin:   coin.VECHAIN,
 			From:   originSender,
 			To:     originReceiver,
 			Fee:    types.Amount(fee),
@@ -153,7 +141,6 @@ func (p *Platform) NormalizeTokenTransaction(srcTx Tx, receipt TxReceipt) (types
 			Block:  srcTx.Meta.BlockNumber,
 			Status: types.StatusCompleted,
 			Meta: types.TokenTransfer{
-				// the only supported Token on VeChain is its Gas token
 				Name:     gasTokenName,
 				TokenID:  originReceiver,
 				Value:    types.Amount(value),
@@ -167,6 +154,56 @@ func (p *Platform) NormalizeTokenTransaction(srcTx Tx, receipt TxReceipt) (types
 	return txs, nil
 }
 
+func normalizeRevertedTokenTransaction(srcTx Tx, receipt TxReceipt) (types.TxPage, error) {
+	txs := make(types.TxPage, 0)
+
+	fee, err := numbers.HexToDecimal(receipt.Paid)
+	if err != nil {
+		return txs, err
+	}
+
+	originSender, err := address.EIP55Checksum(blockatlas.GetValidParameter(srcTx.Origin, srcTx.Meta.TxOrigin))
+	if err != nil {
+		return txs, err
+	}
+
+	var to string
+	if len(srcTx.Clauses) > 0 {
+		to = srcTx.Clauses[0].To
+		if checksumTo, err := address.EIP55Checksum(to); err == nil {
+			to = checksumTo
+		}
+	} else {
+		return txs, errors.New("NormalizeBlockTransaction: srcTx.Clauses not found: " + srcTx.Id)
+	}
+
+	if to != gasTokenAddress {
+		return txs, nil
+	}
+
+	txs = append(txs, types.Tx{
+		ID:     srcTx.Id,
+		Coin:   coin.VECHAIN,
+		From:   originSender,
+		To:     to,
+		Fee:    types.Amount(fee),
+		Date:   srcTx.Meta.BlockTimestamp,
+		Type:   types.TxTokenTransfer,
+		Block:  srcTx.Meta.BlockNumber,
+		Status: types.StatusError,
+		Meta: types.TokenTransfer{
+			Name:     gasTokenName,
+			TokenID:  gasTokenAddress,
+			Value:    "0",
+			Symbol:   gasTokenSymbol,
+			Decimals: gasTokenDecimals,
+			From:     originSender,
+			To:       to,
+		},
+	})
+	return txs, nil
+}
+
 func (p *Platform) GetTxsByAddress(address string) (types.TxPage, error) {
 	headBlock, err := p.CurrentBlockNumber()
 	if err != nil {


Test patch:
diff --git a/platform/vechain/transaction_test.go b/platform/vechain/transaction_test.go
index 1220a93..29c2b3b 100644
--- a/platform/vechain/transaction_test.go
+++ b/platform/vechain/transaction_test.go
@@ -69,9 +69,14 @@ func TestNormalizeTokenTransaction(t *testing.T) {
 		receiptFile string
 		address     string
 		expected    types.TxPage
+		wantErr     error
 	}{
-		{"Normalize outgoing VTHO tx", "outgoing_vtho_tx.json", "outgoing_vtho_receipt.json", "0xe99399dd211eF54c301A5d1AA813471d92122eA8", types.TxPage{
-			{
+		{
+			name:        "Normalize outgoing VTHO tx",
+			txFile:      "outgoing_vtho_tx.json",
+			receiptFile: "outgoing_vtho_receipt.json",
+			address:     "0xe99399dd211eF54c301A5d1AA813471d92122eA8",
+			expected: types.TxPage{{
 				ID:        "0x0677f91de4787d295087acec0a7ba317b0019fbf296fed630fdb5afbfca97a58",
 				Coin:      coin.VECHAIN,
 				From:      "0xe99399dd211eF54c301A5d1AA813471d92122eA8",
@@ -91,10 +96,15 @@ func TestNormalizeTokenTransaction(t *testing.T) {
 					Value:    types.Amount("7000000000000000000"),
 					Decimals: 18,
 				},
-			},
-		}},
-		{"Normalize incoming VTHO tx", "incoming_vtho_tx.json", "incoming_vtho_receipt.json", "0xe99399dd211eF54c301A5d1AA813471d92122eA8", types.TxPage{
-			{
+			}},
+			wantErr: nil,
+		},
+		{
+			name:        "Normalize incoming VTHO tx",
+			txFile:      "incoming_vtho_tx.json",
+			receiptFile: "incoming_vtho_receipt.json",
+			address:     "0xe99399dd211eF54c301A5d1AA813471d92122eA8",
+			expected: types.TxPage{{
 				ID:        "0xb356fa7b3a371f1518a5f9bc51e951d0dac2ef04d58b532c7ca50a52aa5cddb4",
 				Coin:      coin.VECHAIN,
 				From:      "0xB5e883349e68aB59307d1604555AC890fAC47128",
@@ -114,25 +124,19 @@ func TestNormalizeTokenTransaction(t *testing.T) {
 					Value:    types.Amount("1000000000000000000000"),
 					Decimals: 18,
 				},
-			},
-		}},
-		{"Normalize reverted token transfer", "reverted_tx.json", "reverted_receipt.json", "0x7cFFB7632252Bae3766734d61F148f0Ea78Fc08C", types.TxPage{
-			{
-				ID:     "0x7fae32a743e42eaec54642e2a5742a185299f5b4bedaf12c60f65705661de932",
-				Coin:   coin.VECHAIN,
-				From:   "0x7cFFB7632252Bae3766734d61F148f0Ea78Fc08C",
-				To:     "0xf8e1fAa0367298b55F57Ed17F7a2FF3F5F1D1628",
-				Date:   1610326580,
-				Type:   types.TxTokenTransfer,
-				Fee:    types.Amount("82618000000000000000"),
-				Status: types.StatusError,
-				Block:  7982675,
-			},
-		}},
+			}},
+			wantErr: nil,
+		},
+		{
+			name:        "Normalize reverted token transfer",
+			txFile:      "reverted_tx.json",
+			receiptFile: "reverted_receipt.json",
+			address:     "0x7cFFB7632252Bae3766734d61F148f0Ea78Fc08C",
+			expected:    types.TxPage{},
+			wantErr:     nil,
+		},
 	}
 
-	platform := Platform{}
-
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			var tx Tx
@@ -143,12 +147,12 @@ func TestNormalizeTokenTransaction(t *testing.T) {
 			err = mock.JsonModelFromFilePath("mocks/"+tt.receiptFile, &receipt)
 			assert.Nil(t, err)
 
-			actual, err := platform.NormalizeTokenTransaction(tx, receipt)
-			assert.Nil(t, err)
+			actual, err := NormalizeTokenTransaction(tx, receipt)
+			assert.Equal(t, err, tt.wantErr)
 
-			updateTransactionDirection(&actual[0], tt.address)
-
-			assert.Equal(t, len(actual), 1, "tx could not be normalized")
+			if len(actual) != 0 {
+				updateTransactionDirection(&actual[0], tt.address)
+			}
 			assert.Equal(t, tt.expected, actual, "tx don't equal")
 		})
 	}