Complex Contracts Simple Explained: Solmate FixedPointMathLib

Complex Contracts Simple Explained: Solmate FixedPointMathLib

Let’s take a look at the following library from Solmate:

This might look scary for a new junior auditor. The good news is - it isn’t scary for much longer!

Lets dive into it:

First you can see the library name: “FixedPointMathLib”, which is nothing else than arithmetic operations for floating numbers, remember, solidity cannot handle this natively since it rounds down.

Example: There is no 100e18 * 0.5, you simply cannot do this in solidity.

So this library aims to solve this problem, let’s specifically focus on the first 4 operations and dissect them. Generally it can be explained to operate with fixed float numbers using 1e18 as base. This means if i want to do 100 * 0.5, i can simply do 100 * 0.5e18 / 1e18 - thats all the magic behind it.

Examples with 0.5 as multiplier / divisor:

1. mulWadDown: 99e18 * 0.5

To multiply 99 (in WAD, which is 99×101899×1018) by 0.5 (which must also be represented in WAD as 0.5×10180.5×1018 or 0.5e180.5e18) and round down:

uint256 result = FixedPointMathLib.mulWadDown(99e18, 0.5e18); = 45.5e18

2. mulWadUp: 99e18 * 0.5

Using the same numbers for mulWadUp:

uint256 result = FixedPointMathLib.mulWadUp(99e18, 0.5e18); = 45.5e18

3. divWadDown: 99e / 0.5

For divWadDown, which divides two fixed-point numbers and rounds the result down:

uint256 result = FixedPointMathLib.divWadDown(99e18, 0.5e18);

Since divWadDown rounds down, the result is 198e18, but in this case, there is no fractional part to round down from, so the result remains 198e18.

4. divWadUp: 99e180 / 0.5

For divWadUp, which also divides two fixed-point numbers but rounds the result up:

uint256 result = FixedPointMathLib.divWadUp(99e18, 0.5e18);

However, divWadUp would round up if there was any fractional part. In this scenario, since the division results in an exact number without a fractional remainder, rounding up does not change the result, and it remains 198e18.

The good thing about this library is that you can determine explicitly if it rounds up or down, which is not possible with AAVE’s WadRayMath library.