Commit 453a1982 by Manuel Aráoz Committed by GitHub

Merge pull request #184 from maraoz/safemath

Make SafeMath a library
parents 58814299 7592122e
...@@ -4,26 +4,26 @@ pragma solidity ^0.4.8; ...@@ -4,26 +4,26 @@ pragma solidity ^0.4.8;
/** /**
* Math operations with safety checks * Math operations with safety checks
*/ */
contract SafeMath { library SafeMath {
function safeMul(uint a, uint b) internal returns (uint) { function mul(uint a, uint b) internal returns (uint) {
uint c = a * b; uint c = a * b;
assert(a == 0 || c / a == b); assert(a == 0 || c / a == b);
return c; return c;
} }
function safeDiv(uint a, uint b) internal returns (uint) { function div(uint a, uint b) internal returns (uint) {
assert(b > 0); assert(b > 0);
uint c = a / b; uint c = a / b;
assert(a == b * c + a % b); assert(a == b * c + a % b);
return c; return c;
} }
function safeSub(uint a, uint b) internal returns (uint) { function sub(uint a, uint b) internal returns (uint) {
assert(b <= a); assert(b <= a);
return a - b; return a - b;
} }
function safeAdd(uint a, uint b) internal returns (uint) { function add(uint a, uint b) internal returns (uint) {
uint c = a + b; uint c = a + b;
assert(c >= a); assert(c >= a);
return c; return c;
......
...@@ -9,14 +9,16 @@ import '../SafeMath.sol'; ...@@ -9,14 +9,16 @@ import '../SafeMath.sol';
* Base contract supporting async send for pull payments. * Base contract supporting async send for pull payments.
* Inherit from this contract and use asyncSend instead of send. * Inherit from this contract and use asyncSend instead of send.
*/ */
contract PullPayment is SafeMath { contract PullPayment {
using SafeMath for uint;
mapping(address => uint) public payments; mapping(address => uint) public payments;
uint public totalPayments; uint public totalPayments;
// store sent amount as credit to be pulled, called by payer // store sent amount as credit to be pulled, called by payer
function asyncSend(address dest, uint amount) internal { function asyncSend(address dest, uint amount) internal {
payments[dest] = safeAdd(payments[dest], amount); payments[dest] = payments[dest].add(amount);
totalPayments = safeAdd(totalPayments, amount); totalPayments = totalPayments.add(amount);
} }
// withdraw accumulated balance, called by payee // withdraw accumulated balance, called by payee
...@@ -32,7 +34,7 @@ contract PullPayment is SafeMath { ...@@ -32,7 +34,7 @@ contract PullPayment is SafeMath {
throw; throw;
} }
totalPayments = safeSub(totalPayments, payment); totalPayments = totalPayments.sub(payment);
payments[payee] = 0; payments[payee] = 0;
if (!payee.send(payment)) { if (!payee.send(payment)) {
......
...@@ -9,21 +9,24 @@ import '../SafeMath.sol'; ...@@ -9,21 +9,24 @@ import '../SafeMath.sol';
* Basic token * Basic token
* Basic version of StandardToken, with no allowances * Basic version of StandardToken, with no allowances
*/ */
contract BasicToken is ERC20Basic, SafeMath { contract BasicToken is ERC20Basic {
using SafeMath for uint;
mapping(address => uint) balances; mapping(address => uint) balances;
/* /*
* Fix for the ERC20 short address attack * Fix for the ERC20 short address attack
*/ */
modifier onlyPayloadSize(uint size) { modifier onlyPayloadSize(uint size) {
assert(msg.data.length >= size + 4); if(msg.data.length < size + 4) {
throw;
}
_; _;
} }
function transfer(address _to, uint _value) onlyPayloadSize(2 * 32) { function transfer(address _to, uint _value) onlyPayloadSize(2 * 32) {
balances[msg.sender] = safeSub(balances[msg.sender], _value); balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = safeAdd(balances[_to], _value); balances[_to] = balances[_to].add(_value);
Transfer(msg.sender, _to, _value); Transfer(msg.sender, _to, _value);
} }
......
...@@ -32,10 +32,10 @@ contract CrowdsaleToken is StandardToken { ...@@ -32,10 +32,10 @@ contract CrowdsaleToken is StandardToken {
throw; throw;
} }
uint tokens = safeMul(msg.value, getPrice()); uint tokens = msg.value.mul(getPrice());
totalSupply = safeAdd(totalSupply, tokens); totalSupply = totalSupply.add(tokens);
balances[recipient] = safeAdd(balances[recipient], tokens); balances[recipient] = balances[recipient].add(tokens);
if (!multisig.send(msg.value)) { if (!multisig.send(msg.value)) {
throw; throw;
......
...@@ -10,7 +10,6 @@ import './ERC20Basic.sol'; ...@@ -10,7 +10,6 @@ import './ERC20Basic.sol';
*/ */
contract ERC20 is ERC20Basic { contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) constant returns (uint); function allowance(address owner, address spender) constant returns (uint);
function transferFrom(address from, address to, uint value); function transferFrom(address from, address to, uint value);
function approve(address spender, uint value); function approve(address spender, uint value);
event Approval(address indexed owner, address indexed spender, uint value); event Approval(address indexed owner, address indexed spender, uint value);
......
...@@ -29,8 +29,8 @@ contract MintableToken is StandardToken, Ownable { ...@@ -29,8 +29,8 @@ contract MintableToken is StandardToken, Ownable {
} }
function mint(address _to, uint _amount) onlyOwner canMint returns (bool) { function mint(address _to, uint _amount) onlyOwner canMint returns (bool) {
totalSupply = safeAdd(totalSupply, _amount); totalSupply = totalSupply.add(_amount);
balances[_to] = safeAdd(balances[_to], _amount); balances[_to] = balances[_to].add(_amount);
Mint(_to, _amount); Mint(_to, _amount);
return true; return true;
} }
......
...@@ -19,12 +19,12 @@ contract StandardToken is BasicToken, ERC20 { ...@@ -19,12 +19,12 @@ contract StandardToken is BasicToken, ERC20 {
function transferFrom(address _from, address _to, uint _value) { function transferFrom(address _from, address _to, uint _value) {
var _allowance = allowed[_from][msg.sender]; var _allowance = allowed[_from][msg.sender];
// Check is not needed because safeSub(_allowance, _value) will already throw if this condition is not met // Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
// if (_value > _allowance) throw; // if (_value > _allowance) throw;
balances[_to] = safeAdd(balances[_to], _value); balances[_to] = balances[_to].add(_value);
balances[_from] = safeSub(balances[_from], _value); balances[_from] = balances[_from].sub(_value);
allowed[_from][msg.sender] = safeSub(_allowance, _value); allowed[_from][msg.sender] = _allowance.sub(_value);
Transfer(_from, _to, _value); Transfer(_from, _to, _value);
} }
......
...@@ -52,8 +52,8 @@ contract VestedToken is StandardToken, LimitedTransferToken { ...@@ -52,8 +52,8 @@ contract VestedToken is StandardToken, LimitedTransferToken {
grants[_holder][_grantId] = grants[_holder][grants[_holder].length - 1]; grants[_holder][_grantId] = grants[_holder][grants[_holder].length - 1];
grants[_holder].length -= 1; grants[_holder].length -= 1;
balances[msg.sender] = safeAdd(balances[msg.sender], nonVested); balances[msg.sender] = balances[msg.sender].add(nonVested);
balances[_holder] = safeSub(balances[_holder], nonVested); balances[_holder] = balances[_holder].sub(nonVested);
Transfer(_holder, msg.sender, nonVested); Transfer(_holder, msg.sender, nonVested);
} }
...@@ -98,32 +98,33 @@ contract VestedToken is StandardToken, LimitedTransferToken { ...@@ -98,32 +98,33 @@ contract VestedToken is StandardToken, LimitedTransferToken {
return tokens; return tokens;
} }
uint256 cliffTokens = safeDiv(safeMul(tokens, safeSub(cliff, start)), safeSub(vesting, start)); uint256 cliffTokens = tokens.mul(cliff.sub(start)).div(vesting.sub(start));
vestedTokens = cliffTokens; vestedTokens = cliffTokens;
uint256 vestingTokens = safeSub(tokens, cliffTokens); uint256 vestingTokens = tokens.sub(cliffTokens);
vestedTokens = safeAdd(vestedTokens, safeDiv(safeMul(vestingTokens, safeSub(time, cliff)), safeSub(vesting, cliff))); vestedTokens = vestedTokens.add(vestingTokens.mul(time.sub(cliff)).div(vesting.sub(cliff)));
} }
function nonVestedTokens(TokenGrant grant, uint64 time) private constant returns (uint256) { function nonVestedTokens(TokenGrant grant, uint64 time) private constant returns (uint256) {
return safeSub(grant.value, vestedTokens(grant, time)); return grant.value.sub(vestedTokens(grant, time));
} }
function lastTokenIsTransferableDate(address holder) constant public returns (uint64 date) { function lastTokenIsTransferableDate(address holder) constant public returns (uint64 date) {
date = uint64(now); date = uint64(now);
uint256 grantIndex = grants[holder].length; uint256 grantIndex = grants[holder].length;
for (uint256 i = 0; i < grantIndex; i++) { for (uint256 i = 0; i < grantIndex; i++) {
date = max64(grants[holder][i].vesting, date); date = SafeMath.max64(grants[holder][i].vesting, date);
} }
} }
function transferableTokens(address holder, uint64 time) constant public returns (uint256 nonVested) { function transferableTokens(address holder, uint64 time) constant public returns (uint256 nonVested) {
uint256 grantIndex = grants[holder].length; uint256 grantIndex = grants[holder].length;
for (uint256 i = 0; i < grantIndex; i++) { for (uint256 i = 0; i < grantIndex; i++) {
nonVested = safeAdd(nonVested, nonVestedTokens(grants[holder][i], time)); uint256 current = nonVestedTokens(grants[holder][i], time);
nonVested = nonVested.add(current);
} }
return min256(safeSub(balances[holder], nonVested), super.transferableTokens(holder, time)); return SafeMath.min256(balances[holder].sub(nonVested), super.transferableTokens(holder, time));
} }
} }
...@@ -4,18 +4,18 @@ pragma solidity ^0.4.8; ...@@ -4,18 +4,18 @@ pragma solidity ^0.4.8;
import '../../contracts/SafeMath.sol'; import '../../contracts/SafeMath.sol';
contract SafeMathMock is SafeMath { contract SafeMathMock {
uint public result; uint public result;
function multiply(uint a, uint b) { function multiply(uint a, uint b) {
result = safeMul(a, b); result = SafeMath.mul(a, b);
} }
function subtract(uint a, uint b) { function subtract(uint a, uint b) {
result = safeSub(a, b); result = SafeMath.sub(a, b);
} }
function add(uint a, uint b) { function add(uint a, uint b) {
result = safeAdd(a, b); result = SafeMath.add(a, b);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment