1

I have this foundry function and I don't have any idea how to pass an array of structs to batchList function

function test_ListMockERC721() public {
    vm.prank(add1);
    erc721Mock.mint(msg.sender);
    marketsc.batchList([[erc721Mock, 1, 0, add1, 1], [erc721Mock, 2, 0, add1, 1]]);
}

This is the function signature from the smart contract:

function batchList(InputOrder[] calldata inputOrders) external;

2 Answers 2

2
+50

I assume that InputOrder is a structure. Then the solution is:

function test_ListMockERC721() public {
    vm.prank(add1);
    erc721Mock.mint(msg.sender);
    marketsc.InputOrder[] memory inputOtders = new marketsc.InputOrder[](2);
    inputOtders[0] = marketsc.InputOrder(erc721Mock, 1, 0, add1, 1);
    inputOtders[1] = marketsc.InputOrder(erc721Mock, 2, 0, add1, 1);
    marketsc.batchList(inputOtders);
}
1

Since solidity does not natively support passing an array of structs in a function from the outside of the smart contract, you have to decompose the struct array into several basic type arrays and reassemble them in the function. Here is a sample array of structs:

struct InputOrder {
address token;    
uint256 tokenId;
uint256 tokenAmount;
address payable recipient;  
uint8 v;    
bytes32 r;   
bytes32 s;   }

If you want to pass an array of InputOrder structs, we need to decompose them into 7 arrays: an address array for the token, a uint array for the tokenId, a uint array for the tokenAmount, an address array for the recipient, a uint8 array for v, a bytes32 array for r, and a bytes32 array for s. Your smart contract batchList function could look something like this:

function batchList(
    address[] calldata token,
    uint256[] calldata tokenId,
    uint256[] calldata tokenAmount,
    address[] calldata recipient,
    uint8[] calldata v,
    bytes32[] calldata r,
    bytes32[] calldata s
) external {
    // Here you can iterate through one of the arrays (i.e., token array) and then
    // reconstruct your struct using the corresponding index for other arrays.
    for (uint i = 0; i < token.length; i++) {
        InputOrder memory inputOrder = InputOrder({
            token: token[i],
            tokenId: tokenId[i],
            tokenAmount: tokenAmount[i],
            recipient: recipient[i],
            v: v[i],
            r: r[i],
            s: s[i]
        });
        // Do something with inputOrder
    }
}

In your test function, you can call the batchList function as follows:

function test_ListMockERC721() public {
    // other code here.
    marketsc.batchList(
        [erc721Mock, erc721Mock],
        [1, 2],
        [0, 0],
        [add1, add1],
        [1, 1],
        [bytes32 exampleR, bytes32 exampleR],
        [bytes32 exampleS, bytes32 exampleS]
    );
}

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.