@0x/contracts-staking: Implement better overflow detection in LibFixedMath.
This commit is contained in:
@@ -7,7 +7,7 @@ import { artifacts, TestLibFixedMathContract } from '../../src';
|
||||
|
||||
import { assertRoughlyEquals, fromFixed, toDecimal, toFixed } from '../utils/number_utils';
|
||||
|
||||
blockchainTests('LibFixedMath unit tests', env => {
|
||||
blockchainTests.only('LibFixedMath unit tests', env => {
|
||||
let testContract: TestLibFixedMathContract;
|
||||
|
||||
before(async () => {
|
||||
@@ -131,6 +131,19 @@ blockchainTests('LibFixedMath unit tests', env => {
|
||||
const tx = testContract.mulDiv.callAsync(toFixed(a), new BigNumber(n), new BigNumber(d));
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('int(-1) * int(1) / int(-1) == int(1)', async () => {
|
||||
const [a, n, d] = [-1, 1, -1];
|
||||
const r = await testContract.mulDiv.callAsync(new BigNumber(a), new BigNumber(n), new BigNumber(d));
|
||||
assertFixedEquals(r, fromFixed(1));
|
||||
});
|
||||
|
||||
it('-1 * int(1) / int(-1) == 1', async () => {
|
||||
const [a, n, d] = [-1, 1, -1];
|
||||
const r = await testContract.mulDiv.callAsync(toFixed(a), new BigNumber(n), new BigNumber(d));
|
||||
assertFixedEquals(r, 1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('add()', () => {
|
||||
@@ -170,13 +183,41 @@ blockchainTests('LibFixedMath unit tests', env => {
|
||||
it('throws on underflow', async () => {
|
||||
const [a, b] = [MIN_FIXED_VALUE, new BigNumber(-1)];
|
||||
const expectedError = new FixedMathRevertErrors.BinOpError(
|
||||
FixedMathRevertErrors.BinOpErrorCodes.SubtractionUnderflow,
|
||||
FixedMathRevertErrors.BinOpErrorCodes.AdditionOverflow,
|
||||
a,
|
||||
b,
|
||||
);
|
||||
const tx = testContract.add.callAsync(a, b);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('MIN_FIXED + MIN_FIXED throws', async () => {
|
||||
const [a, b] = [MIN_FIXED_VALUE, MIN_FIXED_VALUE];
|
||||
const expectedError = new FixedMathRevertErrors.BinOpError(
|
||||
FixedMathRevertErrors.BinOpErrorCodes.AdditionOverflow,
|
||||
a,
|
||||
b,
|
||||
);
|
||||
const tx = testContract.add.callAsync(a, b);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('MAX_FIXED + MAX_FIXED throws', async () => {
|
||||
const [a, b] = [MAX_FIXED_VALUE, MAX_FIXED_VALUE];
|
||||
const expectedError = new FixedMathRevertErrors.BinOpError(
|
||||
FixedMathRevertErrors.BinOpErrorCodes.AdditionOverflow,
|
||||
a,
|
||||
b,
|
||||
);
|
||||
const tx = testContract.add.callAsync(a, b);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('MIN_FIXED + MAX_FIXED == int(-1)', async () => {
|
||||
const [a, b] = [MIN_FIXED_VALUE, MAX_FIXED_VALUE];
|
||||
const r = await testContract.add.callAsync(a, b);
|
||||
expect(r).to.bignumber.eq(-1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sub()', () => {
|
||||
@@ -205,7 +246,7 @@ blockchainTests('LibFixedMath unit tests', env => {
|
||||
it('throws on underflow', async () => {
|
||||
const [a, b] = [MIN_FIXED_VALUE, new BigNumber(1)];
|
||||
const expectedError = new FixedMathRevertErrors.BinOpError(
|
||||
FixedMathRevertErrors.BinOpErrorCodes.SubtractionUnderflow,
|
||||
FixedMathRevertErrors.BinOpErrorCodes.AdditionOverflow,
|
||||
a,
|
||||
b.negated(),
|
||||
);
|
||||
@@ -223,6 +264,46 @@ blockchainTests('LibFixedMath unit tests', env => {
|
||||
const tx = testContract.sub.callAsync(a, b);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('MIN_FIXED - MIN_FIXED throws', async () => {
|
||||
const [a, b] = [MIN_FIXED_VALUE, MIN_FIXED_VALUE];
|
||||
// This fails because `-MIN_FIXED_VALUE == MIN_FIXED_VALUE` because of
|
||||
// twos-complement.
|
||||
const expectedError = new FixedMathRevertErrors.BinOpError(
|
||||
FixedMathRevertErrors.BinOpErrorCodes.AdditionOverflow,
|
||||
a,
|
||||
b,
|
||||
);
|
||||
const tx = testContract.sub.callAsync(a, b);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('MAX_FIXED - MAX_FIXED == 0', async () => {
|
||||
const [a, b] = [MAX_FIXED_VALUE, MAX_FIXED_VALUE];
|
||||
const r = await testContract.sub.callAsync(a, b);
|
||||
return expect(r).to.bignumber.eq(0);
|
||||
});
|
||||
|
||||
it('MIN_FIXED - MAX_FIXED throws', async () => {
|
||||
const [a, b] = [MIN_FIXED_VALUE, MAX_FIXED_VALUE];
|
||||
const expectedError = new FixedMathRevertErrors.BinOpError(
|
||||
FixedMathRevertErrors.BinOpErrorCodes.AdditionOverflow,
|
||||
a,
|
||||
b.negated(),
|
||||
);
|
||||
const tx = testContract.sub.callAsync(a, b);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('MAX_FIXED - MIN_FIXED throws', async () => {
|
||||
const [a, b] = [MAX_FIXED_VALUE, MIN_FIXED_VALUE];
|
||||
const expectedError = new FixedMathRevertErrors.SignedValueError(
|
||||
FixedMathRevertErrors.ValueErrorCodes.TooSmall,
|
||||
b,
|
||||
);
|
||||
const tx = testContract.sub.callAsync(a, b);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mul()', () => {
|
||||
|
||||
Reference in New Issue
Block a user