aboutsummaryrefslogtreecommitdiffstats
path: root/packages/utils/src/abi_encoder
diff options
context:
space:
mode:
authorGreg Hysen <greg.hysen@gmail.com>2019-02-06 09:28:31 +0800
committerGreg Hysen <greg.hysen@gmail.com>2019-02-06 09:30:54 +0800
commit2326dcdb129674677674690b300fec1245149a48 (patch)
treec406f575cd6b111761b3a605b925e2763419a662 /packages/utils/src/abi_encoder
parentb5eb47f60930d040b94177023cd147834f98db1d (diff)
downloaddexon-0x-contracts-2326dcdb129674677674690b300fec1245149a48.tar
dexon-0x-contracts-2326dcdb129674677674690b300fec1245149a48.tar.gz
dexon-0x-contracts-2326dcdb129674677674690b300fec1245149a48.tar.bz2
dexon-0x-contracts-2326dcdb129674677674690b300fec1245149a48.tar.lz
dexon-0x-contracts-2326dcdb129674677674690b300fec1245149a48.tar.xz
dexon-0x-contracts-2326dcdb129674677674690b300fec1245149a48.tar.zst
dexon-0x-contracts-2326dcdb129674677674690b300fec1245149a48.zip
Handle NULL input for all data types
Diffstat (limited to 'packages/utils/src/abi_encoder')
-rw-r--r--packages/utils/src/abi_encoder/abstract_data_types/data_type.ts3
-rw-r--r--packages/utils/src/abi_encoder/abstract_data_types/types/set.ts21
-rw-r--r--packages/utils/src/abi_encoder/calldata/raw_calldata.ts5
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/address.ts5
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/bool.ts5
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts5
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/int.ts12
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/pointer.ts5
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/static_bytes.ts7
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/string.ts5
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/uint.ts12
-rw-r--r--packages/utils/src/abi_encoder/utils/constants.ts6
12 files changed, 85 insertions, 6 deletions
diff --git a/packages/utils/src/abi_encoder/abstract_data_types/data_type.ts b/packages/utils/src/abi_encoder/abstract_data_types/data_type.ts
index f23324721..bd4711baf 100644
--- a/packages/utils/src/abi_encoder/abstract_data_types/data_type.ts
+++ b/packages/utils/src/abi_encoder/abstract_data_types/data_type.ts
@@ -47,7 +47,7 @@ export abstract class DataType {
const hasSelector = !_.isUndefined(selector);
const rawCalldata = new RawCalldata(calldata, hasSelector);
const rules_ = _.isUndefined(rules) ? constants.DEFAULT_DECODING_RULES : rules;
- const value = this.generateValue(rawCalldata, rules_);
+ const value = rawCalldata.getSizeInBytes() > 0 ? this.generateValue(rawCalldata, rules_) : this.getDefaultValue(rules_);
return value;
}
@@ -71,6 +71,7 @@ export abstract class DataType {
public abstract generateCalldataBlock(value: any, parentBlock?: CalldataBlock): CalldataBlock;
public abstract generateValue(calldata: RawCalldata, rules: DecodingRules): any;
+ public abstract getDefaultValue(rules?: DecodingRules): any;
public abstract getSignatureType(): string;
public abstract isStatic(): boolean;
}
diff --git a/packages/utils/src/abi_encoder/abstract_data_types/types/set.ts b/packages/utils/src/abi_encoder/abstract_data_types/types/set.ts
index 2c6c4b0f6..d45088482 100644
--- a/packages/utils/src/abi_encoder/abstract_data_types/types/set.ts
+++ b/packages/utils/src/abi_encoder/abstract_data_types/types/set.ts
@@ -97,6 +97,27 @@ export abstract class AbstractSetDataType extends DataType {
return isStatic;
}
+ public getDefaultValue(rules?: DecodingRules): any[] | object {
+ let defaultValue: any[] | object;
+ if (this._isArray && _.isUndefined(this._arrayLength)) {
+ defaultValue = [];
+ } else if (!_.isUndefined(rules) && rules.shouldConvertStructsToObjects && !this._isArray) {
+ defaultValue = {};
+ _.each(this._memberIndexByName, (idx: number, key: string) => {
+ const member = this._members[idx];
+ const memberValue = member.getDefaultValue();
+ (defaultValue as { [key: string]: any })[key] = memberValue;
+ });
+ } else {
+ defaultValue = [];
+ _.each(this._members, (member: DataType, idx: number) => {
+ const memberValue = member.getDefaultValue();
+ (defaultValue as any[]).push(memberValue);
+ });
+ }
+ return defaultValue;
+ }
+
protected _generateCalldataBlockFromArray(value: any[], parentBlock?: CalldataBlock): SetCalldataBlock {
// Sanity check: if the set has a defined length then `value` must have the same length.
if (!_.isUndefined(this._arrayLength) && value.length !== this._arrayLength) {
diff --git a/packages/utils/src/abi_encoder/calldata/raw_calldata.ts b/packages/utils/src/abi_encoder/calldata/raw_calldata.ts
index 189841989..dbc9d4942 100644
--- a/packages/utils/src/abi_encoder/calldata/raw_calldata.ts
+++ b/packages/utils/src/abi_encoder/calldata/raw_calldata.ts
@@ -79,4 +79,9 @@ export class RawCalldata {
public getSelector(): string {
return this._selector;
}
+
+ public getSizeInBytes(): number {
+ const sizeInBytes = this._value.byteLength;
+ return sizeInBytes;
+ }
}
diff --git a/packages/utils/src/abi_encoder/evm_data_types/address.ts b/packages/utils/src/abi_encoder/evm_data_types/address.ts
index 2278830eb..7e92d3888 100644
--- a/packages/utils/src/abi_encoder/evm_data_types/address.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types/address.ts
@@ -12,6 +12,7 @@ export class AddressDataType extends AbstractBlobDataType {
private static readonly _ADDRESS_SIZE_IN_BYTES = 20;
private static readonly _DECODED_ADDRESS_OFFSET_IN_BYTES =
constants.EVM_WORD_WIDTH_IN_BYTES - AddressDataType._ADDRESS_SIZE_IN_BYTES;
+ private static readonly _DEFAULT_VALUE = '0x0000000000000000000000000000000000000000';
public static matchType(type: string): boolean {
return type === SolidityTypes.Address;
@@ -43,6 +44,10 @@ export class AddressDataType extends AbstractBlobDataType {
return valueLowercase;
}
+ public getDefaultValue(): string {
+ return AddressDataType._DEFAULT_VALUE;
+ }
+
public getSignatureType(): string {
return SolidityTypes.Address;
}
diff --git a/packages/utils/src/abi_encoder/evm_data_types/bool.ts b/packages/utils/src/abi_encoder/evm_data_types/bool.ts
index ffccd6e53..54b516bb0 100644
--- a/packages/utils/src/abi_encoder/evm_data_types/bool.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types/bool.ts
@@ -10,6 +10,7 @@ import { constants } from '../utils/constants';
export class BoolDataType extends AbstractBlobDataType {
private static readonly _SIZE_KNOWN_AT_COMPILE_TIME: boolean = true;
+ private static readonly _DEFAULT_VALUE: boolean =false;
public static matchType(type: string): boolean {
return type === SolidityTypes.Bool;
@@ -47,6 +48,10 @@ export class BoolDataType extends AbstractBlobDataType {
return value;
}
+ public getDefaultValue(): boolean {
+ return BoolDataType._DEFAULT_VALUE;
+ }
+
public getSignatureType(): string {
return SolidityTypes.Bool;
}
diff --git a/packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts b/packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts
index fa38b63c0..0dd40fed2 100644
--- a/packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts
@@ -9,6 +9,7 @@ import { constants } from '../utils/constants';
export class DynamicBytesDataType extends AbstractBlobDataType {
private static readonly _SIZE_KNOWN_AT_COMPILE_TIME: boolean = false;
+ private static readonly _DEFAULT_VALUE = "0x";
public static matchType(type: string): boolean {
return type === SolidityTypes.Bytes;
@@ -65,6 +66,10 @@ export class DynamicBytesDataType extends AbstractBlobDataType {
return value;
}
+ public getDefaultValue(): string {
+ return DynamicBytesDataType._DEFAULT_VALUE;
+ }
+
public getSignatureType(): string {
return SolidityTypes.Bytes;
}
diff --git a/packages/utils/src/abi_encoder/evm_data_types/int.ts b/packages/utils/src/abi_encoder/evm_data_types/int.ts
index f8be1f778..c7e4318eb 100644
--- a/packages/utils/src/abi_encoder/evm_data_types/int.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types/int.ts
@@ -15,6 +15,7 @@ export class IntDataType extends AbstractBlobDataType {
private static readonly _SIZE_KNOWN_AT_COMPILE_TIME: boolean = true;
private static readonly _MAX_WIDTH: number = 256;
private static readonly _DEFAULT_WIDTH: number = IntDataType._MAX_WIDTH;
+ private static readonly _DEFAULT_VALUE = new BigNumber(0);
private readonly _width: number;
private readonly _minValue: BigNumber;
private readonly _maxValue: BigNumber;
@@ -50,13 +51,20 @@ export class IntDataType extends AbstractBlobDataType {
public decodeValue(calldata: RawCalldata): BigNumber | number {
const valueBuf = calldata.popWord();
const value = EncoderMath.safeDecodeNumericValue(valueBuf, this._minValue, this._maxValue);
- const numberOfBytesInUint8 = 8;
- if (this._width === numberOfBytesInUint8) {
+ if (this._width === constants.NUMBER_OF_BYTES_IN_UINT8) {
return value.toNumber();
}
return value;
}
+ public getDefaultValue(): BigNumber | number {
+ const defaultValue = IntDataType._DEFAULT_VALUE;
+ if (this._width === constants.NUMBER_OF_BYTES_IN_UINT8) {
+ return defaultValue.toNumber();
+ }
+ return defaultValue;
+ }
+
public getSignatureType(): string {
return `${SolidityTypes.Int}${this._width}`;
}
diff --git a/packages/utils/src/abi_encoder/evm_data_types/pointer.ts b/packages/utils/src/abi_encoder/evm_data_types/pointer.ts
index 250db7c64..50f68f5ea 100644
--- a/packages/utils/src/abi_encoder/evm_data_types/pointer.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types/pointer.ts
@@ -18,4 +18,9 @@ export class PointerDataType extends AbstractPointerDataType {
public getSignature(isDetailed?: boolean): string {
return this._destination.getSignature(isDetailed);
}
+
+ public getDefaultValue(): any {
+ const defaultValue = this._destination.getDefaultValue();
+ return defaultValue;
+ }
}
diff --git a/packages/utils/src/abi_encoder/evm_data_types/static_bytes.ts b/packages/utils/src/abi_encoder/evm_data_types/static_bytes.ts
index cbf1957d7..a965f6796 100644
--- a/packages/utils/src/abi_encoder/evm_data_types/static_bytes.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types/static_bytes.ts
@@ -58,6 +58,13 @@ export class StaticBytesDataType extends AbstractBlobDataType {
return value;
}
+ public getDefaultValue(): string {
+ const valueBufPadded = constants.EMPTY_EVM_WORD_BUFFER;
+ const valueBuf = valueBufPadded.slice(0, this._width);
+ const value = ethUtil.bufferToHex(valueBuf);
+ return value;
+ }
+
private _sanityCheckValue(value: string | Buffer): void {
if (typeof value === 'string') {
if (!_.startsWith(value, '0x')) {
diff --git a/packages/utils/src/abi_encoder/evm_data_types/string.ts b/packages/utils/src/abi_encoder/evm_data_types/string.ts
index 97ac46442..886f398f9 100644
--- a/packages/utils/src/abi_encoder/evm_data_types/string.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types/string.ts
@@ -9,6 +9,7 @@ import { constants } from '../utils/constants';
export class StringDataType extends AbstractBlobDataType {
private static readonly _SIZE_KNOWN_AT_COMPILE_TIME: boolean = false;
+ private static readonly _DEFAULT_VALUE = "";
public static matchType(type: string): boolean {
return type === SolidityTypes.String;
@@ -52,6 +53,10 @@ export class StringDataType extends AbstractBlobDataType {
return value;
}
+ public getDefaultValue(): string {
+ return StringDataType._DEFAULT_VALUE;
+ }
+
public getSignatureType(): string {
return SolidityTypes.String;
}
diff --git a/packages/utils/src/abi_encoder/evm_data_types/uint.ts b/packages/utils/src/abi_encoder/evm_data_types/uint.ts
index a82aa789e..9dc141a59 100644
--- a/packages/utils/src/abi_encoder/evm_data_types/uint.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types/uint.ts
@@ -16,6 +16,7 @@ export class UIntDataType extends AbstractBlobDataType {
private static readonly _MAX_WIDTH: number = 256;
private static readonly _DEFAULT_WIDTH: number = UIntDataType._MAX_WIDTH;
private static readonly _MIN_VALUE = new BigNumber(0);
+ private static readonly _DEFAULT_VALUE = new BigNumber(0);
private readonly _width: number;
private readonly _maxValue: BigNumber;
@@ -49,13 +50,20 @@ export class UIntDataType extends AbstractBlobDataType {
public decodeValue(calldata: RawCalldata): BigNumber | number {
const valueBuf = calldata.popWord();
const value = EncoderMath.safeDecodeNumericValue(valueBuf, UIntDataType._MIN_VALUE, this._maxValue);
- const numberOfBytesInUint8 = 8;
- if (this._width === numberOfBytesInUint8) {
+ if (this._width === constants.NUMBER_OF_BYTES_IN_INT8) {
return value.toNumber();
}
return value;
}
+ public getDefaultValue(): BigNumber | number {
+ const defaultValue = UIntDataType._DEFAULT_VALUE;
+ if (this._width === constants.NUMBER_OF_BYTES_IN_INT8) {
+ return defaultValue.toNumber();
+ }
+ return defaultValue;
+ }
+
public getSignatureType(): string {
return `${SolidityTypes.Uint}${this._width}`;
}
diff --git a/packages/utils/src/abi_encoder/utils/constants.ts b/packages/utils/src/abi_encoder/utils/constants.ts
index fc586f295..e14814e2e 100644
--- a/packages/utils/src/abi_encoder/utils/constants.ts
+++ b/packages/utils/src/abi_encoder/utils/constants.ts
@@ -14,4 +14,8 @@ export const constants = {
DEFAULT_DECODING_RULES: { shouldConvertStructsToObjects: true } as DecodingRules,
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'),
+ NUMBER_OF_BYTES_IN_UINT8: 8,
+ NUMBER_OF_BYTES_IN_INT8: 8,
+}