code.vegaprotocol.io/vega@v0.79.0/core/assets/erc20/erc20_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package erc20_test
    17  
    18  import (
    19  	"context"
    20  	"encoding/hex"
    21  	"math/big"
    22  	"testing"
    23  	"time"
    24  
    25  	"code.vegaprotocol.io/vega/core/assets/erc20"
    26  	ethnw "code.vegaprotocol.io/vega/core/nodewallets/eth"
    27  	"code.vegaprotocol.io/vega/core/nodewallets/registry"
    28  	"code.vegaprotocol.io/vega/core/types"
    29  	vcrypto "code.vegaprotocol.io/vega/libs/crypto"
    30  	"code.vegaprotocol.io/vega/libs/num"
    31  
    32  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    33  	ethcommon "github.com/ethereum/go-ethereum/common"
    34  	ethtypes "github.com/ethereum/go-ethereum/core/types"
    35  	ethcrypto "github.com/ethereum/go-ethereum/crypto"
    36  	"github.com/stretchr/testify/assert"
    37  	"golang.org/x/crypto/ed25519"
    38  )
    39  
    40  const (
    41  	privKey       = "9feb9cbee69c1eeb30db084544ff8bf92166bf3fddefa6a021b458b4de04c66758a127387b1dff15b71fd7d0a9fd104ed75da4aac549efd5d149051ea57cefaf"
    42  	pubKey        = "58a127387b1dff15b71fd7d0a9fd104ed75da4aac549efd5d149051ea57cefaf"
    43  	tokenID       = "af077ace8cbf3179f826f2d3485b812f6efef07d913f2ed02f295360dd78b30e"
    44  	ethPartyAddr  = "0x1ebe188952ab6035adad21ea1c4f64fd2eac60e1"
    45  	bridgeAddress = "0xcB84d72e61e383767C4DFEb2d8ff7f4FB89abc6e"
    46  )
    47  
    48  var token = &types.AssetDetails{
    49  	Name:     "VEGA",
    50  	Symbol:   "VEGA",
    51  	Decimals: 18,
    52  	Quantum:  num.DecimalFromFloat(1),
    53  	Source: &types.AssetDetailsErc20{
    54  		ERC20: &types.ERC20{
    55  			ContractAddress:   "0x1FaA74E181092A97Fecc923015293ce57eE1208A",
    56  			WithdrawThreshold: num.NewUint(1000),
    57  			LifetimeLimit:     num.NewUint(42),
    58  			ChainID:           "1",
    59  		},
    60  	},
    61  }
    62  
    63  type testERC20 struct {
    64  	*erc20.ERC20
    65  	wallet    *ethnw.Wallet
    66  	ethClient testEthClient
    67  }
    68  
    69  func newTestERC20(t *testing.T) *testERC20 {
    70  	t.Helper()
    71  	wallet := ethnw.NewWallet(testWallet{})
    72  	ethClient := testEthClient{}
    73  	erc20Token, err := erc20.New(tokenID, token, wallet, ethClient)
    74  	assert.NoError(t, err)
    75  
    76  	return &testERC20{
    77  		ERC20:     erc20Token,
    78  		wallet:    wallet,
    79  		ethClient: ethClient,
    80  	}
    81  }
    82  
    83  func TestERC20Signatures(t *testing.T) {
    84  	t.Run("withdraw_asset", testWithdrawAsset)
    85  	t.Run("list_asset", testListAsset)
    86  }
    87  
    88  func testWithdrawAsset(t *testing.T) {
    89  	token := newTestERC20(t)
    90  	now := time.Unix(10000, 0)
    91  	msg, sig, err := token.SignWithdrawal(
    92  		num.NewUint(42),
    93  		ethPartyAddr,
    94  		big.NewInt(84),
    95  		now,
    96  	)
    97  
    98  	assert.NoError(t, err)
    99  	assert.NotNil(t, msg)
   100  	assert.NotNil(t, sig)
   101  	assert.True(t, verifySignature(msg, sig))
   102  	assert.Equal(t, "4b7423e2f005a25150f56fdcea72ccabfb466d94a4a3d1aa3541eed2f1292deabd9de643ccc00d64561806c302c8c9773a028fd0e2778e2b2a6f6b3948c95b06",
   103  		hex.EncodeToString(sig),
   104  	)
   105  }
   106  
   107  func testListAsset(t *testing.T) {
   108  	token := newTestERC20(t)
   109  	msg, sig, err := token.SignListAsset()
   110  
   111  	assert.NoError(t, err)
   112  	assert.NotNil(t, msg)
   113  	assert.NotNil(t, sig)
   114  	assert.True(t, verifySignature(msg, sig))
   115  	assert.Equal(t, "125419bebd3623144c1da43d9cc32fc7cab4b870ade32eda8e2a3b175c22b9dac556c47c195bf44f7d7114964411235e690294683cf252f005809f49c4536400",
   116  		hex.EncodeToString(sig),
   117  	)
   118  }
   119  
   120  type testEthClient struct {
   121  	bind.ContractBackend
   122  }
   123  
   124  func (testEthClient) HeaderByNumber(context.Context, *big.Int) (*ethtypes.Header, error) {
   125  	return nil, nil
   126  }
   127  
   128  func (testEthClient) ChainID(context.Context) (*big.Int, error) {
   129  	return big.NewInt(1), nil
   130  }
   131  
   132  func (testEthClient) IsEthereum() bool {
   133  	return true
   134  }
   135  
   136  func (testEthClient) CollateralBridgeAddress() ethcommon.Address {
   137  	return ethcommon.HexToAddress(bridgeAddress)
   138  }
   139  
   140  func (testEthClient) CurrentHeight(context.Context) (uint64, error) { return 100, nil }
   141  func (testEthClient) ConfirmationsRequired() uint64                 { return 1 }
   142  
   143  type testWallet struct{}
   144  
   145  func (testWallet) Cleanup() error { return nil }
   146  func (testWallet) Name() string   { return "eth" }
   147  func (testWallet) Chain() string  { return "eth" }
   148  func (testWallet) Sign(data []byte) ([]byte, error) {
   149  	priv, _ := hex.DecodeString(privKey)
   150  	return ed25519.Sign(ed25519.PrivateKey(priv), data), nil
   151  }
   152  func (testWallet) Algo() string                                  { return "eth" }
   153  func (testWallet) Version() (string, error)                      { return "1", nil }
   154  func (testWallet) PubKey() vcrypto.PublicKey                     { return vcrypto.PublicKey{} }
   155  func (testWallet) Reload(d registry.EthereumWalletDetails) error { return nil }
   156  
   157  func verifySignature(msg, sig []byte) bool {
   158  	pub, _ := hex.DecodeString(pubKey)
   159  	hash := ethcrypto.Keccak256(msg)
   160  	return ed25519.Verify(ed25519.PublicKey(pub), hash, sig)
   161  }