Remove pragma experimental v0.5.0 and use staticcall is assembly

This commit is contained in:
Amir Bandeali
2018-08-24 00:19:06 -07:00
parent c5f8b9c2d2
commit 0a1ae2c311
6 changed files with 198 additions and 15 deletions

View File

@@ -1,6 +1,6 @@
import { BlockchainLifecycle } from '@0xproject/dev-utils';
import { assetDataUtils, orderHashUtils } from '@0xproject/order-utils';
import { RevertReason, SignedOrder } from '@0xproject/types';
import { RevertReason, SignatureType, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as chai from 'chai';
@@ -14,6 +14,7 @@ import { DummyNoReturnERC20TokenContract } from '../../generated_contract_wrappe
import { ERC20ProxyContract } from '../../generated_contract_wrappers/erc20_proxy';
import { ERC721ProxyContract } from '../../generated_contract_wrappers/erc721_proxy';
import { ExchangeCancelEventArgs, ExchangeContract } from '../../generated_contract_wrappers/exchange';
import { TestStaticCallContract } from '../../generated_contract_wrappers/test_static_call';
import { artifacts } from '../utils/artifacts';
import { expectTransactionFailedAsync } from '../utils/assertions';
import { getLatestBlockTimestampAsync, increaseTimeAndMineBlockAsync } from '../utils/block_timestamp';
@@ -44,6 +45,8 @@ describe('Exchange core', () => {
let exchange: ExchangeContract;
let erc20Proxy: ERC20ProxyContract;
let erc721Proxy: ERC721ProxyContract;
let maliciousWallet: TestStaticCallContract;
let maliciousValidator: TestStaticCallContract;
let signedOrder: SignedOrder;
let erc20Balances: ERC20BalancesByOwner;
@@ -109,6 +112,12 @@ describe('Exchange core', () => {
constants.AWAIT_TRANSACTION_MINED_MS,
);
maliciousWallet = maliciousValidator = await TestStaticCallContract.deployFrom0xArtifactAsync(
artifacts.TestStaticCall,
provider,
txDefaults,
);
defaultMakerAssetAddress = erc20TokenA.address;
defaultTakerAssetAddress = erc20TokenB.address;
@@ -161,6 +170,54 @@ describe('Exchange core', () => {
RevertReason.OrderUnfillable,
);
});
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 web3Wrapper.awaitTransactionSuccessAsync(
await maliciousWallet.approveERC20.sendTransactionAsync(
erc20TokenA.address,
erc20Proxy.address,
constants.INITIAL_ERC20_ALLOWANCE,
),
constants.AWAIT_TRANSACTION_MINED_MS,
);
signedOrder = await orderFactory.newSignedOrderAsync({
makerAddress: maliciousMakerAddress,
makerFee: constants.ZERO_AMOUNT,
});
signedOrder.signature = `0x0${SignatureType.Wallet}`;
await expectTransactionFailedAsync(
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress),
RevertReason.InvalidOrderSignature,
);
});
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,
);
signedOrder = await orderFactory.newSignedOrderAsync({
makerAddress: maliciousValidator.address,
});
signedOrder.signature = `${maliciousValidator.address}0${SignatureType.Validator}`;
await expectTransactionFailedAsync(
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress),
RevertReason.InvalidOrderSignature,
);
});
});
describe('Testing exchange of ERC20 tokens with no return values', () => {

View File

@@ -352,7 +352,7 @@ describe('MixinSignatureValidator', () => {
expect(isValidSignature).to.be.false();
});
it('should not allow `isValidSignature` to update state when SignatureType=Wallet', async () => {
it('should return false when `isValidSignature` attempts to update state and not allow state to be updated when SignatureType=Wallet', async () => {
// Create EIP712 signature
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
const orderHashBuffer = ethUtil.toBuffer(orderHashHex);
@@ -366,13 +366,12 @@ describe('MixinSignatureValidator', () => {
]);
const signatureHex = ethUtil.bufferToHex(signature);
// Validate signature
await expectContractCallFailedWithoutReasonAsync(
signatureValidator.publicIsValidSignature.callAsync(
orderHashHex,
maliciousWallet.address,
signatureHex,
),
const isValid = await signatureValidator.publicIsValidSignature.callAsync(
orderHashHex,
maliciousWallet.address,
signatureHex,
);
expect(isValid).to.be.equal(false);
});
it('should return true when SignatureType=Validator, signature is valid and validator is approved', async () => {
@@ -405,15 +404,18 @@ describe('MixinSignatureValidator', () => {
expect(isValidSignature).to.be.false();
});
it('should not allow `isValidSignature` to update state when SignatureType=Validator', async () => {
it('should return false when `isValidSignature` attempts to update state and not allow state to be updated when SignatureType=Validator', async () => {
const validatorAddress = ethUtil.toBuffer(`${maliciousValidator.address}`);
const signatureType = ethUtil.toBuffer(`0x${SignatureType.Validator}`);
const signature = Buffer.concat([validatorAddress, signatureType]);
const signatureHex = ethUtil.bufferToHex(signature);
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
await expectContractCallFailedWithoutReasonAsync(
signatureValidator.publicIsValidSignature.callAsync(orderHashHex, signerAddress, signatureHex),
const isValid = await signatureValidator.publicIsValidSignature.callAsync(
orderHashHex,
maliciousValidator.address,
signatureHex,
);
expect(isValid).to.be.equal(false);
});
it('should return false when SignatureType=Validator, signature is valid and validator is not approved', async () => {
// Set approval of signature validator to false