Skip to content

Commit

Permalink
feat: unchecked stdMath::delta
Browse files Browse the repository at this point in the history
* impl: unchecked stdMath
* lib: update forge-std commit to v1.5.3
* build: update unoptimized key
* test: update gas snapshot
  • Loading branch information
xenide authored Apr 12, 2023
1 parent ac8d890 commit e25c319
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 45 deletions.
74 changes: 37 additions & 37 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ AssetManagedPairTest:testSwap_AfterLoss(uint256) (runs: 256, μ: 717044, ~: 7130
AssetManagedPairTest:testSync(uint256,uint256,uint256,uint256) (runs: 256, μ: 462262, ~: 462651)
AssetManagedPairTest:testSyncManaged_ConstantProduct(uint256,uint256) (runs: 256, μ: 325602, ~: 325610)
AssetManagedPairTest:testSyncManaged_Stable(uint256,uint256) (runs: 256, μ: 381828, ~: 383927)
ConstantProductMathTest:testCalcLogPrice_ReturnsOneWeiWhenPriceDiffGreaterThan1e18(uint256,uint256) (runs: 256, μ: 9379, ~: 9225)
ConstantProductMathTest:testConstantProductOracleMath() (gas: 27832)
ConstantProductMathTest:testCalcLogPrice_ReturnsOneWeiWhenPriceDiffGreaterThan1e18(uint256,uint256) (runs: 256, μ: 9380, ~: 9147)
ConstantProductMathTest:testConstantProductOracleMath() (gas: 28248)
ConstantProductPairGas:testGasBurn() (gas: 87712)
ConstantProductPairGas:testGasMint() (gas: 95051)
ConstantProductPairGas:testGasMint_Initial() (gas: 187383)
Expand All @@ -35,24 +35,24 @@ ConstantProductPairTest:testMint_UnderMinimumLiquidity() (gas: 4726455)
ConstantProductPairTest:testOracle_ClampedPrice_AtLimit() (gas: 182818)
ConstantProductPairTest:testOracle_ClampedPrice_NoDiffWithinLimit() (gas: 182788)
ConstantProductPairTest:testOracle_ClampedPrice_OverLimit() (gas: 183298)
ConstantProductPairTest:testOracle_CorrectLiquidity() (gas: 233383)
ConstantProductPairTest:testOracle_CorrectPrice() (gas: 258922)
ConstantProductPairTest:testOracle_CorrectPriceDiffDecimals() (gas: 4900556)
ConstantProductPairTest:testOracle_LiquidityAtMaximum() (gas: 208439)
ConstantProductPairTest:testOracle_CorrectLiquidity() (gas: 233525)
ConstantProductPairTest:testOracle_CorrectPrice() (gas: 259064)
ConstantProductPairTest:testOracle_CorrectPriceDiffDecimals() (gas: 4900632)
ConstantProductPairTest:testOracle_LiquidityAtMaximum() (gas: 208505)
ConstantProductPairTest:testOracle_NoWriteInSameTimestamp() (gas: 187868)
ConstantProductPairTest:testOracle_OverflowAccLiquidity() (gas: 108528)
ConstantProductPairTest:testOracle_OverflowAccPrice() (gas: 162386)
ConstantProductPairTest:testOracle_SimplePrices() (gas: 255761)
ConstantProductPairTest:testOracle_SimplePrices() (gas: 255969)
ConstantProductPairTest:testOracle_WrapsAroundAfterFull() (gas: 3119951465)
ConstantProductPairTest:testPlatformFee_Disable() (gas: 394979)
ConstantProductPairTest:testPlatformFee_DisableReenable() (gas: 552184)
ConstantProductPairTest:testSwap() (gas: 83187)
ConstantProductPairTest:testSwap_ExactOut(uint256) (runs: 256, μ: 93853, ~: 93566)
ConstantProductPairTest:testSwap_ExactOut(uint256) (runs: 256, μ: 93875, ~: 93847)
ConstantProductPairTest:testSwap_ExactOutExceedReserves() (gas: 38021)
ConstantProductPairTest:testSwap_ExactOut_NewReservesExceedUint104() (gas: 82261)
ConstantProductPairTest:testSwap_ExtremeAmounts() (gas: 4869206)
ConstantProductPairTest:testSwap_MinInt256() (gas: 14921)
ConstantProductPairTest:testSwap_Reenter() (gas: 80167)
ConstantProductPairTest:testSwap_Reenter() (gas: 80233)
ConstantProductPairTest:testWriteObservations() (gas: 209517)
FlashSwapTest:testSwap_FlashSwap_ExactIn(uint256) (runs: 256, μ: 222172, ~: 226898)
FlashSwapTest:testSwap_FlashSwap_ExactOut(uint256) (runs: 256, μ: 227550, ~: 227673)
Expand All @@ -74,17 +74,17 @@ OracleCallerTest:testObservation_NotWhitelisted(uint256) (runs: 256, μ: 86936,
OracleCallerTest:testWhitelistAddress() (gas: 146540)
OracleCallerTest:testWhitelistAddress_NotOwner() (gas: 15193)
OracleWriterTest:testMaxChangeRate_Default() (gas: 66182)
OracleWriterTest:testObservation_NotOracleCaller(uint256) (runs: 256, μ: 77022, ~: 77469)
OracleWriterTest:testObservation_NotOracleCaller(uint256) (runs: 256, μ: 77005, ~: 77469)
OracleWriterTest:testOracle_CompareLiquidityTwoCurves_Balanced() (gas: 184656)
OracleWriterTest:testOracle_SamePriceDiffLiq() (gas: 10131658)
OracleWriterTest:testOracle_SamePriceSameLiq() (gas: 10131687)
OracleWriterTest:testOracle_SameReservesDiffPrice() (gas: 10132116)
OracleWriterTest:testSetMaxChangeRate_OnlyFactory() (gas: 87592)
OracleWriterTest:testSetMaxChangeRate_TooHigh(uint256) (runs: 256, μ: 76644, ~: 76596)
OracleWriterTest:testSetMaxChangeRate_TooHigh(uint256) (runs: 256, μ: 76617, ~: 76596)
OracleWriterTest:testSetMaxChangeRate_TooLow() (gas: 68080)
OracleWriterTest:testUpdateOracleCaller() (gas: 113355)
OracleWriterTest:testUpdateOracleCaller_NoChange() (gas: 81491)
OracleWriterTest:testUpdateOracle_WriteOldReservesNotNew() (gas: 278126)
OracleWriterTest:testUpdateOracle_WriteOldReservesNotNew() (gas: 278278)
PairTest:testCustomPlatformFee_OffByDefault() (gas: 71886)
PairTest:testCustomSwapFee_OffByDefault() (gas: 66117)
PairTest:testEmitEventOnCreation() (gas: 9645425)
Expand Down Expand Up @@ -133,32 +133,32 @@ StablePairGas:testGasSwap_UpdateOracleClamped() (gas: 109607)
StablePairTest:testAttackWhileRampingDown_LongInterval() (gas: 205397)
StablePairTest:testAttackWhileRampingDown_ShortInterval() (gas: 204823)
StablePairTest:testBurn() (gas: 143263)
StablePairTest:testBurn_DiffDecimalPlaces(uint256) (runs: 256, μ: 5295234, ~: 5294750)
StablePairTest:testBurn_DiffDecimalPlaces(uint256) (runs: 256, μ: 5295254, ~: 5294750)
StablePairTest:testBurn_LastInvariantUseReserveInsteadOfBalance() (gas: 242098)
StablePairTest:testBurn_Reenter() (gas: 53552)
StablePairTest:testBurn_WhenRampingA(uint256) (runs: 256, μ: 400434, ~: 400513)
StablePairTest:testBurn_WhenRampingA(uint256) (runs: 256, μ: 400450, ~: 400618)
StablePairTest:testBurn_Zero() (gas: 80543)
StablePairTest:testFactoryAmpTooHigh() (gas: 341324)
StablePairTest:testFactoryAmpTooLow() (gas: 336281)
StablePairTest:testGetCurrentA() (gas: 32471)
StablePairTest:testMint() (gas: 114746)
StablePairTest:testMintFee_DiffPlatformFees(uint256) (runs: 256, μ: 6562426, ~: 6566365)
StablePairTest:testMintFee_WhenRampingA_PoolBalanced(uint256) (runs: 256, μ: 6721305, ~: 6721476)
StablePairTest:testMintFee_WhenRampingA_PoolUnbalanced(uint256) (runs: 256, μ: 6160667, ~: 6160166)
StablePairTest:testMintFee_DiffPlatformFees(uint256) (runs: 256, μ: 6562486, ~: 6566420)
StablePairTest:testMintFee_WhenRampingA_PoolBalanced(uint256) (runs: 256, μ: 6721308, ~: 6721476)
StablePairTest:testMintFee_WhenRampingA_PoolUnbalanced(uint256) (runs: 256, μ: 6160605, ~: 6160166)
StablePairTest:testMint_NonOptimalProportion() (gas: 148110)
StablePairTest:testMint_NonOptimalProportion_ThenBurn() (gas: 307363)
StablePairTest:testMint_OnlyTransferOneToken() (gas: 5066412)
StablePairTest:testMint_PlatformFeeOff() (gas: 120271)
StablePairTest:testMint_Reenter() (gas: 53399)
StablePairTest:testMint_WhenRampingA(uint256) (runs: 256, μ: 421022, ~: 421200)
StablePairTest:testMint_WhenRampingA(uint256) (runs: 256, μ: 421029, ~: 421200)
StablePairTest:testOracle_ClampedPrice_NoDiffWithinLimit() (gas: 203674)
StablePairTest:testOracle_CorrectLiquidity() (gas: 254682)
StablePairTest:testOracle_CorrectPrice() (gas: 310188)
StablePairTest:testOracle_LiquidityAtMaximum() (gas: 233312)
StablePairTest:testOracle_CorrectLiquidity() (gas: 254812)
StablePairTest:testOracle_CorrectPrice() (gas: 310318)
StablePairTest:testOracle_LiquidityAtMaximum() (gas: 233367)
StablePairTest:testOracle_NoWriteInSameTimestamp() (gas: 219081)
StablePairTest:testOracle_OverflowAccLiquidity() (gas: 114117)
StablePairTest:testOracle_OverflowAccPrice() (gas: 179072)
StablePairTest:testOracle_SimplePrices() (gas: 348260)
StablePairTest:testOracle_SimplePrices() (gas: 348435)
StablePairTest:testOracle_WrapsAroundAfterFull() (gas: 4231878708)
StablePairTest:testPlatformFee_Disable() (gas: 456142)
StablePairTest:testPlatformFee_DisableReenable() (gas: 665552)
Expand All @@ -170,27 +170,27 @@ StablePairTest:testRampA_MaxSpeed() (gas: 26514)
StablePairTest:testRampA_OnlyFactory() (gas: 8756)
StablePairTest:testRampA_SetAtMaximum() (gas: 25178)
StablePairTest:testRampA_SetAtMinimum() (gas: 25199)
StablePairTest:testRampA_SwappingDuringRampingDown(uint256,uint256,uint256,uint256) (runs: 256, μ: 509548, ~: 513101)
StablePairTest:testRampA_SwappingDuringRampingUp(uint256,uint256,uint256,uint256) (runs: 256, μ: 509326, ~: 513090)
StablePairTest:testRampA_SwappingDuringRampingDown(uint256,uint256,uint256,uint256) (runs: 256, μ: 509891, ~: 514556)
StablePairTest:testRampA_SwappingDuringRampingUp(uint256,uint256,uint256,uint256) (runs: 256, μ: 509508, ~: 513091)
StablePairTest:testStopRampA() (gas: 33936)
StablePairTest:testStopRampA_Early(uint256) (runs: 256, μ: 42371, ~: 42484)
StablePairTest:testStopRampA_Late(uint256) (runs: 256, μ: 41255, ~: 41380)
StablePairTest:testStopRampA_Early(uint256) (runs: 256, μ: 42424, ~: 42550)
StablePairTest:testStopRampA_Late(uint256) (runs: 256, μ: 41268, ~: 41380)
StablePairTest:testStopRampA_OnlyFactory() (gas: 8449)
StablePairTest:testSwap() (gas: 87483)
StablePairTest:testSwap_BetterPerformanceThanConstantProduct() (gas: 128904)
StablePairTest:testSwap_DiffAs(uint256,uint256,uint256) (runs: 256, μ: 5311790, ~: 5312168)
StablePairTest:testSwap_DiffSwapFees(uint256) (runs: 256, μ: 5313118, ~: 5315486)
StablePairTest:testSwap_DiffAs(uint256,uint256,uint256) (runs: 256, μ: 5311761, ~: 5312168)
StablePairTest:testSwap_DiffSwapFees(uint256) (runs: 256, μ: 5313126, ~: 5315486)
StablePairTest:testSwap_ExactInExceedUint104() (gas: 79325)
StablePairTest:testSwap_ExactOutExceedReserves() (gas: 38131)
StablePairTest:testSwap_IncreasingSwapFees(uint256,uint256,uint256) (runs: 256, μ: 307491, ~: 307455)
StablePairTest:testSwap_IncreasingSwapFees(uint256,uint256,uint256) (runs: 256, μ: 307492, ~: 307455)
StablePairTest:testSwap_MinInt256() (gas: 14998)
StablePairTest:testSwap_Reenter() (gas: 90355)
StablePairTest:testSwap_Token0ExactOut(uint256) (runs: 256, μ: 121875, ~: 110172)
StablePairTest:testSwap_Token1ExactOut(uint256) (runs: 256, μ: 122337, ~: 110307)
StablePairTest:testSwap_VeryLargeLiquidity(uint256) (runs: 256, μ: 5282066, ~: 5285561)
StablePairTest:testSwap_VerySmallLiquidity(uint256,uint256,uint256) (runs: 256, μ: 5280547, ~: 5279722)
StablePairTest:testSwap_Reenter() (gas: 90421)
StablePairTest:testSwap_Token0ExactOut(uint256) (runs: 256, μ: 121666, ~: 110227)
StablePairTest:testSwap_Token1ExactOut(uint256) (runs: 256, μ: 121867, ~: 110362)
StablePairTest:testSwap_VeryLargeLiquidity(uint256) (runs: 256, μ: 5281984, ~: 5281441)
StablePairTest:testSwap_VerySmallLiquidity(uint256,uint256,uint256) (runs: 256, μ: 5280310, ~: 5279692)
StablePairTest:testSwap_ZeroInput() (gas: 14470)
StablePairTest:testWriteObservations() (gas: 243594)
StdMathTest:testPercentDelta() (gas: 578)
StdMathTest:testPercentDelta_MinusOne() (gas: 579)
StdMathTest:testPercentDelta_PlusOne() (gas: 536)
StdMathTest:testPercentDelta() (gas: 643)
StdMathTest:testPercentDelta_MinusOne() (gas: 644)
StdMathTest:testPercentDelta_PlusOne() (gas: 601)
2 changes: 1 addition & 1 deletion lib/forge-std
Submodule forge-std updated 1 files
+1 −5 src/StdMath.sol
6 changes: 3 additions & 3 deletions scripts/unoptimized-deployer-meta
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"constant_product_hash": "0x331cc67f13638cfb7ba5843198a0c38a5b4eee0162ae0f20eddc07e8cbf0732e",
"factory_hash": "0x282a99019ed382d1037d5d34b6bf9ca045737c0bca2642a38c4dd0a5cc7d76c3",
"constant_product_hash": "0xd42c24652292f1d010c199a1902937404331f86155feb0045f7f4ccaa53288e0",
"factory_hash": "0x4809cda82093eabbe5c089c6ec04d08debfff7cb44748ac3e6a417e874f7c0c1",
"oracle_caller_hash": "0x62fc6a5b4ecef14f3dbc069a342221c05473817912414ef348074314902a145a",
"stable_hash": "0xb7344aa6cc1780d46e643f82f5726bf00965c157ff312dda28eb30eb4938d16a"
"stable_hash": "0x6cb319a261af453dc63b30b3a6962bf8293b740d1878d723d3fa3384a0b9320c"
}
5 changes: 3 additions & 2 deletions src/ReservoirPair.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;

import { stdMath } from "forge-std/Test.sol";
import { SafeCast } from "@openzeppelin/utils/math/SafeCast.sol";
import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol";

import { stdMath } from "src/libraries/stdMath.sol";
import { FactoryStoreLib } from "src/libraries/FactoryStore.sol";
import { Bytes32Lib } from "src/libraries/Bytes32.sol";
import { LogCompression } from "src/libraries/LogCompression.sol";
Expand Down Expand Up @@ -44,6 +44,7 @@ abstract contract ReservoirPair is IAssetManagedPair, ReservoirERC20 {
using Bytes32Lib for bytes32;
using SafeCast for uint256;
using SafeTransferLib for address;
using stdMath for uint256;

uint256 public constant MINIMUM_LIQUIDITY = 10 ** 3;
uint256 public constant FEE_ACCURACY = 1_000_000; // 100%
Expand Down Expand Up @@ -529,7 +530,7 @@ abstract contract ReservoirPair is IAssetManagedPair, ReservoirERC20 {
return (aCurrRawPrice, int112(LogCompression.toLowResLog(aCurrRawPrice)));
}

if (stdMath.percentDelta(aCurrRawPrice, aPrevClampedPrice) > maxChangeRate * aTimeElapsed) {
if (aCurrRawPrice.percentDelta(aPrevClampedPrice) > maxChangeRate * aTimeElapsed) {
// clamp the price
if (aCurrRawPrice > aPrevClampedPrice) {
rClampedPrice = aPrevClampedPrice * (1e18 + (maxChangeRate * aTimeElapsed)) / 1e18;
Expand Down
5 changes: 3 additions & 2 deletions src/libraries/StableMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
pragma solidity ^0.8.0;

import { MathUtils } from "src/libraries/MathUtils.sol";
import { stdMath } from "forge-std/Test.sol";
import { stdMath } from "src/libraries/stdMath.sol";

library StableMath {
using MathUtils for uint256;
using stdMath for uint256;

/// @dev Extra precision for intermediate calculations.
uint256 public constant A_PRECISION = 100;
Expand Down Expand Up @@ -109,7 +110,7 @@ library StableMath {
}
// NB: Sometimes the iteration gets stuck in an oscillating loop so if it is close enough we
// return it anyway
uint256 percentDelta = stdMath.percentDelta(D, prevD);
uint256 percentDelta = D.percentDelta(prevD);
if (percentDelta <= 0.0000000000004e18) {
return (D + prevD) / 2;
}
Expand Down
20 changes: 20 additions & 0 deletions src/libraries/stdMath.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;

// Our gas-optimized implementation of forge-std's stdMath library
// We should inherit and override the relevant functions in the future when they make them virtual
library stdMath {
function delta(uint256 a, uint256 b) internal pure returns (uint256) {
// SAFETY: The subtraction can never underflow as we explicitly sub the
// smaller value from the larger.
unchecked {
return a > b ? a - b : b - a;
}
}

function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 absDelta = delta(a, b);

return absDelta * 1e18 / b;
}
}

0 comments on commit e25c319

Please sign in to comment.