added order matching functions to Taker actor.

This commit is contained in:
Greg Hysen
2020-01-10 17:07:58 -08:00
parent 5ea3bcf59e
commit e01d32ef1a

View File

@@ -4,6 +4,8 @@ import { TransactionReceiptWithDecodedLogs, TxData } from 'ethereum-types';
import { validFillOrderAssertion } from '../assertions/fillOrder';
import { AssertionResult } from '../assertions/function_assertion';
import { validMatchOrdersAssertion } from '../assertions/matchOrders';
import { validMatchOrdersWithMaximalFillAssertion } from '../assertions/matchOrdersWithMaximalFill';
import { DeploymentManager } from '../deployment_manager';
import { Pseudorandom } from '../utils/pseudorandom';
@@ -42,6 +44,8 @@ export function TakerMixin<TBase extends Constructor>(Base: TBase): TBase & Cons
this.actor.simulationActions = {
...this.actor.simulationActions,
validFillOrder: this._validFillOrder(),
validMatchOrders: this._validMatchOrders(),
validMatchOrdersWithMaximalFill: this._validMatchOrdersWithMaximalFill(),
};
}
@@ -63,6 +67,42 @@ export function TakerMixin<TBase extends Constructor>(Base: TBase): TBase & Cons
});
}
/**
* Matches two orders using `matchOrders`. Defaults to paying the protocol fee in ETH.
*/
public async matchOrdersAsync(
leftOrder: SignedOrder,
rightOrder: SignedOrder,
txData: Partial<TxData> = {},
): Promise<TransactionReceiptWithDecodedLogs> {
return this.actor.deployment.exchange
.matchOrders(leftOrder, rightOrder, leftOrder.signature, rightOrder.signature)
.awaitTransactionSuccessAsync({
from: this.actor.address,
gasPrice: DeploymentManager.gasPrice,
value: DeploymentManager.protocolFee,
...txData,
});
}
/**
* Matches two orders using `matchOrdersWithMaximalFill`. Defaults to paying the protocol fee in ETH.
*/
public async matchOrdersWithMaximalFillAsync(
leftOrder: SignedOrder,
rightOrder: SignedOrder,
txData: Partial<TxData> = {},
): Promise<TransactionReceiptWithDecodedLogs> {
return this.actor.deployment.exchange
.matchOrdersWithMaximalFill(leftOrder, rightOrder, leftOrder.signature, rightOrder.signature)
.awaitTransactionSuccessAsync({
from: this.actor.address,
gasPrice: DeploymentManager.gasPrice,
value: DeploymentManager.protocolFee,
...txData,
});
}
private async *_validFillOrder(): AsyncIterableIterator<AssertionResult | void> {
const { actors } = this.actor.simulationEnvironment!;
const assertion = validFillOrderAssertion(this.actor.deployment, this.actor.simulationEnvironment!);
@@ -85,6 +125,53 @@ export function TakerMixin<TBase extends Constructor>(Base: TBase): TBase & Cons
}
}
}
private async *_validMatchOrders(): AsyncIterableIterator<AssertionResult | void> {
const { actors } = this.actor.simulationEnvironment!;
const assertion = validMatchOrdersAssertion(this.actor.deployment, this.actor.simulationEnvironment!);
while (true) {
// Choose a maker to be the other side of the order
const maker = Pseudorandom.sample(filterActorsByRole(actors, Maker));
if (maker === undefined) {
yield;
} else {
// Maker creates and signs matchable orders
const [leftOrder, rightOrder] = await maker.createMatchableOrdersAsync(this.actor);
// Taker executes the fill with a random msg.value, so that sometimes the
// protocol fee is paid in ETH and other times it's paid in WETH.
yield assertion.executeAsync([leftOrder, rightOrder, leftOrder.signature, rightOrder.signature], {
from: this.actor.address,
value: Pseudorandom.integer(0, DeploymentManager.protocolFee.times(2)),
});
}
}
}
private async *_validMatchOrdersWithMaximalFill(): AsyncIterableIterator<AssertionResult | void> {
const { actors } = this.actor.simulationEnvironment!;
const assertion = validMatchOrdersWithMaximalFillAssertion(
this.actor.deployment,
this.actor.simulationEnvironment!,
);
while (true) {
// Choose a maker to be the other side of the order
const maker = Pseudorandom.sample(filterActorsByRole(actors, Maker));
if (maker === undefined) {
yield;
} else {
// Maker creates and signs matchable orders
const [leftOrder, rightOrder] = await maker.createMatchableOrdersAsync(this.actor);
// Taker executes the fill with a random msg.value, so that sometimes the
// protocol fee is paid in ETH and other times it's paid in WETH.
yield assertion.executeAsync([leftOrder, rightOrder, leftOrder.signature, rightOrder.signature], {
from: this.actor.address,
value: Pseudorandom.integer(0, DeploymentManager.protocolFee.times(2)),
});
}
}
}
};
}