From f7a709cddc77dcb05b76b305fc71bc6a182ad709 Mon Sep 17 00:00:00 2001 From: OliverNChalk <11343499+OliverNChalk@users.noreply.github.com> Date: Sun, 7 Jul 2024 16:04:39 -0500 Subject: [PATCH] review: oliver * don't use associated functions when the operation is not associated * factor out _validateTokens * use A/B when unsorted; 0/1 when sorted * avoid unnecessary temporary array * update gas snapshot * fix: collapse validation logic * refactor: rename FlagsLib into RoutesLib * fix: process 2 hop route before 3 hop route * gas: update snapshot --------- Co-authored-by: A.L. --- .gas-snapshot | 102 +++++++++--------- src/ReservoirPriceOracle.sol | 74 ++++++------- src/libraries/OracleErrors.sol | 3 +- src/libraries/{FlagsLib.sol => RoutesLib.sol} | 6 +- test/unit/ReservoirPriceOracle.t.sol | 8 +- .../{FlagsLib.t.sol => RoutesLib.t.sol} | 18 ++-- 6 files changed, 105 insertions(+), 106 deletions(-) rename src/libraries/{FlagsLib.sol => RoutesLib.sol} (94%) rename test/unit/libraries/{FlagsLib.t.sol => RoutesLib.t.sol} (72%) diff --git a/.gas-snapshot b/.gas-snapshot index 44ffc75..39f09f6 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,74 +1,74 @@ -FlagsLibTest:testGetDecimalDifference() (gas: 3974) -FlagsLibTest:testIsCompositeRoute() (gas: 4341) -FlagsLibTest:testPackSimplePrice(int8,uint256) (runs: 256, μ: 7791, ~: 7555) -QueryProcessorTest:testFindNearestSample_CanFindExactValue(uint32,uint256,uint256,uint256) (runs: 256, μ: 67735642, ~: 76032605) -QueryProcessorTest:testFindNearestSample_CanFindIntermediateValue(uint32,uint256,uint256,uint256) (runs: 256, μ: 65799154, ~: 75921271) +QueryProcessorTest:testFindNearestSample_CanFindExactValue(uint32,uint256,uint256,uint256) (runs: 256, μ: 67585746, ~: 76007063) +QueryProcessorTest:testFindNearestSample_CanFindIntermediateValue(uint32,uint256,uint256,uint256) (runs: 256, μ: 67051023, ~: 76087612) QueryProcessorTest:testFindNearestSample_NotInitialized() (gas: 1056945756) -QueryProcessorTest:testFindNearestSample_OneSample(uint256) (runs: 256, μ: 80323, ~: 80360) +QueryProcessorTest:testFindNearestSample_OneSample(uint256) (runs: 256, μ: 80325, ~: 80360) QueryProcessorTest:testGetInstantValue() (gas: 124248) QueryProcessorTest:testGetInstantValue_NotInitialized(uint256) (runs: 256, μ: 19397, ~: 19397) -QueryProcessorTest:testGetInstantValue_NotInitialized_BeyondBufferSize(uint8,uint16) (runs: 256, μ: 68389656, ~: 68389600) -QueryProcessorTest:testGetPastAccumulator_BufferEmpty(uint8) (runs: 256, μ: 27031, ~: 27087) -QueryProcessorTest:testGetPastAccumulator_ExactMatch(uint32,uint256,uint256,uint16) (runs: 256, μ: 69753539, ~: 80758108) -QueryProcessorTest:testGetPastAccumulator_ExactMatch_LatestAccumulator(uint32,uint256,uint256) (runs: 256, μ: 69259342, ~: 79254030) -QueryProcessorTest:testGetPastAccumulator_ExactMatch_OldestAccumulator(uint32,uint256,uint256) (runs: 256, μ: 69289298, ~: 79285630) -QueryProcessorTest:testGetPastAccumulator_ExtrapolatesBeyondLatest(uint32,uint256,uint256,uint256) (runs: 256, μ: 65772814, ~: 75892463) -QueryProcessorTest:testGetPastAccumulator_InterpolatesBetweenPastAccumulators(uint32,uint256,uint256,uint256) (runs: 256, μ: 65806837, ~: 75927279) -QueryProcessorTest:testGetPastAccumulator_InvalidAgo(uint32,uint256,uint256,uint256) (runs: 256, μ: 65764408, ~: 75884174) -QueryProcessorTest:testGetPastAccumulator_QueryTooOld(uint32,uint256,uint256,uint256) (runs: 256, μ: 65775927, ~: 75894057) -QueryProcessorTest:testGetTimeWeightedAverage(uint32,uint256,uint256,uint256,uint256) (runs: 256, μ: 107971505, ~: 117069798) +QueryProcessorTest:testGetInstantValue_NotInitialized_BeyondBufferSize(uint8,uint16) (runs: 256, μ: 68389647, ~: 68389600) +QueryProcessorTest:testGetPastAccumulator_BufferEmpty(uint8) (runs: 256, μ: 27017, ~: 27087) +QueryProcessorTest:testGetPastAccumulator_ExactMatch(uint32,uint256,uint256,uint16) (runs: 256, μ: 69289018, ~: 79307245) +QueryProcessorTest:testGetPastAccumulator_ExactMatch_LatestAccumulator(uint32,uint256,uint256) (runs: 256, μ: 70900090, ~: 79224986) +QueryProcessorTest:testGetPastAccumulator_ExactMatch_OldestAccumulator(uint32,uint256,uint256) (runs: 256, μ: 70930212, ~: 79256586) +QueryProcessorTest:testGetPastAccumulator_ExtrapolatesBeyondLatest(uint32,uint256,uint256,uint256) (runs: 256, μ: 67024575, ~: 76058923) +QueryProcessorTest:testGetPastAccumulator_InterpolatesBetweenPastAccumulators(uint32,uint256,uint256,uint256) (runs: 256, μ: 67058609, ~: 76093620) +QueryProcessorTest:testGetPastAccumulator_InvalidAgo(uint32,uint256,uint256,uint256) (runs: 256, μ: 67016184, ~: 76050634) +QueryProcessorTest:testGetPastAccumulator_QueryTooOld(uint32,uint256,uint256,uint256) (runs: 256, μ: 67027596, ~: 76060517) +QueryProcessorTest:testGetTimeWeightedAverage(uint32,uint256,uint256,uint256,uint256) (runs: 256, μ: 101761121, ~: 108597954) QueryProcessorTest:testGetTimeWeightedAverage_BadSecs() (gas: 10995) -ReservoirPriceOracleTest:testClearRoute() (gas: 52085) -ReservoirPriceOracleTest:testClearRoute_AllWordsCleared() (gas: 155034) +ReservoirPriceOracleTest:testClearRoute() (gas: 50974) +ReservoirPriceOracleTest:testClearRoute_AllWordsCleared() (gas: 151907) ReservoirPriceOracleTest:testDesignatePair() (gas: 29091) ReservoirPriceOracleTest:testDesignatePair_IncorrectPair() (gas: 21111) ReservoirPriceOracleTest:testDesignatePair_NotOwner() (gas: 17531) ReservoirPriceOracleTest:testDesignatePair_TokenOrderReversed() (gas: 30729) ReservoirPriceOracleTest:testGasBountyAvailable(uint256) (runs: 256, μ: 9929, ~: 9925) ReservoirPriceOracleTest:testGasBountyAvailable_Zero() (gas: 8961) -ReservoirPriceOracleTest:testGetLatest(uint32) (runs: 256, μ: 92679, ~: 92614) +ReservoirPriceOracleTest:testGetLatest(uint32) (runs: 256, μ: 92685, ~: 92614) ReservoirPriceOracleTest:testGetLatest_Inverted() (gas: 96786) -ReservoirPriceOracleTest:testGetQuote(uint256,uint256) (runs: 256, μ: 35782, ~: 35886) +ReservoirPriceOracleTest:testGetQuote(uint256,uint256) (runs: 256, μ: 35198, ~: 35302) ReservoirPriceOracleTest:testGetQuote_AmountInTooLarge() (gas: 12963) -ReservoirPriceOracleTest:testGetQuote_BaseIsVault(uint256) (runs: 256, μ: 418221, ~: 417982) -ReservoirPriceOracleTest:testGetQuote_ComplicatedDecimals() (gas: 10352967) -ReservoirPriceOracleTest:testGetQuote_Inverse(uint256,uint256) (runs: 256, μ: 37892, ~: 38058) -ReservoirPriceOracleTest:testGetQuote_MultipleHops() (gas: 114257) -ReservoirPriceOracleTest:testGetQuote_MultipleHops_Inverse() (gas: 114512) -ReservoirPriceOracleTest:testGetQuote_MultipleHops_PriceZero() (gas: 126984) -ReservoirPriceOracleTest:testGetQuote_NoFallbackOracle() (gas: 21084) -ReservoirPriceOracleTest:testGetQuote_PriceZero() (gas: 16486) -ReservoirPriceOracleTest:testGetQuote_RandomizeAllParam_1HopRoute(uint256,uint256,address,address,uint8,uint8) (runs: 256, μ: 5327988, ~: 5328070) -ReservoirPriceOracleTest:testGetQuote_RandomizeAllParam_2HopRoute(uint256,uint256,uint256,address,address,address,uint8,uint8,uint8) (runs: 256, μ: 10493634, ~: 10493649) +ReservoirPriceOracleTest:testGetQuote_BaseIsVault(uint256) (runs: 256, μ: 417430, ~: 417188) +ReservoirPriceOracleTest:testGetQuote_ComplicatedDecimals() (gas: 10350840) +ReservoirPriceOracleTest:testGetQuote_Inverse(uint256,uint256) (runs: 256, μ: 37311, ~: 37474) +ReservoirPriceOracleTest:testGetQuote_MultipleHops() (gas: 113391) +ReservoirPriceOracleTest:testGetQuote_MultipleHops_Inverse() (gas: 113646) +ReservoirPriceOracleTest:testGetQuote_MultipleHops_PriceZero() (gas: 125259) +ReservoirPriceOracleTest:testGetQuote_NoFallbackOracle() (gas: 20875) +ReservoirPriceOracleTest:testGetQuote_PriceZero() (gas: 15902) +ReservoirPriceOracleTest:testGetQuote_RandomizeAllParam_1HopRoute(uint256,uint256,address,address,uint8,uint8) (runs: 256, μ: 5327381, ~: 5327411) +ReservoirPriceOracleTest:testGetQuote_RandomizeAllParam_2HopRoute(uint256,uint256,uint256,address,address,address,uint8,uint8,uint8) (runs: 256, μ: 10492723, ~: 10492862) ReservoirPriceOracleTest:testGetQuote_SameBaseQuote(uint256,address) (runs: 256, μ: 8963, ~: 8963) -ReservoirPriceOracleTest:testGetQuote_UseFallback() (gas: 38730) -ReservoirPriceOracleTest:testGetQuote_ZeroIn() (gas: 39315) -ReservoirPriceOracleTest:testGetQuotes(uint256,uint256) (runs: 256, μ: 33271, ~: 33375) +ReservoirPriceOracleTest:testGetQuote_UseFallback() (gas: 38312) +ReservoirPriceOracleTest:testGetQuote_ZeroIn() (gas: 38147) +ReservoirPriceOracleTest:testGetQuotes(uint256,uint256) (runs: 256, μ: 32687, ~: 32791) ReservoirPriceOracleTest:testGetTimeWeightedAverage() (gas: 141765) ReservoirPriceOracleTest:testGetTimeWeightedAverage_Inverted() (gas: 120958) ReservoirPriceOracleTest:testSetFallbackOracle_NotOwner() (gas: 10938) -ReservoirPriceOracleTest:testSetRoute() (gas: 58807) -ReservoirPriceOracleTest:testSetRoute_InvalidRoute() (gas: 18004) -ReservoirPriceOracleTest:testSetRoute_InvalidRouteLength() (gas: 17633) -ReservoirPriceOracleTest:testSetRoute_MultipleHops() (gas: 196034) -ReservoirPriceOracleTest:testSetRoute_NotSorted() (gas: 12095) -ReservoirPriceOracleTest:testSetRoute_OverwriteExisting() (gas: 162438) -ReservoirPriceOracleTest:testSetRoute_SameToken() (gas: 12070) +ReservoirPriceOracleTest:testSetRoute() (gas: 58216) +ReservoirPriceOracleTest:testSetRoute_InvalidRoute() (gas: 17990) +ReservoirPriceOracleTest:testSetRoute_InvalidRouteLength() (gas: 17619) +ReservoirPriceOracleTest:testSetRoute_MultipleHops() (gas: 193395) +ReservoirPriceOracleTest:testSetRoute_NotSorted() (gas: 12102) +ReservoirPriceOracleTest:testSetRoute_OverwriteExisting() (gas: 160967) +ReservoirPriceOracleTest:testSetRoute_SameToken() (gas: 12115) ReservoirPriceOracleTest:testUndesignatePair() (gas: 30257) ReservoirPriceOracleTest:testUndesignatePair_NotOwner() (gas: 15288) -ReservoirPriceOracleTest:testUpdatePriceDeviationThreshold(uint256) (runs: 256, μ: 21331, ~: 21085) -ReservoirPriceOracleTest:testUpdatePrice_BeyondThreshold() (gas: 214357) -ReservoirPriceOracleTest:testUpdatePrice_BeyondThreshold_InsufficientReward(uint256) (runs: 256, μ: 203578, ~: 203794) -ReservoirPriceOracleTest:testUpdatePrice_BeyondThreshold_ZeroRecipient() (gas: 196179) -ReservoirPriceOracleTest:testUpdatePrice_FirstUpdate() (gas: 203806) -ReservoirPriceOracleTest:testUpdatePrice_IntermediateRoutes() (gas: 15868736) -ReservoirPriceOracleTest:testUpdatePrice_PriceOutOfRange() (gas: 5351311) -ReservoirPriceOracleTest:testUpdatePrice_WithinThreshold() (gas: 204695) +ReservoirPriceOracleTest:testUpdatePriceDeviationThreshold(uint256) (runs: 256, μ: 21328, ~: 21085) +ReservoirPriceOracleTest:testUpdatePrice_BeyondThreshold() (gas: 213770) +ReservoirPriceOracleTest:testUpdatePrice_BeyondThreshold_InsufficientReward(uint256) (runs: 256, μ: 202989, ~: 203067) +ReservoirPriceOracleTest:testUpdatePrice_BeyondThreshold_ZeroRecipient() (gas: 195593) +ReservoirPriceOracleTest:testUpdatePrice_FirstUpdate() (gas: 203220) +ReservoirPriceOracleTest:testUpdatePrice_IntermediateRoutes() (gas: 15867847) +ReservoirPriceOracleTest:testUpdatePrice_PriceOutOfRange() (gas: 5350717) +ReservoirPriceOracleTest:testUpdatePrice_WithinThreshold() (gas: 204109) ReservoirPriceOracleTest:testUpdateRewardGasAmount() (gas: 19033) ReservoirPriceOracleTest:testUpdateRewardGasAmount_NotOwner() (gas: 10984) -ReservoirPriceOracleTest:testUpdateTwapPeriod(uint256) (runs: 256, μ: 21743, ~: 21828) -ReservoirPriceOracleTest:testUpdateTwapPeriod_InvalidTwapPeriod(uint256) (runs: 256, μ: 17863, ~: 18164) -ReservoirPriceOracleTest:testWritePriceCache(uint256) (runs: 256, μ: 29936, ~: 29697) +ReservoirPriceOracleTest:testUpdateTwapPeriod(uint256) (runs: 256, μ: 21745, ~: 21828) +ReservoirPriceOracleTest:testUpdateTwapPeriod_InvalidTwapPeriod(uint256) (runs: 256, μ: 17861, ~: 18164) +ReservoirPriceOracleTest:testWritePriceCache(uint256) (runs: 256, μ: 29939, ~: 29697) +RoutesLibTest:testGetDecimalDifference() (gas: 3974) +RoutesLibTest:testIsCompositeRoute() (gas: 4341) +RoutesLibTest:testPackSimplePrice(int8,uint256) (runs: 256, μ: 7786, ~: 7555) SamplesTest:testAccumulator() (gas: 3959) SamplesTest:testAccumulator_BadVariableRequest() (gas: 3523) SamplesTest:testInstant() (gas: 3909) diff --git a/src/ReservoirPriceOracle.sol b/src/ReservoirPriceOracle.sol index 90256be..5e9fe8d 100644 --- a/src/ReservoirPriceOracle.sol +++ b/src/ReservoirPriceOracle.sol @@ -18,12 +18,12 @@ import { ReentrancyGuard } from "lib/amm-core/lib/solmate/src/utils/ReentrancyGu import { FixedPointMathLib } from "lib/amm-core/lib/solady/src/utils/FixedPointMathLib.sol"; import { LibSort } from "lib/solady/src/utils/LibSort.sol"; import { Constants } from "src/libraries/Constants.sol"; -import { FlagsLib } from "src/libraries/FlagsLib.sol"; +import { RoutesLib } from "src/libraries/RoutesLib.sol"; contract ReservoirPriceOracle is IPriceOracle, IReservoirPriceOracle, Owned(msg.sender), ReentrancyGuard { using FixedPointMathLib for uint256; using LibSort for address[]; - using FlagsLib for *; + using RoutesLib for bytes32; using QueryProcessor for ReservoirPair; /////////////////////////////////////////////////////////////////////////////////////////////// @@ -192,10 +192,14 @@ contract ReservoirPriceOracle is IPriceOracle, IReservoirPriceOracle, Owned(msg. // INTERNAL FUNCTIONS // /////////////////////////////////////////////////////////////////////////////////////////////// - function _validatePair(ReservoirPair aPair) internal pure { + function _validatePair(ReservoirPair aPair) private pure { if (address(aPair) == address(0)) revert OracleErrors.NoDesignatedPair(); } + function _validateTokens(address aToken0, address aToken1) private pure { + if (aToken1 <= aToken0) revert OracleErrors.InvalidTokensProvided(); + } + function _getTimeWeightedAverageSingle(OracleAverageQuery memory aQuery) internal view returns (uint256 rResult) { ReservoirPair lPair = pairs[aQuery.base][aQuery.quote]; _validatePair(lPair); @@ -248,20 +252,18 @@ contract ReservoirPriceOracle is IPriceOracle, IReservoirPriceOracle, Owned(msg. view returns (address[] memory rRoute, int256 rDecimalDiff, uint256 rPrice) { - address[] memory lResults = new address[](Constants.MAX_ROUTE_LENGTH); bytes32 lSlot = Utils.calculateSlot(aToken0, aToken1); bytes32 lFirstWord; - uint256 lRouteLength; assembly { lFirstWord := sload(lSlot) } // simple route if (lFirstWord.isSimplePrice()) { - lResults[0] = aToken0; - lResults[1] = aToken1; - lRouteLength = 2; + rRoute = new address[](2); + rRoute[0] = aToken0; + rRoute[1] = aToken1; rDecimalDiff = lFirstWord.getDecimalDifference(); rPrice = lFirstWord.getPrice(); } @@ -269,50 +271,46 @@ contract ReservoirPriceOracle is IPriceOracle, IReservoirPriceOracle, Owned(msg. else if (lFirstWord.isCompositeRoute()) { address lSecondToken = lFirstWord.getTokenFirstWord(); - lResults[0] = aToken0; - lResults[1] = lSecondToken; - - if (lFirstWord.is3HopRoute()) { + if (lFirstWord.is2HopRoute()) { + rRoute = new address[](3); + rRoute[2] = aToken1; + } else { + assert(lFirstWord.is3HopRoute()); bytes32 lSecondWord; assembly { lSecondWord := sload(add(lSlot, 1)) } address lThirdToken = lSecondWord.getThirdToken(); - lResults[2] = lThirdToken; - lResults[3] = aToken1; - lRouteLength = 4; - } else { - lResults[2] = aToken1; - lRouteLength = 3; + rRoute = new address[](4); + rRoute[2] = lThirdToken; + rRoute[3] = aToken1; } + + rRoute[0] = aToken0; + rRoute[1] = lSecondToken; } // no route - // solhint-disable-next-line no-empty-blocks - else if (lFirstWord.isUninitialized()) { } - - rRoute = new address[](lRouteLength); - for (uint256 i = 0; i < lRouteLength; ++i) { - rRoute[i] = lResults[i]; + else if (lFirstWord.isUninitialized()) { + rRoute = new address[](0); } } /// Calculate the storage slot for this intermediate segment and read it to see if there is an existing /// route. If there isn't an existing route, we write it as well. - /// @dev assumed that aToken0 and aToken1 are not necessarily sorted - function _checkAndPopulateIntermediateRoute(address aToken0, address aToken1) internal { - (address lLowerToken, address lHigherToken) = Utils.sortTokens(aToken0, aToken1); + function _checkAndPopulateIntermediateRoute(address aTokenA, address aTokenB) private { + (address lToken0, address lToken1) = Utils.sortTokens(aTokenA, aTokenB); - bytes32 lSlot = Utils.calculateSlot(lLowerToken, lHigherToken); + bytes32 lSlot = Utils.calculateSlot(lToken0, lToken1); bytes32 lData; assembly { lData := sload(lSlot) } if (lData == bytes32(0)) { address[] memory lIntermediateRoute = new address[](2); - lIntermediateRoute[0] = lLowerToken; - lIntermediateRoute[1] = lHigherToken; - setRoute(lLowerToken, lHigherToken, lIntermediateRoute); + lIntermediateRoute[0] = lToken0; + lIntermediateRoute[1] = lToken1; + setRoute(lToken0, lToken1, lIntermediateRoute); } } @@ -346,7 +344,7 @@ contract ReservoirPriceOracle is IPriceOracle, IReservoirPriceOracle, Owned(msg. int256 lDiff = lData.getDecimalDifference(); - lData = lDiff.packSimplePrice(aNewPrice); + lData = RoutesLib.packSimplePrice(lDiff, aNewPrice); assembly { sstore(lSlot, lData) } @@ -498,8 +496,7 @@ contract ReservoirPriceOracle is IPriceOracle, IReservoirPriceOracle, Owned(msg. function setRoute(address aToken0, address aToken1, address[] memory aRoute) public onlyOwner { uint256 lRouteLength = aRoute.length; - if (aToken0 == aToken1) revert OracleErrors.SameToken(); - if (aToken1 < aToken0) revert OracleErrors.TokensUnsorted(); + _validateTokens(aToken0, aToken1); if (lRouteLength > Constants.MAX_ROUTE_LENGTH || lRouteLength < 2) revert OracleErrors.InvalidRouteLength(); if (aRoute[0] != aToken0 || aRoute[lRouteLength - 1] != aToken1) revert OracleErrors.InvalidRoute(); @@ -513,7 +510,7 @@ contract ReservoirPriceOracle is IPriceOracle, IReservoirPriceOracle, Owned(msg. int256 lDiff = int256(lToken1Decimals) - int256(lToken0Decimals); - bytes32 lData = lDiff.packSimplePrice(0); + bytes32 lData = RoutesLib.packSimplePrice(lDiff, 0); assembly { // Write data to storage. sstore(lSlot, lData) @@ -525,12 +522,12 @@ contract ReservoirPriceOracle is IPriceOracle, IReservoirPriceOracle, Owned(msg. address lThirdToken = aRoute[2]; if (lRouteLength == 3) { - bytes32 lData = lSecondToken.pack2HopRoute(); + bytes32 lData = RoutesLib.pack2HopRoute(lSecondToken); assembly { sstore(lSlot, lData) } } else if (lRouteLength == 4) { - (bytes32 lFirstWord, bytes32 lSecondWord) = lSecondToken.pack3HopRoute(lThirdToken); + (bytes32 lFirstWord, bytes32 lSecondWord) = RoutesLib.pack3HopRoute(lSecondToken, lThirdToken); // Write two words to storage. assembly { @@ -546,8 +543,7 @@ contract ReservoirPriceOracle is IPriceOracle, IReservoirPriceOracle, Owned(msg. } function clearRoute(address aToken0, address aToken1) external onlyOwner { - if (aToken0 == aToken1) revert OracleErrors.SameToken(); - if (aToken1 < aToken0) revert OracleErrors.TokensUnsorted(); + _validateTokens(aToken0, aToken1); (address[] memory lRoute,,) = _getRouteDecimalDifferencePrice(aToken0, aToken1); diff --git a/src/libraries/OracleErrors.sol b/src/libraries/OracleErrors.sol index 3a70260..310f313 100644 --- a/src/libraries/OracleErrors.sol +++ b/src/libraries/OracleErrors.sol @@ -7,11 +7,10 @@ library OracleErrors { error IncorrectTokensDesignatePair(); error InvalidRoute(); error InvalidRouteLength(); + error InvalidTokensProvided(); error InvalidTwapPeriod(); error NoDesignatedPair(); error PriceDeviationThresholdTooHigh(); - error SameToken(); - error TokensUnsorted(); error UnsupportedTokenDecimals(); // query errors diff --git a/src/libraries/FlagsLib.sol b/src/libraries/RoutesLib.sol similarity index 94% rename from src/libraries/FlagsLib.sol rename to src/libraries/RoutesLib.sol index 3d7ad57..72b4a83 100644 --- a/src/libraries/FlagsLib.sol +++ b/src/libraries/RoutesLib.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; -library FlagsLib { +library RoutesLib { bytes32 public constant FLAG_UNINITIALIZED = bytes32(hex"00"); bytes32 public constant FLAG_SIMPLE_PRICE = bytes32(hex"01"); bytes32 public constant FLAG_2_HOP_ROUTE = bytes32(hex"02"); @@ -19,6 +19,10 @@ library FlagsLib { return aData[0] & hex"02" > 0; } + function is2HopRoute(bytes32 aData) internal pure returns (bool) { + return aData[0] == FLAG_2_HOP_ROUTE; + } + function is3HopRoute(bytes32 aData) internal pure returns (bool) { return aData[0] == FLAG_3_HOP_ROUTE; } diff --git a/test/unit/ReservoirPriceOracle.t.sol b/test/unit/ReservoirPriceOracle.t.sol index 00fa54d..6082106 100644 --- a/test/unit/ReservoirPriceOracle.t.sol +++ b/test/unit/ReservoirPriceOracle.t.sol @@ -13,7 +13,7 @@ import { ReservoirPriceOracle, IERC20, IPriceOracle, - FlagsLib + RoutesLib } from "src/ReservoirPriceOracle.sol"; import { Bytes32Lib } from "amm-core/libraries/Bytes32.sol"; import { EnumerableSetLib } from "lib/solady/src/utils/EnumerableSetLib.sol"; @@ -23,7 +23,7 @@ import { StubERC4626 } from "test/mock/StubERC4626.sol"; contract ReservoirPriceOracleTest is BaseTest { using Utils for *; - using FlagsLib for *; + using RoutesLib for *; using Bytes32Lib for *; using EnumerableSetLib for EnumerableSetLib.AddressSet; using FixedPointMathLib for uint256; @@ -941,7 +941,7 @@ contract ReservoirPriceOracleTest is BaseTest { lRoute[1] = lToken1; // act & assert - vm.expectRevert(OracleErrors.SameToken.selector); + vm.expectRevert(OracleErrors.InvalidTokensProvided.selector); _oracle.setRoute(lToken0, lToken1, lRoute); } @@ -954,7 +954,7 @@ contract ReservoirPriceOracleTest is BaseTest { lRoute[1] = lToken1; // act & assert - vm.expectRevert(OracleErrors.TokensUnsorted.selector); + vm.expectRevert(OracleErrors.InvalidTokensProvided.selector); _oracle.setRoute(lToken0, lToken1, lRoute); } diff --git a/test/unit/libraries/FlagsLib.t.sol b/test/unit/libraries/RoutesLib.t.sol similarity index 72% rename from test/unit/libraries/FlagsLib.t.sol rename to test/unit/libraries/RoutesLib.t.sol index e2f1021..3b1db8d 100644 --- a/test/unit/libraries/FlagsLib.t.sol +++ b/test/unit/libraries/RoutesLib.t.sol @@ -3,18 +3,18 @@ pragma solidity ^0.8.0; import { Test, console2, stdError } from "forge-std/Test.sol"; -import { FlagsLib } from "src/libraries/FlagsLib.sol"; +import { RoutesLib } from "src/libraries/RoutesLib.sol"; -contract FlagsLibTest is Test { - using FlagsLib for bytes32; - using FlagsLib for int256; +contract RoutesLibTest is Test { + using RoutesLib for bytes32; + using RoutesLib for int256; function testIsCompositeRoute() external pure { // arrange - bytes32 lUninitialized = FlagsLib.FLAG_UNINITIALIZED; - bytes32 l1HopRoute = FlagsLib.FLAG_SIMPLE_PRICE; - bytes32 l2HopRoute = FlagsLib.FLAG_2_HOP_ROUTE; - bytes32 l3HopRoute = FlagsLib.FLAG_3_HOP_ROUTE; + bytes32 lUninitialized = RoutesLib.FLAG_UNINITIALIZED; + bytes32 l1HopRoute = RoutesLib.FLAG_SIMPLE_PRICE; + bytes32 l2HopRoute = RoutesLib.FLAG_2_HOP_ROUTE; + bytes32 l3HopRoute = RoutesLib.FLAG_3_HOP_ROUTE; // act & assert assertTrue(l2HopRoute.isCompositeRoute()); @@ -43,7 +43,7 @@ contract FlagsLibTest is Test { bytes32 lResult = int256(aDiff).packSimplePrice(lPrice); // assert - assertEq(lResult[0], FlagsLib.FLAG_SIMPLE_PRICE); + assertEq(lResult[0], RoutesLib.FLAG_SIMPLE_PRICE); assertEq(lResult[1], bytes1(uint8(aDiff))); assertEq(lResult.getPrice(), lPrice); }