1

Getting this error:

Copying of type struct ArrayTest.swapDataStruct memory[] memory to storage not yet supported 

when I try to assign a parameter to the function which is an array of structs to an array of structs property inside the contract's function. Not quite sure how to do the assignment, but the remix compiler doesn't like the assignment, even though the Hardhat compiler didn't complain.

Also, if I want to test passing in struct values to the array parameter in Remix, what format do I have to enter the data in the Remix execute function field as a parameter value to the function?

Thanks in advance for any help!

// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

contract ArrayTest {
    
    struct swapDataStruct {
    address token0Address;
    uint256 token0Amount; 
    address token1Address;
    uint256 token1Amount;
    string dexType; 
    uint256 timeout; 
    address routerAddress;
    uint24 poolFee; 
}

swapDataStruct[] private swapDataArray;

function requestSwap(swapDataStruct[] memory _swapDataArray) public {

    swapDataArray = _swapDataArray;

    // Do something with the property swapDataArray

  }

}

2 Answers 2

1

Solidity does not support direct assignment of an array of structs from memory to storage.

However, to work around this limitation, you can iterate through the elements of the array and assign them individually, like:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

contract ArrayTest {
    struct swapDataStruct {
        address token0Address;
        uint256 token0Amount;
        address token1Address;
        uint256 token1Amount;
        string dexType;
        uint256 timeout;
        address routerAddress;
        uint24 poolFee;
    }

    swapDataStruct[] private swapDataArray;

    function requestSwap(swapDataStruct[] memory _swapDataArray) public {
        for (uint256 i = 0; i < _swapDataArray.length; i++) {
            swapDataArray.push(_swapDataArray[i]);
        }
        // Do something with the property swapDataArray
    }
}

3

Understanding the Error

The error you encountered: "Copying of type struct ArrayTest.swapDataStruct memory[] memory to storage not yet supported" arises due to Solidity's type system and memory management. When you try to assign a whole array of memory structs directly to a storage array, Solidity currently does not support this operation because of the significant differences in how memory and storage are handled.

In Solidity, memory arrays are temporary and exist only during the execution of a function, whereas storage arrays are persistent and written to the blockchain.

A More Robust Solution

You can iterate through each element in the memory array and append it to the storage array using the push() method. This method is gas-efficient as it avoids copying the entire array at once and instead copies one element at a time.

Here’s an enhanced version of your contract with added comments for clarity and additional best practices:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

contract ArrayTest {
    struct SwapDataStruct {
        address token0Address;
        uint256 token0Amount; 
        address token1Address;
        uint256 token1Amount;
        string dexType; 
        uint256 timeout; 
        address routerAddress;
        uint24 poolFee; 
    }

    SwapDataStruct[] private swapDataArray;

    function requestSwap(SwapDataStruct[] memory _swapDataArray) public {
        for (uint256 i = 0; i < _swapDataArray.length; i++) {
            swapDataArray.push(_swapDataArray[i]);
        }
        // Further processing can be added here.
    }
}

Testing Struct Arrays in Remix

To test this function in Remix, you need to format the input correctly. Since your function requestSwap takes an array of structs, you must pass the data as an array of struct objects. Here’s the format you’d use in the Remix "Deploy & Run Transactions" panel:

[{
    "token0Address": "0x...",
    "token0Amount": "1000000000000000000",
    "token1Address": "0x...",
    "token1Amount": "5000000000000000000",
    "dexType": "Uniswap",
    "timeout": "3600",
    "routerAddress": "0x...",
    "poolFee": "3000"
}]

Make sure to replace placeholder values with actual addresses and numbers. This JSON-like structure represents each struct as an object within the array.

*The full text of this answer was passed through GPT-4 with the prompt (notifying according to the policy https://ethereum.stackexchange.com/help/gen-ai-policy): "Correct the grammatical errors without changing the actual meaning of the text"

4
  • 2
    Your answer look like something generated with AI. This statement Directly assigning a memory array to a storage array would potentially involve copying an unknown amount of data isn't true. In your own example it is copying the data from memory.
    – Ismael
    Commented May 3 at 4:57
  • 1
    Under testing struct arrays in Remix, I found that I actually had to submit the data like this to Remix: [[structVariable1, structVariable2, structVariable3]] as a tuple -- I'm not sure if your format is different or equivalent. Commented May 5 at 10:24
  • 1
    Please see ethereum.stackexchange.com/help/gen-ai-policy Your answers may get deleted per policy.
    – eth
    Commented May 9 at 5:03
  • Added required changes Commented May 10 at 8:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.