Skip to content
Justin SilverTECHNOLOGY, TRAVEL & EVERYTHING IN BETWEEN
Libraries & Tools
Solidity mathnpm

unsafe-math

unsafe-math provides arithmetic helpers for uint256 and int256, plus the U256 and I256 custom types. Its purpose is to make unchecked calculations available where surrounding logic already establishes the valid range. The README covers method calls, operator overloads, comparisons and conversions between these representations. A bounded counter is a useful place to understand the approach because the condition that permits each decrement is visible beside the operation. Treat that condition as part of the implementation. The helper supplies the calculation, while your contract supplies the reason its result stays valid.

Establish bounds before changing arithmetic

Start with an operation whose inputs and result you can bound. For an unsigned decrement, the useful precondition is that the value exceeds zero. For addition or multiplication, reason about the largest possible result. Document those bounds near the call so later changes to input limits do not silently invalidate them. The README describes possible gas savings when overflow is already ruled out. Measure the actual contract before treating a replacement as an optimization.

Install the arithmetic library

Use the package name from the README. Check compiler requirements across imported files. Although UnsafeMath.sol declares ^0.8.0, the current U256 and I256 type files declare ^0.8.19.

npm install -D @0xdoublesharp/unsafe-math

Replace one bounded calculation at a time

  1. Choose the operation

    Find a calculation with a clear input range. Record the invariant that prevents overflow or underflow, including any checks that establish it.

  2. Select the representation

    Use library methods on uint256 or int256, or choose a custom numeric type when operator overloads improve the surrounding code.

  3. Exercise the boundaries

    Check zero, the largest permitted input and the first rejected input. Include signed boundaries and conversions when the operation uses them.

  4. Compare the result and cost

    Confirm the contract still produces the intended values for its valid domain. Compare gas under the same compiler and optimizer settings.

Decrement only after checking for zero

Inside a Solidity contract, import UnsafeMath.sol and enable its methods with the using directive shown here. This fragment follows the README counter pattern. The loop condition supplies the lower bound needed for dec().

import { UnsafeMath } from '@0xdoublesharp/unsafe-math/contracts/UnsafeMath.sol';

using UnsafeMath for uint256;

// Inside a function, with remaining declared as uint256:
while (remaining != 0) {
    remaining = remaining.dec();
}

Review the semantics of each helper

Unchecked addition, subtraction and multiplication can wrap when a result exceeds its type. The source also uses assembly for some operations, so inspect the selected helper rather than assuming it behaves exactly like a checked Solidity expression. Conversions deserve their own bounds review, particularly when narrowing a value or changing signedness. The library makes these operations convenient to call. It does not prove that the caller established a safe range.