Created
October 20, 2021 06:06
-
-
Save tcoulter/cefc10c40e2b87447fe54086f780947a to your computer and use it in GitHub Desktop.
Sweet sweet overflow checking in Yul (almost assembly)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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()!"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment