@0x/contracts-exchange-libs
: Add explicit tests for LibMath
and LibFillResults
functions.
`@0x/contracts-exchange-libs`: Add tests for `ReferenceFunctions`.
This commit is contained in:
parent
a179a6892c
commit
293510c087
@ -1,16 +1,17 @@
|
||||
import {
|
||||
blockchainTests,
|
||||
constants,
|
||||
describe,
|
||||
testCombinatoriallyWithReferenceFunc,
|
||||
uint256Values,
|
||||
expect,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { FillResults } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { artifacts, ReferenceFunctions, TestLibsContract } from '../src';
|
||||
|
||||
blockchainTests('LibFillResults', env => {
|
||||
const CHAIN_ID = 1337;
|
||||
const { ONE_ETHER, MAX_UINT256 } = constants;
|
||||
let libsContract: TestLibsContract;
|
||||
|
||||
before(async () => {
|
||||
@ -23,47 +24,76 @@ blockchainTests('LibFillResults', env => {
|
||||
});
|
||||
|
||||
describe('addFillResults', () => {
|
||||
function makeFillResults(value: BigNumber): FillResults {
|
||||
// HACK(dorothy-zbornak): We reuse values across fields,
|
||||
// but this is fine because `addFillResults()` never does
|
||||
// any math between them.
|
||||
return {
|
||||
makerAssetFilledAmount: value,
|
||||
takerAssetFilledAmount: value,
|
||||
makerFeePaid: value,
|
||||
takerFeePaid: value,
|
||||
};
|
||||
}
|
||||
describe('explicit tests', () => {
|
||||
const DEFAULT_FILL_RESULTS = [
|
||||
{
|
||||
makerAssetFilledAmount: ONE_ETHER,
|
||||
takerAssetFilledAmount: ONE_ETHER.times(2),
|
||||
makerFeePaid: ONE_ETHER.times(0.001),
|
||||
takerFeePaid: ONE_ETHER.times(0.002),
|
||||
},
|
||||
{
|
||||
makerAssetFilledAmount: ONE_ETHER.times(0.01),
|
||||
takerAssetFilledAmount: ONE_ETHER.times(2).times(0.01),
|
||||
makerFeePaid: ONE_ETHER.times(0.001).times(0.01),
|
||||
takerFeePaid: ONE_ETHER.times(0.002).times(0.01),
|
||||
},
|
||||
];
|
||||
|
||||
async function referenceAddFillResultsAsync(
|
||||
totalValue: BigNumber,
|
||||
singleValue: BigNumber,
|
||||
): Promise<FillResults> {
|
||||
return ReferenceFunctions.addFillResults(
|
||||
makeFillResults(totalValue),
|
||||
makeFillResults(singleValue),
|
||||
);
|
||||
}
|
||||
it('matches the output of the reference function', async () => {
|
||||
const [ a, b ] = DEFAULT_FILL_RESULTS;
|
||||
const expected = ReferenceFunctions.addFillResults(a, b);
|
||||
const actual = await libsContract.addFillResults.callAsync(a, b);
|
||||
expect(actual).to.deep.equal(expected);
|
||||
});
|
||||
|
||||
async function testAddFillResultsAsync(
|
||||
totalValue: BigNumber,
|
||||
singleValue: BigNumber,
|
||||
): Promise<FillResults> {
|
||||
return libsContract.addFillResults.callAsync(
|
||||
makeFillResults(totalValue),
|
||||
makeFillResults(singleValue),
|
||||
);
|
||||
}
|
||||
it('reverts if computing `makerAssetFilledAmount` overflows', async () => {
|
||||
const [ a, b ] = _.cloneDeep(DEFAULT_FILL_RESULTS);
|
||||
b.makerAssetFilledAmount = MAX_UINT256;
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256AdditionOverflow,
|
||||
a.makerAssetFilledAmount,
|
||||
b.makerAssetFilledAmount,
|
||||
);
|
||||
return expect(libsContract.addFillResults.callAsync(a, b))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
// TODO(dorothy-zbornak): Do we really need these?
|
||||
// Just a couple edge cases would likely suffice.
|
||||
describe.optional('combinatorial tests', () => {
|
||||
testCombinatoriallyWithReferenceFunc(
|
||||
'addFillResults',
|
||||
referenceAddFillResultsAsync,
|
||||
testAddFillResultsAsync,
|
||||
[uint256Values, uint256Values],
|
||||
);
|
||||
it('reverts if computing `takerAssetFilledAmount` overflows', async () => {
|
||||
const [ a, b ] = _.cloneDeep(DEFAULT_FILL_RESULTS);
|
||||
b.takerAssetFilledAmount = MAX_UINT256;
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256AdditionOverflow,
|
||||
a.takerAssetFilledAmount,
|
||||
b.takerAssetFilledAmount,
|
||||
);
|
||||
return expect(libsContract.addFillResults.callAsync(a, b))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('reverts if computing `makerFeePaid` overflows', async () => {
|
||||
const [ a, b ] = _.cloneDeep(DEFAULT_FILL_RESULTS);
|
||||
b.makerFeePaid = MAX_UINT256;
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256AdditionOverflow,
|
||||
a.makerFeePaid,
|
||||
b.makerFeePaid,
|
||||
);
|
||||
return expect(libsContract.addFillResults.callAsync(a, b))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('reverts if computing `takerFeePaid` overflows', async () => {
|
||||
const [ a, b ] = _.cloneDeep(DEFAULT_FILL_RESULTS);
|
||||
b.takerFeePaid = MAX_UINT256;
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256AdditionOverflow,
|
||||
a.takerFeePaid,
|
||||
b.takerFeePaid,
|
||||
);
|
||||
return expect(libsContract.addFillResults.callAsync(a, b))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,15 +1,19 @@
|
||||
import {
|
||||
blockchainTests,
|
||||
constants,
|
||||
describe,
|
||||
expect,
|
||||
testCombinatoriallyWithReferenceFunc,
|
||||
uint256Values,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { LibMathRevertErrors } from '@0x/order-utils';
|
||||
import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
|
||||
|
||||
import { artifacts, ReferenceFunctions, TestLibsContract } from '../src';
|
||||
|
||||
blockchainTests('LibMath', env => {
|
||||
const CHAIN_ID = 1337;
|
||||
const { ONE_ETHER, MAX_UINT256, MAX_UINT256_ROOT, ZERO_AMOUNT } = constants;
|
||||
let libsContract: TestLibsContract;
|
||||
|
||||
before(async () => {
|
||||
@ -48,6 +52,43 @@ blockchainTests('LibMath', env => {
|
||||
[uint256Values, uint256Values, uint256Values],
|
||||
);
|
||||
});
|
||||
|
||||
describe('explicit tests', () => {
|
||||
it('matches the reference function output', async () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expected = ReferenceFunctions.getPartialAmountFloor(numerator, denominator, target);
|
||||
const actual = await libsContract.getPartialAmountFloor.callAsync(numerator, denominator, target);
|
||||
expect(actual).to.bignumber.eq(expected);
|
||||
});
|
||||
|
||||
it('reverts if `denominator` is zero', async () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ZERO_AMOUNT;
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256DivisionByZero,
|
||||
numerator.times(target),
|
||||
denominator,
|
||||
);
|
||||
return expect(libsContract.getPartialAmountFloor.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('reverts if `numerator * target` overflows', async () => {
|
||||
const numerator = MAX_UINT256;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = MAX_UINT256_ROOT.times(2);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
|
||||
numerator,
|
||||
target,
|
||||
);
|
||||
return expect(libsContract.getPartialAmountFloor.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPartialAmountCeil', () => {
|
||||
@ -59,6 +100,44 @@ blockchainTests('LibMath', env => {
|
||||
[uint256Values, uint256Values, uint256Values],
|
||||
);
|
||||
});
|
||||
|
||||
describe('explicit tests', () => {
|
||||
it('matches the reference function output', async () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expected = ReferenceFunctions.getPartialAmountCeil(numerator, denominator, target);
|
||||
const actual = await libsContract.getPartialAmountCeil.callAsync(numerator, denominator, target);
|
||||
expect(actual).to.bignumber.eq(expected);
|
||||
});
|
||||
|
||||
it('reverts if `denominator` is zero', async () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ZERO_AMOUNT;
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
// This will actually manifest as a subtraction underflow.
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256SubtractionUnderflow,
|
||||
denominator,
|
||||
new BigNumber(1),
|
||||
);
|
||||
return expect(libsContract.getPartialAmountCeil.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('reverts if `numerator * target` overflows', async () => {
|
||||
const numerator = MAX_UINT256;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = MAX_UINT256_ROOT.times(2);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
|
||||
numerator,
|
||||
target,
|
||||
);
|
||||
return expect(libsContract.getPartialAmountCeil.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('safeGetPartialAmountFloor', () => {
|
||||
@ -70,6 +149,52 @@ blockchainTests('LibMath', env => {
|
||||
[uint256Values, uint256Values, uint256Values],
|
||||
);
|
||||
});
|
||||
|
||||
describe('explicit tests', () => {
|
||||
it('matches the reference function output', async () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expected = ReferenceFunctions.safeGetPartialAmountFloor(numerator, denominator, target);
|
||||
const actual = await libsContract.safeGetPartialAmountFloor.callAsync(numerator, denominator, target);
|
||||
expect(actual).to.bignumber.eq(expected);
|
||||
});
|
||||
|
||||
it('reverts for a rounding error', async () => {
|
||||
const numerator = new BigNumber(1e3);
|
||||
const denominator = new BigNumber(1e4);
|
||||
const target = new BigNumber(333);
|
||||
const expectedError = new LibMathRevertErrors.RoundingError(
|
||||
numerator,
|
||||
denominator,
|
||||
target,
|
||||
);
|
||||
return expect(libsContract.safeGetPartialAmountFloor.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('reverts if `denominator` is zero', async () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ZERO_AMOUNT;
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expectedError = new LibMathRevertErrors.DivisionByZeroError();
|
||||
return expect(libsContract.safeGetPartialAmountFloor.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('reverts if `numerator * target` overflows', async () => {
|
||||
const numerator = MAX_UINT256;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = MAX_UINT256_ROOT.times(2);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
|
||||
numerator,
|
||||
target,
|
||||
);
|
||||
return expect(libsContract.safeGetPartialAmountFloor.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('safeGetPartialAmountCeil', () => {
|
||||
@ -81,6 +206,52 @@ blockchainTests('LibMath', env => {
|
||||
[uint256Values, uint256Values, uint256Values],
|
||||
);
|
||||
});
|
||||
|
||||
describe('explicit tests', () => {
|
||||
it('matches the reference function output', async () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expected = ReferenceFunctions.safeGetPartialAmountCeil(numerator, denominator, target);
|
||||
const actual = await libsContract.safeGetPartialAmountCeil.callAsync(numerator, denominator, target);
|
||||
expect(actual).to.bignumber.eq(expected);
|
||||
});
|
||||
|
||||
it('reverts for a rounding error', async () => {
|
||||
const numerator = new BigNumber(1e3);
|
||||
const denominator = new BigNumber(1e4);
|
||||
const target = new BigNumber(333);
|
||||
const expectedError = new LibMathRevertErrors.RoundingError(
|
||||
numerator,
|
||||
denominator,
|
||||
target,
|
||||
);
|
||||
return expect(libsContract.safeGetPartialAmountCeil.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('reverts if `denominator` is zero', async () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ZERO_AMOUNT;
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expectedError = new LibMathRevertErrors.DivisionByZeroError();
|
||||
return expect(libsContract.safeGetPartialAmountCeil.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('reverts if `numerator * target` overflows', async () => {
|
||||
const numerator = MAX_UINT256;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = MAX_UINT256_ROOT.times(2);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
|
||||
numerator,
|
||||
target,
|
||||
);
|
||||
return expect(libsContract.safeGetPartialAmountCeil.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isRoundingErrorFloor', () => {
|
||||
@ -92,6 +263,55 @@ blockchainTests('LibMath', env => {
|
||||
[uint256Values, uint256Values, uint256Values],
|
||||
);
|
||||
});
|
||||
|
||||
describe('explicit tests', () => {
|
||||
it('returns true for a rounding error', async () => {
|
||||
const numerator = new BigNumber(1e3);
|
||||
const denominator = new BigNumber(1e4);
|
||||
const target = new BigNumber(333);
|
||||
const actual = await libsContract.isRoundingErrorFloor.callAsync(numerator, denominator, target);
|
||||
expect(actual).to.eq(true);
|
||||
});
|
||||
|
||||
it('returns false for not a rounding error', async () => {
|
||||
const numerator = new BigNumber(1e3);
|
||||
const denominator = new BigNumber(1e4);
|
||||
const target = new BigNumber(5e2);
|
||||
const actual = await libsContract.isRoundingErrorFloor.callAsync(numerator, denominator, target);
|
||||
expect(actual).to.eq(false);
|
||||
});
|
||||
|
||||
it('matches the reference function output', async () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expected = ReferenceFunctions.isRoundingErrorFloor(numerator, denominator, target);
|
||||
const actual = await libsContract.isRoundingErrorFloor.callAsync(numerator, denominator, target);
|
||||
expect(actual).to.eq(expected);
|
||||
});
|
||||
|
||||
it('reverts if `denominator` is zero', async () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ZERO_AMOUNT;
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expectedError = new LibMathRevertErrors.DivisionByZeroError();
|
||||
return expect(libsContract.isRoundingErrorFloor.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('reverts if `numerator * target` overflows', async () => {
|
||||
const numerator = MAX_UINT256;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = MAX_UINT256_ROOT.times(2);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
|
||||
numerator,
|
||||
target,
|
||||
);
|
||||
return expect(libsContract.isRoundingErrorFloor.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isRoundingErrorCeil', () => {
|
||||
@ -103,5 +323,54 @@ blockchainTests('LibMath', env => {
|
||||
[uint256Values, uint256Values, uint256Values],
|
||||
);
|
||||
});
|
||||
|
||||
describe('explicit tests', () => {
|
||||
it('returns true for a rounding error', async () => {
|
||||
const numerator = new BigNumber(1e3);
|
||||
const denominator = new BigNumber(1e4);
|
||||
const target = new BigNumber(333);
|
||||
const actual = await libsContract.isRoundingErrorFloor.callAsync(numerator, denominator, target);
|
||||
expect(actual).to.eq(true);
|
||||
});
|
||||
|
||||
it('returns false for not a rounding error', async () => {
|
||||
const numerator = new BigNumber(1e3);
|
||||
const denominator = new BigNumber(1e4);
|
||||
const target = new BigNumber(5e2);
|
||||
const actual = await libsContract.isRoundingErrorFloor.callAsync(numerator, denominator, target);
|
||||
expect(actual).to.eq(false);
|
||||
});
|
||||
|
||||
it('matches the reference function output', async () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expected = ReferenceFunctions.isRoundingErrorCeil(numerator, denominator, target);
|
||||
const actual = await libsContract.isRoundingErrorCeil.callAsync(numerator, denominator, target);
|
||||
expect(actual).to.eq(expected);
|
||||
});
|
||||
|
||||
it('reverts if `denominator` is zero', async () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ZERO_AMOUNT;
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expectedError = new LibMathRevertErrors.DivisionByZeroError();
|
||||
return expect(libsContract.isRoundingErrorCeil.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('reverts if `numerator * target` overflows', async () => {
|
||||
const numerator = MAX_UINT256;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = MAX_UINT256_ROOT.times(2);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
|
||||
numerator,
|
||||
target,
|
||||
);
|
||||
return expect(libsContract.isRoundingErrorCeil.callAsync(numerator, denominator, target))
|
||||
.to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
310
contracts/exchange-libs/test/reference_functions.ts
Normal file
310
contracts/exchange-libs/test/reference_functions.ts
Normal file
@ -0,0 +1,310 @@
|
||||
import {
|
||||
constants,
|
||||
describe,
|
||||
expect,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { LibMathRevertErrors } from '@0x/order-utils';
|
||||
import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import {
|
||||
addFillResults,
|
||||
getPartialAmountCeil,
|
||||
getPartialAmountFloor,
|
||||
isRoundingErrorCeil,
|
||||
isRoundingErrorFloor,
|
||||
safeGetPartialAmountCeil,
|
||||
safeGetPartialAmountFloor,
|
||||
} from '../src/reference_functions';
|
||||
|
||||
describe('Reference Functions', () => {
|
||||
const { ONE_ETHER, MAX_UINT256, MAX_UINT256_ROOT, ZERO_AMOUNT } = constants;
|
||||
describe('LibFillResults', () => {
|
||||
|
||||
describe('addFillResults', () => {
|
||||
const DEFAULT_FILL_RESULTS = [
|
||||
{
|
||||
makerAssetFilledAmount: ONE_ETHER,
|
||||
takerAssetFilledAmount: ONE_ETHER.times(2),
|
||||
makerFeePaid: ONE_ETHER.times(0.001),
|
||||
takerFeePaid: ONE_ETHER.times(0.002),
|
||||
},
|
||||
{
|
||||
makerAssetFilledAmount: ONE_ETHER.times(0.01),
|
||||
takerAssetFilledAmount: ONE_ETHER.times(2).times(0.01),
|
||||
makerFeePaid: ONE_ETHER.times(0.001).times(0.01),
|
||||
takerFeePaid: ONE_ETHER.times(0.002).times(0.01),
|
||||
},
|
||||
];
|
||||
|
||||
it('reverts if computing `makerAssetFilledAmount` overflows', () => {
|
||||
const [ a, b ] = _.cloneDeep(DEFAULT_FILL_RESULTS);
|
||||
b.makerAssetFilledAmount = MAX_UINT256;
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256AdditionOverflow,
|
||||
a.makerAssetFilledAmount,
|
||||
b.makerAssetFilledAmount,
|
||||
);
|
||||
expect(() => addFillResults(a, b)).to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if computing `takerAssetFilledAmount` overflows', () => {
|
||||
const [ a, b ] = _.cloneDeep(DEFAULT_FILL_RESULTS);
|
||||
b.takerAssetFilledAmount = MAX_UINT256;
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256AdditionOverflow,
|
||||
a.takerAssetFilledAmount,
|
||||
b.takerAssetFilledAmount,
|
||||
);
|
||||
expect(() => addFillResults(a, b)).to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if computing `makerFeePaid` overflows', () => {
|
||||
const [ a, b ] = _.cloneDeep(DEFAULT_FILL_RESULTS);
|
||||
b.makerFeePaid = MAX_UINT256;
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256AdditionOverflow,
|
||||
a.makerFeePaid,
|
||||
b.makerFeePaid,
|
||||
);
|
||||
expect(() => addFillResults(a, b)).to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if computing `takerFeePaid` overflows', () => {
|
||||
const [ a, b ] = _.cloneDeep(DEFAULT_FILL_RESULTS);
|
||||
b.takerFeePaid = MAX_UINT256;
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256AdditionOverflow,
|
||||
a.takerFeePaid,
|
||||
b.takerFeePaid,
|
||||
);
|
||||
expect(() => addFillResults(a, b)).to.throw(expectedError.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('LibMath', () => {
|
||||
describe('getPartialAmountFloor', () => {
|
||||
describe('explicit tests', () => {
|
||||
it('reverts if `denominator` is zero', () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ZERO_AMOUNT;
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256DivisionByZero,
|
||||
numerator.times(target),
|
||||
denominator,
|
||||
);
|
||||
return expect(() => getPartialAmountFloor(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if `numerator * target` overflows', () => {
|
||||
const numerator = MAX_UINT256;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = MAX_UINT256_ROOT.times(2);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
|
||||
numerator,
|
||||
target,
|
||||
);
|
||||
return expect(() => getPartialAmountFloor(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPartialAmountCeil', () => {
|
||||
describe('explicit tests', () => {
|
||||
it('reverts if `denominator` is zero', () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ZERO_AMOUNT;
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
// This will actually manifest as a subtraction underflow.
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256SubtractionUnderflow,
|
||||
denominator,
|
||||
new BigNumber(1),
|
||||
);
|
||||
return expect(() => getPartialAmountCeil(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if `numerator * target` overflows', () => {
|
||||
const numerator = MAX_UINT256;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = MAX_UINT256_ROOT.times(2);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
|
||||
numerator,
|
||||
target,
|
||||
);
|
||||
return expect(() => getPartialAmountCeil(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('safeGetPartialAmountFloor', () => {
|
||||
describe('explicit tests', () => {
|
||||
it('reverts for a rounding error', () => {
|
||||
const numerator = new BigNumber(1e3);
|
||||
const denominator = new BigNumber(1e4);
|
||||
const target = new BigNumber(333);
|
||||
const expectedError = new LibMathRevertErrors.RoundingError(
|
||||
numerator,
|
||||
denominator,
|
||||
target,
|
||||
);
|
||||
return expect(() => safeGetPartialAmountFloor(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if `denominator` is zero', () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ZERO_AMOUNT;
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expectedError = new LibMathRevertErrors.DivisionByZeroError();
|
||||
return expect(() => safeGetPartialAmountFloor(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if `numerator * target` overflows', () => {
|
||||
const numerator = MAX_UINT256;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = MAX_UINT256_ROOT.times(2);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
|
||||
numerator,
|
||||
target,
|
||||
);
|
||||
return expect(() => safeGetPartialAmountFloor(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('safeGetPartialAmountCeil', () => {
|
||||
describe('explicit tests', () => {
|
||||
it('reverts for a rounding error', () => {
|
||||
const numerator = new BigNumber(1e3);
|
||||
const denominator = new BigNumber(1e4);
|
||||
const target = new BigNumber(333);
|
||||
const expectedError = new LibMathRevertErrors.RoundingError(
|
||||
numerator,
|
||||
denominator,
|
||||
target,
|
||||
);
|
||||
return expect(() => safeGetPartialAmountCeil(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if `denominator` is zero', () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ZERO_AMOUNT;
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expectedError = new LibMathRevertErrors.DivisionByZeroError();
|
||||
return expect(() => safeGetPartialAmountCeil(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if `numerator * target` overflows', () => {
|
||||
const numerator = MAX_UINT256;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = MAX_UINT256_ROOT.times(2);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
|
||||
numerator,
|
||||
target,
|
||||
);
|
||||
return expect(() => safeGetPartialAmountCeil(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isRoundingErrorFloor', () => {
|
||||
describe('explicit tests', () => {
|
||||
it('returns true for a rounding error', () => {
|
||||
const numerator = new BigNumber(1e3);
|
||||
const denominator = new BigNumber(1e4);
|
||||
const target = new BigNumber(333);
|
||||
const actual = isRoundingErrorFloor(numerator, denominator, target);
|
||||
expect(actual).to.eq(true);
|
||||
});
|
||||
|
||||
it('returns false for not a rounding error', () => {
|
||||
const numerator = new BigNumber(1e3);
|
||||
const denominator = new BigNumber(1e4);
|
||||
const target = new BigNumber(5e2);
|
||||
const actual = isRoundingErrorFloor(numerator, denominator, target);
|
||||
expect(actual).to.eq(false);
|
||||
});
|
||||
|
||||
it('reverts if `denominator` is zero', () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ZERO_AMOUNT;
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expectedError = new LibMathRevertErrors.DivisionByZeroError();
|
||||
return expect(() => isRoundingErrorFloor(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if `numerator * target` overflows', () => {
|
||||
const numerator = MAX_UINT256;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = MAX_UINT256_ROOT.times(2);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
|
||||
numerator,
|
||||
target,
|
||||
);
|
||||
return expect(() => isRoundingErrorFloor(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isRoundingErrorCeil', () => {
|
||||
describe('explicit tests', () => {
|
||||
it('returns true for a rounding error', () => {
|
||||
const numerator = new BigNumber(1e3);
|
||||
const denominator = new BigNumber(1e4);
|
||||
const target = new BigNumber(333);
|
||||
const actual = isRoundingErrorFloor(numerator, denominator, target);
|
||||
expect(actual).to.eq(true);
|
||||
});
|
||||
|
||||
it('returns false for not a rounding error', () => {
|
||||
const numerator = new BigNumber(1e3);
|
||||
const denominator = new BigNumber(1e4);
|
||||
const target = new BigNumber(5e2);
|
||||
const actual = isRoundingErrorFloor(numerator, denominator, target);
|
||||
expect(actual).to.eq(false);
|
||||
});
|
||||
|
||||
it('reverts if `denominator` is zero', () => {
|
||||
const numerator = ONE_ETHER;
|
||||
const denominator = ZERO_AMOUNT;
|
||||
const target = ONE_ETHER.times(0.01);
|
||||
const expectedError = new LibMathRevertErrors.DivisionByZeroError();
|
||||
return expect(() => isRoundingErrorCeil(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if `numerator * target` overflows', () => {
|
||||
const numerator = MAX_UINT256;
|
||||
const denominator = ONE_ETHER.dividedToIntegerBy(2);
|
||||
const target = MAX_UINT256_ROOT.times(2);
|
||||
const expectedError = new SafeMathRevertErrors.SafeMathError(
|
||||
SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
|
||||
numerator,
|
||||
target,
|
||||
);
|
||||
return expect(() => isRoundingErrorCeil(numerator, denominator, target))
|
||||
.to.throw(expectedError.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user