aboutsummaryrefslogtreecommitdiffstats
path: root/packages/utils/src/abi_encoder/evm_data_types/number.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/utils/src/abi_encoder/evm_data_types/number.ts')
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/number.ts71
1 files changed, 6 insertions, 65 deletions
diff --git a/packages/utils/src/abi_encoder/evm_data_types/number.ts b/packages/utils/src/abi_encoder/evm_data_types/number.ts
index 86acdce07..053a574e3 100644
--- a/packages/utils/src/abi_encoder/evm_data_types/number.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types/number.ts
@@ -1,11 +1,11 @@
import { DataItem } from 'ethereum-types';
-import * as ethUtil from 'ethereumjs-util';
import * as _ from 'lodash';
import { BigNumber } from '../../configured_bignumber';
import { DataTypeFactory, PayloadDataType } from '../abstract_data_types';
import { RawCalldata } from '../calldata';
import * as Constants from '../utils/constants';
+import * as EncoderMath from '../utils/math';
export abstract class Number extends PayloadDataType {
private static readonly _SIZE_KNOWN_AT_COMPILE_TIME: boolean = true;
@@ -25,73 +25,14 @@ export abstract class Number extends PayloadDataType {
: (this._width = Number._DEFAULT_WIDTH);
}
- public encodeValue(value_: BigNumber | string | number): Buffer {
- const value = new BigNumber(value_, 10);
- if (value.greaterThan(this.getMaxValue())) {
- throw new Error(`Tried to assign value of ${value}, which exceeds max value of ${this.getMaxValue()}`);
- } else if (value.lessThan(this.getMinValue())) {
- throw new Error(`Tried to assign value of ${value}, which exceeds min value of ${this.getMinValue()}`);
- }
-
- let valueBuf: Buffer;
- if (value.greaterThanOrEqualTo(0)) {
- valueBuf = ethUtil.setLengthLeft(
- ethUtil.toBuffer(`0x${value.toString(Constants.HEX_BASE)}`),
- Constants.EVM_WORD_WIDTH_IN_BYTES,
- );
- } else {
- // BigNumber can't write a negative hex value, so we use twos-complement conversion to do it ourselves.
- // Step 1/3: Convert value to positive binary string
- const binBase = 2;
- const valueBin = value.times(-1).toString(binBase);
-
- // Step 2/3: Invert binary value
- let invertedValueBin = '1'.repeat(Constants.EVM_WORD_WIDTH_IN_BITS - valueBin.length);
- _.each(valueBin, (bit: string) => {
- invertedValueBin += bit === '1' ? '0' : '1';
- });
- const invertedValue = new BigNumber(invertedValueBin, binBase);
-
- // Step 3/3: Add 1 to inverted value
- // The result is the two's-complement represent of the input value.
- const negativeValue = invertedValue.plus(1);
-
- // Convert the negated value to a hex string
- valueBuf = ethUtil.setLengthLeft(
- ethUtil.toBuffer(`0x${negativeValue.toString(Constants.HEX_BASE)}`),
- Constants.EVM_WORD_WIDTH_IN_BYTES,
- );
- }
-
- return valueBuf;
+ public encodeValue(value: BigNumber | string | number): Buffer {
+ const encodedValue = EncoderMath.safeEncodeNumericValue(value, this.getMinValue(), this.getMaxValue());
+ return encodedValue;
}
public decodeValue(calldata: RawCalldata): BigNumber {
- const paddedValueBuf = calldata.popWord();
- const paddedValueHex = ethUtil.bufferToHex(paddedValueBuf);
- let value = new BigNumber(paddedValueHex, 16);
- if (this.getMinValue().lessThan(0)) {
- // Check if we're negative
- const valueBin = value.toString(Constants.BIN_BASE);
- if (valueBin.length === Constants.EVM_WORD_WIDTH_IN_BITS && valueBin[0].startsWith('1')) {
- // Negative
- // Step 1/3: Invert binary value
- let invertedValueBin = '';
- _.each(valueBin, (bit: string) => {
- invertedValueBin += bit === '1' ? '0' : '1';
- });
- const invertedValue = new BigNumber(invertedValueBin, Constants.BIN_BASE);
-
- // Step 2/3: Add 1 to inverted value
- // The result is the two's-complement represent of the input value.
- const positiveValue = invertedValue.plus(1);
-
- // Step 3/3: Invert positive value
- const negativeValue = positiveValue.times(-1);
- value = negativeValue;
- }
- }
-
+ const valueBuf = calldata.popWord();
+ const value = EncoderMath.safeDecodeNumericValue(valueBuf, this.getMinValue(), this.getMaxValue());
return value;
}