-
Notifications
You must be signed in to change notification settings - Fork 42
Description
There is a bug in the way the mapping names are used. Given the following contract;
pragma solidity ^0.4.24;
contract Storage {
mapping (address => uint) public myFirstArray123;
mapping (address => uint) public mySecondArray;
}
Note that both functions refer to the same mapping.
This compiles to 60806040526004361060485763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166357092fea8114604d57806390f1f82d14608a575b600080fd5b348015605857600080fd5b50607873ffffffffffffffffffffffffffffffffffffffff6004351660b5565b60408051918252519081900360200190f35b348015609557600080fd5b50607873ffffffffffffffffffffffffffffffffffffffff6004351660c7565b60016020526000908152604090205481565b600060208190529081526040902054815600a165627a7a723058208d63c3e798dc9103a25dc8a216e21a6f924b5c584f8eb37ad4d0a8f5cd59bfd20029.
This will decompile as
mapping (unknown => unknown) mapping1;
mapping (unknown => unknown) mapping2;
function 57092fea() public view {
return(mapping1[_arg0]);
}
function 90f1f82d() public view {
return(mapping1[_arg0]);
}
The public getter functions refer now to the same mapping, although there are two mappings.
This happens becase the SLOAD instruction will create a MappingLoad using count = Object.keys(state.mappings).indexOf(mappingLocation.toString()).
When 57092fea is decompiled, it will point to mySecondArray, which is the only hence first mapping, so it has count=1 and will print (incorrectly) as mapping1.
When 90f1f82d is decompiled, it will point to myFirstArray123, which has a lower storage index, so it's the first mapping with count=1 and will print as mapping1.
I fixed it locally by not using a count variable but storing the mappingLocation, and using that in the MappingLoad.toString() function to construct a proper name. This seems to solve the issue. Are you open to a pull request?