diff --git a/.gas-snapshot b/.gas-snapshot index 641515ba..c4c5c840 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -279,12 +279,12 @@ FixedPointMathLibTest:testSqrt(uint256) (runs: 256, μ: 997, ~: 1013) FixedPointMathLibTest:testSqrtBack(uint256) (runs: 256, μ: 15210, ~: 340) FixedPointMathLibTest:testSqrtBackHashed(uint256) (runs: 256, μ: 59066, ~: 59500) FixedPointMathLibTest:testSqrtBackHashedSingle() (gas: 58937) -LibStringTest:testDifferentiallyFuzzToString(uint256,bytes) (runs: 256, μ: 20875, ~: 8988) -LibStringTest:testDifferentiallyFuzzToStringInt(int256,bytes) (runs: 256, μ: 20129, ~: 8360) +LibStringTest:testDifferentiallyFuzzToString(uint256,bytes) (runs: 256, μ: 20892, ~: 8988) +LibStringTest:testDifferentiallyFuzzToStringInt(int256,bytes) (runs: 256, μ: 20081, ~: 8356) LibStringTest:testToString() (gas: 10069) LibStringTest:testToStringDirty() (gas: 8145) -LibStringTest:testToStringIntNegative() (gas: 11096) -LibStringTest:testToStringIntPositive() (gas: 10509) +LibStringTest:testToStringIntNegative() (gas: 9634) +LibStringTest:testToStringIntPositive() (gas: 10481) LibStringTest:testToStringOverwrite() (gas: 506) MerkleProofLibTest:testValidProofSupplied() (gas: 2153) MerkleProofLibTest:testVerifyEmptyMerkleProofSuppliedLeafAndRootDifferent() (gas: 1458) diff --git a/lib/ds-test b/lib/ds-test index 9310e879..cd98eff2 160000 --- a/lib/ds-test +++ b/lib/ds-test @@ -1 +1 @@ -Subproject commit 9310e879db8ba3ea6d5c6489a579118fd264a3f5 +Subproject commit cd98eff28324bfac652e63a239a60632a761790b diff --git a/src/utils/LibString.sol b/src/utils/LibString.sol index b0576b9d..97c89e0b 100644 --- a/src/utils/LibString.sol +++ b/src/utils/LibString.sol @@ -5,9 +5,24 @@ pragma solidity >=0.8.0; /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol) /// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibString.sol) library LibString { - function toString(int256 value) internal pure returns (string memory) { + function toString(int256 value) internal pure returns (string memory str) { + if (value >= 0) return toString(uint256(value)); + unchecked { - return value >= 0 ? toString(uint256(value)) : string(abi.encodePacked("-", toString(uint256(-value)))); + str = toString(uint256(-value)); + + /// @solidity memory-safe-assembly + assembly { + // Note: This is only safe because we over-allocate memory + // and write the string from right to left in toString(uint256), + // and thus can be sure that sub(str, 1) is an unused memory location. + + let length := mload(str) // Load the string length. + // Put the - character at the start of the string contents. + mstore(str, 45) // 45 is the ASCII code for the - character. + str := sub(str, 1) // Move back the string pointer by a byte. + mstore(str, add(length, 1)) // Update the string length. + } } }