code.vegaprotocol.io/vega@v0.79.0/core/bridges/erc20_multisigcontrol_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 bridges_test
    17  
    18  import (
    19  	"crypto/ed25519"
    20  	"encoding/hex"
    21  	"testing"
    22  
    23  	"code.vegaprotocol.io/vega/core/bridges"
    24  	"code.vegaprotocol.io/vega/libs/num"
    25  
    26  	"github.com/ethereum/go-ethereum/crypto"
    27  	"github.com/stretchr/testify/assert"
    28  )
    29  
    30  const (
    31  	privKey = "9feb9cbee69c1eeb30db084544ff8bf92166bf3fddefa6a021b458b4de04c66758a127387b1dff15b71fd7d0a9fd104ed75da4aac549efd5d149051ea57cefaf"
    32  	pubKey  = "58a127387b1dff15b71fd7d0a9fd104ed75da4aac549efd5d149051ea57cefaf"
    33  
    34  	chainID = "31337"
    35  )
    36  
    37  func TestERC20MultiSigControl(t *testing.T) {
    38  	t.Run("set threshold", testSetThreshold)
    39  	t.Run("add signer", testAddSigner)
    40  	t.Run("remove signer", testRemoveSigner)
    41  }
    42  
    43  func testSetThreshold(t *testing.T) {
    44  	tcs := []struct {
    45  		name     string
    46  		v1       bool
    47  		expected string
    48  	}{
    49  		{
    50  			name:     "v1 scheme",
    51  			v1:       true,
    52  			expected: "537eee3a9151d3f9a0a076c9521d3ca014efaefb20fd9be1b36c1e2475897f82b79b0de759b24a52a1a66c272c85628acd182a3cef2ae92b91a595f8d8123c06",
    53  		},
    54  		{
    55  			name:     "v2 scheme",
    56  			v1:       false,
    57  			expected: "e1bc702b74ca31f08d1d3534b6b147f641cf94713a809dd5b7ed5cb6e61b1892f1d2327ef14194bac488f41a661b805c6ca2f3daba7108eee46949229a126c0e",
    58  		},
    59  	}
    60  
    61  	for _, tc := range tcs {
    62  		signer := testSigner{}
    63  		bridge := bridges.NewERC20MultiSigControl(signer, chainID, tc.v1)
    64  		sig, err := bridge.SetThreshold(
    65  			1000,
    66  			"0x1FaA74E181092A97Fecc923015293ce57eE1208A",
    67  			num.NewUint(42),
    68  		)
    69  
    70  		assert.NoError(t, err)
    71  		assert.NotNil(t, sig.Message)
    72  		assert.NotNil(t, sig.Signature)
    73  		assert.True(t, signer.Verify(sig.Message, sig.Signature))
    74  		assert.Equal(t, tc.expected, sig.Signature.Hex())
    75  	}
    76  }
    77  
    78  func testAddSigner(t *testing.T) {
    79  	tcs := []struct {
    80  		name     string
    81  		v1       bool
    82  		expected string
    83  	}{
    84  		{
    85  			name:     "v1 scheme",
    86  			v1:       true,
    87  			expected: "52201353f14009c7638a6460af9340871de8d34a198d4957a142aa8098922829d4963eff0e6951fdecfe04566c865225b4c41dd2393b40d4de76fb9819142d0c",
    88  		},
    89  		{
    90  			name:     "v2 scheme",
    91  			v1:       false,
    92  			expected: "67e5a71935eaf134f4cbfadbefa96e510c97d6198accfcec76b046ee46ecd59fe4ae6f371973a8f4be7a67dd20b38c421b0f24061f1c95fe1e9322d04997e407",
    93  		},
    94  	}
    95  
    96  	for _, tc := range tcs {
    97  		signer := testSigner{}
    98  		bridge := bridges.NewERC20MultiSigControl(signer, chainID, tc.v1)
    99  		sig, err := bridge.AddSigner(
   100  			"0xE20c747a7389B7De2c595658277132f188A074EE",
   101  			"0x1FaA74E181092A97Fecc923015293ce57eE1208A",
   102  			num.NewUint(42),
   103  		)
   104  
   105  		assert.NoError(t, err)
   106  		assert.NotNil(t, sig.Message)
   107  		assert.NotNil(t, sig)
   108  		assert.True(t, signer.Verify(sig.Message, sig.Signature))
   109  
   110  		assert.Equal(t, tc.expected, sig.Signature.Hex())
   111  	}
   112  }
   113  
   114  func testRemoveSigner(t *testing.T) {
   115  	tcs := []struct {
   116  		name     string
   117  		v1       bool
   118  		expected string
   119  	}{
   120  		{
   121  			name:     "v1 scheme",
   122  			v1:       true,
   123  			expected: "4bf8057aa87a4ec5049766b0eb40426c9ba0464cda2ce203d16c590f3153657689143161908923b0c6ab32dec57c4c5aca7e4aaef24b8d22362413908868ea00",
   124  		},
   125  		{
   126  			name:     "v2 scheme",
   127  			v1:       false,
   128  			expected: "648f08b810bcbe589b79f7476f48de6e2c3528fbb059427f3876745dec51128952210d5e509e307d0dc2f6ba67f65bda7a28d96a8d31a365d04398cdde78150b",
   129  		},
   130  	}
   131  
   132  	for _, tc := range tcs {
   133  		signer := testSigner{}
   134  		bridge := bridges.NewERC20MultiSigControl(signer, chainID, tc.v1)
   135  		sig, err := bridge.RemoveSigner(
   136  			"0xE20c747a7389B7De2c595658277132f188A074EE",
   137  			"0x1FaA74E181092A97Fecc923015293ce57eE1208A",
   138  			num.NewUint(42),
   139  		)
   140  
   141  		assert.NoError(t, err)
   142  		assert.NotNil(t, sig.Message)
   143  		assert.NotNil(t, sig)
   144  		assert.True(t, signer.Verify(sig.Message, sig.Signature))
   145  		assert.Equal(t, tc.expected, sig.Signature.Hex())
   146  	}
   147  }
   148  
   149  type testSigner struct{}
   150  
   151  func (s testSigner) Algo() string { return "ed25519" }
   152  
   153  func (s testSigner) Sign(msg []byte) ([]byte, error) {
   154  	priv, _ := hex.DecodeString(privKey)
   155  
   156  	return ed25519.Sign(ed25519.PrivateKey(priv), msg), nil
   157  }
   158  
   159  func (s testSigner) Verify(msg, sig []byte) bool {
   160  	pub, _ := hex.DecodeString(pubKey)
   161  	hash := crypto.Keccak256(msg)
   162  
   163  	return ed25519.Verify(ed25519.PublicKey(pub), hash, sig)
   164  }