Skip to content

Instantly share code, notes, and snippets.

@transmissions11
Last active January 28, 2022 05:46
Show Gist options
  • Save transmissions11/51d312b0df478207b3224791bbab2182 to your computer and use it in GitHub Desktop.
Save transmissions11/51d312b0df478207b3224791bbab2182 to your computer and use it in GitHub Desktop.
mulDiv Optimization Challenge
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
assembly {
// Store x * y in z for now.
z := mul(x, y)
// Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
revert(0, 0)
}
// Divide z by the denominator.
z := div(z, denominator)
}
}
function mulDivUp(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
assembly {
// Store x * y in z for now.
z := mul(x, y)
// Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
revert(0, 0)
}
// Compute z + (denominator - 1).
let zUp := add(z, sub(denominator, 1))
// If the addition overflowed, revert.
if lt(zUp, z) {
revert(0, 0)
}
// Divide zUp by the denominator.
z := div(zUp, denominator)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment