aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/utils/src/abi_encoder/calldata.ts33
-rw-r--r--packages/utils/src/abi_encoder/constants.ts2
-rw-r--r--packages/utils/src/abi_encoder/data_type.ts19
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types.ts4
-rw-r--r--packages/utils/test/abi_encoder_test.ts4
-rw-r--r--packages/utils/test/optimizer_abis.ts339
-rw-r--r--packages/utils/test/return_value_abis.ts98
7 files changed, 463 insertions, 36 deletions
diff --git a/packages/utils/src/abi_encoder/calldata.ts b/packages/utils/src/abi_encoder/calldata.ts
index 9f91f8495..0c45d6198 100644
--- a/packages/utils/src/abi_encoder/calldata.ts
+++ b/packages/utils/src/abi_encoder/calldata.ts
@@ -90,12 +90,7 @@ export abstract class CalldataBlock {
export class PayloadCalldataBlock extends CalldataBlock {
private readonly _payload: Buffer;
- constructor(
- name: string,
- signature: string,
- parentName: string,
- payload: Buffer,
- ) {
+ constructor(name: string, signature: string, parentName: string, payload: Buffer) {
const headerSizeInBytes = 0;
const bodySizeInBytes = payload.byteLength;
super(name, signature, parentName, headerSizeInBytes, bodySizeInBytes);
@@ -120,13 +115,7 @@ export class DependentCalldataBlock extends CalldataBlock {
private readonly _dependency: CalldataBlock;
private _aliasFor: CalldataBlock | undefined;
- constructor(
- name: string,
- signature: string,
- parentName: string,
- dependency: CalldataBlock,
- parent: CalldataBlock,
- ) {
+ constructor(name: string, signature: string, parentName: string, dependency: CalldataBlock, parent: CalldataBlock) {
const headerSizeInBytes = DependentCalldataBlock._EMPTY_HEADER_SIZE;
const bodySizeInBytes = DependentCalldataBlock._DEPENDENT_PAYLOAD_SIZE_IN_BYTES;
super(name, signature, parentName, headerSizeInBytes, bodySizeInBytes);
@@ -408,7 +397,13 @@ export class Calldata {
line = `\n${offsetStr}${value}${nameStr}`;
} else {
offsetStr = `0x${offset.toString(Constants.HEX_BASE)}`.padEnd(offsetPadding);
- value = ethUtil.stripHexPrefix(ethUtil.bufferToHex(block.toBuffer().slice(evmWordStartIndex, Constants.EVM_WORD_WIDTH_IN_BYTES))).padEnd(valuePadding);
+ value = ethUtil
+ .stripHexPrefix(
+ ethUtil.bufferToHex(
+ block.toBuffer().slice(evmWordStartIndex, Constants.EVM_WORD_WIDTH_IN_BYTES),
+ ),
+ )
+ .padEnd(valuePadding);
if (block instanceof MemberCalldataBlock) {
nameStr = `### ${prettyName.padEnd(namePadding)}`;
line = `\n${offsetStr}${value}${nameStr}`;
@@ -420,7 +415,11 @@ export class Calldata {
for (let j = Constants.EVM_WORD_WIDTH_IN_BYTES; j < size; j += Constants.EVM_WORD_WIDTH_IN_BYTES) {
offsetStr = `0x${(offset + j).toString(Constants.HEX_BASE)}`.padEnd(offsetPadding);
- value = ethUtil.stripHexPrefix(ethUtil.bufferToHex(block.toBuffer().slice(j, j + Constants.EVM_WORD_WIDTH_IN_BYTES))).padEnd(valuePadding);
+ value = ethUtil
+ .stripHexPrefix(
+ ethUtil.bufferToHex(block.toBuffer().slice(j, j + Constants.EVM_WORD_WIDTH_IN_BYTES)),
+ )
+ .padEnd(valuePadding);
nameStr = ' '.repeat(namePadding);
line = `${line}\n${offsetStr}${value}${nameStr}`;
}
@@ -465,7 +464,9 @@ export class RawCalldata {
}
const valueBuf = ethUtil.toBuffer(value);
if (hasSelectorPrefix) {
- this._selector = ethUtil.bufferToHex(valueBuf.slice(Constants.HEX_SELECTOR_BYTE_OFFSET_IN_CALLDATA, Constants.HEX_SELECTOR_LENGTH_IN_BYTES));
+ this._selector = ethUtil.bufferToHex(
+ valueBuf.slice(Constants.HEX_SELECTOR_BYTE_OFFSET_IN_CALLDATA, Constants.HEX_SELECTOR_LENGTH_IN_BYTES),
+ );
this._value = valueBuf.slice(Constants.HEX_SELECTOR_LENGTH_IN_BYTES); // disregard selector
} else {
this._selector = '0x';
diff --git a/packages/utils/src/abi_encoder/constants.ts b/packages/utils/src/abi_encoder/constants.ts
index b52630d74..bc5b985e0 100644
--- a/packages/utils/src/abi_encoder/constants.ts
+++ b/packages/utils/src/abi_encoder/constants.ts
@@ -3,4 +3,4 @@ export const HEX_BASE = 16;
export const BIN_BASE = 2;
export const HEX_SELECTOR_LENGTH_IN_CHARS = 10;
export const HEX_SELECTOR_LENGTH_IN_BYTES = 4;
-export const HEX_SELECTOR_BYTE_OFFSET_IN_CALLDATA = 0; \ No newline at end of file
+export const HEX_SELECTOR_BYTE_OFFSET_IN_CALLDATA = 0;
diff --git a/packages/utils/src/abi_encoder/data_type.ts b/packages/utils/src/abi_encoder/data_type.ts
index 926023468..4370cb253 100644
--- a/packages/utils/src/abi_encoder/data_type.ts
+++ b/packages/utils/src/abi_encoder/data_type.ts
@@ -74,12 +74,7 @@ export abstract class PayloadDataType extends DataType {
const signature = this.getSignature();
const parentName = parentBlock === undefined ? '' : parentBlock.getName();
const relocatable = false;
- const block = new PayloadCalldataBlock(
- name,
- signature,
- parentName,
- encodedValue,
- );
+ const block = new PayloadCalldataBlock(name, signature, parentName, encodedValue);
return block;
}
@@ -115,13 +110,7 @@ export abstract class DependentDataType extends DataType {
const name = this.getDataItem().name;
const signature = this.getSignature();
const parentName = parentBlock === undefined ? '' : parentBlock.getName();
- const block = new DependentCalldataBlock(
- name,
- signature,
- parentName,
- dependencyBlock,
- parentBlock,
- );
+ const block = new DependentCalldataBlock(name, signature, parentName, dependencyBlock, parentBlock);
return block;
}
@@ -232,7 +221,7 @@ export abstract class MemberDataType extends DataType {
const methodBlock: MemberCalldataBlock = new MemberCalldataBlock(
this.getDataItem().name,
this.getSignature(),
- parentName
+ parentName,
);
let members = this.members;
@@ -257,7 +246,7 @@ export abstract class MemberDataType extends DataType {
const methodBlock: MemberCalldataBlock = new MemberCalldataBlock(
this.getDataItem().name,
this.getSignature(),
- parentName
+ parentName,
);
const memberBlocks: CalldataBlock[] = [];
let childMap = _.cloneDeep(this.memberMap);
diff --git a/packages/utils/src/abi_encoder/evm_data_types.ts b/packages/utils/src/abi_encoder/evm_data_types.ts
index b862e9396..76837361e 100644
--- a/packages/utils/src/abi_encoder/evm_data_types.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types.ts
@@ -276,7 +276,7 @@ export class Byte extends PayloadDataType {
if (valueBuf.byteLength > this.width) {
throw new Error(
`Tried to assign ${value} (${
- valueBuf.byteLength
+ valueBuf.byteLength
} bytes), which exceeds max bytes that can be stored in a ${this.getSignature()}`,
);
} else if (value.length % 2 !== 0) {
@@ -548,7 +548,7 @@ export class Method extends MemberDataType {
export class EvmDataTypeFactory implements DataTypeFactory {
private static instance: DataTypeFactory;
- private constructor() { }
+ private constructor() {}
public static getInstance(): DataTypeFactory {
if (!EvmDataTypeFactory.instance) {
diff --git a/packages/utils/test/abi_encoder_test.ts b/packages/utils/test/abi_encoder_test.ts
index 0220984b0..c7986fa00 100644
--- a/packages/utils/test/abi_encoder_test.ts
+++ b/packages/utils/test/abi_encoder_test.ts
@@ -102,7 +102,7 @@ describe.only('ABI Encoder', () => {
it('Duplicate Dynamic Arrays with Dynamic Elements', async () => {
// Generate calldata
const method = new AbiEncoder.Method(OptimizedAbis.duplicateDynamicArraysWithDynamicElements);
- const array1 = ["Hello", "World"];
+ const array1 = ['Hello', 'World'];
const array2 = array1;
const args = [array1, array2];
// Validata calldata
@@ -138,7 +138,7 @@ describe.only('ABI Encoder', () => {
it('Duplicate Static Arrays with Dynamic Elements', async () => {
// Generate calldata
const method = new AbiEncoder.Method(OptimizedAbis.duplicateStaticArraysWithDynamicElements);
- const array1 = ["Hello", "World"];
+ const array1 = ['Hello', 'World'];
const array2 = array1;
const args = [array1, array2];
// Validata calldata
diff --git a/packages/utils/test/optimizer_abis.ts b/packages/utils/test/optimizer_abis.ts
new file mode 100644
index 000000000..ea562e5b5
--- /dev/null
+++ b/packages/utils/test/optimizer_abis.ts
@@ -0,0 +1,339 @@
+import { MethodAbi } from 'ethereum-types';
+
+export const duplicateDynamicArraysWithStaticElements = {
+ constant: false,
+ inputs: [
+ {
+ name: 'array1',
+ type: 'uint[]',
+ },
+ {
+ name: 'array2',
+ type: 'uint[]',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const duplicateDynamicArraysWithDynamicElements = {
+ constant: false,
+ inputs: [
+ {
+ name: 'array1',
+ type: 'string[]',
+ },
+ {
+ name: 'array2',
+ type: 'string[]',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const duplicateStaticArraysWithStaticElements = {
+ constant: false,
+ inputs: [
+ {
+ name: 'array1',
+ type: 'uint[2]',
+ },
+ {
+ name: 'array2',
+ type: 'uint[2]',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const duplicateStaticArraysWithDynamicElements = {
+ constant: false,
+ inputs: [
+ {
+ name: 'array1',
+ type: 'string[2]',
+ },
+ {
+ name: 'array2',
+ type: 'string[2]',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const duplicateArrayElements = {
+ constant: false,
+ inputs: [
+ {
+ name: 'array',
+ type: 'string[]',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const duplicateTupleFields = {
+ constant: false,
+ inputs: [
+ {
+ components: [
+ {
+ name: 'field1',
+ type: 'string',
+ },
+ {
+ name: 'field2',
+ type: 'string',
+ },
+ ],
+ name: 'Tuple',
+ type: 'tuple',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const duplicateStrings = {
+ constant: false,
+ inputs: [
+ {
+ name: 'string1',
+ type: 'string',
+ },
+ {
+ name: 'string2',
+ type: 'string',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const duplicateBytes = {
+ constant: false,
+ inputs: [
+ {
+ name: 'bytes1',
+ type: 'bytes',
+ },
+ {
+ name: 'bytes2',
+ type: 'bytes',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const duplicateTuples = {
+ constant: false,
+ inputs: [
+ {
+ components: [
+ {
+ name: 'field1',
+ type: 'string',
+ },
+ {
+ name: 'field2',
+ type: 'uint',
+ },
+ ],
+ name: 'Tuple',
+ type: 'tuple',
+ },
+ {
+ components: [
+ {
+ name: 'field1',
+ type: 'string',
+ },
+ {
+ name: 'field2',
+ type: 'uint',
+ },
+ ],
+ name: 'Tuple',
+ type: 'tuple',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const duplicateArraysNestedInTuples = {
+ constant: false,
+ inputs: [
+ {
+ components: [
+ {
+ name: 'field',
+ type: 'uint[]',
+ },
+ ],
+ name: 'Tuple1',
+ type: 'tuple',
+ },
+ {
+ components: [
+ {
+ name: 'field',
+ type: 'uint[]',
+ },
+ {
+ name: 'extraField',
+ type: 'string',
+ },
+ ],
+ name: 'Tuple2',
+ type: 'tuple',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const duplicateTuplesNestedInTuples = {
+ constant: false,
+ inputs: [
+ {
+ components: [
+ {
+ components: [
+ {
+ name: 'nestedField',
+ type: 'string',
+ },
+ ],
+ name: 'field',
+ type: 'tuple',
+ },
+ ],
+ name: 'Tuple1',
+ type: 'tuple',
+ },
+ {
+ components: [
+ {
+ components: [
+ {
+ name: 'nestedField',
+ type: 'string',
+ },
+ ],
+ name: 'field',
+ type: 'tuple',
+ },
+ {
+ name: 'extraField',
+ type: 'string',
+ },
+ ],
+ name: 'Tuple1',
+ type: 'tuple',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const duplicateTwoDimensionalArrays = {
+ constant: false,
+ inputs: [
+ {
+ name: 'array1',
+ type: 'string[][]',
+ },
+ {
+ name: 'array2',
+ type: 'string[][]',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const arrayElementsDuplicatedAsSeparateParameter = {
+ constant: false,
+ inputs: [
+ {
+ name: 'stringArray',
+ type: 'string[]',
+ },
+ {
+ name: 'string',
+ type: 'string',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const arrayElementsDuplicatedAsTupleFields = {
+ constant: false,
+ inputs: [
+ {
+ name: 'uint8Array',
+ type: 'uint8[]',
+ },
+ {
+ components: [
+ {
+ name: 'uint',
+ type: 'uint',
+ },
+ ],
+ name: 'uintTuple',
+ type: 'tuple[]',
+ },
+ ],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
diff --git a/packages/utils/test/return_value_abis.ts b/packages/utils/test/return_value_abis.ts
new file mode 100644
index 000000000..847559dac
--- /dev/null
+++ b/packages/utils/test/return_value_abis.ts
@@ -0,0 +1,98 @@
+import { MethodAbi } from 'ethereum-types';
+
+export const noReturnValues = {
+ constant: false,
+ inputs: [],
+ name: 'simpleFunction',
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const singleStaticReturnValue = {
+ constant: false,
+ inputs: [],
+ name: 'simpleFunction',
+ outputs: [
+ {
+ name: 'Bytes4',
+ type: 'bytes4',
+ },
+ ],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const multipleStaticReturnValues = {
+ constant: false,
+ inputs: [],
+ name: 'simpleFunction',
+ outputs: [
+ {
+ name: 'val1',
+ type: 'bytes4',
+ },
+ {
+ name: 'val2',
+ type: 'bytes4',
+ },
+ ],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const singleDynamicReturnValue = {
+ constant: false,
+ inputs: [],
+ name: 'simpleFunction',
+ outputs: [
+ {
+ name: 'val',
+ type: 'bytes',
+ },
+ ],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const multipleDynamicReturnValues = {
+ constant: false,
+ inputs: [],
+ name: 'simpleFunction',
+ outputs: [
+ {
+ name: 'val1',
+ type: 'bytes',
+ },
+ {
+ name: 'val2',
+ type: 'bytes',
+ },
+ ],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;
+
+export const mixedStaticAndDynamicReturnValues = {
+ constant: false,
+ inputs: [],
+ name: 'simpleFunction',
+ outputs: [
+ {
+ name: 'val1',
+ type: 'bytes4',
+ },
+ {
+ name: 'val2',
+ type: 'bytes',
+ },
+ ],
+ payable: false,
+ stateMutability: 'nonpayable',
+ type: 'function',
+} as MethodAbi;