aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Hysen <greg.hysen@gmail.com>2019-02-06 10:01:38 +0800
committerGreg Hysen <greg.hysen@gmail.com>2019-02-06 10:01:38 +0800
commit2ad6bd394504fe8d89ce6189aef18bb705ad7625 (patch)
tree8d14edeb79be7103e25ad1b74e01566b01a51ce7
parent2326dcdb129674677674690b300fec1245149a48 (diff)
downloaddexon-0x-contracts-2ad6bd394504fe8d89ce6189aef18bb705ad7625.tar
dexon-0x-contracts-2ad6bd394504fe8d89ce6189aef18bb705ad7625.tar.gz
dexon-0x-contracts-2ad6bd394504fe8d89ce6189aef18bb705ad7625.tar.bz2
dexon-0x-contracts-2ad6bd394504fe8d89ce6189aef18bb705ad7625.tar.lz
dexon-0x-contracts-2ad6bd394504fe8d89ce6189aef18bb705ad7625.tar.xz
dexon-0x-contracts-2ad6bd394504fe8d89ce6189aef18bb705ad7625.tar.zst
dexon-0x-contracts-2ad6bd394504fe8d89ce6189aef18bb705ad7625.zip
Test cases for handling NULL input for all data types
-rw-r--r--packages/utils/src/abi_encoder/utils/constants.ts3
-rw-r--r--packages/utils/test/abi_encoder/evm_data_types_test.ts171
2 files changed, 162 insertions, 12 deletions
diff --git a/packages/utils/src/abi_encoder/utils/constants.ts b/packages/utils/src/abi_encoder/utils/constants.ts
index e14814e2e..db190c3a6 100644
--- a/packages/utils/src/abi_encoder/utils/constants.ts
+++ b/packages/utils/src/abi_encoder/utils/constants.ts
@@ -1,4 +1,5 @@
import { DecodingRules, EncodingRules } from './rules';
+import * as ethUtil from 'ethereumjs-util';
export const constants = {
EVM_WORD_WIDTH_IN_BYTES: 32,
@@ -15,7 +16,7 @@ export const constants = {
DEFAULT_ENCODING_RULES: { shouldOptimize: true, shouldAnnotate: false } as EncodingRules,
/* tslint:enable no-object-literal-type-assertion */
EMPTY_EVM_WORD_STRING: '0x0000000000000000000000000000000000000000000000000000000000000000',
- EMPTY_EVM_WORD_BUFFER: new Buffer('0x0000000000000000000000000000000000000000000000000000000000000000'),
+ EMPTY_EVM_WORD_BUFFER: ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000000'),
NUMBER_OF_BYTES_IN_UINT8: 8,
NUMBER_OF_BYTES_IN_INT8: 8,
}
diff --git a/packages/utils/test/abi_encoder/evm_data_types_test.ts b/packages/utils/test/abi_encoder/evm_data_types_test.ts
index c146890e0..c09c0d929 100644
--- a/packages/utils/test/abi_encoder/evm_data_types_test.ts
+++ b/packages/utils/test/abi_encoder/evm_data_types_test.ts
@@ -11,6 +11,7 @@ const expect = chai.expect;
describe('ABI Encoder: EVM Data Type Encoding/Decoding', () => {
const encodingRules: AbiEncoder.EncodingRules = { shouldOptimize: false }; // optimizer is tested separately.
+ const nullEncodedArgs = '0x';
describe('Array', () => {
it('Fixed size; Static elements', async () => {
// Create DataType object
@@ -207,6 +208,51 @@ describe('ABI Encoder: EVM Data Type Encoding/Decoding', () => {
dataType.encode(args, encodingRules);
}).to.throw('Tried to assign NaN value');
});
+ it('Should decode NULL to default values (Fixed size; Static elements)', async () => {
+ // Create DataType object
+ const testDataItem = { name: 'testArray', type: 'int[2]' };
+ const dataType = new AbiEncoder.Array(testDataItem);
+ const args = [new BigNumber(0), new BigNumber(0)];
+ // Decode Encoded Args and validate result
+ const decodedArgs = dataType.decode(nullEncodedArgs);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
+ it('Should decode NULL to default values (Dynamic size; Static elements)', async () => {
+ // Create DataType object
+ const testDataItem = { name: 'testArray', type: 'int[]' };
+ const dataType = new AbiEncoder.Array(testDataItem);
+ const args: BigNumber[] = [];
+ // Decode Encoded Args and validate result
+ const decodedArgs = dataType.decode(nullEncodedArgs);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
+ it('Should decode NULL to default values (Fixed size; Dynamic elements)', async () => {
+ // Create DataType object
+ const testDataItem = { name: 'testArray', type: 'string[2]' };
+ const dataType = new AbiEncoder.Array(testDataItem);
+ const args = ['', ''];
+ // Decode Encoded Args and validate result
+ const decodedArgs = dataType.decode(nullEncodedArgs);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
+ it('Should decode NULL to default values (Dynamic size; Dynamic elements)', async () => {
+ // Create DataType object
+ const testDataItem = { name: 'testArray', type: 'string[]' };
+ const dataType = new AbiEncoder.Array(testDataItem);
+ const args: string[] = [];
+ // Decode Encoded Args and validate result
+ const decodedArgs = dataType.decode(nullEncodedArgs);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
+ it('Should decode NULL to default values (Dynamic Size; Multidimensional; Dynamic Elements)', async () => {
+ // Create DataType object
+ const testDataItem = { name: 'testArray', type: 'bytes[][]' };
+ const dataType = new AbiEncoder.Array(testDataItem);
+ const args: string[][] = [];
+ // Decode Encoded Args and validate result
+ const decodedArgs = dataType.decode(nullEncodedArgs);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
});
describe('Tuple', () => {
@@ -407,6 +453,46 @@ describe('ABI Encoder: EVM Data Type Encoding/Decoding', () => {
dataType.encode(args, encodingRules);
}).to.throw('Could not assign tuple to object: missing key \'field_2\' in object {"field_1":"-5"}');
});
+ it('Should decode NULL to default values (static elements only)', async () => {
+ // Create DataType object
+ const testDataItem = {
+ name: 'Tuple',
+ type: 'tuple',
+ components: [{ name: 'field_1', type: 'int32' }, { name: 'field_2', type: 'bool' }],
+ };
+ const dataType = new AbiEncoder.Tuple(testDataItem);
+ // Construct args to be encoded
+ const args = { field_1: new BigNumber(0), field_2: false };
+ // Decode Encoded Args and validate result
+ const decodingRules: AbiEncoder.DecodingRules = { shouldConvertStructsToObjects: true };
+ const decodedArgs = dataType.decode(nullEncodedArgs, decodingRules);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
+ it('Should decode NULL to default values (static and dynamic elements)', async () => {
+ // Create DataType object
+ const testDataItem = {
+ name: 'Tuple',
+ type: 'tuple',
+ components: [
+ { name: 'field_1', type: 'int32' },
+ { name: 'field_2', type: 'string' },
+ { name: 'field_3', type: 'bool' },
+ { name: 'field_4', type: 'bytes' },
+ ],
+ };
+ const dataType = new AbiEncoder.Tuple(testDataItem);
+ // Construct args to be encoded
+ const args = {
+ field_1: new BigNumber(0),
+ field_2: '',
+ field_3: false,
+ field_4: '0x',
+ };
+ // Decode Encoded Args and validate result
+ const decodingRules: AbiEncoder.DecodingRules = { shouldConvertStructsToObjects: true };
+ const decodedArgs = dataType.decode(nullEncodedArgs, decodingRules);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
});
describe('Address', () => {
@@ -450,6 +536,15 @@ describe('ABI Encoder: EVM Data Type Encoding/Decoding', () => {
dataType.encode(args, encodingRules);
}).to.throw(`Invalid address: '${args}'`);
});
+ it('Should decode NULL to default value of address zero', async () => {
+ // Create DataType object
+ const testDataItem = { name: 'Address', type: 'address' };
+ const dataType = new AbiEncoder.Address(testDataItem);
+ const args = '0x0000000000000000000000000000000000000000';
+ // Decode Encoded Args and validate result
+ const decodedArgs = dataType.decode(nullEncodedArgs);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
});
describe('Bool', () => {
@@ -489,23 +584,14 @@ describe('ABI Encoder: EVM Data Type Encoding/Decoding', () => {
const argsEncodedFromSignature = dataTypeFromSignature.encode(args);
expect(argsEncodedFromSignature).to.be.deep.equal(expectedEncodedArgs);
});
- it('Null should decode as False', async () => {
- // Hack @hysz: there are some cases where `false` is encoded as 0x instead of 0x0.
+ it('Should decode NULL to default value of False', async () => {
// Create DataType object
const testDataItem = { name: 'Boolean', type: 'bool' };
const dataType = new AbiEncoder.Bool(testDataItem);
- // Construct args to be encoded
const args = false;
- // Encode Args and validate result
- const encodedArgs = '0x';
- const expectedEncodedArgs = '0x0000000000000000000000000000000000000000000000000000000000000000';
// Decode Encoded Args and validate result
- const decodedArgs = dataType.decode(encodedArgs);
+ const decodedArgs = dataType.decode(nullEncodedArgs);
expect(decodedArgs).to.be.deep.equal(args);
- // Validate signature
- const dataTypeFromSignature = AbiEncoder.create(dataType.getSignature(true));
- const argsEncodedFromSignature = dataTypeFromSignature.encode(args);
- expect(argsEncodedFromSignature).to.be.deep.equal(expectedEncodedArgs);
});
});
@@ -705,6 +791,15 @@ describe('ABI Encoder: EVM Data Type Encoding/Decoding', () => {
dataType.encode(args, encodingRules);
}).to.throw();
});
+ it('Should decode NULL to default value of 0', async () => {
+ // Create DataType object
+ const testDataItem = { name: 'Integer (256)', type: 'int' };
+ const dataType = new AbiEncoder.Int(testDataItem);
+ const args = new BigNumber(0);
+ // Decode Encoded Args and validate result
+ const decodedArgs = dataType.decode(nullEncodedArgs);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
});
describe('Unsigned Integer', () => {
@@ -867,6 +962,15 @@ describe('ABI Encoder: EVM Data Type Encoding/Decoding', () => {
dataType.encode(args, encodingRules);
}).to.throw();
});
+ it('Should decode NULL to default value of 0', async () => {
+ // Create DataType object
+ const testDataItem = { name: 'Unsigned Integer (256)', type: 'uint' };
+ const dataType = new AbiEncoder.UInt(testDataItem);
+ const args = new BigNumber(0);
+ // Decode Encoded Args and validate result
+ const decodedArgs = dataType.decode(nullEncodedArgs);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
});
describe('Static Bytes', () => {
@@ -1030,6 +1134,33 @@ describe('ABI Encoder: EVM Data Type Encoding/Decoding', () => {
dataType.encode(args, encodingRules);
}).to.throw('Tried to assign 0x010, which is contains a half-byte. Use full bytes only.');
});
+ it('Should decode NULL to default value - Single Byte (byte)', async () => {
+ // Create DataType object
+ const testDataItem = { name: 'Static Byte', type: 'byte' };
+ const dataType = new AbiEncoder.StaticBytes(testDataItem);
+ const args = '0x00';
+ // Decode Encoded Args and validate result
+ const decodedArgs = dataType.decode(nullEncodedArgs);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
+ it('Should decode NULL to default value - 4 Bytes (bytes4)', async () => {
+ // Create DataType object
+ const testDataItem = { name: 'Static Bytes4', type: 'bytes4' };
+ const dataType = new AbiEncoder.StaticBytes(testDataItem);
+ const args = '0x00000000';
+ // Decode Encoded Args and validate result
+ const decodedArgs = dataType.decode(nullEncodedArgs);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
+ it('Should decode NULL to default value - 32 Bytes (bytes32)', async () => {
+ // Create DataType object
+ const testDataItem = { name: 'Static Bytes32', type: 'bytes32' };
+ const dataType = new AbiEncoder.StaticBytes(testDataItem);
+ const args = '0x0000000000000000000000000000000000000000000000000000000000000000';
+ // Decode Encoded Args and validate result
+ const decodedArgs = dataType.decode(nullEncodedArgs);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
});
describe('Dynamic Bytes', () => {
@@ -1117,6 +1248,15 @@ describe('ABI Encoder: EVM Data Type Encoding/Decoding', () => {
dataType.encode(args, encodingRules);
}).to.throw('Tried to assign 0x010, which is contains a half-byte. Use full bytes only.');
});
+ it('Should decode NULL to empty byte array', async () => {
+ // Create DataType object
+ const testDataItem = { name: 'Dynamic Bytes', type: 'bytes' };
+ const dataType = new AbiEncoder.DynamicBytes(testDataItem);
+ const args = '0x';
+ // Decode Encoded Args and validate result
+ const decodedArgs = dataType.decode(nullEncodedArgs);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
});
describe('String', () => {
@@ -1182,5 +1322,14 @@ describe('ABI Encoder: EVM Data Type Encoding/Decoding', () => {
const argsEncodedFromSignature = dataTypeFromSignature.encode(args);
expect(argsEncodedFromSignature).to.be.deep.equal(expectedEncodedArgs);
});
+ it('Should decode NULL to empty string', async () => {
+ // Create DataType object
+ const testDataItem = { name: 'String', type: 'string' };
+ const dataType = new AbiEncoder.String(testDataItem);
+ // Decode Encoded Args and validate result
+ const args = '';
+ const decodedArgs = dataType.decode(nullEncodedArgs);
+ expect(decodedArgs).to.be.deep.equal(args);
+ });
});
});