Skip to content

Instantly share code, notes, and snippets.

@tcoulter
Created October 20, 2021 06:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tcoulter/ac340a135de819f251db9726e3d0d8d7 to your computer and use it in GitHub Desktop.
Save tcoulter/ac340a135de819f251db9726e3d0d8d7 to your computer and use it in GitHub Desktop.
Sweet sweet overflow protection in Yul (almost assembly)
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Test {
function fmul(
uint256 x,
uint256 y,
uint256 baseUnit
) public pure returns (uint256 z) {
assembly {
let a := mul(x, y) //
switch eq(div(a, x), y) // multiplication overflow check
case 1 { z := div(a, baseUnit) }
case 0 { revert(0, 0) }
}
}
function fdiv(
uint256 x,
uint256 y,
uint256 baseUnit
) public pure returns (uint256 z) {
assembly {
let a := mul(x, baseUnit)
switch eq(div(a, x), baseUnit) // multiplication overflow check
case 1 { z := div(a, y) }
case 0 { revert(0, 0) }
}
}
// Primative tests - call through remix
function testFmulThrowsOnOverflow() public pure {
uint256 x = type(uint256).max;
uint256 y = 2; // needs to be > 1
uint256 baseUnit = 10;
fmul(x, y, baseUnit);
revert("fmul() did not throw");
}
function testFmulHappyPath() public pure returns(uint256 result) {
uint256 x = 5;
uint256 y = 2; // needs to be > 1
uint256 baseUnit = 10;
result = fmul(x, y, baseUnit);
require(result == 1, "Unexpected result from fmul()!");
}
function testFdivThrowsOnOverflow() public pure {
uint256 x = type(uint256).max;
uint256 y = 10;
uint256 baseUnit = 2; // needs to be > 1
fdiv(x, y, baseUnit);
revert("fmul() did not throw");
}
function testFdivHappyPath() public pure returns(uint256 result) {
uint256 x = 5;
uint256 y = 10;
uint256 baseUnit = 2; // needs to be > 1
result = fdiv(x, y, baseUnit);
require(result == 1, "Unexpected result from fmul()!");
}
}
@tcoulter
Copy link
Author

Note: That GPL-3 license identifier at the top was the result of a bad copy paste. I hereby release this under MIT, free for everyone. Viva la freedom!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment