Use string argument encoding with new encoder
This commit is contained in:
		@@ -107,7 +107,6 @@ describe('Asset Transfer Proxies', () => {
 | 
			
		||||
            constants.AWAIT_TRANSACTION_MINED_MS,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // Configure ERC721Proxy
 | 
			
		||||
        await web3Wrapper.awaitTransactionSuccessAsync(
 | 
			
		||||
            await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(authorized, {
 | 
			
		||||
@@ -115,7 +114,6 @@ describe('Asset Transfer Proxies', () => {
 | 
			
		||||
            }),
 | 
			
		||||
            constants.AWAIT_TRANSACTION_MINED_MS,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        await web3Wrapper.awaitTransactionSuccessAsync(
 | 
			
		||||
            await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, {
 | 
			
		||||
                from: owner,
 | 
			
		||||
@@ -123,7 +121,6 @@ describe('Asset Transfer Proxies', () => {
 | 
			
		||||
            constants.AWAIT_TRANSACTION_MINED_MS,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // Configure MultiAssetProxy
 | 
			
		||||
        await web3Wrapper.awaitTransactionSuccessAsync(
 | 
			
		||||
            await multiAssetProxy.addAuthorizedAddress.sendTransactionAsync(authorized, {
 | 
			
		||||
@@ -131,14 +128,12 @@ describe('Asset Transfer Proxies', () => {
 | 
			
		||||
            }),
 | 
			
		||||
            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,
 | 
			
		||||
@@ -146,7 +141,6 @@ describe('Asset Transfer Proxies', () => {
 | 
			
		||||
            constants.AWAIT_TRANSACTION_MINED_MS,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // Deploy and configure ERC20 tokens
 | 
			
		||||
        const numDummyErc20ToDeploy = 2;
 | 
			
		||||
        [erc20TokenA, erc20TokenB] = await erc20Wrapper.deployDummyTokensAsync(
 | 
			
		||||
@@ -172,7 +166,6 @@ describe('Asset Transfer Proxies', () => {
 | 
			
		||||
            constants.DUMMY_TOKEN_TOTAL_SUPPLY,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        await erc20Wrapper.setBalancesAndAllowancesAsync();
 | 
			
		||||
        await web3Wrapper.awaitTransactionSuccessAsync(
 | 
			
		||||
            await noReturnErc20Token.setBalance.sendTransactionAsync(fromAddress, constants.INITIAL_ERC20_BALANCE),
 | 
			
		||||
 
 | 
			
		||||
@@ -1046,7 +1046,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.Fillable;
 | 
			
		||||
            expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
			
		||||
            expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.be.equal(expectedOrderStatus);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return the correct orderInfo for a fully filled order', async () => {
 | 
			
		||||
            await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
 | 
			
		||||
@@ -1056,7 +1056,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.FullyFilled;
 | 
			
		||||
            expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
			
		||||
            expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.be.equal(expectedOrderStatus);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return the correct orderInfo for a partially filled order', async () => {
 | 
			
		||||
            const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
 | 
			
		||||
@@ -1067,7 +1067,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.Fillable;
 | 
			
		||||
            expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
			
		||||
            expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.be.equal(expectedOrderStatus);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return the correct orderInfo for a cancelled and unfilled order', async () => {
 | 
			
		||||
            await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
 | 
			
		||||
@@ -1077,7 +1077,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.Cancelled;
 | 
			
		||||
            expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
			
		||||
            expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.be.equal(expectedOrderStatus);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return the correct orderInfo for a cancelled and partially filled order', async () => {
 | 
			
		||||
            const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
 | 
			
		||||
@@ -1089,7 +1089,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.Cancelled;
 | 
			
		||||
            expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
			
		||||
            expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.be.equal(expectedOrderStatus);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return the correct orderInfo for an expired and unfilled order', async () => {
 | 
			
		||||
            const currentTimestamp = await getLatestBlockTimestampAsync();
 | 
			
		||||
@@ -1101,7 +1101,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.Expired;
 | 
			
		||||
            expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
			
		||||
            expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.be.equal(expectedOrderStatus);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return the correct orderInfo for an expired and partially filled order', async () => {
 | 
			
		||||
            const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
 | 
			
		||||
@@ -1115,7 +1115,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.Expired;
 | 
			
		||||
            expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
			
		||||
            expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.be.equal(expectedOrderStatus);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return the correct orderInfo for an expired and fully filled order', async () => {
 | 
			
		||||
            await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
 | 
			
		||||
@@ -1129,7 +1129,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.FullyFilled;
 | 
			
		||||
            expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
			
		||||
            expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.be.equal(expectedOrderStatus);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return the correct orderInfo for an order with a makerAssetAmount of 0', async () => {
 | 
			
		||||
            signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetAmount: new BigNumber(0) });
 | 
			
		||||
@@ -1139,7 +1139,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.InvalidMakerAssetAmount;
 | 
			
		||||
            expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
			
		||||
            expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.be.equal(expectedOrderStatus);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return the correct orderInfo for an order with a takerAssetAmount of 0', async () => {
 | 
			
		||||
            signedOrder = await orderFactory.newSignedOrderAsync({ takerAssetAmount: new BigNumber(0) });
 | 
			
		||||
@@ -1149,7 +1149,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.InvalidTakerAssetAmount;
 | 
			
		||||
            expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
			
		||||
            expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.be.equal(expectedOrderStatus);
 | 
			
		||||
            expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,6 @@ import {
 | 
			
		||||
    testCombinatoriallyWithReferenceFuncAsync,
 | 
			
		||||
    txDefaults,
 | 
			
		||||
    uint256Values,
 | 
			
		||||
    orderUtils,
 | 
			
		||||
    web3Wrapper,
 | 
			
		||||
} from '@0x/contracts-test-utils';
 | 
			
		||||
import { BlockchainLifecycle } from '@0x/dev-utils';
 | 
			
		||||
@@ -453,7 +452,7 @@ describe('Exchange core internal functions', () => {
 | 
			
		||||
            };
 | 
			
		||||
            await web3Wrapper.awaitTransactionSuccessAsync(
 | 
			
		||||
                await testExchange.publicUpdateFilledState.sendTransactionAsync(
 | 
			
		||||
                    orderUtils.getOrderWithoutExchangeAddress(emptySignedOrder),
 | 
			
		||||
                    emptySignedOrder,
 | 
			
		||||
                    constants.NULL_ADDRESS,
 | 
			
		||||
                    orderHash,
 | 
			
		||||
                    orderTakerAssetFilledAmount,
 | 
			
		||||
 
 | 
			
		||||
@@ -68,6 +68,7 @@ export class {{contractName}}Contract extends BaseContract {
 | 
			
		||||
        );
 | 
			
		||||
        const iface = new ethers.utils.Interface(abi);
 | 
			
		||||
        const deployInfo = iface.deployFunction;
 | 
			
		||||
        console.log('*'.repeat(50), `\n${JSON.stringify(deployInfo)}`);
 | 
			
		||||
        const txData = deployInfo.encode(bytecode, [{{> params inputs=ctor.inputs}}]);
 | 
			
		||||
        const web3Wrapper = new Web3Wrapper(provider);
 | 
			
		||||
        const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync(
 | 
			
		||||
 
 | 
			
		||||
@@ -41,12 +41,6 @@ export class BaseContract {
 | 
			
		||||
    ): any {
 | 
			
		||||
        return _.map(values, (value: any, i: number) => formatABIDataItem(abis[i], value, formatter));
 | 
			
		||||
    }
 | 
			
		||||
    protected static _lowercaseAddress(type: string, value: string): string {
 | 
			
		||||
        return type === 'address' ? value.toLowerCase() : value;
 | 
			
		||||
    }
 | 
			
		||||
    protected static _bigNumberToString(_type: string, value: any): any {
 | 
			
		||||
        return _.isObject(value) && value.isBigNumber ? value.toString() : value;
 | 
			
		||||
    }
 | 
			
		||||
    protected static _lookupConstructorAbi(abi: ContractAbi): ConstructorAbi {
 | 
			
		||||
        const constructorAbiIfExists = _.find(
 | 
			
		||||
            abi,
 | 
			
		||||
@@ -67,9 +61,6 @@ export class BaseContract {
 | 
			
		||||
            return defaultConstructorAbi;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    protected static _bnToBigNumber(_type: string, value: any): any {
 | 
			
		||||
        return _.isObject(value) && value._hex ? new BigNumber(value.toString()) : value;
 | 
			
		||||
    }
 | 
			
		||||
    protected static async _applyDefaultsToTxDataAsync<T extends Partial<TxData | TxDataPayable>>(
 | 
			
		||||
        txData: T,
 | 
			
		||||
        txDefaults: Partial<TxData>,
 | 
			
		||||
@@ -99,11 +90,11 @@ export class BaseContract {
 | 
			
		||||
    // the given inputAbi. An argument may not be considered safely encodeable
 | 
			
		||||
    // if it overflows the corresponding Solidity type, there is a bug in the
 | 
			
		||||
    // encoder, or the encoder performs unsafe type coercion.
 | 
			
		||||
    public static strictArgumentEncodingCheck(inputAbi: DataItem[], args: any[]): void {
 | 
			
		||||
        const coder = new ethers.utils.AbiCoder();
 | 
			
		||||
    public static strictArgumentEncodingCheck(inputAbi: DataItem[], args: any[]): string {
 | 
			
		||||
        const abiEncoder = AbiEncoder.create(inputAbi);
 | 
			
		||||
        const params = abiUtils.parseEthersParams(inputAbi);
 | 
			
		||||
        const rawEncoded = coder.encode(inputAbi, args);
 | 
			
		||||
        const rawDecoded = coder.decode(inputAbi, rawEncoded);
 | 
			
		||||
        const rawEncoded = abiEncoder.encode(args);
 | 
			
		||||
        const rawDecoded = abiEncoder.decodeAsArray(rawEncoded);
 | 
			
		||||
        for (let i = 0; i < rawDecoded.length; i++) {
 | 
			
		||||
            const original = args[i];
 | 
			
		||||
            const decoded = rawDecoded[i];
 | 
			
		||||
@@ -115,6 +106,13 @@ export class BaseContract {
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return rawEncoded;
 | 
			
		||||
    }
 | 
			
		||||
       protected static _lowercaseAddress(type: string, value: string): string {
 | 
			
		||||
                return type === 'address' ? value.toLowerCase() : value;
 | 
			
		||||
            }
 | 
			
		||||
            protected static _bigNumberToString(_type: string, value: any): any {
 | 
			
		||||
                return _.isObject(value) && value.isBigNumber ? value.toString() : value;
 | 
			
		||||
           }
 | 
			
		||||
    protected _lookupAbiEncoder(functionSignature: string): AbiEncoder.Method {
 | 
			
		||||
        const abiEncoder = this._abiEncoderByFunctionSignature[functionSignature];
 | 
			
		||||
@@ -143,21 +141,8 @@ export class BaseContract {
 | 
			
		||||
        if (inputAbi === undefined) {
 | 
			
		||||
            throw new Error(`Undefined Method Input ABI`);
 | 
			
		||||
        }
 | 
			
		||||
        const params = abiUtils.parseEthersParams(inputAbi);
 | 
			
		||||
        const rawEncoded = abiEncoder.encode(functionArguments);
 | 
			
		||||
        const rawDecoded = abiEncoder.decodeAsArray(rawEncoded);
 | 
			
		||||
        for (let i = 0; i < rawDecoded.length; i++) {
 | 
			
		||||
            const original = functionArguments[i];
 | 
			
		||||
            const decoded = rawDecoded[i];
 | 
			
		||||
            if (!abiUtils.isAbiDataEqual(params.names[i], params.types[i], original, decoded)) {
 | 
			
		||||
                throw new Error(
 | 
			
		||||
                    `Cannot safely encode argument: ${params.names[i]} (${original}) of type ${
 | 
			
		||||
                        params.types[i]
 | 
			
		||||
                    }. (Possible type overflow or other encoding error)`,
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return rawEncoded;
 | 
			
		||||
        const abiEncodedArguments = abiEncoder.encode(functionArguments);////BaseContract.strictArgumentEncodingCheck(inputAbi, functionArguments);
 | 
			
		||||
        return abiEncodedArguments;
 | 
			
		||||
    }
 | 
			
		||||
    constructor(
 | 
			
		||||
        contractName: string,
 | 
			
		||||
 
 | 
			
		||||
@@ -51,6 +51,12 @@ export abstract class DataType {
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public decodeAsArray(returndata: string, rules?: DecodingRules): any {
 | 
			
		||||
        const value = this.decode(returndata, rules);
 | 
			
		||||
        const valuesAsArray = _.isObject(value) ? _.values(value) : [value];
 | 
			
		||||
        return valuesAsArray;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getSignature(detailed?: boolean): string {
 | 
			
		||||
        if (_.isEmpty(this._dataItem.name) || !detailed) return this.getSignatureType();
 | 
			
		||||
        const name = this.getDataItem().name;
 | 
			
		||||
 
 | 
			
		||||
@@ -135,21 +135,23 @@ export class EvmDataTypeFactory implements DataTypeFactory {
 | 
			
		||||
// Convenience function
 | 
			
		||||
export function create(input: DataItem | DataItem[] | string): DataType {
 | 
			
		||||
    // Handle different types of input
 | 
			
		||||
    let dataItems: DataItem[] = [];
 | 
			
		||||
    if (typeof(input) === 'string') {
 | 
			
		||||
        dataItems = generateDataItemsFromSignature(input);
 | 
			
		||||
    } else if(input instanceof Array) {
 | 
			
		||||
        dataItems = input as DataItem[];
 | 
			
		||||
    } else {
 | 
			
		||||
        dataItems = [input as DataItem];
 | 
			
		||||
    }
 | 
			
		||||
    // Create single data item from input
 | 
			
		||||
    let dataItem: DataItem = dataItems.length === 1 ? dataItems[0] : {
 | 
			
		||||
    const isSignature = typeof(input) === 'string';
 | 
			
		||||
    const isTupleSignature = isSignature && (input as string).startsWith('(');
 | 
			
		||||
    const parseAsTuple = isTupleSignature || _.isArray(input);
 | 
			
		||||
    // Create input `dataItem`
 | 
			
		||||
    let dataItem: DataItem;
 | 
			
		||||
    if(parseAsTuple) {
 | 
			
		||||
        const dataItems = isSignature ? generateDataItemsFromSignature(input as string) : input as DataItem[];
 | 
			
		||||
        dataItem = {
 | 
			
		||||
            name: '',
 | 
			
		||||
            type: 'tuple',
 | 
			
		||||
            components: dataItems
 | 
			
		||||
        };
 | 
			
		||||
    } else {
 | 
			
		||||
        dataItem = isSignature ? generateDataItemsFromSignature(input as string)[0] : input as DataItem;
 | 
			
		||||
    }
 | 
			
		||||
    // Create data type
 | 
			
		||||
    return EvmDataTypeFactory.getInstance().create(dataItem);
 | 
			
		||||
    const dataType = EvmDataTypeFactory.getInstance().create(dataItem);
 | 
			
		||||
    return dataType;
 | 
			
		||||
}
 | 
			
		||||
/* tslint:enable no-construct */
 | 
			
		||||
 
 | 
			
		||||
@@ -35,12 +35,6 @@ export class MethodDataType extends AbstractSetDataType {
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public decodeAsArray(returndata: string, rules?: DecodingRules): any {
 | 
			
		||||
        const value = this.decode(returndata, rules);
 | 
			
		||||
        const valuesAsArray = _.isObject(value) ? _.values(value) : [value];
 | 
			
		||||
        return valuesAsArray;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public encodeReturnValues(value: any, rules?: EncodingRules): string {
 | 
			
		||||
        const returnData = this._returnDataType.encode(value, rules);
 | 
			
		||||
        return returnData;
 | 
			
		||||
 
 | 
			
		||||
@@ -13,4 +13,4 @@ export {
 | 
			
		||||
    UInt,
 | 
			
		||||
    create,
 | 
			
		||||
} from './evm_data_type_factory';
 | 
			
		||||
//export { fromSignature } from './utils/signatureParser';
 | 
			
		||||
export { DataType } from './abstract_data_types/data_type';
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user