From 74f3c5b30e7cdc62600bffba45dbb6416bea5e09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Petruni=C4=87?= Date: Tue, 3 Sep 2024 11:28:49 +0200 Subject: [PATCH] feat: erc20 additional data (#356) --- .github/workflows/deploy_testnet.yml | 2 +- chains/evm/executor/message-handler.go | 13 ++++++- chains/evm/executor/message-handler_test.go | 37 ++++++++++++++++++- chains/evm/listener/depositHandlers/erc20.go | 10 ++++- .../listener/depositHandlers/erc20_test.go | 13 ++++++- 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/.github/workflows/deploy_testnet.yml b/.github/workflows/deploy_testnet.yml index 9a3b6225..19274339 100644 --- a/.github/workflows/deploy_testnet.yml +++ b/.github/workflows/deploy_testnet.yml @@ -169,4 +169,4 @@ jobs: fields: repo,message,commit,author,action,job,eventName,ref,workflow # selectable (default: repo,message) env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} # required - if: always() \ No newline at end of file + if: always() diff --git a/chains/evm/executor/message-handler.go b/chains/evm/executor/message-handler.go index 8597eca6..7c3962ce 100644 --- a/chains/evm/executor/message-handler.go +++ b/chains/evm/executor/message-handler.go @@ -6,6 +6,7 @@ package executor import ( "bytes" "errors" + "fmt" "math/big" "github.com/ethereum/go-ethereum/common" @@ -88,8 +89,8 @@ func PermissionlessGenericMessageHandler(msg *transfer.TransferMessage) (*propos } func ERC20MessageHandler(msg *transfer.TransferMessage) (*proposal.Proposal, error) { - if len(msg.Data.Payload) != 2 { - return nil, errors.New("malformed payload. Len of payload should be 2") + if len(msg.Data.Payload) != 2 && len(msg.Data.Payload) != 3 { + return nil, fmt.Errorf("wrong payload length %d", len(msg.Data.Payload)) } amount, ok := msg.Data.Payload[0].([]byte) if !ok { @@ -104,6 +105,14 @@ func ERC20MessageHandler(msg *transfer.TransferMessage) (*proposal.Proposal, err recipientLen := big.NewInt(int64(len(recipient))).Bytes() data = append(data, common.LeftPadBytes(recipientLen, 32)...) // length of recipient (uint256) data = append(data, recipient...) // recipient ([]byte) + if len(msg.Data.Payload) == 3 { + optionalMessage, ok := msg.Data.Payload[2].([]byte) + if !ok { + return nil, errors.New("wrong optional message format") + } + + data = append(data, optionalMessage...) + } return proposal.NewProposal(msg.Source, msg.Destination, transfer.TransferProposalData{ DepositNonce: msg.Data.DepositNonce, diff --git a/chains/evm/executor/message-handler_test.go b/chains/evm/executor/message-handler_test.go index d7d1673d..02b30d98 100644 --- a/chains/evm/executor/message-handler_test.go +++ b/chains/evm/executor/message-handler_test.go @@ -20,7 +20,7 @@ import ( "github.com/stretchr/testify/suite" ) -var errIncorrectERC20PayloadLen = errors.New("malformed payload. Len of payload should be 2") +var errIncorrectERC20PayloadLen = errors.New("wrong payload length 1") var errIncorrectERC721PayloadLen = errors.New("malformed payload. Len of payload should be 3") var errIncorrectGenericPayloadLen = errors.New("malformed payload. Len of payload should be 1") var errIncorrectERC1155PayloadLen = errors.New("malformed payload. Len of payload should be 4") @@ -47,7 +47,6 @@ func (s *ERC20HandlerTestSuite) SetupTest() {} func (s *ERC20HandlerTestSuite) TearDownTest() {} func (s *ERC20HandlerTestSuite) TestERC20HandleMessage() { - message := &message.Message{ Source: 1, Destination: 0, @@ -70,6 +69,40 @@ func (s *ERC20HandlerTestSuite) TestERC20HandleMessage() { s.NotNil(prop) } +func (s *ERC20HandlerTestSuite) TestERC20HandleMessage_WithOptionalMessage() { + amount := []byte{2} + recipient := []byte{241, 229, 143, 177, 119, 4, 194, 218, 132, 121, 165, 51, 249, 250, 212, 173, 9, 147, 202, 107} + optionalMessage := []byte("optionalMessage") + + expectedData := common.LeftPadBytes(amount, 32) + expectedData = append(expectedData, common.LeftPadBytes(big.NewInt(int64(len(recipient))).Bytes(), 32)...) + expectedData = append(expectedData, recipient...) + expectedData = append(expectedData, optionalMessage...) + + message := &message.Message{ + Source: 1, + Destination: 0, + Data: transfer.TransferMessageData{ + DepositNonce: 1, + ResourceId: [32]byte{0}, + Payload: []interface{}{ + amount, + recipient, + optionalMessage, + }, + Type: transfer.FungibleTransfer, + }, + Type: transfer.TransferMessageType, + } + + mh := executor.TransferMessageHandler{} + prop, err := mh.HandleMessage(message) + + s.Nil(err) + s.NotNil(prop) + s.Equal(prop.Data.(transfer.TransferProposalData).Data, expectedData) +} + func (s *ERC20HandlerTestSuite) TestERC20HandleMessageIncorrectDataLen() { message := &message.Message{ Source: 1, diff --git a/chains/evm/listener/depositHandlers/erc20.go b/chains/evm/listener/depositHandlers/erc20.go index c7932819..1ffa339e 100644 --- a/chains/evm/listener/depositHandlers/erc20.go +++ b/chains/evm/listener/depositHandlers/erc20.go @@ -43,13 +43,21 @@ func (dh *Erc20DepositHandler) HandleDeposit( amount, recipientAddress, } + + metadata := make(map[string]interface{}) + // append optional message if it exists + if len(calldata) > int(96+recipientAddressLength.Int64()) { + metadata["gasLimit"] = new(big.Int).SetBytes(calldata[64+recipientAddressLength.Int64() : 96+recipientAddressLength.Int64()]).Uint64() + payload = append(payload, calldata[64+recipientAddressLength.Int64():]) + } + return message.NewMessage( sourceID, destID, transfer.TransferMessageData{ DepositNonce: nonce, ResourceId: resourceID, - Metadata: nil, + Metadata: metadata, Payload: payload, Type: transfer.FungibleTransfer, }, diff --git a/chains/evm/listener/depositHandlers/erc20_test.go b/chains/evm/listener/depositHandlers/erc20_test.go index 362e9c55..7ed00ff0 100644 --- a/chains/evm/listener/depositHandlers/erc20_test.go +++ b/chains/evm/listener/depositHandlers/erc20_test.go @@ -32,8 +32,15 @@ func TestRunErc20HandlerTestSuite(t *testing.T) { func (s *Erc20HandlerTestSuite) TestErc20HandleEvent() { // 0xf1e58fb17704c2da8479a533f9fad4ad0993ca6b recipientByteSlice := []byte{241, 229, 143, 177, 119, 4, 194, 218, 132, 121, 165, 51, 249, 250, 212, 173, 9, 147, 202, 107} + maxFee := big.NewInt(200000) + optionalMessage := common.LeftPadBytes(maxFee.Bytes(), 32) + optionalMessage = append(optionalMessage, []byte("optionalMessage")...) + + metadata := make(map[string]interface{}) + metadata["gasLimit"] = uint64(200000) calldata := evm.ConstructErc20DepositData(recipientByteSlice, big.NewInt(2)) + calldata = append(calldata, optionalMessage...) depositLog := &events.Deposit{ DestinationDomainID: 0, ResourceID: [32]byte{0}, @@ -45,7 +52,7 @@ func (s *Erc20HandlerTestSuite) TestErc20HandleEvent() { sourceID := uint8(1) amountParsed := calldata[:32] - recipientAddressParsed := calldata[64:] + recipientAddressParsed := calldata[64 : 64+len(recipientByteSlice)] expected := &message.Message{ Source: sourceID, @@ -56,8 +63,10 @@ func (s *Erc20HandlerTestSuite) TestErc20HandleEvent() { Payload: []interface{}{ amountParsed, recipientAddressParsed, + optionalMessage, }, - Type: transfer.FungibleTransfer, + Type: transfer.FungibleTransfer, + Metadata: metadata, }, Type: transfer.TransferMessageType, ID: "messageID",