Signed Integer Array
Overview
- Severity: High
- Confidence: High
- Affected Versions: 0.4.7 - 0.5.9
What is the Signed Integer Array vulnerability?
In certain earlier versions of the Solidity compiler, literal arrays containing negative signed integer values were not properly converted when being written into storage slots of their associated smart contracts. The values were instead being converted to positive integers, which could potentially affect the behavior of the contract in unexpected ways if logic depended on those array values.
Further reading: Solidity Storage Array Bug Announcement
Technical example of vulnerable code
// SPDX-License-Identifier: Unlicense
pragma solidity 0.4.7;
contract BadRewardArray {
uint256 rewardPool;
uint256 rewardShare;
int[3] claimedRewards = [-1, -1, -1];
constructor() {
rewardPool = msg.value();
rewardShare = (rewardPool / 3) - 1;
}
function claim(uint8 slot) private {
if (claimedRewards[slot] == -1) {
claimedRewards[slot] = 1;
msg.sender.transfer(rewardShare);
}
}
}
In the example above, contract BadRewardArray
is intended to be initialized with three available Ether rewards, which can be claimed by the first callers to the claim()
function. However, because this contract is being compiled using an affected version of the Solidity compiler and declares the literal array value of claimedRewards
with negative values, these will be recorded incorrectly as positive values. As a result, the claim()
function's logic will never succeed for any caller.
Technical example of how to fix the vulnerability
// SPDX-License-Identifier: Unlicense
pragma solidity 0.6.0;
contract RewardArray {
uint256 rewardPool;
uint256 rewardShare;
int[3] claimedRewards = [0, 0, 0];
constructor() {
rewardPool = msg.value();
rewardShare = (rewardPool / 3) - 1;
}
function claim(uint8 slot) private {
if (claimedRewards[slot] == 0) {
claimedRewards[slot] = 1;
msg.sender.transfer(rewardShare);
}
}
}
In the corrected RewardArray
contract above, the claimedRewards
array is initialized with zero values instead of negative values. In addition, the pragma specifies a newer version of the Solidity compiler that is not affected by the Signed Integer Array vulnerability.