From 38a05a3e43d9d3af2b3757f11cd5c98bb7a7886c Mon Sep 17 00:00:00 2001 From: Nikola Pavlov <144679078+tx-nikola@users.noreply.github.com> Date: Mon, 16 Dec 2024 13:56:56 +0100 Subject: [PATCH] fix: pass arguments for the contract functions in the correct order (#347) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # What ❔ This PR fixes the bug where the contract function arguments are not passed in the correct order. ## Why ❔ In order to call the contract functions correctly, we need to pass the arguments in the right order. # Explanation The issue was that we were trying to get `Object.entries(params)` without actually sorting it, so, for example, contract [0xE1D6A50E7101c8f8db77352897Ee3f1AC53f782B](https://explorer.zksync.io/address/0xE1D6A50E7101c8f8db77352897Ee3f1AC53f782B#contract#write-proxy), the `revokeRole` function asks for `[role, account]` arguments to be passed. In the form object, it looks like this: ``` { account: "0xExample", role: "0xExample } ``` and when we run `Object.entries(params)` we always get it like this: ``` [ ["account", "0x969Bb8Ae65602B4F8f9B459a11084e591c4491C7"], ["role", "0x03c321230b026fb61a5a21f62c5f618751ec6d8435327f673bae5bfa570e5879"]] ] ``` and later after we map it, it becomes `["0x969Bb8Ae65602B4F8f9B459a11084e591c4491C7", "0x03c321230b026fb61a5a21f62c5f618751ec6d8435327f673bae5bfa570e5879"]` - swapping the arguments from their intended places. This issue was happening when someone types the account first, therefore forms become ``` { account: "0xExample", role: "0xExample } ``` instead of ``` { role: "0xExample, account: "0xExample" } ``` thus messing up the order of the arguments in the function call. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. --------- Co-authored-by: Vasyl Ivanchuk --- .../src/composables/useContractInteraction.ts | 20 +++++++++---------- .../useContractInteraction.spec.ts | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/app/src/composables/useContractInteraction.ts b/packages/app/src/composables/useContractInteraction.ts index dea7b67cf..a6050b0c6 100644 --- a/packages/app/src/composables/useContractInteraction.ts +++ b/packages/app/src/composables/useContractInteraction.ts @@ -45,16 +45,16 @@ export default (context = useContext()) => { const signer = await getL2Signer(); const contract = new Contract(address, [abiFragment], signer!); const method = contract[abiFragment.name]; - const methodArguments = Object.entries(params) - .filter(([key]) => key !== PAYABLE_AMOUNT_PARAM_NAME) - .map(([, inputValue]) => { - if (inputValue === "true") { - inputValue = true; - } else if (inputValue === "false") { - inputValue = false; - } - return inputValue; - }); + const abiFragmentNames = abiFragment.inputs.map((abiInput) => abiInput.name); + const methodArguments = abiFragmentNames.map((abiFragmentName) => { + if (params[abiFragmentName] === "true") { + return true; + } + if (params[abiFragmentName] === "false") { + return false; + } + return params[abiFragmentName]; + }); const valueMethodOption = { value: parseEther((params[PAYABLE_AMOUNT_PARAM_NAME] as string) ?? "0"), }; diff --git a/packages/app/tests/composables/useContractInteraction.spec.ts b/packages/app/tests/composables/useContractInteraction.spec.ts index 55a07fd4f..d3cc5b31e 100644 --- a/packages/app/tests/composables/useContractInteraction.spec.ts +++ b/packages/app/tests/composables/useContractInteraction.spec.ts @@ -115,7 +115,7 @@ describe("useContractInteraction:", () => { }, { [PAYABLE_AMOUNT_PARAM_NAME]: "0.1", - address: ["0x0cc725e6ba24e7db79f62f22a7994a8ee33adc1b"], + spender: ["0x0cc725e6ba24e7db79f62f22a7994a8ee33adc1b"], } ); expect(mock.mock.lastCall).toEqual([ @@ -162,7 +162,7 @@ describe("useContractInteraction:", () => { "0x0cc725e6ba24e7db79f62f22a7994a8ee33adc1b", { ...abiFragment, - inputs: [], + inputs: [{ internalType: "bool", name: "bool", type: "bool" }], stateMutability: "payable", }, {