Refactored the SafeMath errors

This commit is contained in:
James Towle 2019-06-17 10:57:33 -07:00 committed by Amir Bandeali
parent e916daf5fd
commit a46b13967a
6 changed files with 51 additions and 70 deletions

View File

@ -1831,7 +1831,8 @@ describe('ERC1155Proxy', () => {
// check balances before transfer // check balances before transfer
const expectedInitialBalances = [spenderInitialFungibleBalance, receiverInitialFungibleBalance]; const expectedInitialBalances = [spenderInitialFungibleBalance, receiverInitialFungibleBalance];
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances); await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
const expectedError = new SafeMathRevertErrors.Uint256UnderflowError( const expectedError = new SafeMathRevertErrors.SafeMathError(
SafeMathRevertErrors.SafeMathErrorCodes.Uint256SubtractionUnderflow,
spenderInitialFungibleBalance, spenderInitialFungibleBalance,
valuesToTransfer[0].times(valueMultiplier), valuesToTransfer[0].times(valueMultiplier),
); );

View File

@ -12,16 +12,13 @@ import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
import * as chai from 'chai'; import * as chai from 'chai';
import { LogWithDecodedArgs } from 'ethereum-types'; import { LogWithDecodedArgs } from 'ethereum-types';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { import {
artifacts,
DummyERC1155ReceiverBatchTokenReceivedEventArgs, DummyERC1155ReceiverBatchTokenReceivedEventArgs,
DummyERC1155ReceiverContract, DummyERC1155ReceiverContract,
ERC1155MintableContract, ERC1155MintableContract,
artifacts,
} from '../src'; } from '../src';
import { Erc1155Wrapper } from './utils/erc1155_wrapper'; import { Erc1155Wrapper } from './utils/erc1155_wrapper';
chaiSetup.configure(); chaiSetup.configure();
const expect = chai.expect; const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
@ -172,7 +169,8 @@ describe('ERC1155Token', () => {
const tokenToTransfer = fungibleToken; const tokenToTransfer = fungibleToken;
const valueToTransfer = spenderInitialFungibleBalance.plus(1); const valueToTransfer = spenderInitialFungibleBalance.plus(1);
// create the expected error (a uint256 underflow) // create the expected error (a uint256 underflow)
const expectedError = new SafeMathRevertErrors.Uint256UnderflowError( const expectedError = new SafeMathRevertErrors.SafeMathError(
SafeMathRevertErrors.SafeMathErrorCodes.Uint256SubtractionUnderflow,
spenderInitialFungibleBalance, spenderInitialFungibleBalance,
valueToTransfer, valueToTransfer,
); );
@ -348,7 +346,8 @@ describe('ERC1155Token', () => {
const valuesToTransfer = [spenderInitialFungibleBalance.plus(1)]; const valuesToTransfer = [spenderInitialFungibleBalance.plus(1)];
// create the expected error (a uint256 underflow) // create the expected error (a uint256 underflow)
const expectedError = new SafeMathRevertErrors.Uint256UnderflowError( const expectedError = new SafeMathRevertErrors.SafeMathError(
SafeMathRevertErrors.SafeMathErrorCodes.Uint256SubtractionUnderflow,
spenderInitialFungibleBalance, spenderInitialFungibleBalance,
valuesToTransfer[0], valuesToTransfer[0],
); );

View File

@ -50,15 +50,12 @@ const emptySignedOrder: SignedOrder = {
signature: '', signature: '',
}; };
const overflowErrorForCall = () => new SafeMathRevertErrors.Uint256OverflowError(); const safeMathErrorForCall = () => new SafeMathRevertErrors.SafeMathError();
describe('Exchange core internal functions', () => { describe('Exchange core internal functions', () => {
let chainId: number; let chainId: number;
let testExchange: TestExchangeInternalsContract; let testExchange: TestExchangeInternalsContract;
let overflowErrorForSendTransaction: ( let safeMathErrorForSendTransaction: () => Error | undefined;
a?: BigNumber | number | string,
b?: BigNumber | number | string,
) => Error | undefined;
let divisionByZeroErrorForCall: Error | undefined; let divisionByZeroErrorForCall: Error | undefined;
let roundingErrorForCall: Error | undefined; let roundingErrorForCall: Error | undefined;
@ -79,7 +76,7 @@ describe('Exchange core internal functions', () => {
txDefaults, txDefaults,
new BigNumber(chainId), new BigNumber(chainId),
); );
overflowErrorForSendTransaction = overflowErrorForCall; safeMathErrorForSendTransaction = safeMathErrorForCall;
divisionByZeroErrorForCall = new Error(RevertReason.DivisionByZero); divisionByZeroErrorForCall = new Error(RevertReason.DivisionByZero);
roundingErrorForCall = new Error(RevertReason.RoundingError); roundingErrorForCall = new Error(RevertReason.RoundingError);
}); });
@ -105,10 +102,10 @@ describe('Exchange core internal functions', () => {
const remainderTimes1000 = remainder.multipliedBy('1000'); const remainderTimes1000 = remainder.multipliedBy('1000');
const isError = remainderTimes1000.gte(product); const isError = remainderTimes1000.gte(product);
if (product.isGreaterThan(MAX_UINT256)) { if (product.isGreaterThan(MAX_UINT256)) {
throw overflowErrorForCall(); throw safeMathErrorForCall();
} }
if (remainderTimes1000.isGreaterThan(MAX_UINT256)) { if (remainderTimes1000.isGreaterThan(MAX_UINT256)) {
throw overflowErrorForCall(); throw safeMathErrorForCall();
} }
return isError; return isError;
} }
@ -133,10 +130,10 @@ describe('Exchange core internal functions', () => {
const errorTimes1000 = error.multipliedBy('1000'); const errorTimes1000 = error.multipliedBy('1000');
const isError = errorTimes1000.gte(product); const isError = errorTimes1000.gte(product);
if (product.isGreaterThan(MAX_UINT256)) { if (product.isGreaterThan(MAX_UINT256)) {
throw overflowErrorForCall(); throw safeMathErrorForCall();
} }
if (errorTimes1000.isGreaterThan(MAX_UINT256)) { if (errorTimes1000.isGreaterThan(MAX_UINT256)) {
throw overflowErrorForCall(); throw safeMathErrorForCall();
} }
return isError; return isError;
} }
@ -155,7 +152,7 @@ describe('Exchange core internal functions', () => {
} }
const product = numerator.multipliedBy(target); const product = numerator.multipliedBy(target);
if (product.isGreaterThan(MAX_UINT256)) { if (product.isGreaterThan(MAX_UINT256)) {
throw overflowErrorForCall(); throw safeMathErrorForCall();
} }
return product.dividedToIntegerBy(denominator); return product.dividedToIntegerBy(denominator);
} }
@ -189,7 +186,7 @@ describe('Exchange core internal functions', () => {
(totalVal: BigNumber, singleVal: BigNumber) => { (totalVal: BigNumber, singleVal: BigNumber) => {
const newTotal = totalVal.plus(singleVal); const newTotal = totalVal.plus(singleVal);
if (newTotal.isGreaterThan(MAX_UINT256)) { if (newTotal.isGreaterThan(MAX_UINT256)) {
throw overflowErrorForCall(); throw safeMathErrorForCall();
} }
return newTotal; return newTotal;
}, },
@ -283,7 +280,7 @@ describe('Exchange core internal functions', () => {
} }
const product = numerator.multipliedBy(target); const product = numerator.multipliedBy(target);
if (product.isGreaterThan(MAX_UINT256)) { if (product.isGreaterThan(MAX_UINT256)) {
throw overflowErrorForCall(); throw safeMathErrorForCall();
} }
return product.dividedToIntegerBy(denominator); return product.dividedToIntegerBy(denominator);
} }
@ -314,7 +311,7 @@ describe('Exchange core internal functions', () => {
const product = numerator.multipliedBy(target); const product = numerator.multipliedBy(target);
const offset = product.plus(denominator.minus(1)); const offset = product.plus(denominator.minus(1));
if (offset.isGreaterThan(MAX_UINT256)) { if (offset.isGreaterThan(MAX_UINT256)) {
throw overflowErrorForCall(); throw safeMathErrorForCall();
} }
const result = offset.dividedToIntegerBy(denominator); const result = offset.dividedToIntegerBy(denominator);
if (product.mod(denominator).eq(0)) { if (product.mod(denominator).eq(0)) {
@ -371,7 +368,7 @@ describe('Exchange core internal functions', () => {
const product = numerator.multipliedBy(target); const product = numerator.multipliedBy(target);
const offset = product.plus(denominator.minus(1)); const offset = product.plus(denominator.minus(1));
if (offset.isGreaterThan(MAX_UINT256)) { if (offset.isGreaterThan(MAX_UINT256)) {
throw overflowErrorForCall(); throw safeMathErrorForCall();
} }
const result = offset.dividedToIntegerBy(denominator); const result = offset.dividedToIntegerBy(denominator);
if (product.mod(denominator).eq(0)) { if (product.mod(denominator).eq(0)) {
@ -445,8 +442,8 @@ describe('Exchange core internal functions', () => {
): Promise<BigNumber> { ): Promise<BigNumber> {
const totalFilledAmount = takerAssetFilledAmount.plus(orderTakerAssetFilledAmount); const totalFilledAmount = takerAssetFilledAmount.plus(orderTakerAssetFilledAmount);
if (totalFilledAmount.isGreaterThan(MAX_UINT256)) { if (totalFilledAmount.isGreaterThan(MAX_UINT256)) {
// FIXME throw overflowErrorForSendTransaction(takerAssetFilledAmount, orderTakerAssetFilledAmount); // FIXME throw safeMathErrorForSendTransaction(takerAssetFilledAmount, orderTakerAssetFilledAmount);
throw overflowErrorForSendTransaction(); throw safeMathErrorForSendTransaction();
} }
return totalFilledAmount; return totalFilledAmount;
} }

View File

@ -6,40 +6,28 @@ import "./RichErrors.sol";
contract MixinSafeMathRichErrors is contract MixinSafeMathRichErrors is
RichErrors RichErrors
{ {
// bytes4(keccak256("Uint256OverflowError(uint256,uint256)")) // bytes4(keccak256("SafeMathError(uint8,uint256,uint256)"))
bytes4 internal constant UINT256_OVERFLOW_ERROR = bytes4 internal constant SAFE_MATH_ERROR =
0x55101607; 0x35a51a70;
// bytes4(keccak256("Uint256UnderflowError(uint256,uint256)")) enum SafeMathErrorCodes {
bytes4 internal constant UINT256_UNDERFLOW_ERROR = UINT256_ADDITION_OVERFLOW,
0x60ee612f; UINT256_MULTIPLICATION_OVERFLOW,
UINT256_SUBTRACTION_UNDERFLOW
// solhint-disable func-name-mixedcase
function Uint256OverflowError(
uint256 a,
uint256 b
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
UINT256_OVERFLOW_ERROR,
a,
b
);
} }
function Uint256UnderflowError( // solhint-disable func-name-mixedcase
function SafeMathError(
SafeMathErrorCodes errorCode,
uint256 a, uint256 a,
uint256 b uint256 b
) )
internal internal
pure pure returns (bytes memory)
returns (bytes memory)
{ {
return abi.encodeWithSelector( return abi.encodeWithSelector(
UINT256_UNDERFLOW_ERROR, SAFE_MATH_ERROR,
errorCode,
a, a,
b b
); );

View File

@ -17,7 +17,8 @@ contract SafeMath is
} }
uint256 c = a * b; uint256 c = a * b;
if (c / a != b) { if (c / a != b) {
_rrevert(Uint256OverflowError( _rrevert(SafeMathError(
SafeMathErrorCodes.UINT256_MULTIPLICATION_OVERFLOW,
a, a,
b b
)); ));
@ -40,7 +41,8 @@ contract SafeMath is
returns (uint256) returns (uint256)
{ {
if (b > a) { if (b > a) {
_rrevert(Uint256UnderflowError( _rrevert(SafeMathError(
SafeMathErrorCodes.UINT256_SUBTRACTION_UNDERFLOW,
a, a,
b b
)); ));
@ -55,7 +57,8 @@ contract SafeMath is
{ {
uint256 c = a + b; uint256 c = a + b;
if (c < a) { if (c < a) {
_rrevert(Uint256OverflowError( _rrevert(SafeMathError(
SafeMathErrorCodes.UINT256_ADDITION_OVERFLOW,
a, a,
b b
)); ));

View File

@ -3,27 +3,20 @@ import { RevertError } from './revert_error';
// tslint:disable:max-classes-per-file // tslint:disable:max-classes-per-file
export class Uint256OverflowError extends RevertError { export enum SafeMathErrorCodes {
constructor(a?: BigNumber | number | string, b?: BigNumber | number | string) { Uint256AdditionOverflow,
super('Uint256OverflowError', 'Uint256OverflowError(uint256 a, uint256 b)', { Uint256MultiplicationOverflow,
Uint256SubtractionUnderflow,
}
export class SafeMathError extends RevertError {
constructor(error?: SafeMathErrorCodes, a?: BigNumber | number | string, b?: BigNumber | number | string) {
super('SafeMathError', 'SafeMathError(uint8 error, uint256 a, uint256 b)', {
error,
a, a,
b, b,
}); });
} }
} }
export class Uint256UnderflowError extends RevertError { RevertError.registerType(SafeMathError);
constructor(a?: BigNumber | number | string, b?: BigNumber | number | string) {
super('Uint256UnderflowError', 'Uint256UnderflowError(uint256 a, uint256 b)', {
a,
b,
});
}
}
const types = [Uint256OverflowError, Uint256UnderflowError];
// Register the types we've defined.
for (const type of types) {
RevertError.registerType(type);
}