Skip to content
This repository was archived by the owner on Jan 18, 2023. It is now read-only.

Commit 2ef2789

Browse files
authored
Merge pull request #2 from jimpo/fix-overflow-bug
Fix overflow bug
2 parents de1e3ab + d8488c0 commit 2ef2789

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

contracts/SetToken.sol

+4-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ contract SetToken is StandardToken, DetailedERC20("", "", 18), Set {
7171
uint currentUnits = units[i];
7272

7373
// The transaction will fail if any of the tokens fail to transfer
74-
assert(ERC20(currentToken).transferFrom(msg.sender, this, currentUnits * quantity));
74+
uint transferValue = SafeMath.mul(currentUnits, quantity);
75+
assert(ERC20(currentToken).transferFrom(msg.sender, this, transferValue));
7576
}
7677

7778
// If successful, increment the balance of the user’s {Set} token
@@ -107,7 +108,8 @@ contract SetToken is StandardToken, DetailedERC20("", "", 18), Set {
107108
uint currentUnits = units[i];
108109

109110
// The transaction will fail if any of the tokens fail to transfer
110-
assert(ERC20(currentToken).transfer(msg.sender, currentUnits * quantity));
111+
uint transferValue = SafeMath.mul(currentUnits, quantity);
112+
assert(ERC20(currentToken).transfer(msg.sender, transferValue));
111113
}
112114

113115
LogRedemption(msg.sender, quantity);

test/setToken.js

+36-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ const assert = require('chai').assert;
33
const SetToken = artifacts.require('SetToken');
44
const StandardTokenMock = artifacts.require('StandardTokenMock');
55

6+
const BigNumber = require('bignumber.js');
7+
68
const expectedExceptionPromise = require('./helpers/expectedException.js');
79
web3.eth.getTransactionReceiptMined = require('./helpers/getTransactionReceiptMined.js');
810

@@ -41,7 +43,7 @@ contract('{Set}', function(accounts) {
4143

4244
it('should not allow creation of a {Set} with no inputs', async () => {
4345
return expectedExceptionPromise(
44-
() => SetToken.new([], [], { from: testAccount }),
46+
() => SetToken.new([], [], name, symbol, { from: testAccount }),
4547
3000000,
4648
);
4749
});
@@ -141,7 +143,6 @@ contract('{Set}', function(accounts) {
141143

142144
assert.exists(setToken, 'Set Token does not exist');
143145
});
144-
145146
it('should have the basic information correct', async () => {
146147
// Assert correct name
147148
let setTokenName = await setToken.name({ from: testAccount });
@@ -280,5 +281,38 @@ contract('{Set}', function(accounts) {
280281
assert.strictEqual(postIssueBalanceIndexofOwner.toString(), '0');
281282
});
282283
}
284+
285+
it('should disallow issuing a quantity of tokens that would trigger an overflow', async () => {
286+
var units = 2;
287+
288+
// This creates a SetToken with only one backing token.
289+
setToken = await SetToken.new(
290+
[tokenB.address],
291+
[units],
292+
setName,
293+
setSymbol,
294+
{ from: testAccount },
295+
);
296+
297+
var quantity = 100;
298+
var quantityB = quantity * units;
299+
300+
await tokenB.approve(setToken.address, quantityB, {
301+
from: testAccount,
302+
});
303+
304+
// Set quantity to 2^254 + 100. This quantity * 2 will overflow a
305+
// uint256 and equal 200.
306+
var overflow = new BigNumber('0x8000000000000000000000000000000000000000000000000000000000000000');
307+
var quantityOverflow = overflow.plus(quantity);
308+
309+
await expectedExceptionPromise(
310+
() =>
311+
setToken.issue(quantityOverflow, {
312+
from: testAccount,
313+
}),
314+
3000000,
315+
);
316+
});
283317
});
284318
});

0 commit comments

Comments
 (0)