Add function assertions required for staking rewards fuzzing: withdrawDelegatorRewards, finalizePool, and endEpoch. Also adds payProtocolFee-related assertions to fillOrder

This commit is contained in:
Michael Zhu
2019-12-04 14:44:19 -08:00
parent fff3c1eb36
commit 4663eec950
27 changed files with 817 additions and 239 deletions

View File

@@ -1,5 +1,5 @@
import { ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { blockchainTests, constants, describe, expect, shortZip } from '@0x/contracts-test-utils';
import { blockchainTests, constants, describe, expect, shortZip, toBaseUnitAmount } from '@0x/contracts-test-utils';
import { BigNumber, StakingRevertErrors } from '@0x/utils';
import * as _ from 'lodash';
@@ -9,7 +9,6 @@ import { FinalizerActor } from './actors/finalizer_actor';
import { PoolOperatorActor } from './actors/pool_operator_actor';
import { StakerActor } from './actors/staker_actor';
import { deployAndConfigureContractsAsync, StakingApiWrapper } from './utils/api_wrapper';
import { toBaseUnitAmount } from './utils/number_utils';
// tslint:disable:no-unnecessary-type-assertion
// tslint:disable:max-file-line-count

View File

@@ -1,5 +1,5 @@
import { ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { blockchainTests, describe } from '@0x/contracts-test-utils';
import { blockchainTests, describe, toBaseUnitAmount } from '@0x/contracts-test-utils';
import { BigNumber, StakingRevertErrors } from '@0x/utils';
import * as _ from 'lodash';
@@ -7,7 +7,6 @@ import { StakeInfo, StakeStatus } from '../src/types';
import { StakerActor } from './actors/staker_actor';
import { deployAndConfigureContractsAsync, StakingApiWrapper } from './utils/api_wrapper';
import { toBaseUnitAmount } from './utils/number_utils';
// tslint:disable:no-unnecessary-type-assertion
blockchainTests.resets('Stake Statuses', env => {

View File

@@ -1,20 +1,18 @@
import {
assertIntegerRoughlyEquals as assertRoughlyEquals,
blockchainTests,
constants,
expect,
filterLogsToArguments,
getRandomInteger,
Numberish,
randomAddress,
toBaseUnitAmount,
} from '@0x/contracts-test-utils';
import { BigNumber, hexUtils } from '@0x/utils';
import { LogEntry } from 'ethereum-types';
import { artifacts } from '../artifacts';
import {
assertIntegerRoughlyEquals as assertRoughlyEquals,
getRandomInteger,
toBaseUnitAmount,
} from '../utils/number_utils';
import {
TestDelegatorRewardsContract,

View File

@@ -1,10 +1,13 @@
import {
assertIntegerRoughlyEquals,
blockchainTests,
constants,
expect,
filterLogsToArguments,
getRandomInteger,
Numberish,
shortZip,
toBaseUnitAmount,
} from '@0x/contracts-test-utils';
import { BigNumber, hexUtils, StakingRevertErrors } from '@0x/utils';
import { LogEntry } from 'ethereum-types';
@@ -13,7 +16,6 @@ import * as _ from 'lodash';
import { constants as stakingConstants } from '../../src/constants';
import { artifacts } from '../artifacts';
import { assertIntegerRoughlyEquals, getRandomInteger, toBaseUnitAmount } from '../utils/number_utils';
import {
IStakingEventsEpochEndedEventArgs,

View File

@@ -1,9 +1,14 @@
import { blockchainTests, Numberish } from '@0x/contracts-test-utils';
import {
assertRoughlyEquals,
blockchainTests,
getRandomInteger,
getRandomPortion,
Numberish,
toDecimal,
} from '@0x/contracts-test-utils';
import { BigNumber } from '@0x/utils';
import * as _ from 'lodash';
import { assertRoughlyEquals, getRandomInteger, getRandomPortion, toDecimal } from '../utils/number_utils';
import { artifacts } from '../artifacts';
import { TestCobbDouglasContract } from '../wrappers';

View File

@@ -1,10 +1,16 @@
import { blockchainTests, expect, Numberish } from '@0x/contracts-test-utils';
import { BigNumber, FixedMathRevertErrors, hexUtils } from '@0x/utils';
import {
assertRoughlyEquals,
blockchainTests,
expect,
fromFixed,
Numberish,
toDecimal,
toFixed,
} from '@0x/contracts-test-utils';
import { BigNumber, FixedMathRevertErrors } from '@0x/utils';
import { Decimal } from 'decimal.js';
import * as _ from 'lodash';
import { assertRoughlyEquals, fromFixed, toDecimal, toFixed } from '../utils/number_utils';
import { artifacts } from '../artifacts';
import { TestLibFixedMathContract } from '../wrappers';

View File

@@ -1,9 +1,8 @@
import { blockchainTests, expect } from '@0x/contracts-test-utils';
import { blockchainTests, expect, toBaseUnitAmount } from '@0x/contracts-test-utils';
import { BigNumber } from '@0x/utils';
import * as _ from 'lodash';
import { constants as stakingConstants } from '../../src/constants';
import { toBaseUnitAmount } from '../utils/number_utils';
import { artifacts } from '../artifacts';
import { TestMixinCumulativeRewardsContract } from '../wrappers';
@@ -74,7 +73,9 @@ blockchainTests.resets('MixinCumulativeRewards unit tests', env => {
await testContract
.addCumulativeReward(testPoolId, testRewards[0].numerator, testRewards[0].denominator)
.awaitTransactionSuccessAsync();
const mostRecentCumulativeReward = await testContract.getMostRecentCumulativeReward(testPoolId).callAsync();
const [mostRecentCumulativeReward] = await testContract
.getMostRecentCumulativeReward(testPoolId)
.callAsync();
expect(mostRecentCumulativeReward).to.deep.equal(testRewards[0]);
});
@@ -86,7 +87,9 @@ blockchainTests.resets('MixinCumulativeRewards unit tests', env => {
await testContract
.addCumulativeReward(testPoolId, testRewards[1].numerator, testRewards[1].denominator)
.awaitTransactionSuccessAsync();
const mostRecentCumulativeReward = await testContract.getMostRecentCumulativeReward(testPoolId).callAsync();
const [mostRecentCumulativeReward] = await testContract
.getMostRecentCumulativeReward(testPoolId)
.callAsync();
expect(mostRecentCumulativeReward).to.deep.equal(testRewards[0]);
});
@@ -98,7 +101,9 @@ blockchainTests.resets('MixinCumulativeRewards unit tests', env => {
await testContract
.addCumulativeReward(testPoolId, testRewards[1].numerator, testRewards[1].denominator)
.awaitTransactionSuccessAsync();
const mostRecentCumulativeReward = await testContract.getMostRecentCumulativeReward(testPoolId).callAsync();
const [mostRecentCumulativeReward] = await testContract
.getMostRecentCumulativeReward(testPoolId)
.callAsync();
expect(mostRecentCumulativeReward).to.deep.equal(sumOfTestRewardsNormalized);
});
});

View File

@@ -3,6 +3,7 @@ import {
constants,
expect,
filterLogsToArguments,
getRandomInteger,
Numberish,
randomAddress,
} from '@0x/contracts-test-utils';
@@ -19,8 +20,6 @@ import {
TestProtocolFeesEvents,
} from '../wrappers';
import { getRandomInteger } from '../utils/number_utils';
blockchainTests('Protocol Fees unit tests', env => {
let ownerAddress: string;
let exchangeAddress: string;

View File

@@ -1,4 +1,4 @@
import { BlockchainTestsEnvironment, expect, txDefaults } from '@0x/contracts-test-utils';
import { BlockchainTestsEnvironment, expect, toBaseUnitAmount, txDefaults } from '@0x/contracts-test-utils';
import { BigNumber } from '@0x/utils';
import { DecodedLogEntry, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import * as _ from 'lodash';
@@ -8,7 +8,6 @@ import { artifacts } from '../artifacts';
import { TestCumulativeRewardTrackingContract, TestCumulativeRewardTrackingEvents } from '../wrappers';
import { StakingApiWrapper } from './api_wrapper';
import { toBaseUnitAmount } from './number_utils';
export enum TestAction {
Finalize,

View File

@@ -1,116 +0,0 @@
import { expect, Numberish } from '@0x/contracts-test-utils';
import { BigNumber } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper';
import * as crypto from 'crypto';
import { Decimal } from 'decimal.js';
Decimal.set({ precision: 80 });
/**
* Convert `x` to a `Decimal` type.
*/
export function toDecimal(x: Numberish): Decimal {
if (BigNumber.isBigNumber(x)) {
return new Decimal(x.toString(10));
}
return new Decimal(x);
}
/**
* Generate a random integer between `min` and `max`, inclusive.
*/
export function getRandomInteger(min: Numberish, max: Numberish): BigNumber {
const range = new BigNumber(max).minus(min);
return getRandomPortion(range).plus(min);
}
/**
* Generate a random integer between `0` and `total`, inclusive.
*/
export function getRandomPortion(total: Numberish): BigNumber {
return new BigNumber(total).times(getRandomFloat(0, 1)).integerValue(BigNumber.ROUND_HALF_UP);
}
/**
* Generate a random, high-precision decimal between `min` and `max`, inclusive.
*/
export function getRandomFloat(min: Numberish, max: Numberish): BigNumber {
// Generate a really high precision number between [0, 1]
const r = new BigNumber(crypto.randomBytes(32).toString('hex'), 16).dividedBy(new BigNumber(2).pow(256).minus(1));
return new BigNumber(max)
.minus(min)
.times(r)
.plus(min);
}
export const FIXED_POINT_BASE = new BigNumber(2).pow(127);
/**
* Convert `n` to fixed-point integer represenatation.
*/
export function toFixed(n: Numberish): BigNumber {
return new BigNumber(n).times(FIXED_POINT_BASE).integerValue();
}
/**
* Convert `n` from fixed-point integer represenatation.
*/
export function fromFixed(n: Numberish): BigNumber {
return new BigNumber(n).dividedBy(FIXED_POINT_BASE);
}
/**
* Converts two decimal numbers to integers with `precision` digits, then returns
* the absolute difference.
*/
export function getNumericalDivergence(a: Numberish, b: Numberish, precision: number = 18): number {
const _a = new BigNumber(a);
const _b = new BigNumber(b);
const maxIntegerDigits = Math.max(
_a.integerValue(BigNumber.ROUND_DOWN).sd(true),
_b.integerValue(BigNumber.ROUND_DOWN).sd(true),
);
const _toInteger = (n: BigNumber) => {
const base = 10 ** (precision - maxIntegerDigits);
return n.times(base).integerValue(BigNumber.ROUND_DOWN);
};
return _toInteger(_a)
.minus(_toInteger(_b))
.abs()
.toNumber();
}
/**
* Asserts that two numbers are equal up to `precision` digits.
*/
export function assertRoughlyEquals(actual: Numberish, expected: Numberish, precision: number = 18): void {
if (getNumericalDivergence(actual, expected, precision) <= 1) {
return;
}
expect(actual).to.bignumber.eq(expected);
}
/**
* Asserts that two numbers are equal with up to `maxError` difference between them.
*/
export function assertIntegerRoughlyEquals(actual: Numberish, expected: Numberish, maxError: number = 1): void {
const diff = new BigNumber(actual)
.minus(expected)
.abs()
.toNumber();
if (diff <= maxError) {
return;
}
expect(actual).to.bignumber.eq(expected);
}
/**
* Converts `amount` into a base unit amount with a specified number of digits. If
* no digits are provided, this defaults to 18 digits.
*/
export function toBaseUnitAmount(amount: Numberish, decimals?: number): BigNumber {
const amountAsBigNumber = new BigNumber(amount);
const baseDecimals = decimals !== undefined ? decimals : 18;
const baseUnitAmount = Web3Wrapper.toBaseUnitAmount(amountAsBigNumber, baseDecimals);
return baseUnitAmount;
}