Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
@0xdoublesharp/unsafe-math
Advanced tools
Unchecked uint256 and int256 math operations for Solidity 0.8
This library and custom user types allow for the use of unchecked math operations when appropriate. Gas savings can be realized when it is already known that the results will not overflow.
npm install -D @0xdoublesharp/unsafe-math
yarn add -D @0xdoublesharp/unsafe-math
UnsafeMath
The UnsafeMath
library provides unchecked math operations for uint256
and int256
types with Solidity 0.8.0+. It also provides interoperability and conversion for the U256
and I256
user defined types.
uint256
Use the UnsafeMath
library for uint256
types to perform unchecked math operations on two unsigned integers.
using UnsafeMath for uint256;
_uint256.add(uint256 _addend)
: add a uint256 to a uint256_uint256.sub(uint256 _subtrahend)
: subtract a uint256 from a uint256_uint256.inc()
: increment a uint256_uint256.dec()
: decrement a uint256_uint256.mul(uint256 _multiplier)
: multiply a uint256 by a uint256_uint256.div(uint256 _divisor)
: divide a uint256 from a uint256_uint256.mod(uint256 _divisor)
: get the modulus of uint256s_uint256.exp(uint256 _exponent)
: raise a uint256 by an exponentimport { UnsafeMath } from '@0xdoublesharp/unsafe-math/contracts/UnsafeMath.sol';
contract ContractA {
using UnsafeMath for uint256;
function add(uint256 a, uint256 b) external pure returns (uint256) {
return a.add(b);
}
function while(uint256 times) external pure {
uint256 _iter = times;
while (_iter != 0) {
_iter = _iter.dec();
int64 _int64 = int64(_iter);
// ...
}
}
function for(uint256 times) external pure {
for (uint256 _iter; _iter < times; _iter = _iter.inc()) {
int64 _int64 = int64(_iter);
// ...
}
}
}
int256
Use the UnsafeMath
library for int256
types to perform unchecked math operations on two signed integers. Note that exp()
is not available for signed integers.
using UnsafeMath for int256;
_int256.add(int256 _addend)
: add an int256 to an int256_int256.sub(int256 _subtrahend)
: subtract an int256 from an int256_int256.inc()
: increment an int256 value_int256.dec()
: decrement an int256_int256.mul(int256 _multiplier)
: multiply an int256 by an int256_int256.div(int256 _divisor)
: divide an int256 from an int256_int256.mod(int256 _divisor)
: get the modulus of int256simport { UnsafeMath } from '@0xdoublesharp/unsafe-math/contracts/UnsafeMath.sol';
contract ContractB {
using UnsafeMath for int256;
function sub(int256 a, int256 b) external pure returns (int256) {
return a.sub(b);
}
}
U256
Used with U256
to access helper methods for interacting with uint256
types and functionality not available in overloaded operators, such as bit shifting and exponential operations.
using UnsafeMath for U256;
_U256.add(uint256 _addend)
: add a U256 to a uint256_U256.sub(uint256 _subtrahend)
: subtract a U256 from a uint256_U256.inc()
: increment a U256_U256.dec()
: decrement a U256_U256.mul(uint256 _multiplier)
: multiply a U256 by a uint256_U256.div(uint256 _divisor)
: divide a uint256 from a U256_U256.mod(uint256 _divisor)
: get the modulus of U256 and uint256_U256.exp(uint256 _exponent)
: raise a U256 by an exponent_U256.eq(uint256 _compare)
: compare U256 and uint256 equality_U256.neq(uint256 _compare)
: compare U256 and uint256 non-equality_U256.lt(uint256 _compare)
: compare U256 and uint256 less than uint256_U256.lte(uint256 _compare)
: compare U256 less than or equal to uint256_U256.gt(uint256 _compare
: compare U256 greater than uint256_U256.gte(uint256 _compare)
: compare U256 greater than or equal to uint256_U256.and(uint256 _operator)
: bitwise AND on U256 and uint256_U256.or(uint256 _operator)
: bitwise OR on U256 and uint256_U256.xor(uint256 _operator)
: bitwise XOR on U256 and uint256_U256.not()
: bitwise NOT on U256_U256.rshift(U256 _shift)
: right shift U256 by U256_U256.lshift(U256 _shift)
: right shift U256 by U256_U256.rshift(uint256 _shift)
: right shift U256 by uint256_U256.lshift(uint256 _shift)
: right shift U256 by uint256_U256.asUint8()
: U256 to uint8_U256.asUint16()
: U256 to uint16_U256.asUint32()
: U256 to uint32_U256.asUint64()
: U256 to uint64_U256.asUint128()
: U256 to uint128_U256.asUint256()
: U256 to uint256_U256.asInt8()
: U256 to int8_U256.asInt16()
: U256 to int16_U256.asInt32()
: U256 to int32_U256.asInt64()
: U256 to int64_U256.asInt128()
: U256 to int128_U256.asInt256()
: U256 to int256_uint256.asU256()
: convert a uint256 to U256_int256.asU256()
: convert an int256 to U256import { UnsafeMath, U256 } from '@0xdoublesharp/unsafe-math/contracts/UnsafeMath.sol';
contract ContractA {
using UnsafeMath for U256;
using UnsafeMath for uint256;
using UnsafeMath for int256;
function add(int256 a, uint256 b) external pure returns (uint256) {
return a.asU256().add(b).asUint256();
}
function sub(uint256 a, uint256 b) external pure returns (uint256) {
return (a.asU256() - b.asU256()).asUint256();
}
}
I256
Use with I256
to access helper methods for interacting with int256
types and functionality not available in overloaded operators.
using UnsafeMath for I256;
_I256.add(uint256 _addend)
: add an I256 to a int256_I256.sub(uint256 _subtrahend)
: subtract an I256 from a int256_I256.inc()
: increment an I256_I256.dec()
: decrement an I256_I256.mul(uint256 _multiplier)
: multiply an I256 by a int256_I256.div(uint256 _divisor)
: divide a int256 from an I256_I256.mod(uint256 _divisor)
: get the modulus of U256 and uint256_I256.eq(uint256 _compare)
: compare U256 and uint256 equality_I256.neq(uint256 _compare)
: compare U256 and uint256 non-equality_I256.lt(uint256 _compare)
: compare U256 and uint256 less than uint256_I256.lte(uint256 _compare)
: compare U256 less than or equal to uint256_I256.gt(uint256 _compare
: compare U256 greater than uint256_I256.gte(uint256 _compare)
: compare U256 greater than or equal to uint256_I256.and(uint256 _operator)
: bitwise AND on U256 and uint256_I256.or(uint256 _operator)
: bitwise OR on U256 and uint256_I256.xor(uint256 _operator)
: bitwise XOR on U256 and uint256_I256.not()
: bitwise NOT on U256_I256.asUint8()
: U256 to uint8_I256.asUint16()
: U256 to uint16_I256.asUint32()
: U256 to uint32_I256.asUint64()
: U256 to uint64_I256.asUint128()
: U256 to uint128_I256.asUint256()
: U256 to uint256_I256.asInt8()
: U256 to int8_I256.asInt16()
: U256 to int16_I256.asInt32()
: U256 to int32_I256.asInt64()
: U256 to int64_I256.asInt128()
: U256 to int128_I256.asInt256()
: U256 to int256_uint256.asI256()
: convert a int256 to I256_int256.asI256()
: convert an int256 to I256import { UnsafeMath, I256 } from '@0xdoublesharp/unsafe-math/contracts/UnsafeMath.sol';
contract ContractB {
using UnsafeMath for I256;
using UnsafeMath for uint256;
using UnsafeMath for int256;
function add(int256 a, uint256 b) external pure returns (int256) {
I256 _a = a.asI256();
return _a.add(int256(b)).asInt256();
}
function sub(uint256 a, uint256 b) external pure returns (int256) {
I256 _a = a.asI256();
I256 _b = b.asI256();
return (a - b).asInt256();
}
}
U256
and I256
User defined types with operator overloads are also provided to take advantage of the latest Solidity features. Use U256
for unchecked unsigned integer operations, or I256
for unchecked signed integer operations. Helper methods are also provided for interoperating with uint256
and int256
via the UnsafeMath
library.
The overloads also provide comparison and bitwise operators where available.
U256
The U256
user defined type can perform unchecked math operations using overloaded operators.
_u256 + _u256
: add a U256 to a U256_u256 - _u256
: subtract a U256 from a U256_u256 * _u256
: multiply a U256 by a U256_u256 / _u256
: divide a U256 from a U256_u256 % _u256
: get the modulus of U256s_u256 == _u256
: compare U256 equality_u256 != _u256
: compare U256 non-equality_u256 < _u256
: compare U256 less than U256_u256 <= _u256
: compare U256 less than or equal to U256_u256 > _u256
: compare U256 greater than U256_u256 >= _u256
: compare U256 greater than or equal to U256_u256 & _u256
: bitwise AND on U256_u256 | _u256
: bitwise OR on U256_u256 ^ _u256
: bitwise XOR on U256~_u256
: bitwise NOT on U256import { U256 } from '@0xdoublesharp/unsafe-math/contracts/types/U256.sol';
contract ContractA {
function add(uint256 a, uint256 b) external pure returns (uint256) {
return (U256.wrap(a) - U256.wrap(b)).asUint256();
}
function while(uint256 times) external pure {
U256 _iter = U256.wrap(times);
while (_iter.neq(0)) {
_iter = _iter.dec();
uint256 _uint256 = _iter.asUint256();
int64 _int64 = _iter.asInt64();
// ...
}
}
function for(uint256 times) external pure {
U256 _times = U256.wrap(times);
for (U256 _iter; _iter < _times; _iter = _iter.inc()) {
uint256 _uint256 = _iter.asUint256();
int64 _int64 = _iter.asInt64();
// ...
}
}
}
I256
The I256
user defined type can perform unchecked math operations using overloaded operators.
_i256 + _i256
: add a I256 to a I256_i256 - _i256
: subtract a I256 from a I256_i256 * _i256
: multiply a I256 by a I256_i256 / _i256
: divide a I256 from a I256_i256 % _i256
: get the modulus of I256s_i256 == _i256
: compare I256 equality_i256 != _i256
: compare I256 non-equality_i256 < _i256
: compare I256 less than I256_i256 <= _i256
: compare I256 less than or equal to I256_i256 > _i256
: compare I256 greater than I256_i256 >= _i256
: compare I256 greater than or equal to I256_i256 & _i256
: bitwise AND on I256_i256 | _i256
: bitwise OR on I256_i256 ^ _i256
: bitwise XOR on I256~_i256
: bitwise NOT on I256import { I256 } from '@0xdoublesharp/unsafe-math/contracts/types/I256.sol';
contract ContractB {
function add(int256 a, int256 b) external pure returns (int256) {
return (I256.wrap(a) - I256.wrap(b)).asInt256();
}
}
See GAS_REPORT.
FAQs
Unchecked uint256 and int256 math operations for Solidity 0.8
We found that @0xdoublesharp/unsafe-math demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.