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 }