# Solc Compiler oversight? Innappropriate mapping declaration overwrites storage

I have written a contract that has the mapping storage variable A & B. These variables get initialized with some values in constructor. A method getBalance returns the balance from mapping A & B.

In the method I declared another mapping - thinking that it would give a compilation error (since mapping allowed for storage only). Instead it lead to a strange behavior - appears that the new local mapping overwrites mappingA.

Result without local mapping (100, 200) as expected Result with local mapping (500, 200) <<< Why?

/** Tested in Truffle/TestRPC **/

contract Mapping {

function Mapping() {
// constructor
balancesA[msg.sender] = 100;
balancesB[msg.sender] = 200;
}

// If these 2 lines are commented then behavior is as expected
balancers[msg.sender] = 500;

}
}

• I can confirm that. The mapping in the function seems to collide with the first mapping that was declared properly. – Rob Hitchens - B9lab Mar 1 '17 at 13:20
• Have you tried running it on testnet (or private network)? Sometimes TestRPC behaves differently then "real" network - maybe thats the case. – radmen Mar 1 '17 at 13:38
• I can reproduce in Geth too. – Xavier Leprêtre B9lab Mar 1 '17 at 18:08
• @ACloudFan It looks like it's bug report time. Do you want to do the honors? – Rob Hitchens - B9lab Mar 2 '17 at 4:46
• Bug aside, the return parameters aren't being used correctly. Should be returns (uint, uint) rather than being named, or balanceA = balancesA[addr]; etc – o0ragman0o Mar 3 '17 at 0:50

Opened an issue here, github, ethereum, solidity, issue 1731: https://github.com/ethereum/solidity/issues/1731

If I understand their process correctly, original issue 1731 is closed by issue 1737 which is now merged. Possibly the compiler is going to emit an error for this sort of thing in the future.

Both thumbs up for the devs!

https://github.com/ethereum/solidity/pull/1737

Aside from that it is a bug in solidity (as it should notice that uninitialized variable is used), it worth mentioning that the code is not correct also.

The problem is that mapping(address => uint) balancers in function body does not allocate new mapping. It just introduces variable balancers which can reference some mapping (allocated elsewhere).

In the example balancers is not initialized and coincidentially references balancesA. Hence the unexpected behavior.

From Solidity docs:

Mappings are only allowed for state variables (or as storage reference types in internal functions).

I'm afraid this is not a bug. I very much agree that it's a problem and presents a huge trap, though.

mapping(address => uint) memory balancers;