mirror of
https://github.com/status-im/snt-voting.git
synced 2025-02-23 15:48:10 +00:00
use safemath to prevent totalBallots overflow
This patches a vulnerability discovered where someone can pass in large ballot sizes and cause an overflow to pass the check below
This commit is contained in:
parent
ed58fb0873
commit
e7a45595cb
57
contracts/math/SafeMath.sol
Normal file
57
contracts/math/SafeMath.sol
Normal file
@ -0,0 +1,57 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
/**
|
||||
* @title SafeMath
|
||||
* @dev Unsigned math operations with safety checks that revert on error
|
||||
*/
|
||||
library SafeMath {
|
||||
/**
|
||||
* @dev Multiplies two unsigned integers, reverts on overflow.
|
||||
*/
|
||||
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
|
||||
// benefit is lost if 'b' is also tested.
|
||||
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint256 c = a * b;
|
||||
require(c / a == b);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
|
||||
*/
|
||||
function div(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// Solidity only automatically asserts when dividing by 0
|
||||
require(b > 0);
|
||||
uint256 c = a / b;
|
||||
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
|
||||
*/
|
||||
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b <= a);
|
||||
uint256 c = a - b;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Adds two unsigned integers, reverts on overflow.
|
||||
*/
|
||||
function add(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
uint256 c = a + b;
|
||||
require(c >= a);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
}
|
@ -3,9 +3,11 @@ pragma solidity ^0.4.24;
|
||||
import "../common/Controlled.sol";
|
||||
import "../token/MiniMeToken.sol";
|
||||
import "../rlp/RLPHelper.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
|
||||
|
||||
contract PollManager is Controlled {
|
||||
using SafeMath for uint256;
|
||||
|
||||
struct Poll {
|
||||
uint startBlock;
|
||||
@ -182,7 +184,7 @@ contract PollManager is Controlled {
|
||||
|
||||
uint totalBallots = 0;
|
||||
for(uint8 i = 0; i < _ballots.length; i++){
|
||||
totalBallots += _ballots[i]; // Use safe math here
|
||||
totalBallots += totalBallots.add(_ballots[i]);
|
||||
|
||||
p.ballots[i][msg.sender] = _ballots[i];
|
||||
|
||||
@ -257,7 +259,6 @@ contract PollManager is Controlled {
|
||||
bool _finalized,
|
||||
uint _voters,
|
||||
address _author,
|
||||
uint _rewards,
|
||||
uint[100] _tokenTotal,
|
||||
uint[100] _quadraticVotes,
|
||||
uint[100] _votersByBallot
|
||||
@ -276,7 +277,6 @@ contract PollManager is Controlled {
|
||||
_author = p.author;
|
||||
_finalized = (!p.canceled) && (block.number >= _endTime);
|
||||
_voters = p.voters;
|
||||
_rewards = p.rewards;
|
||||
|
||||
for(uint8 i = 0; i < p.numBallots; i++){
|
||||
_tokenTotal[i] = p.results[i];
|
||||
@ -337,7 +337,7 @@ contract PollManager is Controlled {
|
||||
totalVotes += p.results[i];
|
||||
}
|
||||
require(token.balanceOf(msg.sender) >= claimerVotes, "Can not claim with less tokens");
|
||||
uint amount = (p.rewards * claimerVotes) / totalVotes;
|
||||
uint amount = p.rewards.mul(claimerVotes).div(totalVotes);
|
||||
p.paidClaims[msg.sender] = true;
|
||||
require(token.transfer(msg.sender, amount), "Reward token transfer failed");
|
||||
emit RewardClaimed(_idPoll, msg.sender, amount);
|
||||
@ -353,7 +353,7 @@ contract PollManager is Controlled {
|
||||
Poll storage p = _polls[_idPoll];
|
||||
require(block.number >= p.startBlock && block.timestamp < p.endTime && !p.canceled, "Poll is inactive");
|
||||
require(token.transferFrom(msg.sender, address(this), _amount), "Failed to transfer tokens in");
|
||||
p.rewards += amount;
|
||||
p.rewards += _amount;
|
||||
emit RewardAdded(_idPoll, msg.sender, _amount);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user