Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

Commit

Permalink
Add fillOrder tests that use the StaticCallProxy
Browse files Browse the repository at this point in the history
  • Loading branch information
abandeali1 committed Jun 10, 2019
1 parent 5d9c9c5 commit 416045a
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 88 deletions.
243 changes: 155 additions & 88 deletions contracts/exchange/test/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
ERC721ProxyContract,
ERC721Wrapper,
MultiAssetProxyContract,
StaticCallProxyContract,
TestStaticCallTargetContract,
} from '@0x/contracts-asset-proxy';
import { ERC1155MintableContract } from '@0x/contracts-erc1155';
import {
Expand Down Expand Up @@ -69,6 +71,8 @@ describe('Exchange core', () => {
let erc721Proxy: ERC721ProxyContract;
let erc1155Proxy: ERC721ProxyContract;
let multiAssetProxy: MultiAssetProxyContract;
let staticCallProxy: StaticCallProxyContract;
let staticCallTarget: TestStaticCallTargetContract;
let maliciousWallet: TestStaticCallReceiverContract;
let maliciousValidator: TestStaticCallReceiverContract;
let erc1155Contract: ERC1155MintableContract;
Expand Down Expand Up @@ -113,6 +117,11 @@ describe('Exchange core', () => {
provider,
txDefaults,
);
staticCallProxy = await StaticCallProxyContract.deployFrom0xArtifactAsync(
proxyArtifacts.StaticCallProxy,
provider,
txDefaults,
);
const numDummyErc20ToDeploy = 3;
[erc20TokenA, erc20TokenB, zrxToken] = await erc20Wrapper.deployDummyTokensAsync(
numDummyErc20ToDeploy,
Expand Down Expand Up @@ -141,73 +150,30 @@ describe('Exchange core', () => {
);

// Configure ERC20Proxy
await web3Wrapper.awaitTransactionSuccessAsync(
await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, {
from: owner,
}),
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, {
from: owner,
}),
constants.AWAIT_TRANSACTION_MINED_MS,
);
await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(exchange.address, { from: owner });
await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(multiAssetProxy.address, { from: owner });

// Configure ERC721Proxy
await web3Wrapper.awaitTransactionSuccessAsync(
await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, {
from: owner,
}),
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, {
from: owner,
}),
constants.AWAIT_TRANSACTION_MINED_MS,
);
await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(exchange.address, { from: owner });
await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(multiAssetProxy.address, { from: owner });

// Configure ERC1155Proxy
await web3Wrapper.awaitTransactionSuccessAsync(
await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, {
from: owner,
}),
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, {
from: owner,
}),
constants.AWAIT_TRANSACTION_MINED_MS,
);
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(exchange.address, { from: owner });
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(multiAssetProxy.address, { from: owner });

// Configure MultiAssetProxy
await web3Wrapper.awaitTransactionSuccessAsync(
await multiAssetProxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, {
from: owner,
}),
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await multiAssetProxy.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, {
from: owner,
}),
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await multiAssetProxy.registerAssetProxy.sendTransactionAsync(erc721Proxy.address, {
from: owner,
}),
constants.AWAIT_TRANSACTION_MINED_MS,
);
await multiAssetProxy.addAuthorizedAddress.awaitTransactionSuccessAsync(exchange.address, { from: owner });
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(erc20Proxy.address, { from: owner });
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(erc721Proxy.address, { from: owner });
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(staticCallProxy.address, { from: owner });

// Configure Exchange
exchangeWrapper = new ExchangeWrapper(exchange, provider);
await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner);
await exchangeWrapper.registerAssetProxyAsync(erc1155Proxy.address, owner);
await exchangeWrapper.registerAssetProxyAsync(multiAssetProxy.address, owner);
await exchangeWrapper.registerAssetProxyAsync(staticCallProxy.address, owner);

// Configure ERC20 tokens
await erc20Wrapper.setBalancesAndAllowancesAsync();
Expand Down Expand Up @@ -268,10 +234,7 @@ describe('Exchange core', () => {
signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetData: assetDataUtils.encodeERC20AssetData(reentrantErc20Token.address),
});
await web3Wrapper.awaitTransactionSuccessAsync(
await reentrantErc20Token.setCurrentFunction.sendTransactionAsync(functionId),
constants.AWAIT_TRANSACTION_MINED_MS,
);
await reentrantErc20Token.setCurrentFunction.awaitTransactionSuccessAsync(functionId);
await expectTransactionFailedAsync(
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress),
RevertReason.TransferFailed,
Expand Down Expand Up @@ -310,20 +273,14 @@ describe('Exchange core', () => {

it('should revert if `isValidSignature` tries to update state when SignatureType=Wallet', async () => {
const maliciousMakerAddress = maliciousWallet.address;
await web3Wrapper.awaitTransactionSuccessAsync(
await erc20TokenA.setBalance.sendTransactionAsync(
maliciousMakerAddress,
constants.INITIAL_ERC20_BALANCE,
),
constants.AWAIT_TRANSACTION_MINED_MS,
await erc20TokenA.setBalance.awaitTransactionSuccessAsync(
maliciousMakerAddress,
constants.INITIAL_ERC20_BALANCE,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await maliciousWallet.approveERC20.sendTransactionAsync(
erc20TokenA.address,
erc20Proxy.address,
constants.INITIAL_ERC20_ALLOWANCE,
),
constants.AWAIT_TRANSACTION_MINED_MS,
await maliciousWallet.approveERC20.awaitTransactionSuccessAsync(
erc20TokenA.address,
erc20Proxy.address,
constants.INITIAL_ERC20_ALLOWANCE,
);
signedOrder = await orderFactory.newSignedOrderAsync({
makerAddress: maliciousMakerAddress,
Expand All @@ -338,13 +295,10 @@ describe('Exchange core', () => {

it('should revert if `isValidSignature` tries to update state when SignatureType=Validator', async () => {
const isApproved = true;
await web3Wrapper.awaitTransactionSuccessAsync(
await exchange.setSignatureValidatorApproval.sendTransactionAsync(
maliciousValidator.address,
isApproved,
{ from: makerAddress },
),
constants.AWAIT_TRANSACTION_MINED_MS,
await exchange.setSignatureValidatorApproval.awaitTransactionSuccessAsync(
maliciousValidator.address,
isApproved,
{ from: makerAddress },
);
signedOrder.signature = `${maliciousValidator.address}0${SignatureType.Validator}`;
await expectTransactionFailedAsync(
Expand Down Expand Up @@ -399,17 +353,14 @@ describe('Exchange core', () => {
constants.DUMMY_TOKEN_DECIMALS,
constants.DUMMY_TOKEN_TOTAL_SUPPLY,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await noReturnErc20Token.setBalance.sendTransactionAsync(makerAddress, constants.INITIAL_ERC20_BALANCE),
constants.AWAIT_TRANSACTION_MINED_MS,
await noReturnErc20Token.setBalance.awaitTransactionSuccessAsync(
makerAddress,
constants.INITIAL_ERC20_BALANCE,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await noReturnErc20Token.approve.sendTransactionAsync(
erc20Proxy.address,
constants.INITIAL_ERC20_ALLOWANCE,
{ from: makerAddress },
),
constants.AWAIT_TRANSACTION_MINED_MS,
await noReturnErc20Token.approve.awaitTransactionSuccessAsync(
erc20Proxy.address,
constants.INITIAL_ERC20_ALLOWANCE,
{ from: makerAddress },
);
});
it('should transfer the correct amounts when makerAssetAmount === takerAssetAmount', async () => {
Expand Down Expand Up @@ -1516,6 +1467,122 @@ describe('Exchange core', () => {
});
});

describe('Testing orders that utilize StaticCallProxy', () => {
before(async () => {
staticCallTarget = await TestStaticCallTargetContract.deployFrom0xArtifactAsync(
proxyArtifacts.TestStaticCallTarget,
provider,
txDefaults,
);
});
it('should revert if the staticcall is unsuccessful', async () => {
const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData(new BigNumber(1));
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
constants.KECCAK256_NULL,
);
signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData: assetData });
await expectTransactionFailedAsync(
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress),
RevertReason.TargetNotEven,
);
});
it('should fill the order if the staticcall is successful', async () => {
const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData(
constants.ZERO_AMOUNT,
);
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
constants.KECCAK256_NULL,
);
signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData: assetData });

const initialMakerZrxBalance = await zrxToken.balanceOf.callAsync(makerAddress);
const initialTakerZrxBalance = await zrxToken.balanceOf.callAsync(takerAddress);
const initialFeeRecipientZrxBalance = await zrxToken.balanceOf.callAsync(feeRecipientAddress);
const initialMakerBalanceB = await erc20TokenB.balanceOf.callAsync(makerAddress);
const initialTakerBalanceB = await erc20TokenB.balanceOf.callAsync(takerAddress);

await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);

const finalMakerZrxBalance = await zrxToken.balanceOf.callAsync(makerAddress);
const finalTakerZrxBalance = await zrxToken.balanceOf.callAsync(takerAddress);
const finalFeeRecipientZrxBalance = await zrxToken.balanceOf.callAsync(feeRecipientAddress);
const finalMakerBalanceB = await erc20TokenB.balanceOf.callAsync(makerAddress);
const finalTakerBalanceB = await erc20TokenB.balanceOf.callAsync(takerAddress);

expect(finalMakerZrxBalance).to.bignumber.equal(initialMakerZrxBalance.minus(signedOrder.makerFee));
expect(finalTakerZrxBalance).to.bignumber.equal(initialTakerZrxBalance.minus(signedOrder.takerFee));
expect(finalFeeRecipientZrxBalance).to.bignumber.equal(
initialFeeRecipientZrxBalance.plus(signedOrder.makerFee).plus(signedOrder.takerFee),
);
expect(finalMakerBalanceB).to.bignumber.equal(initialMakerBalanceB.plus(signedOrder.takerAssetAmount));
expect(finalTakerBalanceB).to.bignumber.equal(initialTakerBalanceB.minus(signedOrder.takerAssetAmount));
});
it('should revert if the staticcall is unsuccessful using the MultiAssetProxy', async () => {
const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData(new BigNumber(1));
const staticCallAssetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
constants.KECCAK256_NULL,
);
const assetData = assetDataUtils.encodeMultiAssetData(
[new BigNumber(1), new BigNumber(1)],
[assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress), staticCallAssetData],
);
signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData: assetData });
await expectTransactionFailedAsync(
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress),
RevertReason.TargetNotEven,
);
});
it('should fill the order is the staticcall is successful using the MultiAssetProxy', async () => {
const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData(
constants.ZERO_AMOUNT,
);
const staticCallAssetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
constants.KECCAK256_NULL,
);
const assetData = assetDataUtils.encodeMultiAssetData(
[new BigNumber(1), new BigNumber(1)],
[assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress), staticCallAssetData],
);
signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData: assetData });

const initialMakerZrxBalance = await zrxToken.balanceOf.callAsync(makerAddress);
const initialTakerZrxBalance = await zrxToken.balanceOf.callAsync(takerAddress);
const initialFeeRecipientZrxBalance = await zrxToken.balanceOf.callAsync(feeRecipientAddress);
const initialMakerBalanceA = await erc20TokenA.balanceOf.callAsync(makerAddress);
const initialTakerBalanceA = await erc20TokenA.balanceOf.callAsync(takerAddress);
const initialMakerBalanceB = await erc20TokenB.balanceOf.callAsync(makerAddress);
const initialTakerBalanceB = await erc20TokenB.balanceOf.callAsync(takerAddress);

await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);

const finalMakerZrxBalance = await zrxToken.balanceOf.callAsync(makerAddress);
const finalTakerZrxBalance = await zrxToken.balanceOf.callAsync(takerAddress);
const finalFeeRecipientZrxBalance = await zrxToken.balanceOf.callAsync(feeRecipientAddress);
const finalMakerBalanceA = await erc20TokenA.balanceOf.callAsync(makerAddress);
const finalTakerBalanceA = await erc20TokenA.balanceOf.callAsync(takerAddress);
const finalMakerBalanceB = await erc20TokenB.balanceOf.callAsync(makerAddress);
const finalTakerBalanceB = await erc20TokenB.balanceOf.callAsync(takerAddress);

expect(finalMakerZrxBalance).to.bignumber.equal(initialMakerZrxBalance.minus(signedOrder.makerFee));
expect(finalTakerZrxBalance).to.bignumber.equal(initialTakerZrxBalance.minus(signedOrder.takerFee));
expect(finalFeeRecipientZrxBalance).to.bignumber.equal(
initialFeeRecipientZrxBalance.plus(signedOrder.makerFee).plus(signedOrder.takerFee),
);
expect(finalMakerBalanceA).to.bignumber.equal(initialMakerBalanceA.minus(signedOrder.makerAssetAmount));
expect(finalTakerBalanceA).to.bignumber.equal(initialTakerBalanceA.plus(signedOrder.makerAssetAmount));
expect(finalMakerBalanceB).to.bignumber.equal(initialMakerBalanceB.plus(signedOrder.takerAssetAmount));
expect(finalTakerBalanceB).to.bignumber.equal(initialTakerBalanceB.minus(signedOrder.takerAssetAmount));
});
});

describe('getOrderInfo', () => {
beforeEach(async () => {
signedOrder = await orderFactory.newSignedOrderAsync();
Expand Down
3 changes: 3 additions & 0 deletions packages/order-utils/src/asset_data_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,9 @@ export const assetDataUtils = {
case AssetProxyId.MultiAsset:
assetDataUtils.assertIsMultiAssetData(assetData);
break;
case AssetProxyId.StaticCall:
assetDataUtils.assertIsStaticCallAssetData(assetData);
break;
default:
throw new Error(`Unrecognized asset proxy id: ${assetProxyId}`);
}
Expand Down

0 comments on commit 416045a

Please sign in to comment.