Implemented a hacky version of the fillOrder
fuzz tests
This commit is contained in:
parent
1e44a9c942
commit
36df5dc721
@ -1,6 +1,9 @@
|
||||
import { constants, getRandomInteger, hexRandom } from '@0x/contracts-test-utils';
|
||||
import { Order } from '@0x/types';
|
||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { validFillOrderCompleteFillAssertion } from '../assertions/fillOrder';
|
||||
import { AssertionResult } from '../assertions/function_assertion';
|
||||
import { validJoinStakingPoolAssertion } from '../assertions/joinStakingPool';
|
||||
|
||||
@ -33,6 +36,7 @@ export function PoolMemberMixin<TBase extends Constructor>(Base: TBase): TBase &
|
||||
this.actor.simulationActions = {
|
||||
...this.actor.simulationActions,
|
||||
validJoinStakingPool: this._validJoinStakingPool(),
|
||||
validFillOrderCompleteFill: this._validFillOrderCompleteFill(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -46,7 +50,6 @@ export function PoolMemberMixin<TBase extends Constructor>(Base: TBase): TBase &
|
||||
.awaitTransactionSuccessAsync({ from: this.actor.address });
|
||||
}
|
||||
|
||||
// FIXME(jalextowle): I need to make sure that this is being sent from the actor's address
|
||||
private async *_validJoinStakingPool(): AsyncIterableIterator<AssertionResult | void> {
|
||||
const { stakingPools } = this.actor.simulationEnvironment!;
|
||||
const assertion = validJoinStakingPoolAssertion(this.actor.deployment);
|
||||
@ -55,8 +58,39 @@ export function PoolMemberMixin<TBase extends Constructor>(Base: TBase): TBase &
|
||||
if (poolId === undefined) {
|
||||
yield undefined;
|
||||
} else {
|
||||
console.log('Attempting to join pool');
|
||||
yield assertion.executeAsync({ args: [poolId], txData: {} });
|
||||
yield assertion.executeAsync({ args: [poolId], txData: { from: this.actor.address } });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async *_validFillOrderCompleteFill(): AsyncIterableIterator<AssertionResult | void> {
|
||||
const { marketMakers } = this.actor.simulationEnvironment!;
|
||||
const assertion = validFillOrderCompleteFillAssertion(this.actor.deployment);
|
||||
while (true) {
|
||||
const maker = _.sample(marketMakers);
|
||||
if (maker === undefined) {
|
||||
yield undefined;
|
||||
} else {
|
||||
// Configure the maker's token balances so that the order will definitely be fillable.
|
||||
await Promise.all([
|
||||
...this.actor.deployment.tokens.erc20.map(async token => maker.configureERC20TokenAsync(token)),
|
||||
...this.actor.deployment.tokens.erc20.map(async token =>
|
||||
this.actor.configureERC20TokenAsync(token),
|
||||
),
|
||||
this.actor.configureERC20TokenAsync(
|
||||
this.actor.deployment.tokens.weth,
|
||||
this.actor.deployment.staking.stakingProxy.address,
|
||||
),
|
||||
]);
|
||||
|
||||
const order = await maker.signOrderAsync({
|
||||
makerAssetAmount: getRandomInteger(constants.ZERO_AMOUNT, constants.INITIAL_ERC20_BALANCE),
|
||||
takerAssetAmount: getRandomInteger(constants.ZERO_AMOUNT, constants.INITIAL_ERC20_BALANCE),
|
||||
});
|
||||
yield assertion.executeAsync({
|
||||
args: [order, order.takerAssetAmount, order.signature],
|
||||
txData: { from: this.actor.address },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,16 +80,11 @@ export function PoolOperatorMixin<TBase extends Constructor>(Base: TBase): TBase
|
||||
}
|
||||
|
||||
private async *_validCreateStakingPool(): AsyncIterableIterator<AssertionResult> {
|
||||
console.log(10);
|
||||
const { stakingPools } = this.actor.simulationEnvironment!;
|
||||
console.log(11);
|
||||
const assertion = validCreateStakingPoolAssertion(this.actor.deployment, stakingPools);
|
||||
console.log(12);
|
||||
while (true) {
|
||||
const operatorShare = getRandomInteger(0, constants.PPM).toNumber();
|
||||
console.log(13);
|
||||
yield assertion.executeAsync({ args: [operatorShare, false], txData: { from: this.actor.address } });
|
||||
console.log(14);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,9 @@ export function validCreateStakingPoolAssertion(
|
||||
): FunctionAssertion<[number, boolean], string, string> {
|
||||
const { stakingWrapper } = deployment.staking;
|
||||
|
||||
return new FunctionAssertion<[number, boolean], string, string>(stakingWrapper.createStakingPool, {
|
||||
return new FunctionAssertion<[number, boolean], string, string>(
|
||||
stakingWrapper.createStakingPool.bind(stakingWrapper),
|
||||
{
|
||||
// Returns the expected ID of th created pool
|
||||
before: async () => {
|
||||
const lastPoolId = await stakingWrapper.lastPoolId().callAsync();
|
||||
@ -37,18 +39,12 @@ export function validCreateStakingPoolAssertion(
|
||||
txData: Partial<TxData>;
|
||||
},
|
||||
) => {
|
||||
console.log(100);
|
||||
logUtils.log(`createStakingPool(${args.args[0]}, ${args.args[1]}) => ${expectedPoolId}`);
|
||||
console.log(101);
|
||||
|
||||
// Checks the logs for the new poolId, verifies that it is as expected
|
||||
console.log(result.receipt);
|
||||
const log = result.receipt!.logs[0]; // tslint:disable-line:no-non-null-assertion
|
||||
console.log(102);
|
||||
const actualPoolId = (log as any).args.poolId;
|
||||
console.log(103);
|
||||
expect(actualPoolId).to.equal(expectedPoolId);
|
||||
console.log(104);
|
||||
|
||||
// Adds the new pool to local state
|
||||
pools[actualPoolId] = {
|
||||
@ -56,7 +52,7 @@ export function validCreateStakingPoolAssertion(
|
||||
operatorShare: args.args[0],
|
||||
delegatedStake: new StoredBalance(),
|
||||
};
|
||||
console.log(105);
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -16,7 +16,9 @@ export function validDecreaseStakingPoolOperatorShareAssertion(
|
||||
): FunctionAssertion<[string, number], {}, void> {
|
||||
const { stakingWrapper } = deployment.staking;
|
||||
|
||||
return new FunctionAssertion<[string, number], {}, void>(stakingWrapper.decreaseStakingPoolOperatorShare, {
|
||||
return new FunctionAssertion<[string, number], {}, void>(
|
||||
stakingWrapper.decreaseStakingPoolOperatorShare.bind(stakingWrapper),
|
||||
{
|
||||
after: async (_beforeInfo, _result: FunctionResult, args: { args: [string, number] }) => {
|
||||
const poolId = args.args[0];
|
||||
const expectedOperatorShare = args.args[1];
|
||||
@ -29,5 +31,6 @@ export function validDecreaseStakingPoolOperatorShareAssertion(
|
||||
// Updates the pool in local state.
|
||||
pools[poolId].operatorShare = operatorShare;
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
import { constants, expect, filterLogsToArguments } from '@0x/contracts-test-utils';
|
||||
import { FillResults, Order } from '@0x/types';
|
||||
import { BigNumber, logUtils } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { Maker } from '../actors/maker';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
|
||||
import { FunctionArguments, FunctionAssertion, FunctionResult } from './function_assertion';
|
||||
|
||||
export function validFillOrderCompleteFillAssertion(
|
||||
deployment: DeploymentManager,
|
||||
): FunctionAssertion<[Order, BigNumber, string], {}, FillResults> {
|
||||
const exchange = deployment.exchange;
|
||||
|
||||
return new FunctionAssertion<[Order, BigNumber, string], {}, FillResults>(exchange.fillOrder.bind(exchange), {
|
||||
after: async (_beforeInfo, result: FunctionResult, args: FunctionArguments<[Order, BigNumber, string]>) => {
|
||||
expect(result.success).to.be.true();
|
||||
logUtils.log(`Order filled by ${args.txData.from}`);
|
||||
},
|
||||
});
|
||||
}
|
@ -3,7 +3,6 @@ import { TransactionReceiptWithDecodedLogs, TxData } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
|
||||
export type GenericContractFunction<T> = (...args: any[]) => ContractFunctionObj<T>;
|
||||
|
||||
export interface FunctionArguments<TArgs extends any[]> {
|
||||
@ -58,12 +57,12 @@ export class FunctionAssertion<TArgs extends any[], TBefore, ReturnDataType> imp
|
||||
|
||||
// The wrapper function that will be wrapped in assertions.
|
||||
public wrapperFunction: (
|
||||
...args: any[] // tslint:disable-line:trailing-comma
|
||||
...args: TArgs // tslint:disable-line:trailing-comma
|
||||
) => ContractTxFunctionObj<ReturnDataType> | ContractFunctionObj<ReturnDataType>;
|
||||
|
||||
constructor(
|
||||
wrapperFunction: (
|
||||
...args: any[] // tslint:disable-line:trailing-comma
|
||||
...args: TArgs // tslint:disable-line:trailing-comma
|
||||
) => ContractTxFunctionObj<ReturnDataType> | ContractFunctionObj<ReturnDataType>,
|
||||
condition: Partial<Condition<TArgs, TBefore>> = {},
|
||||
) {
|
||||
@ -95,18 +94,12 @@ export class FunctionAssertion<TArgs extends any[], TBefore, ReturnDataType> imp
|
||||
try {
|
||||
const functionWithArgs = this.wrapperFunction(...args.args) as ContractTxFunctionObj<ReturnDataType>;
|
||||
callResult.data = await functionWithArgs.callAsync(args.txData);
|
||||
|
||||
console.log(functionWithArgs);
|
||||
|
||||
callResult.receipt =
|
||||
functionWithArgs.awaitTransactionSuccessAsync !== undefined
|
||||
? await functionWithArgs.awaitTransactionSuccessAsync(args.txData) // tslint:disable-line:await-promise
|
||||
: undefined;
|
||||
// tslint:enable:await-promise
|
||||
} catch (error) {
|
||||
console.log('got here');
|
||||
console.log(error);
|
||||
|
||||
callResult.data = error;
|
||||
callResult.success = false;
|
||||
callResult.receipt = undefined;
|
||||
|
@ -7,7 +7,9 @@ import { DeploymentManager } from '../deployment_manager';
|
||||
import { FunctionArguments, FunctionAssertion, FunctionResult } from './function_assertion';
|
||||
|
||||
export function validJoinStakingPoolAssertion(deployment: DeploymentManager): FunctionAssertion<[string], {}, void> {
|
||||
return new FunctionAssertion<[string], {}, void>(deployment.staking.stakingWrapper.joinStakingPoolAsMaker, {
|
||||
const { stakingWrapper } = deployment.staking;
|
||||
|
||||
return new FunctionAssertion<[string], {}, void>(stakingWrapper.joinStakingPoolAsMaker.bind(stakingWrapper), {
|
||||
after: async (_beforeInfo, _result: FunctionResult, args: FunctionArguments<[string]>) => {
|
||||
const poolId = args.args[0];
|
||||
|
||||
@ -32,11 +34,11 @@ export function validJoinStakingPoolAssertion(deployment: DeploymentManager): Fu
|
||||
);
|
||||
expect(logArgs).to.be.deep.eq([
|
||||
{
|
||||
maker: args.txData.from,
|
||||
makerAddress: args.txData.from,
|
||||
poolId,
|
||||
},
|
||||
]);
|
||||
const joinedPoolId = deployment.staking.stakingWrapper.poolIdByMaker(args.txData.from);
|
||||
const joinedPoolId = await deployment.staking.stakingWrapper.poolIdByMaker(args.txData.from).callAsync();
|
||||
expect(joinedPoolId).to.be.eq(poolId);
|
||||
|
||||
console.log(`Pool ${poolId} joined by ${args.txData.from}`); /* tslint:disable-line:no-console */
|
||||
|
@ -85,7 +85,9 @@ export function validMoveStakeAssertion(
|
||||
): FunctionAssertion<[StakeInfo, StakeInfo, BigNumber], {}, void> {
|
||||
const { stakingWrapper } = deployment.staking;
|
||||
|
||||
return new FunctionAssertion<[StakeInfo, StakeInfo, BigNumber], {}, void>(stakingWrapper.moveStake, {
|
||||
return new FunctionAssertion<[StakeInfo, StakeInfo, BigNumber], {}, void>(
|
||||
stakingWrapper.moveStake.bind(stakingWrapper),
|
||||
{
|
||||
after: async (
|
||||
_beforeInfo: {},
|
||||
_result: FunctionResult,
|
||||
@ -120,7 +122,9 @@ export function validMoveStakeAssertion(
|
||||
const globalUndelegatedStake = await stakingWrapper
|
||||
.getGlobalStakeByStatus(StakeStatus.Undelegated)
|
||||
.callAsync();
|
||||
const globalDelegatedStake = await stakingWrapper.getGlobalStakeByStatus(StakeStatus.Delegated).callAsync();
|
||||
const globalDelegatedStake = await stakingWrapper
|
||||
.getGlobalStakeByStatus(StakeStatus.Delegated)
|
||||
.callAsync();
|
||||
expect(globalUndelegatedStake).to.deep.equal(globalStake[StakeStatus.Undelegated]);
|
||||
expect(globalDelegatedStake).to.deep.equal(globalStake[StakeStatus.Delegated]);
|
||||
|
||||
@ -134,5 +138,6 @@ export function validMoveStakeAssertion(
|
||||
expect(totalStakeDelegated).to.deep.equal(pools[poolId].delegatedStake);
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ export function validStakeAssertion(
|
||||
): FunctionAssertion<[BigNumber], LocalBalanceStore, void> {
|
||||
const { stakingWrapper, zrxVault } = deployment.staking;
|
||||
|
||||
return new FunctionAssertion(stakingWrapper.stake, {
|
||||
return new FunctionAssertion(stakingWrapper.stake.bind(stakingWrapper), {
|
||||
before: async (args: FunctionArguments<[BigNumber]>) => {
|
||||
const [amount] = args.args;
|
||||
|
||||
|
@ -33,7 +33,7 @@ export function validUnstakeAssertion(
|
||||
): FunctionAssertion<[BigNumber], LocalBalanceStore, void> {
|
||||
const { stakingWrapper, zrxVault } = deployment.staking;
|
||||
|
||||
return new FunctionAssertion(stakingWrapper.unstake, {
|
||||
return new FunctionAssertion(stakingWrapper.unstake.bind(stakingWrapper), {
|
||||
before: async (args: FunctionArguments<[BigNumber]>) => {
|
||||
const [amount] = args.args;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { GlobalStakeByStatus, StakeStatus, StakingPoolById, StoredBalance } from '@0x/contracts-staking';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { Maker } from './actors/maker';
|
||||
import { AssertionResult } from './assertions/function_assertion';
|
||||
import { BlockchainBalanceStore } from './balances/blockchain_balance_store';
|
||||
import { DeploymentManager } from './deployment_manager';
|
||||
@ -14,7 +15,11 @@ export class SimulationEnvironment {
|
||||
};
|
||||
public stakingPools: StakingPoolById = {};
|
||||
|
||||
public constructor(public readonly deployment: DeploymentManager, public balanceStore: BlockchainBalanceStore) {}
|
||||
public constructor(
|
||||
public readonly deployment: DeploymentManager,
|
||||
public balanceStore: BlockchainBalanceStore,
|
||||
public marketMakers: Maker[] = [],
|
||||
) {}
|
||||
}
|
||||
|
||||
export abstract class Simulation {
|
||||
|
@ -8,7 +8,7 @@ import { FunctionArguments, FunctionAssertion, FunctionResult } from '../asserti
|
||||
|
||||
const { ZERO_AMOUNT, MAX_UINT256 } = constants;
|
||||
|
||||
blockchainTests.resets.only('FunctionAssertion Unit Tests', env => {
|
||||
blockchainTests.resets('FunctionAssertion Unit Tests', env => {
|
||||
let exampleContract: TestFrameworkContract;
|
||||
|
||||
before(async () => {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { blockchainTests } from '@0x/contracts-test-utils';
|
||||
import { blockchainTests, constants } from '@0x/contracts-test-utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { Maker } from '../framework/actors/maker';
|
||||
import { PoolMember } from '../framework/actors/pool_member';
|
||||
import { PoolOperator } from '../framework/actors/pool_operator';
|
||||
import { AssertionResult } from '../framework/assertions/function_assertion';
|
||||
@ -27,6 +28,7 @@ class PoolMembershipSimulation extends Simulation {
|
||||
const actions = [
|
||||
operator.simulationActions.validCreateStakingPool,
|
||||
member.simulationActions.validJoinStakingPool,
|
||||
member.simulationActions.validFillOrderCompleteFill,
|
||||
];
|
||||
|
||||
while (true) {
|
||||
@ -36,17 +38,45 @@ class PoolMembershipSimulation extends Simulation {
|
||||
}
|
||||
}
|
||||
|
||||
blockchainTests('pool membership fuzz test', env => {
|
||||
it('fuzz', async () => {
|
||||
const deployment = await DeploymentManager.deployAsync(env, {
|
||||
numErc20TokensToDeploy: 0,
|
||||
blockchainTests.skip('pool membership fuzz test', env => {
|
||||
let deployment: DeploymentManager;
|
||||
let maker: Maker;
|
||||
|
||||
before(async () => {
|
||||
deployment = await DeploymentManager.deployAsync(env, {
|
||||
numErc20TokensToDeploy: 2,
|
||||
numErc721TokensToDeploy: 0,
|
||||
numErc1155TokensToDeploy: 0,
|
||||
});
|
||||
|
||||
const makerToken = deployment.tokens.erc20[0];
|
||||
const takerToken = deployment.tokens.erc20[1];
|
||||
|
||||
const orderConfig = {
|
||||
feeRecipientAddress: constants.NULL_ADDRESS,
|
||||
makerAssetData: deployment.assetDataEncoder.ERC20Token(makerToken.address).getABIEncodedTransactionData(),
|
||||
takerAssetData: deployment.assetDataEncoder.ERC20Token(takerToken.address).getABIEncodedTransactionData(),
|
||||
makerFeeAssetData: deployment.assetDataEncoder
|
||||
.ERC20Token(makerToken.address)
|
||||
.getABIEncodedTransactionData(),
|
||||
takerFeeAssetData: deployment.assetDataEncoder
|
||||
.ERC20Token(takerToken.address)
|
||||
.getABIEncodedTransactionData(),
|
||||
makerFee: constants.ZERO_AMOUNT,
|
||||
takerFee: constants.ZERO_AMOUNT,
|
||||
};
|
||||
|
||||
maker = new Maker({
|
||||
name: 'maker',
|
||||
deployment,
|
||||
orderConfig,
|
||||
});
|
||||
});
|
||||
|
||||
it('fuzz', async () => {
|
||||
const balanceStore = new BlockchainBalanceStore({}, {});
|
||||
|
||||
const simulationEnv = new SimulationEnvironment(deployment, balanceStore);
|
||||
const simulationEnv = new SimulationEnvironment(deployment, balanceStore, [maker]);
|
||||
const simulation = new PoolMembershipSimulation(simulationEnv);
|
||||
return simulation.fuzzAsync();
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user