diff --git a/integrationTests/relayers/slowTests/ethToMultiversXWithChainSimulator_test.go b/integrationTests/relayers/slowTests/ethToMultiversXWithChainSimulator_test.go index 83883a65..21d90bf5 100644 --- a/integrationTests/relayers/slowTests/ethToMultiversXWithChainSimulator_test.go +++ b/integrationTests/relayers/slowTests/ethToMultiversXWithChainSimulator_test.go @@ -37,8 +37,6 @@ func TestRelayersShouldExecuteTransfers(t *testing.T) { GenerateTestUSDCToken(), GenerateTestMEMEToken(), ) - - // TODO: add a test for the withdrawTotalFeesOnEthereum functionality } func TestRelayersShouldExecuteTransfersWithSCCallsWithArguments(t *testing.T) { @@ -129,6 +127,9 @@ func testRelayersWithChainSimulatorAndTokens(tb testing.TB, manualStopChan chan processFunc := func(tb testing.TB, setup *framework.TestSetup) bool { if startsFromEthFlow.process() && startsFromMvXFlow.process() { + setup.TestWithdrawTotalFeesOnEthereumForTokens(startsFromMvXFlow.tokens...) + setup.TestWithdrawTotalFeesOnEthereumForTokens(startsFromEthFlow.tokens...) + return true } diff --git a/integrationTests/relayers/slowTests/framework/chainSimulatorWrapper.go b/integrationTests/relayers/slowTests/framework/chainSimulatorWrapper.go index 9631467d..49bb6633 100644 --- a/integrationTests/relayers/slowTests/framework/chainSimulatorWrapper.go +++ b/integrationTests/relayers/slowTests/framework/chainSimulatorWrapper.go @@ -362,3 +362,21 @@ func computeTransactionSignature(senderSk []byte, tx *transaction.FrontendTransa return signer.Sign(privateKey, dataToSign) } + +// ExecuteVMQuery will try to execute a VM query and return the results +func (instance *chainSimulatorWrapper) ExecuteVMQuery( + ctx context.Context, + scAddress *MvxAddress, + function string, + hexParams []string, +) [][]byte { + vmRequest := &data.VmValueRequest{ + Address: scAddress.Bech32(), + FuncName: function, + Args: hexParams, + } + response, err := instance.Proxy().ExecuteVMQuery(ctx, vmRequest) + require.Nil(instance, err) + + return response.Data.ReturnData +} diff --git a/integrationTests/relayers/slowTests/framework/interface.go b/integrationTests/relayers/slowTests/framework/interface.go index 2e879ea4..7b5e9db6 100644 --- a/integrationTests/relayers/slowTests/framework/interface.go +++ b/integrationTests/relayers/slowTests/framework/interface.go @@ -42,6 +42,7 @@ type ChainSimulatorWrapper interface { GetESDTBalance(ctx context.Context, address *MvxAddress, token string) string GetBlockchainTimeStamp(ctx context.Context) uint64 GetTransactionResult(ctx context.Context, hash string) *data.TransactionOnNetwork + ExecuteVMQuery(ctx context.Context, scAddress *MvxAddress, function string, hexParams []string) [][]byte } // EthereumBlockchainClient defines the operations supported by the Ethereum client diff --git a/integrationTests/relayers/slowTests/framework/multiversxHandler.go b/integrationTests/relayers/slowTests/framework/multiversxHandler.go index 146ca6c2..87cc9af2 100644 --- a/integrationTests/relayers/slowTests/framework/multiversxHandler.go +++ b/integrationTests/relayers/slowTests/framework/multiversxHandler.go @@ -31,6 +31,7 @@ const ( setCallsGasLimit = 80000000 // 80 million issueTokenGasLimit = 70000000 // 70 million createDepositGasLimit = 20000000 // 20 million + generalSCCallGasLimit = 50000000 // 50 million gasLimitPerDataByte = 1500 aggregatorContractPath = "testdata/contracts/mvx/multiversx-price-aggregator-sc.wasm" @@ -69,6 +70,10 @@ const ( unwrapTokenFunction = "unwrapToken" setBridgedTokensWrapperAddressFunction = "setBridgedTokensWrapperAddress" setMultiTransferAddressFunction = "setMultiTransferAddress" + withdrawRefundFeesForEthereumFunction = "withdrawRefundFeesForEthereum" + getRefundFeesForEthereumFunction = "getRefundFeesForEthereum" + withdrawTransactionFeesFunction = "withdrawTransactionFees" + getTransactionFeesFunction = "getTransactionFees" initSupplyMintBurnEsdtSafe = "initSupplyMintBurnEsdtSafe" initSupplyEsdtSafe = "initSupplyEsdtSafe" ) @@ -940,6 +945,60 @@ func (handler *MultiversxHandler) SendDepositTransactionFromMultiversx(ctx conte log.Info("MultiversX->Ethereum transaction sent", "hash", hash, "status", txResult.Status) } +// TestWithdrawFees will try to withdraw the fees for the provided token from the safe contract to the owner +func (handler *MultiversxHandler) TestWithdrawFees( + ctx context.Context, + token string, + expectedDeltaForRefund *big.Int, + expectedDeltaForAccumulated *big.Int, +) { + handler.withdrawFees(ctx, token, expectedDeltaForRefund, getRefundFeesForEthereumFunction, withdrawRefundFeesForEthereumFunction) + handler.withdrawFees(ctx, token, expectedDeltaForAccumulated, getTransactionFeesFunction, withdrawTransactionFeesFunction) +} + +func (handler *MultiversxHandler) withdrawFees(ctx context.Context, + token string, + expectedDelta *big.Int, + getFunction string, + withdrawFunction string, +) { + queryParams := []string{ + hex.EncodeToString([]byte(token)), + } + responseData := handler.ChainSimulator.ExecuteVMQuery(ctx, handler.SafeAddress, getFunction, queryParams) + value := big.NewInt(0).SetBytes(responseData[0]) + require.Equal(handler, expectedDelta.String(), value.String()) + if expectedDelta.Cmp(zeroValueBigInt) == 0 { + return + } + + handler.ChainSimulator.GenerateBlocks(ctx, 5) // ensure block finality + initialBalanceStr := handler.ChainSimulator.GetESDTBalance(ctx, handler.OwnerKeys.MvxAddress, token) + initialBalance, ok := big.NewInt(0).SetString(initialBalanceStr, 10) + require.True(handler, ok) + + handler.ChainSimulator.ScCall( + ctx, + handler.OwnerKeys.MvxSk, + handler.MultisigAddress, + zeroStringValue, + generalSCCallGasLimit, + withdrawFunction, + []string{ + hex.EncodeToString([]byte(token)), + }, + ) + + handler.ChainSimulator.GenerateBlocks(ctx, 5) // ensure block finality + finalBalanceStr := handler.ChainSimulator.GetESDTBalance(ctx, handler.OwnerKeys.MvxAddress, token) + finalBalance, ok := big.NewInt(0).SetString(finalBalanceStr, 10) + require.True(handler, ok) + + require.Equal(handler, expectedDelta, finalBalance.Sub(finalBalance, initialBalance), + fmt.Sprintf("mismatch on balance check after the call to %s: initial balance: %s, final balance %s, expected delta: %s", + withdrawFunction, initialBalanceStr, finalBalanceStr, expectedDelta.String())) +} + func getHexBool(input bool) string { if input { return hexTrue diff --git a/integrationTests/relayers/slowTests/framework/testSetup.go b/integrationTests/relayers/slowTests/framework/testSetup.go index bcba8a8d..4a43c994 100644 --- a/integrationTests/relayers/slowTests/framework/testSetup.go +++ b/integrationTests/relayers/slowTests/framework/testSetup.go @@ -327,6 +327,27 @@ func (setup *TestSetup) sendFromMultiversxToEthereumForToken(params TestTokenPar } } +// TestWithdrawTotalFeesOnEthereumForTokens will test the withdrawal functionality for the provided test tokens +func (setup *TestSetup) TestWithdrawTotalFeesOnEthereumForTokens(tokensParams ...TestTokenParams) { + for _, param := range tokensParams { + token := setup.TokensRegistry.GetTokenData(param.AbstractTokenIdentifier) + + expectedAccumulated := big.NewInt(0) + for _, operation := range param.TestOperations { + if operation.ValueToSendFromMvX == nil { + continue + } + if operation.ValueToSendFromMvX.Cmp(zeroValueBigInt) == 0 { + continue + } + + expectedAccumulated.Add(expectedAccumulated, feeInt) + } + + setup.MultiversxHandler.TestWithdrawFees(setup.Ctx, token.MvxChainSpecificToken, zeroValueBigInt, expectedAccumulated) + } +} + // Close will close the test subcomponents func (setup *TestSetup) Close() { log.Info(fmt.Sprintf(LogStepMarker, "closing relayers & sc execution module")) diff --git a/integrationTests/relayers/slowTests/testdata/contracts/mvx/esdt-safe.abi.json b/integrationTests/relayers/slowTests/testdata/contracts/mvx/esdt-safe.abi.json index dd9e2d67..28db483f 100644 --- a/integrationTests/relayers/slowTests/testdata/contracts/mvx/esdt-safe.abi.json +++ b/integrationTests/relayers/slowTests/testdata/contracts/mvx/esdt-safe.abi.json @@ -165,13 +165,33 @@ "outputs": [] }, { - "name": "withdrawTotalFeesOnEthereum", + "name": "withdrawRefundFeesForEthereum", "onlyOwner": true, "mutability": "mutable", "inputs": [ { "name": "token_id", "type": "TokenIdentifier" + }, + { + "name": "multisig_owner", + "type": "Address" + } + ], + "outputs": [] + }, + { + "name": "withdrawTransactionFees", + "onlyOwner": true, + "mutability": "mutable", + "inputs": [ + { + "name": "token_id", + "type": "TokenIdentifier" + }, + { + "name": "multisig_owner", + "type": "Address" } ], "outputs": [] @@ -226,6 +246,36 @@ } ] }, + { + "name": "getRefundFeesForEthereum", + "mutability": "readonly", + "inputs": [ + { + "name": "token_id", + "type": "TokenIdentifier" + } + ], + "outputs": [ + { + "type": "BigUint" + } + ] + }, + { + "name": "getTransactionFees", + "mutability": "readonly", + "inputs": [ + { + "name": "token_id", + "type": "TokenIdentifier" + } + ], + "outputs": [ + { + "type": "BigUint" + } + ] + }, { "name": "getBridgedTokensWrapperAddress", "mutability": "readonly", diff --git a/integrationTests/relayers/slowTests/testdata/contracts/mvx/esdt-safe.wasm b/integrationTests/relayers/slowTests/testdata/contracts/mvx/esdt-safe.wasm old mode 100644 new mode 100755 index ad1cc816..2a715ce5 Binary files a/integrationTests/relayers/slowTests/testdata/contracts/mvx/esdt-safe.wasm and b/integrationTests/relayers/slowTests/testdata/contracts/mvx/esdt-safe.wasm differ diff --git a/integrationTests/relayers/slowTests/testdata/contracts/mvx/multisig.abi.json b/integrationTests/relayers/slowTests/testdata/contracts/mvx/multisig.abi.json index 4b6e2ba2..f35ac561 100644 --- a/integrationTests/relayers/slowTests/testdata/contracts/mvx/multisig.abi.json +++ b/integrationTests/relayers/slowTests/testdata/contracts/mvx/multisig.abi.json @@ -218,7 +218,19 @@ "outputs": [] }, { - "name": "withdrawTotalFeesOnEthereum", + "name": "withdrawRefundFeesForEthereum", + "onlyOwner": true, + "mutability": "mutable", + "inputs": [ + { + "name": "token_id", + "type": "TokenIdentifier" + } + ], + "outputs": [] + }, + { + "name": "withdrawTransactionFees", "onlyOwner": true, "mutability": "mutable", "inputs": [ diff --git a/integrationTests/relayers/slowTests/testdata/contracts/mvx/multisig.wasm b/integrationTests/relayers/slowTests/testdata/contracts/mvx/multisig.wasm old mode 100644 new mode 100755 index f80f6c14..00e3e188 Binary files a/integrationTests/relayers/slowTests/testdata/contracts/mvx/multisig.wasm and b/integrationTests/relayers/slowTests/testdata/contracts/mvx/multisig.wasm differ