From d03f13a72929d680ea3ec3123edb9795ccf14049 Mon Sep 17 00:00:00 2001 From: Lawrence Forman Date: Thu, 1 Aug 2019 13:10:48 -0400 Subject: [PATCH] `@0x/contracts-utils`: `LibMath._safeDiv()` now throws a rich revert when dividing by zero. --- .../contracts/src/LibSafeMathRichErrors.sol | 3 ++- contracts/utils/contracts/src/SafeMath.sol | 7 +++++++ contracts/utils/src/reference_functions.ts | 16 +++++++++++----- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/contracts/utils/contracts/src/LibSafeMathRichErrors.sol b/contracts/utils/contracts/src/LibSafeMathRichErrors.sol index a1f39cc41d..0b13af3706 100644 --- a/contracts/utils/contracts/src/LibSafeMathRichErrors.sol +++ b/contracts/utils/contracts/src/LibSafeMathRichErrors.sol @@ -10,7 +10,8 @@ library LibSafeMathRichErrors { enum SafeMathErrorCodes { UINT256_ADDITION_OVERFLOW, UINT256_MULTIPLICATION_OVERFLOW, - UINT256_SUBTRACTION_UNDERFLOW + UINT256_SUBTRACTION_UNDERFLOW, + UINT256_DIVISION_BY_ZERO } // solhint-disable func-name-mixedcase diff --git a/contracts/utils/contracts/src/SafeMath.sol b/contracts/utils/contracts/src/SafeMath.sol index ed22105a9a..1edc1bac93 100644 --- a/contracts/utils/contracts/src/SafeMath.sol +++ b/contracts/utils/contracts/src/SafeMath.sol @@ -30,6 +30,13 @@ contract SafeMath { pure returns (uint256) { + if (b == 0) { + LibRichErrors._rrevert(LibSafeMathRichErrors.SafeMathError( + LibSafeMathRichErrors.SafeMathErrorCodes.UINT256_DIVISION_BY_ZERO, + a, + b + )); + } uint256 c = a / b; return c; } diff --git a/contracts/utils/src/reference_functions.ts b/contracts/utils/src/reference_functions.ts index 717baafc09..e623ef639f 100644 --- a/contracts/utils/src/reference_functions.ts +++ b/contracts/utils/src/reference_functions.ts @@ -1,4 +1,4 @@ -import { AnyRevertError, BigNumber, SafeMathRevertErrors } from '@0x/utils'; +import { BigNumber, SafeMathRevertErrors } from '@0x/utils'; const MAX_UINT256 = new BigNumber(2).pow(256).minus(1); @@ -29,16 +29,22 @@ export function safeSub(a: BigNumber, b: BigNumber): BigNumber { export function safeMul(a: BigNumber, b: BigNumber): BigNumber { const r = a.times(b); if (r.isGreaterThan(MAX_UINT256)) { - // Solidity implementation does not throw a reason. - throw new AnyRevertError(); + throw new SafeMathRevertErrors.SafeMathError( + SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow, + a, + b, + ); } return r; } export function safeDiv(a: BigNumber, b: BigNumber): BigNumber { if (b.isEqualTo(0)) { - // Solidity implementation does not throw a reason. - throw new AnyRevertError(); + throw new SafeMathRevertErrors.SafeMathError( + SafeMathRevertErrors.SafeMathErrorCodes.Uint256DivisionByZero, + a, + b, + ); } return a.dividedToIntegerBy(b); }