Rounding error tests in DydxBridgeProxy

This commit is contained in:
Greg Hysen
2019-12-19 15:53:35 -08:00
parent c1f5322d38
commit 265fa52ace
2 changed files with 148 additions and 15 deletions

View File

@@ -1,8 +1,9 @@
import { DydxBridgeActionType, dydxBridgeDataEncoder, TestDydxBridgeContract } from '@0x/contracts-asset-proxy';
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import { LibMathRevertErrors } from '@0x/contracts-exchange-libs';
import { blockchainTests, constants, describe, expect, toBaseUnitAmount } from '@0x/contracts-test-utils';
import { SignedOrder } from '@0x/order-utils';
import { BigNumber } from '@0x/utils';
import { BigNumber, RevertError } from '@0x/utils';
import { DecodedLogArgs, LogWithDecodedArgs } from 'ethereum-types';
import * as _ from 'lodash';
@@ -23,6 +24,8 @@ blockchainTests.resets('Exchange fills dydx orders', env => {
let taker: Taker;
let orderConfig: Partial<SignedOrder>;
let dydxBridgeProxyAssetData: string;
let deployment: DeploymentManager;
let testTokenAddress: string;
const defaultDepositAction = {
actionType: DydxBridgeActionType.Deposit as number,
accountId: constants.ZERO_AMOUNT,
@@ -44,12 +47,12 @@ blockchainTests.resets('Exchange fills dydx orders', env => {
before(async () => {
// Deploy contracts
const deployment = await DeploymentManager.deployAsync(env, {
deployment = await DeploymentManager.deployAsync(env, {
numErc20TokensToDeploy: 2,
});
testContract = await deployDydxBridgeAsync(deployment, env);
const encodedBridgeData = dydxBridgeDataEncoder.encode({ bridgeData });
const testTokenAddress = await testContract.getTestToken().callAsync();
testTokenAddress = await testContract.getTestToken().callAsync();
dydxBridgeProxyAssetData = deployment.assetDataEncoder
.ERC20Bridge(testTokenAddress, testContract.address, encodedBridgeData)
.getABIEncodedTransactionData();
@@ -228,5 +231,48 @@ blockchainTests.resets('Exchange fills dydx orders', env => {
'takerAssetFilledAmount should equal amountDepositedIntoDydx',
).to.bignumber.equal(dydxFillResults.amountDepositedIntoDydx);
});
it('should revert in DydxBridge when there is a rounding error', async () => {
// This order will not trigger the rounding error in the Exchange,
// but will trigger one in the DydxBridge.
const badDepositAction = {
...defaultDepositAction,
conversionRateNumerator: new BigNumber(5318),
conversionRateDenominator: new BigNumber(47958),
};
const badBridgeData = {
accountNumbers: [new BigNumber(0)],
actions: [badDepositAction],
};
const encodedBridgeData = dydxBridgeDataEncoder.encode({ bridgeData: badBridgeData });
const badDydxBridgeProxyAssetData = deployment.assetDataEncoder
.ERC20Bridge(testTokenAddress, testContract.address, encodedBridgeData)
.getABIEncodedTransactionData();
const signedOrder = await maker.signOrderAsync({
makerAssetData: badDydxBridgeProxyAssetData,
makerAssetAmount: badDepositAction.conversionRateDenominator,
takerAssetAmount: badDepositAction.conversionRateNumerator,
});
const takerAssetFillAmount = new BigNumber(998);
// Compute expected error.
const target = takerAssetFillAmount
.multipliedBy(signedOrder.makerAssetAmount)
.dividedToIntegerBy(signedOrder.takerAssetAmount);
const expectedAssetProxyError = new LibMathRevertErrors.RoundingError(
signedOrder.takerAssetAmount,
signedOrder.makerAssetAmount,
target,
);
// Call fillOrder and assert the rounding error generated by the DydxBridge.
const txPromise = taker.fillOrderAsync(signedOrder, takerAssetFillAmount);
let assetProxyError;
try {
await txPromise.catch();
} catch (e) {
assetProxyError = RevertError.decode(e.values.errorData);
}
expect(assetProxyError).to.deep.equal(expectedAssetProxyError);
});
});
});