1

This is the mapping containing the struct.

    mapping(address => UserFessInfo) public userFeesInfo;

This is the struct UserFeeInfo

    struct UserFessInfo {
    uint256 stakedAmount;
    uint256 stakedWeight;
    uint256 lastStakedBlock;
    uint256 lastClaimedBlock;
    mapping(uint256 => uint256) epochToUserStakedWeight;
}

Now, to retrieve these values for testing I tried to use this syntax in foundry test file.

       (
        uint256 stakedAmount,
        uint256 stakedWeight,
        uint256 lastStakedBlock,
        uint256 lastClaimedBlock,
        mapping(uint256 => uint256) epochToUserStakedWeight
    ) = core.userFeesInfo(bob);

But later I realized that it contains mapping and needed the data location to be set as storage. And I was right as I got this error.

error[6651]: test/StakeAndClaim.t.sol:85:13: TypeError: Data location must be "storage" for variable, but none was given.
        mapping(uint256 => uint256) epochToUserStakedWeight
        ^-------------------------------------------------^

I am confused about how to do this. How to store the struct that is returned from the mapping?

1 Answer 1

1

I believe you need to add 'storage' (or 'memory') in the following line:

mapping(uint256 => uint256) storage epochToUserStakedWeight

To answer your other question, Solidity cannot return the data of mappings inside a struct in the way you are attempting. You can however return the data at a specific place in the mapping.

In the past what I have done is add a view method that returns the value at a specific place in the mapping:

function getUserEpochStakedWeight(address user, uint256 epoch) 
public view returns (uint256) {
   return userFeesInfo[user].epochToUserStakedWeight[epoch];
}

You can access the non-mapping properties in the way your were attempting before but excluding the mapping:

(
   uint256 stakedAmount,
   uint256 stakedWeight,
   uint256 lastStakedBlock,
   uint256 lastClaimedBlock
) = core.userFeesInfo(bob);
3
  • Tried this, but it seems like we are getting the mapping. When I added storage, I got another error saying that LHS has 5 arguments and RHS has 4 arguments. What are your views on this? Like, calling a public mapping doesn't return the mapping inside the struct??? Commented Jul 3, 2023 at 10:22
  • Could it be because you have called it on a mapping or another object? solidity core.userFeesInfo(bob); Is 'core' an object of some type? If it is, the method is called on this object, and that would fill one of the 5 arguments you have set. Commented Jul 3, 2023 at 18:02
  • Core is a deployed instance of contract. I have deployed it using the new keyword, as we do in Foundry. Commented Jul 4, 2023 at 3:34

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.