From 4591a655e6ccc29034ade8f570d8e42cae492a83 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 10 Oct 2022 00:14:27 +0100 Subject: [PATCH 1/5] Mark assembly memory-safe --- src/utils/LibString.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/LibString.sol b/src/utils/LibString.sol index 5752a156..7ec75b63 100644 --- a/src/utils/LibString.sol +++ b/src/utils/LibString.sol @@ -6,7 +6,7 @@ pragma solidity >=0.8.0; /// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibString.sol) library LibString { function toString(uint256 value) internal pure returns (string memory str) { - assembly { + assembly ("memory-safe") { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but we allocate 160 bytes // to keep the free memory pointer word aligned. We'll need 1 word for the length, 1 word for the // trailing zeros padding, and 3 other words for a max of 78 digits. In total: 5 * 32 = 160 bytes. From 533e77e3b47aa8654728a1d22c00b0660408b057 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 14 Oct 2022 19:35:05 +0100 Subject: [PATCH 2/5] Mark FixedPointMath memory-safe --- src/utils/FixedPointMathLib.sol | 14 +++++++------- src/utils/SignedWadMath.sol | 22 +++++++++++----------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/utils/FixedPointMathLib.sol b/src/utils/FixedPointMathLib.sol index 364268c2..2a21a1ae 100644 --- a/src/utils/FixedPointMathLib.sol +++ b/src/utils/FixedPointMathLib.sol @@ -38,7 +38,7 @@ library FixedPointMathLib { uint256 y, uint256 denominator ) internal pure returns (uint256 z) { - assembly { + assembly ("memory-safe") { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) @@ -54,7 +54,7 @@ library FixedPointMathLib { uint256 y, uint256 denominator ) internal pure returns (uint256 z) { - assembly { + assembly ("memory-safe") { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) @@ -71,7 +71,7 @@ library FixedPointMathLib { uint256 n, uint256 scalar ) internal pure returns (uint256 z) { - assembly { + assembly ("memory-safe") { switch x case 0 { switch n @@ -159,7 +159,7 @@ library FixedPointMathLib { //////////////////////////////////////////////////////////////*/ function sqrt(uint256 x) internal pure returns (uint256 z) { - assembly { + assembly ("memory-safe") { let y := x // We start y at x, which will help us make our initial estimate. z := 181 // The "correct" value is 1, but this saves a multiplication later. @@ -223,7 +223,7 @@ library FixedPointMathLib { } function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) { - assembly { + assembly ("memory-safe") { // Mod x by y. Note this will return // 0 instead of reverting if y is zero. z := mod(x, y) @@ -231,7 +231,7 @@ library FixedPointMathLib { } function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) { - assembly { + assembly ("memory-safe") { // Divide x by y. Note this will return // 0 instead of reverting if y is zero. r := div(x, y) @@ -239,7 +239,7 @@ library FixedPointMathLib { } function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - assembly { + assembly ("memory-safe") { // Add 1 to x * y if x % y > 0. Note this will // return 0 instead of reverting if y is zero. z := add(gt(mod(x, y), 0), div(x, y)) diff --git a/src/utils/SignedWadMath.sol b/src/utils/SignedWadMath.sol index c694cda5..6d529fbe 100644 --- a/src/utils/SignedWadMath.sol +++ b/src/utils/SignedWadMath.sol @@ -7,7 +7,7 @@ pragma solidity >=0.8.0; /// @dev Will not revert on overflow, only use where overflow is not possible. function toWadUnsafe(uint256 x) pure returns (int256 r) { - assembly { + assembly ("memory-safe") { // Multiply x by 1e18. r := mul(x, 1000000000000000000) } @@ -17,7 +17,7 @@ function toWadUnsafe(uint256 x) pure returns (int256 r) { /// @dev Will not revert on overflow, only use where overflow is not possible. /// @dev Not meant for negative second amounts, it assumes x is positive. function toDaysWadUnsafe(uint256 x) pure returns (int256 r) { - assembly { + assembly ("memory-safe") { // Multiply x by 1e18 and then divide it by 86400. r := div(mul(x, 1000000000000000000), 86400) } @@ -27,7 +27,7 @@ function toDaysWadUnsafe(uint256 x) pure returns (int256 r) { /// @dev Will not revert on overflow, only use where overflow is not possible. /// @dev Not meant for negative day amounts, it assumes x is positive. function fromDaysWadUnsafe(int256 x) pure returns (uint256 r) { - assembly { + assembly ("memory-safe") { // Multiply x by 86400 and then divide it by 1e18. r := div(mul(x, 86400), 1000000000000000000) } @@ -35,7 +35,7 @@ function fromDaysWadUnsafe(int256 x) pure returns (uint256 r) { /// @dev Will not revert on overflow, only use where overflow is not possible. function unsafeWadMul(int256 x, int256 y) pure returns (int256 r) { - assembly { + assembly ("memory-safe") { // Multiply x by y and divide by 1e18. r := sdiv(mul(x, y), 1000000000000000000) } @@ -44,14 +44,14 @@ function unsafeWadMul(int256 x, int256 y) pure returns (int256 r) { /// @dev Will return 0 instead of reverting if y is zero and will /// not revert on overflow, only use where overflow is not possible. function unsafeWadDiv(int256 x, int256 y) pure returns (int256 r) { - assembly { + assembly ("memory-safe") { // Multiply x by 1e18 and divide it by y. r := sdiv(mul(x, 1000000000000000000), y) } } function wadMul(int256 x, int256 y) pure returns (int256 r) { - assembly { + assembly ("memory-safe") { // Store x * y in r for now. r := mul(x, y) @@ -66,7 +66,7 @@ function wadMul(int256 x, int256 y) pure returns (int256 r) { } function wadDiv(int256 x, int256 y) pure returns (int256 r) { - assembly { + assembly ("memory-safe") { // Store x * 1e18 in r for now. r := mul(x, 1000000000000000000) @@ -119,7 +119,7 @@ function wadExp(int256 x) pure returns (int256 r) { q = ((q * x) >> 96) - 14423608567350463180887372962807573; q = ((q * x) >> 96) + 26449188498355588339934803723976023; - assembly { + assembly ("memory-safe") { // Div in assembly because solidity adds a zero check despite the unchecked. // The q polynomial won't have zeros in the domain as all its roots are complex. // No scaling is necessary because p is already 2**96 too large. @@ -147,7 +147,7 @@ function wadLn(int256 x) pure returns (int256 r) { // ln(x * C) = ln(x) + ln(C), we can simply do nothing here // and add ln(2**96 / 10**18) at the end. - assembly { + assembly ("memory-safe") { r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) @@ -183,7 +183,7 @@ function wadLn(int256 x) pure returns (int256 r) { q = ((q * x) >> 96) + 204048457590392012362485061816622; q = ((q * x) >> 96) + 31853899698501571402653359427138; q = ((q * x) >> 96) + 909429971244387300277376558375; - assembly { + assembly ("memory-safe") { // Div in assembly because solidity adds a zero check despite the unchecked. // The q polynomial is known not to have zeros in the domain. // No scaling required because p is already 2**96 too large. @@ -211,7 +211,7 @@ function wadLn(int256 x) pure returns (int256 r) { /// @dev Will return 0 instead of reverting if y is zero. function unsafeDiv(int256 x, int256 y) pure returns (int256 r) { - assembly { + assembly ("memory-safe") { // Divide x by y. r := sdiv(x, y) } From 2599779d5d732b2ef55c5158961c03e51229b293 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 14 Oct 2022 19:35:22 +0100 Subject: [PATCH 3/5] Mark the rest memory-safe --- src/utils/CREATE3.sol | 2 +- src/utils/MerkleProofLib.sol | 2 +- src/utils/SSTORE2.sol | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils/CREATE3.sol b/src/utils/CREATE3.sol index 96e5554c..eb22f69e 100644 --- a/src/utils/CREATE3.sol +++ b/src/utils/CREATE3.sol @@ -42,7 +42,7 @@ library CREATE3 { bytes memory proxyChildBytecode = PROXY_BYTECODE; address proxy; - assembly { + assembly ("memory-safe") { // Deploy a new contract with our pre-made bytecode via CREATE2. // We start 32 bytes into the code to avoid copying the byte length. proxy := create2(0, add(proxyChildBytecode, 32), mload(proxyChildBytecode), salt) diff --git a/src/utils/MerkleProofLib.sol b/src/utils/MerkleProofLib.sol index ceef023c..994c7b27 100644 --- a/src/utils/MerkleProofLib.sol +++ b/src/utils/MerkleProofLib.sol @@ -10,7 +10,7 @@ library MerkleProofLib { bytes32 root, bytes32 leaf ) internal pure returns (bool isValid) { - assembly { + assembly ("memory-safe") { if proof.length { // Left shifting by 5 is like multiplying by 32. let end := add(proof.offset, shl(5, proof.length)) diff --git a/src/utils/SSTORE2.sol b/src/utils/SSTORE2.sol index 467a93fa..35439374 100644 --- a/src/utils/SSTORE2.sol +++ b/src/utils/SSTORE2.sol @@ -34,7 +34,7 @@ library SSTORE2 { runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit. ); - assembly { + assembly ("memory-safe") { // Deploy a new contract with the generated creation code. // We start 32 bytes into the code to avoid copying the byte length. pointer := create(0, add(creationCode, 32), mload(creationCode)) @@ -79,7 +79,7 @@ library SSTORE2 { uint256 start, uint256 size ) private view returns (bytes memory data) { - assembly { + assembly ("memory-safe") { // Get a pointer to some free memory. data := mload(0x40) From bab8f9cc8865ad58ebec018b8645b69d2a85ecc8 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 14 Oct 2022 19:41:59 +0100 Subject: [PATCH 4/5] SafeTransferLib memory-safe --- src/utils/SafeTransferLib.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils/SafeTransferLib.sol b/src/utils/SafeTransferLib.sol index d08d1b84..5c7710cf 100644 --- a/src/utils/SafeTransferLib.sol +++ b/src/utils/SafeTransferLib.sol @@ -15,7 +15,7 @@ library SafeTransferLib { function safeTransferETH(address to, uint256 amount) internal { bool success; - assembly { + assembly ("memory-safe") { // Transfer the ETH and store if it succeeded or not. success := call(gas(), to, amount, 0, 0, 0, 0) } @@ -35,7 +35,7 @@ library SafeTransferLib { ) internal { bool success; - assembly { + assembly ("memory-safe") { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) @@ -67,7 +67,7 @@ library SafeTransferLib { ) internal { bool success; - assembly { + assembly ("memory-safe") { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) @@ -98,7 +98,7 @@ library SafeTransferLib { ) internal { bool success; - assembly { + assembly ("memory-safe") { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) From 383b64ebac41729783018a1cf8ebc5cfc329360f Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 24 Oct 2022 19:26:01 +0200 Subject: [PATCH 5/5] Use natspec annotation for memory-safe --- src/utils/CREATE3.sol | 3 ++- src/utils/FixedPointMathLib.sol | 21 ++++++++++++++------- src/utils/LibString.sol | 3 ++- src/utils/MerkleProofLib.sol | 3 ++- src/utils/SSTORE2.sol | 6 ++++-- src/utils/SafeTransferLib.sol | 12 ++++++++---- src/utils/SignedWadMath.sol | 33 ++++++++++++++++++++++----------- 7 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/utils/CREATE3.sol b/src/utils/CREATE3.sol index eb22f69e..0d5b341e 100644 --- a/src/utils/CREATE3.sol +++ b/src/utils/CREATE3.sol @@ -42,7 +42,8 @@ library CREATE3 { bytes memory proxyChildBytecode = PROXY_BYTECODE; address proxy; - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Deploy a new contract with our pre-made bytecode via CREATE2. // We start 32 bytes into the code to avoid copying the byte length. proxy := create2(0, add(proxyChildBytecode, 32), mload(proxyChildBytecode), salt) diff --git a/src/utils/FixedPointMathLib.sol b/src/utils/FixedPointMathLib.sol index 2a21a1ae..68877227 100644 --- a/src/utils/FixedPointMathLib.sol +++ b/src/utils/FixedPointMathLib.sol @@ -38,7 +38,8 @@ library FixedPointMathLib { uint256 y, uint256 denominator ) internal pure returns (uint256 z) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) @@ -54,7 +55,8 @@ library FixedPointMathLib { uint256 y, uint256 denominator ) internal pure returns (uint256 z) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) @@ -71,7 +73,8 @@ library FixedPointMathLib { uint256 n, uint256 scalar ) internal pure returns (uint256 z) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { switch x case 0 { switch n @@ -159,7 +162,8 @@ library FixedPointMathLib { //////////////////////////////////////////////////////////////*/ function sqrt(uint256 x) internal pure returns (uint256 z) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { let y := x // We start y at x, which will help us make our initial estimate. z := 181 // The "correct" value is 1, but this saves a multiplication later. @@ -223,7 +227,8 @@ library FixedPointMathLib { } function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Mod x by y. Note this will return // 0 instead of reverting if y is zero. z := mod(x, y) @@ -231,7 +236,8 @@ library FixedPointMathLib { } function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Divide x by y. Note this will return // 0 instead of reverting if y is zero. r := div(x, y) @@ -239,7 +245,8 @@ library FixedPointMathLib { } function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Add 1 to x * y if x % y > 0. Note this will // return 0 instead of reverting if y is zero. z := add(gt(mod(x, y), 0), div(x, y)) diff --git a/src/utils/LibString.sol b/src/utils/LibString.sol index 7ec75b63..b69ccdf7 100644 --- a/src/utils/LibString.sol +++ b/src/utils/LibString.sol @@ -6,7 +6,8 @@ pragma solidity >=0.8.0; /// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibString.sol) library LibString { function toString(uint256 value) internal pure returns (string memory str) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but we allocate 160 bytes // to keep the free memory pointer word aligned. We'll need 1 word for the length, 1 word for the // trailing zeros padding, and 3 other words for a max of 78 digits. In total: 5 * 32 = 160 bytes. diff --git a/src/utils/MerkleProofLib.sol b/src/utils/MerkleProofLib.sol index 994c7b27..8fd7cbd7 100644 --- a/src/utils/MerkleProofLib.sol +++ b/src/utils/MerkleProofLib.sol @@ -10,7 +10,8 @@ library MerkleProofLib { bytes32 root, bytes32 leaf ) internal pure returns (bool isValid) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { if proof.length { // Left shifting by 5 is like multiplying by 32. let end := add(proof.offset, shl(5, proof.length)) diff --git a/src/utils/SSTORE2.sol b/src/utils/SSTORE2.sol index 35439374..23d69803 100644 --- a/src/utils/SSTORE2.sol +++ b/src/utils/SSTORE2.sol @@ -34,7 +34,8 @@ library SSTORE2 { runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit. ); - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Deploy a new contract with the generated creation code. // We start 32 bytes into the code to avoid copying the byte length. pointer := create(0, add(creationCode, 32), mload(creationCode)) @@ -79,7 +80,8 @@ library SSTORE2 { uint256 start, uint256 size ) private view returns (bytes memory data) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Get a pointer to some free memory. data := mload(0x40) diff --git a/src/utils/SafeTransferLib.sol b/src/utils/SafeTransferLib.sol index 5c7710cf..7080fd83 100644 --- a/src/utils/SafeTransferLib.sol +++ b/src/utils/SafeTransferLib.sol @@ -15,7 +15,8 @@ library SafeTransferLib { function safeTransferETH(address to, uint256 amount) internal { bool success; - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Transfer the ETH and store if it succeeded or not. success := call(gas(), to, amount, 0, 0, 0, 0) } @@ -35,7 +36,8 @@ library SafeTransferLib { ) internal { bool success; - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) @@ -67,7 +69,8 @@ library SafeTransferLib { ) internal { bool success; - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) @@ -98,7 +101,8 @@ library SafeTransferLib { ) internal { bool success; - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) diff --git a/src/utils/SignedWadMath.sol b/src/utils/SignedWadMath.sol index 6d529fbe..69239d2c 100644 --- a/src/utils/SignedWadMath.sol +++ b/src/utils/SignedWadMath.sol @@ -7,7 +7,8 @@ pragma solidity >=0.8.0; /// @dev Will not revert on overflow, only use where overflow is not possible. function toWadUnsafe(uint256 x) pure returns (int256 r) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Multiply x by 1e18. r := mul(x, 1000000000000000000) } @@ -17,7 +18,8 @@ function toWadUnsafe(uint256 x) pure returns (int256 r) { /// @dev Will not revert on overflow, only use where overflow is not possible. /// @dev Not meant for negative second amounts, it assumes x is positive. function toDaysWadUnsafe(uint256 x) pure returns (int256 r) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Multiply x by 1e18 and then divide it by 86400. r := div(mul(x, 1000000000000000000), 86400) } @@ -27,7 +29,8 @@ function toDaysWadUnsafe(uint256 x) pure returns (int256 r) { /// @dev Will not revert on overflow, only use where overflow is not possible. /// @dev Not meant for negative day amounts, it assumes x is positive. function fromDaysWadUnsafe(int256 x) pure returns (uint256 r) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Multiply x by 86400 and then divide it by 1e18. r := div(mul(x, 86400), 1000000000000000000) } @@ -35,7 +38,8 @@ function fromDaysWadUnsafe(int256 x) pure returns (uint256 r) { /// @dev Will not revert on overflow, only use where overflow is not possible. function unsafeWadMul(int256 x, int256 y) pure returns (int256 r) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Multiply x by y and divide by 1e18. r := sdiv(mul(x, y), 1000000000000000000) } @@ -44,14 +48,16 @@ function unsafeWadMul(int256 x, int256 y) pure returns (int256 r) { /// @dev Will return 0 instead of reverting if y is zero and will /// not revert on overflow, only use where overflow is not possible. function unsafeWadDiv(int256 x, int256 y) pure returns (int256 r) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Multiply x by 1e18 and divide it by y. r := sdiv(mul(x, 1000000000000000000), y) } } function wadMul(int256 x, int256 y) pure returns (int256 r) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Store x * y in r for now. r := mul(x, y) @@ -66,7 +72,8 @@ function wadMul(int256 x, int256 y) pure returns (int256 r) { } function wadDiv(int256 x, int256 y) pure returns (int256 r) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Store x * 1e18 in r for now. r := mul(x, 1000000000000000000) @@ -119,7 +126,8 @@ function wadExp(int256 x) pure returns (int256 r) { q = ((q * x) >> 96) - 14423608567350463180887372962807573; q = ((q * x) >> 96) + 26449188498355588339934803723976023; - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Div in assembly because solidity adds a zero check despite the unchecked. // The q polynomial won't have zeros in the domain as all its roots are complex. // No scaling is necessary because p is already 2**96 too large. @@ -147,7 +155,8 @@ function wadLn(int256 x) pure returns (int256 r) { // ln(x * C) = ln(x) + ln(C), we can simply do nothing here // and add ln(2**96 / 10**18) at the end. - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) @@ -183,7 +192,8 @@ function wadLn(int256 x) pure returns (int256 r) { q = ((q * x) >> 96) + 204048457590392012362485061816622; q = ((q * x) >> 96) + 31853899698501571402653359427138; q = ((q * x) >> 96) + 909429971244387300277376558375; - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Div in assembly because solidity adds a zero check despite the unchecked. // The q polynomial is known not to have zeros in the domain. // No scaling required because p is already 2**96 too large. @@ -211,7 +221,8 @@ function wadLn(int256 x) pure returns (int256 r) { /// @dev Will return 0 instead of reverting if y is zero. function unsafeDiv(int256 x, int256 y) pure returns (int256 r) { - assembly ("memory-safe") { + /// @solidity memory-safe-assembly + assembly { // Divide x by y. r := sdiv(x, y) }