Skip to content

Commit

Permalink
Merge pull request #11181 from vegaprotocol/10909-chain-in-signatures
Browse files Browse the repository at this point in the history
10909 chain in signatures
  • Loading branch information
jeremyletang authored Apr 24, 2024
2 parents 3fb8f17 + 56d7854 commit 3e1b29f
Show file tree
Hide file tree
Showing 15 changed files with 404 additions and 188 deletions.
39 changes: 20 additions & 19 deletions cmd/vega/commands/bridge/erc20.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ type ERC20Cmd struct {
config.VegaHomeFlag
config.PassphraseFlag
Config nodewallets.Config
PrivateKey string `description:"A ethereum private key to be use to sign the messages" long:"private-key" required:"false"`
PrivateKey string `description:"A ethereum private key to be use to sign the messages" long:"private-key" required:"false"`
ChainID string `description:"The chain-id of the EVM bridge. Not required if generating signatures for the Ethereum bridge" long:"chain-id" required:"false"`

AddSigner ERC20AddSignerCmd `command:"add_signer" description:"Create signature to add a new signer to the erc20 bridge"`
RemoveSigner ERC20RemoveSignerCmd `command:"remove_signer" description:"Create signature to remove a signer from the erc20 bridge"`
Expand Down Expand Up @@ -144,7 +145,7 @@ func (opts *ERC20WithdrawAssetCmd) Execute(_ []string) error {

creation := time.Unix(opts.Creation, 0)

erc20Logic := bridges.NewERC20Logic(w, opts.BridgeAddress)
erc20Logic := bridges.NewERC20Logic(w, opts.BridgeAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
bundle, err := erc20Logic.WithdrawAsset(
opts.TokenAddress, amount, opts.ReceiverAddress, creation, nonce,
)
Expand Down Expand Up @@ -191,7 +192,7 @@ func (opts *ERC20VerifyWithdrawAssetCmd) Execute(_ []string) error {
return errors.New("invalid signatures format")
}

erc20Logic := bridges.NewERC20Logic(nil, opts.BridgeAddress)
erc20Logic := bridges.NewERC20Logic(nil, opts.BridgeAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
addresses, err := erc20Logic.VerifyWithdrawAsset(
opts.TokenAddress, amount, opts.ReceiverAddress, creation, nonce, opts.Signatures,
)
Expand Down Expand Up @@ -238,7 +239,7 @@ func (opts *ERC20ListAssetCmd) Execute(_ []string) error {
return errors.New("invalid withdraw-threshold, needs to be base 10")
}

erc20Logic := bridges.NewERC20Logic(w, opts.BridgeAddress)
erc20Logic := bridges.NewERC20Logic(w, opts.BridgeAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
bundle, err := erc20Logic.ListAsset(
opts.TokenAddress, opts.VegaAssetID, lifetimeLimit, withdrawThreshod, nonce,
)
Expand Down Expand Up @@ -286,7 +287,7 @@ func (opts *ERC20VerifyListAssetCmd) Execute(_ []string) error {
return errors.New("invalid signatures format")
}

erc20Logic := bridges.NewERC20Logic(nil, opts.BridgeAddress)
erc20Logic := bridges.NewERC20Logic(nil, opts.BridgeAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
addresses, err := erc20Logic.VerifyListAsset(
opts.TokenAddress, opts.VegaAssetID, lifetimeLimit, withdrawThreshod, nonce, opts.Signatures,
)
Expand Down Expand Up @@ -322,7 +323,7 @@ func (opts *ERC20RemoveAssetCmd) Execute(_ []string) error {
return errors.New("invalid nonce, needs to be base 10")
}

erc20Logic := bridges.NewERC20Logic(w, opts.BridgeAddress)
erc20Logic := bridges.NewERC20Logic(w, opts.BridgeAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
bundle, err := erc20Logic.RemoveAsset(
opts.TokenAddress, nonce,
)
Expand Down Expand Up @@ -355,7 +356,7 @@ func (opts *ERC20AddSignerCmd) Execute(_ []string) error {
return errors.New("invalid nonce, needs to be base 10")
}

multiSigControl := bridges.NewERC20MultiSigControl(w)
multiSigControl := bridges.NewERC20MultiSigControl(w, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
bundle, err := multiSigControl.AddSigner(
opts.NewSigner, opts.Submitter, nonce,
)
Expand Down Expand Up @@ -388,7 +389,7 @@ func (opts *ERC20RemoveSignerCmd) Execute(_ []string) error {
return errors.New("invalid nonce, needs to be base 10")
}

multiSigControl := bridges.NewERC20MultiSigControl(w)
multiSigControl := bridges.NewERC20MultiSigControl(w, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
bundle, err := multiSigControl.RemoveSigner(
opts.OldSigner, opts.Submitter, nonce,
)
Expand Down Expand Up @@ -425,7 +426,7 @@ func (opts *ERC20SetThresholdCmd) Execute(_ []string) error {
return errors.New("invalid nonce, needs to be base 10 and not overflow")
}

multiSigControl := bridges.NewERC20MultiSigControl(w)
multiSigControl := bridges.NewERC20MultiSigControl(w, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
bundle, err := multiSigControl.SetThreshold(
opts.NewThreshold, opts.Submitter, nonce,
)
Expand Down Expand Up @@ -457,7 +458,7 @@ func (opts *ERC20BurnNonceCmd) Execute(_ []string) error {
return errors.New("invalid nonce, needs to be base 10 and not overflow")
}

multiSigControl := bridges.NewERC20MultiSigControl(w)
multiSigControl := bridges.NewERC20MultiSigControl(w, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
bundle, err := multiSigControl.BurnNonce(opts.Submitter, nonce)
if err != nil {
return fmt.Errorf("unable to generate signature: %w", err)
Expand Down Expand Up @@ -488,7 +489,7 @@ func (opts *ERC20SetBridgeAddressCmd) Execute(_ []string) error {
return errors.New("invalid nonce, needs to be base 10")
}

erc20Logic := bridges.NewERC20AssetPool(w, opts.AssetPoolAddress)
erc20Logic := bridges.NewERC20AssetPool(w, opts.AssetPoolAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
bundle, err := erc20Logic.SetBridgeAddress(
opts.NewAddress, nonce,
)
Expand Down Expand Up @@ -521,7 +522,7 @@ func (opts *ERC20SetMultisigControlCmd) Execute(_ []string) error {
return errors.New("invalid nonce, needs to be base 10")
}

erc20Logic := bridges.NewERC20AssetPool(w, opts.AssetPoolAddress)
erc20Logic := bridges.NewERC20AssetPool(w, opts.AssetPoolAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
bundle, err := erc20Logic.SetMultiSigControl(
opts.NewAddress, nonce,
)
Expand Down Expand Up @@ -553,7 +554,7 @@ func (opts *ERC20GlobalStopCmd) Execute(_ []string) error {
return errors.New("invalid nonce, needs to be base 10 and not overflow")
}

erc20 := bridges.NewERC20Logic(w, opts.BridgeAddress)
erc20 := bridges.NewERC20Logic(w, opts.BridgeAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
bundle, err := erc20.GlobalStop(
nonce,
)
Expand Down Expand Up @@ -585,7 +586,7 @@ func (opts *ERC20GlobalResumeCmd) Execute(_ []string) error {
return errors.New("invalid nonce, needs to be base 10 and not overflow")
}

erc20 := bridges.NewERC20Logic(w, opts.BridgeAddress)
erc20 := bridges.NewERC20Logic(w, opts.BridgeAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
bundle, err := erc20.GlobalResume(
nonce,
)
Expand Down Expand Up @@ -621,7 +622,7 @@ func (opts *ERC20VerifyGlobalResumeCmd) Execute(_ []string) error {
return errors.New("invalid signatures format")
}

erc20 := bridges.NewERC20Logic(nil, opts.BridgeAddress)
erc20 := bridges.NewERC20Logic(nil, opts.BridgeAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
signers, err := erc20.VerifyGlobalResume(
nonce, opts.Signatures,
)
Expand Down Expand Up @@ -671,7 +672,7 @@ func (opts *ERC20SetAssetLimitsCmd) Execute(_ []string) error {
return errors.New("invalid deposit-lifetime-maximum needs to be base 10 and not overflow")
}

erc20 := bridges.NewERC20Logic(w, opts.BridgeAddress)
erc20 := bridges.NewERC20Logic(w, opts.BridgeAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
bundle, err := erc20.SetAssetLimits(
opts.TokenAddress, depositLifetime, threshold, nonce,
)
Expand Down Expand Up @@ -720,7 +721,7 @@ func (opts *ERC20VerifySetAssetLimitsCmd) Execute(_ []string) error {
return errors.New("invalid signatures format")
}

erc20 := bridges.NewERC20Logic(nil, opts.BridgeAddress)
erc20 := bridges.NewERC20Logic(nil, opts.BridgeAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
signers, err := erc20.VerifySetAssetLimits(
opts.TokenAddress, depositLifetime, threshold, nonce, opts.Signatures,
)
Expand Down Expand Up @@ -756,7 +757,7 @@ func (opts *ERC20SetWithdrawDelayCmd) Execute(_ []string) error {
return errors.New("invalid nonce, needs to be base 10 and not overflow")
}

erc20 := bridges.NewERC20Logic(w, opts.BridgeAddress)
erc20 := bridges.NewERC20Logic(w, opts.BridgeAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
bundle, err := erc20.SetWithdrawDelay(
opts.Delay, nonce,
)
Expand Down Expand Up @@ -793,7 +794,7 @@ func (opts *ERC20VerifySetWithdrawDelayCmd) Execute(_ []string) error {
return errors.New("invalid signatures format")
}

erc20Logic := bridges.NewERC20Logic(nil, opts.BridgeAddress)
erc20Logic := bridges.NewERC20Logic(nil, opts.BridgeAddress, erc20Cmd.ChainID, erc20Cmd.ChainID == "")
addresses, err := erc20Logic.VerifyWithdrawDelay(
opts.Delay, nonce, opts.Signatures,
)
Expand Down
2 changes: 2 additions & 0 deletions core/assets/assets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,10 @@ func getTestService(t *testing.T) *testService {
ctrl := gomock.NewController(t)
primaryEthClient := erc20mocks.NewMockETHClient(ctrl)
primaryEthClient.EXPECT().ChainID(gomock.Any()).AnyTimes().Return(big.NewInt(1), nil)
primaryEthClient.EXPECT().IsEthereum().AnyTimes().Return(true)
secondaryEthClient := erc20mocks.NewMockETHClient(ctrl)
secondaryEthClient.EXPECT().ChainID(gomock.Any()).AnyTimes().Return(big.NewInt(2), nil)
secondaryEthClient.EXPECT().IsEthereum().AnyTimes().Return(false)
broker := bmocks.NewMockInterface(ctrl)
primaryBridgeView := mocks.NewMockERC20BridgeView(ctrl)
secondaryBridgeView := mocks.NewMockERC20BridgeView(ctrl)
Expand Down
7 changes: 4 additions & 3 deletions core/assets/erc20/erc20.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type ETHClient interface {
CurrentHeight(context.Context) (uint64, error)
ConfirmationsRequired() uint64
ChainID(ctx context.Context) (*big.Int, error)
IsEthereum() bool
}

type ERC20 struct {
Expand Down Expand Up @@ -144,7 +145,7 @@ func (e *ERC20) SignListAsset() (msg []byte, sig []byte, err error) {
}

source := e.asset.Details.GetERC20()
bundle, err := bridges.NewERC20Logic(e.wallet, bridgeAddress).
bundle, err := bridges.NewERC20Logic(e.wallet, bridgeAddress, e.chainID, e.ethClient.IsEthereum()).
ListAsset(e.address, e.asset.ID, source.LifetimeLimit, source.WithdrawThreshold, nonce)
if err != nil {
return nil, nil, err
Expand All @@ -155,7 +156,7 @@ func (e *ERC20) SignListAsset() (msg []byte, sig []byte, err error) {

func (e *ERC20) SignSetAssetLimits(nonce *num.Uint, lifetimeLimit *num.Uint, withdrawThreshold *num.Uint) (msg []byte, sig []byte, err error) {
bridgeAddress := e.ethClient.CollateralBridgeAddress().Hex()
bundle, err := bridges.NewERC20Logic(e.wallet, bridgeAddress).
bundle, err := bridges.NewERC20Logic(e.wallet, bridgeAddress, e.chainID, e.ethClient.IsEthereum()).
SetAssetLimits(e.address, lifetimeLimit, withdrawThreshold, nonce)
if err != nil {
return nil, nil, err
Expand All @@ -172,7 +173,7 @@ func (e *ERC20) SignWithdrawal(
) (msg []byte, sig []byte, err error) {
nonce, _ := num.UintFromBig(withdrawRef)
bridgeAddress := e.ethClient.CollateralBridgeAddress().Hex()
bundle, err := bridges.NewERC20Logic(e.wallet, bridgeAddress).
bundle, err := bridges.NewERC20Logic(e.wallet, bridgeAddress, e.chainID, e.ethClient.IsEthereum()).
WithdrawAsset(e.address, amount, ethPartyAddress, now, nonce)
if err != nil {
return nil, nil, err
Expand Down
4 changes: 4 additions & 0 deletions core/assets/erc20/erc20_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ func (testEthClient) ChainID(context.Context) (*big.Int, error) {
return big.NewInt(1), nil
}

func (testEthClient) IsEthereum() bool {
return true
}

func (testEthClient) CollateralBridgeAddress() ethcommon.Address {
return ethcommon.HexToAddress(bridgeAddress)
}
Expand Down
14 changes: 14 additions & 0 deletions core/assets/erc20/mocks/eth_client_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions core/bridges/erc20_asset_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ import (
type ERC20AssetPool struct {
signer Signer
poolAddr string
chainID string
v1 bool
}

func NewERC20AssetPool(signer Signer, poolAddr string) *ERC20AssetPool {
func NewERC20AssetPool(signer Signer, poolAddr, chainID string, v1 bool) *ERC20AssetPool {
return &ERC20AssetPool{
signer: signer,
poolAddr: poolAddr,
chainID: chainID,
v1: v1,
}
}

Expand Down Expand Up @@ -76,7 +80,7 @@ func (e ERC20AssetPool) SetBridgeAddress(
return nil, fmt.Errorf("couldn't pack abi message: %w", err)
}

msg, err := packBufAndSubmitter(buf, e.poolAddr)
msg, err := packScheme(buf, e.poolAddr, e.chainID, e.v1)
if err != nil {
return nil, fmt.Errorf("couldn't pack abi message: %w", err)
}
Expand Down Expand Up @@ -124,7 +128,7 @@ func (e ERC20AssetPool) SetMultiSigControl(
return nil, fmt.Errorf("couldn't pack abi message: %w", err)
}

msg, err := packBufAndSubmitter(buf, e.poolAddr)
msg, err := packScheme(buf, e.poolAddr, e.chainID, e.v1)
if err != nil {
return nil, fmt.Errorf("couldn't pack abi message: %w", err)
}
Expand Down
48 changes: 33 additions & 15 deletions core/bridges/erc20_asset_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,37 @@ const (
)

func TestAssetPoolSetBridgeAddress(t *testing.T) {
signer := testSigner{}
pool := bridges.NewERC20AssetPool(signer, erc20AssetPool)
sig, err := pool.SetBridgeAddress(
erc20AssetAddr,
num.NewUint(42),
)

assert.NoError(t, err)
assert.NotNil(t, sig.Message)
assert.NotNil(t, sig.Signature)
assert.True(t, signer.Verify(sig.Message, sig.Signature))
assert.Equal(t,
"2488c05dd36a754db037f22a1d649109573e299a3c135efdb81c6f64632b26101c0b4ce19c896d370abae8d457682b21a4a3322f48380f29932b311b6ab47707",
sig.Signature.Hex(),
)
tcs := []struct {
name string
v1 bool
expected string
}{
{
name: "v1 scheme",
v1: true,
expected: "2488c05dd36a754db037f22a1d649109573e299a3c135efdb81c6f64632b26101c0b4ce19c896d370abae8d457682b21a4a3322f48380f29932b311b6ab47707",
},
{
name: "v2 scheme",
v1: false,
expected: "4b01dfa1a3b77ecc624f678805a74418862cbcb1e32b929e7dce7fbbfa73806ec1f5db1d40d28f4ebcb09d83f59815f04438142612ebc1683158a23c9fbf3a0c",
},
}

for _, tc := range tcs {
t.Run(tc.name, func(tt *testing.T) {
signer := testSigner{}
pool := bridges.NewERC20AssetPool(signer, erc20AssetPool, chainID, tc.v1)
sig, err := pool.SetBridgeAddress(
erc20AssetAddr,
num.NewUint(42),
)

assert.NoError(t, err)
assert.NotNil(t, sig.Message)
assert.NotNil(t, sig.Signature)
assert.True(t, signer.Verify(sig.Message, sig.Signature))
assert.Equal(t, tc.expected, sig.Signature.Hex())
})
}
}
Loading

0 comments on commit 3e1b29f

Please sign in to comment.