diff --git a/.forge-snapshots/positionDescriptor bytecode size.snap b/.forge-snapshots/positionDescriptor bytecode size.snap deleted file mode 100644 index 6f097d73..00000000 --- a/.forge-snapshots/positionDescriptor bytecode size.snap +++ /dev/null @@ -1 +0,0 @@ -31619 \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 9d6618d5..fb9fdc7d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "lib/permit2"] path = lib/permit2 url = https://github.com/Uniswap/permit2 +[submodule "lib/forge-gas-snapshot"] + path = lib/forge-gas-snapshot + url = https://github.com/marktoda/forge-gas-snapshot diff --git a/lib/forge-gas-snapshot b/lib/forge-gas-snapshot new file mode 160000 index 00000000..9fc447c7 --- /dev/null +++ b/lib/forge-gas-snapshot @@ -0,0 +1 @@ +Subproject commit 9fc447c732c89b6dd6352c096042d8d82b44faed diff --git a/lib/v4-core b/lib/v4-core index 3afa83a0..0a849b18 160000 --- a/lib/v4-core +++ b/lib/v4-core @@ -1 +1 @@ -Subproject commit 3afa83a0e3790edb0d6d9e2289555f8e1dce211e +Subproject commit 0a849b1810210bc523da73399d6ed8e4480fd3f5 diff --git a/script/01_PoolManager.s.sol b/script/01_PoolManager.s.sol index e412add9..5d4c5b14 100644 --- a/script/01_PoolManager.s.sol +++ b/script/01_PoolManager.s.sol @@ -13,7 +13,7 @@ contract DeployPoolManager is Script { function run() public returns (IPoolManager manager) { vm.startBroadcast(); - manager = new PoolManager(); + manager = new PoolManager(address(this)); console2.log("PoolManager", address(manager)); vm.stopBroadcast(); diff --git a/snapshots/BaseActionsRouterTest.json b/snapshots/BaseActionsRouterTest.json index ce832601..c423f483 100644 --- a/snapshots/BaseActionsRouterTest.json +++ b/snapshots/BaseActionsRouterTest.json @@ -1,3 +1,3 @@ { - "BaseActionsRouter_mock10commands": "60677" + "BaseActionsRouter_mock10commands": "60674" } \ No newline at end of file diff --git a/snapshots/PaymentsTests.json b/snapshots/PaymentsTests.json index e8fdbdeb..8bd8b1d0 100644 --- a/snapshots/PaymentsTests.json +++ b/snapshots/PaymentsTests.json @@ -1,6 +1,6 @@ { - "Payments_swap_settleFromCaller_takeAllToMsgSender": "129642", - "Payments_swap_settleFromCaller_takeAllToSpecifiedAddress": "131705", - "Payments_swap_settleWithBalance_takeAllToMsgSender": "123910", - "Payments_swap_settleWithBalance_takeAllToSpecifiedAddress": "124052" + "Payments_swap_settleFromCaller_takeAllToMsgSender": "129438", + "Payments_swap_settleFromCaller_takeAllToSpecifiedAddress": "131502", + "Payments_swap_settleWithBalance_takeAllToMsgSender": "123707", + "Payments_swap_settleWithBalance_takeAllToSpecifiedAddress": "123849" } \ No newline at end of file diff --git a/snapshots/PosMGasTest.json b/snapshots/PosMGasTest.json index e3d6088c..38ce6e78 100644 --- a/snapshots/PosMGasTest.json +++ b/snapshots/PosMGasTest.json @@ -1,41 +1,41 @@ { - "PositionManager_burn_empty": "50481", - "PositionManager_burn_empty_native": "50481", - "PositionManager_burn_nonEmpty_native_withClose": "125659", - "PositionManager_burn_nonEmpty_native_withTakePair": "125141", - "PositionManager_burn_nonEmpty_withClose": "132521", - "PositionManager_burn_nonEmpty_withTakePair": "132004", - "PositionManager_collect_native": "146388", - "PositionManager_collect_sameRange": "154966", - "PositionManager_collect_withClose": "154966", - "PositionManager_collect_withTakePair": "154331", - "PositionManager_decreaseLiquidity_native": "112056", - "PositionManager_decreaseLiquidity_withClose": "119847", - "PositionManager_decreaseLiquidity_withTakePair": "119212", - "PositionManager_decrease_burnEmpty": "135318", - "PositionManager_decrease_burnEmpty_native": "128456", - "PositionManager_decrease_sameRange_allLiquidity": "132534", - "PositionManager_decrease_take_take": "120467", - "PositionManager_increaseLiquidity_erc20_withClose": "159127", - "PositionManager_increaseLiquidity_erc20_withSettlePair": "158079", - "PositionManager_increaseLiquidity_native": "140942", - "PositionManager_increase_autocompoundExactUnclaimedFees": "136403", - "PositionManager_increase_autocompoundExcessFeesCredit": "177458", - "PositionManager_increase_autocompound_clearExcess": "148084", - "PositionManager_mint_native": "364815", - "PositionManager_mint_nativeWithSweep_withClose": "373334", - "PositionManager_mint_nativeWithSweep_withSettlePair": "372569", - "PositionManager_mint_onSameTickLower": "317687", - "PositionManager_mint_onSameTickUpper": "318357", - "PositionManager_mint_sameRange": "243926", - "PositionManager_mint_settleWithBalance_sweep": "419134", - "PositionManager_mint_warmedPool_differentRange": "323718", - "PositionManager_mint_withClose": "420240", - "PositionManager_mint_withSettlePair": "419310", - "PositionManager_multicall_initialize_mint": "456088", + "PositionManager_burn_empty": "50479", + "PositionManager_burn_empty_native": "50479", + "PositionManager_burn_nonEmpty_native_withClose": "125652", + "PositionManager_burn_nonEmpty_native_withTakePair": "125134", + "PositionManager_burn_nonEmpty_withClose": "132512", + "PositionManager_burn_nonEmpty_withTakePair": "131994", + "PositionManager_collect_native": "146379", + "PositionManager_collect_sameRange": "154954", + "PositionManager_collect_withClose": "154954", + "PositionManager_collect_withTakePair": "154319", + "PositionManager_decreaseLiquidity_native": "112048", + "PositionManager_decreaseLiquidity_withClose": "119835", + "PositionManager_decreaseLiquidity_withTakePair": "119200", + "PositionManager_decrease_burnEmpty": "135308", + "PositionManager_decrease_burnEmpty_native": "128448", + "PositionManager_decrease_sameRange_allLiquidity": "132522", + "PositionManager_decrease_take_take": "120455", + "PositionManager_increaseLiquidity_erc20_withClose": "158871", + "PositionManager_increaseLiquidity_erc20_withSettlePair": "157823", + "PositionManager_increaseLiquidity_native": "140808", + "PositionManager_increase_autocompoundExactUnclaimedFees": "136396", + "PositionManager_increase_autocompoundExcessFeesCredit": "177446", + "PositionManager_increase_autocompound_clearExcess": "148160", + "PositionManager_mint_native": "364681", + "PositionManager_mint_nativeWithSweep_withClose": "373199", + "PositionManager_mint_nativeWithSweep_withSettlePair": "372435", + "PositionManager_mint_onSameTickLower": "317431", + "PositionManager_mint_onSameTickUpper": "318101", + "PositionManager_mint_sameRange": "243670", + "PositionManager_mint_settleWithBalance_sweep": "418878", + "PositionManager_mint_warmedPool_differentRange": "323462", + "PositionManager_mint_withClose": "419984", + "PositionManager_mint_withSettlePair": "419054", + "PositionManager_multicall_initialize_mint": "455828", "PositionManager_permit": "79076", "PositionManager_permit_secondPosition": "61976", - "PositionManager_permit_twice": "44876", + "PositionManager_permit_twice": "44852", "PositionManager_subscribe": "88168", "PositionManager_unsubscribe": "63080" } \ No newline at end of file diff --git a/snapshots/PositionDescriptorTest.json b/snapshots/PositionDescriptorTest.json index 243553c8..043f425d 100644 --- a/snapshots/PositionDescriptorTest.json +++ b/snapshots/PositionDescriptorTest.json @@ -1,3 +1,3 @@ { - "positionDescriptor bytecode size": "31443" + "positionDescriptor bytecode size": "31728" } \ No newline at end of file diff --git a/snapshots/QuoterTest.json b/snapshots/QuoterTest.json index 53525acd..201b5cce 100644 --- a/snapshots/QuoterTest.json +++ b/snapshots/QuoterTest.json @@ -1,15 +1,15 @@ { - "Quoter_exactInputSingle_oneForZero_multiplePositions": "143930", - "Quoter_exactInputSingle_zeroForOne_multiplePositions": "149382", - "Quoter_exactOutputSingle_oneForZero": "78203", - "Quoter_exactOutputSingle_zeroForOne": "82626", - "Quoter_quoteExactInput_oneHop_1TickLoaded": "120491", - "Quoter_quoteExactInput_oneHop_initializedAfter": "145414", - "Quoter_quoteExactInput_oneHop_startingInitialized": "79437", - "Quoter_quoteExactInput_twoHops": "201179", - "Quoter_quoteExactOutput_oneHop_1TickLoaded": "119782", - "Quoter_quoteExactOutput_oneHop_2TicksLoaded": "149919", - "Quoter_quoteExactOutput_oneHop_initializedAfter": "119850", - "Quoter_quoteExactOutput_oneHop_startingInitialized": "96549", - "Quoter_quoteExactOutput_twoHops": "200630" + "Quoter_exactInputSingle_oneForZero_multiplePositions": "144020", + "Quoter_exactInputSingle_zeroForOne_multiplePositions": "149287", + "Quoter_exactOutputSingle_oneForZero": "78196", + "Quoter_exactOutputSingle_zeroForOne": "82546", + "Quoter_quoteExactInput_oneHop_1TickLoaded": "120406", + "Quoter_quoteExactInput_oneHop_initializedAfter": "145504", + "Quoter_quoteExactInput_oneHop_startingInitialized": "79438", + "Quoter_quoteExactInput_twoHops": "201071", + "Quoter_quoteExactOutput_oneHop_1TickLoaded": "119672", + "Quoter_quoteExactOutput_oneHop_2TicksLoaded": "149779", + "Quoter_quoteExactOutput_oneHop_initializedAfter": "119740", + "Quoter_quoteExactOutput_oneHop_startingInitialized": "96472", + "Quoter_quoteExactOutput_twoHops": "200486" } \ No newline at end of file diff --git a/snapshots/StateViewTest.json b/snapshots/StateViewTest.json index 15054496..7c7b10d2 100644 --- a/snapshots/StateViewTest.json +++ b/snapshots/StateViewTest.json @@ -1,12 +1,12 @@ { - "StateView_extsload_getFeeGrowthGlobals": "2259", - "StateView_extsload_getFeeGrowthInside": "8003", + "StateView_extsload_getFeeGrowthGlobals": "2256", + "StateView_extsload_getFeeGrowthInside": "7994", "StateView_extsload_getLiquidity": "1399", - "StateView_extsload_getPositionInfo": "2829", + "StateView_extsload_getPositionInfo": "2826", "StateView_extsload_getPositionLiquidity": "1651", "StateView_extsload_getSlot0": "1446", "StateView_extsload_getTickBitmap": "1392", - "StateView_extsload_getTickFeeGrowthOutside": "2546", - "StateView_extsload_getTickInfo": "2761", + "StateView_extsload_getTickFeeGrowthOutside": "2543", + "StateView_extsload_getTickInfo": "2758", "StateView_extsload_getTickLiquidity": "1646" } \ No newline at end of file diff --git a/snapshots/V4RouterTest.json b/snapshots/V4RouterTest.json index f229dbf0..839beea8 100644 --- a/snapshots/V4RouterTest.json +++ b/snapshots/V4RouterTest.json @@ -1,26 +1,26 @@ { - "V4Router_Bytecode": "7063", - "V4Router_ExactIn1Hop_nativeIn": "115753", - "V4Router_ExactIn1Hop_nativeOut": "116070", - "V4Router_ExactIn1Hop_oneForZero": "124888", - "V4Router_ExactIn1Hop_zeroForOne": "130611", - "V4Router_ExactIn2Hops": "185452", - "V4Router_ExactIn2Hops_nativeIn": "170594", - "V4Router_ExactIn3Hops": "240296", - "V4Router_ExactIn3Hops_nativeIn": "225438", - "V4Router_ExactInputSingle": "129642", - "V4Router_ExactInputSingle_nativeIn": "114784", - "V4Router_ExactInputSingle_nativeOut": "115069", - "V4Router_ExactOut1Hop_nativeIn_sweepETH": "122016", - "V4Router_ExactOut1Hop_nativeOut": "117134", - "V4Router_ExactOut1Hop_oneForZero": "125952", - "V4Router_ExactOut1Hop_zeroForOne": "129897", - "V4Router_ExactOut2Hops": "183800", - "V4Router_ExactOut2Hops_nativeIn": "175919", - "V4Router_ExactOut3Hops": "237734", - "V4Router_ExactOut3Hops_nativeIn": "229853", - "V4Router_ExactOut3Hops_nativeOut": "217089", - "V4Router_ExactOutputSingle": "128925", - "V4Router_ExactOutputSingle_nativeIn_sweepETH": "121044", - "V4Router_ExactOutputSingle_nativeOut": "116236" + "V4Router_Bytecode": "7158", + "V4Router_ExactIn1Hop_nativeIn": "115672", + "V4Router_ExactIn1Hop_nativeOut": "115929", + "V4Router_ExactIn1Hop_oneForZero": "124744", + "V4Router_ExactIn1Hop_zeroForOne": "130408", + "V4Router_ExactIn2Hops": "185177", + "V4Router_ExactIn2Hops_nativeIn": "170441", + "V4Router_ExactIn3Hops": "239949", + "V4Router_ExactIn3Hops_nativeIn": "225213", + "V4Router_ExactInputSingle": "129438", + "V4Router_ExactInputSingle_nativeIn": "114702", + "V4Router_ExactInputSingle_nativeOut": "114927", + "V4Router_ExactOut1Hop_nativeIn_sweepETH": "121930", + "V4Router_ExactOut1Hop_nativeOut": "117002", + "V4Router_ExactOut1Hop_oneForZero": "125817", + "V4Router_ExactOut1Hop_zeroForOne": "129689", + "V4Router_ExactOut2Hops": "183515", + "V4Router_ExactOut2Hops_nativeIn": "175756", + "V4Router_ExactOut3Hops": "237372", + "V4Router_ExactOut3Hops_nativeIn": "229613", + "V4Router_ExactOut3Hops_nativeOut": "216949", + "V4Router_ExactOutputSingle": "128716", + "V4Router_ExactOutputSingle_nativeIn_sweepETH": "120957", + "V4Router_ExactOutputSingle_nativeOut": "116103" } \ No newline at end of file diff --git a/src/PositionDescriptor.sol b/src/PositionDescriptor.sol index 7cf39d94..7f1ac799 100644 --- a/src/PositionDescriptor.sol +++ b/src/PositionDescriptor.sol @@ -54,14 +54,17 @@ contract PositionDescriptor is IPositionDescriptor { } (, int24 tick,,) = poolManager.getSlot0(poolKey.toId()); + address currency0 = Currency.unwrap(poolKey.currency0); + address currency1 = Currency.unwrap(poolKey.currency1); + // If possible, flip currencies to get the larger currency as the base currency, so that the price (quote/base) is more readable // flip if currency0 priority is greater than currency1 priority - bool _flipRatio = flipRatio(Currency.unwrap(poolKey.currency0), Currency.unwrap(poolKey.currency1)); + bool _flipRatio = flipRatio(currency0, currency1); // If not flipped, quote currency is currency1, base currency is currency0 // If flipped, quote currency is currency0, base currency is currency1 - Currency quoteCurrency = !_flipRatio ? poolKey.currency1 : poolKey.currency0; - Currency baseCurrency = !_flipRatio ? poolKey.currency0 : poolKey.currency1; + address quoteCurrency = !_flipRatio ? currency1 : currency0; + address baseCurrency = !_flipRatio ? currency0 : currency1; return Descriptor.constructTokenURI( Descriptor.ConstructTokenURIParams({ diff --git a/src/base/Notifier.sol b/src/base/Notifier.sol index 2965e574..8f6b3f02 100644 --- a/src/base/Notifier.sol +++ b/src/base/Notifier.sol @@ -9,7 +9,7 @@ import {PositionInfo} from "../libraries/PositionInfoLibrary.sol"; /// @notice Notifier is used to opt in to sending updates to external contracts about position modifications or transfers abstract contract Notifier is INotifier { - using CustomRevert for bytes4; + using CustomRevert for *; ISubscriber private constant NO_SUBSCRIBER = ISubscriber(address(0)); @@ -53,7 +53,7 @@ abstract contract Notifier is INotifier { bool success = _call(newSubscriber, abi.encodeCall(ISubscriber.notifySubscribe, (tokenId, data))); if (!success) { - Wrap__SubscriptionReverted.selector.bubbleUpAndRevertWith(newSubscriber); + newSubscriber.bubbleUpAndRevertWith(ISubscriber.notifySubscribe.selector, SubscriptionReverted.selector); } emit Subscription(tokenId, newSubscriber); @@ -97,7 +97,9 @@ abstract contract Notifier is INotifier { ); if (!success) { - Wrap__ModifyLiquidityNotificationReverted.selector.bubbleUpAndRevertWith(address(_subscriber)); + address(_subscriber).bubbleUpAndRevertWith( + ISubscriber.notifyModifyLiquidity.selector, ModifyLiquidityNotificationReverted.selector + ); } } @@ -108,7 +110,9 @@ abstract contract Notifier is INotifier { _call(address(_subscriber), abi.encodeCall(ISubscriber.notifyTransfer, (tokenId, previousOwner, newOwner))); if (!success) { - Wrap__TransferNotificationReverted.selector.bubbleUpAndRevertWith(address(_subscriber)); + address(_subscriber).bubbleUpAndRevertWith( + ISubscriber.notifyTransfer.selector, TransferNotificationReverted.selector + ); } } diff --git a/src/interfaces/INotifier.sol b/src/interfaces/INotifier.sol index 3eefba3c..abf6148c 100644 --- a/src/interfaces/INotifier.sol +++ b/src/interfaces/INotifier.sol @@ -12,11 +12,11 @@ interface INotifier { /// @notice Thrown when a user specifies a gas limit too low to avoid valid unsubscribe notifications error GasLimitTooLow(); /// @notice Wraps the revert message of the subscriber contract on a reverting subscription - error Wrap__SubscriptionReverted(address subscriber, bytes reason); + error SubscriptionReverted(address subscriber, bytes reason); /// @notice Wraps the revert message of the subscriber contract on a reverting modify liquidity notification - error Wrap__ModifyLiquidityNotificationReverted(address subscriber, bytes reason); + error ModifyLiquidityNotificationReverted(address subscriber, bytes reason); /// @notice Wraps the revert message of the subscriber contract on a reverting transfer notification - error Wrap__TransferNotificationReverted(address subscriber, bytes reason); + error TransferNotificationReverted(address subscriber, bytes reason); /// @notice Thrown when a tokenId already has a subscriber error AlreadySubscribed(uint256 tokenId, address subscriber); diff --git a/src/libraries/Descriptor.sol b/src/libraries/Descriptor.sol index b3d5ef29..ba261f85 100644 --- a/src/libraries/Descriptor.sol +++ b/src/libraries/Descriptor.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; -import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; import {FullMath} from "@uniswap/v4-core/src/libraries/FullMath.sol"; import {LPFeeLibrary} from "@uniswap/v4-core/src/libraries/LPFeeLibrary.sol"; @@ -23,8 +22,8 @@ library Descriptor { struct ConstructTokenURIParams { uint256 tokenId; - Currency quoteCurrency; - Currency baseCurrency; + address quoteCurrency; + address baseCurrency; string quoteCurrencySymbol; string baseCurrencySymbol; uint8 quoteCurrencyDecimals; @@ -52,8 +51,8 @@ library Descriptor { string memory descriptionPartTwo = generateDescriptionPartTwo( params.tokenId.toString(), escapeSpecialCharacters(params.baseCurrencySymbol), - addressToString(Currency.unwrap(params.quoteCurrency)), - addressToString(Currency.unwrap(params.baseCurrency)), + params.quoteCurrency == address(0) ? "Native" : addressToString(params.quoteCurrency), + params.baseCurrency == address(0) ? "Native" : addressToString(params.baseCurrency), params.hooks == address(0) ? "No Hook" : addressToString(params.hooks), feeToPercentString(params.fee) ); @@ -462,8 +461,8 @@ library Descriptor { /// @return svg The SVG image as a string function generateSVGImage(ConstructTokenURIParams memory params) internal pure returns (string memory svg) { SVG.SVGParams memory svgParams = SVG.SVGParams({ - quoteCurrency: addressToString(Currency.unwrap(params.quoteCurrency)), - baseCurrency: addressToString(Currency.unwrap(params.baseCurrency)), + quoteCurrency: addressToString(params.quoteCurrency), + baseCurrency: addressToString(params.baseCurrency), hooks: params.hooks, quoteCurrencySymbol: params.quoteCurrencySymbol, baseCurrencySymbol: params.baseCurrencySymbol, @@ -473,16 +472,16 @@ library Descriptor { tickSpacing: params.tickSpacing, overRange: overRange(params.tickLower, params.tickUpper, params.tickCurrent), tokenId: params.tokenId, - color0: currencyToColorHex(params.quoteCurrency.toId(), 136), - color1: currencyToColorHex(params.baseCurrency.toId(), 136), - color2: currencyToColorHex(params.quoteCurrency.toId(), 0), - color3: currencyToColorHex(params.baseCurrency.toId(), 0), - x1: scale(getCircleCoord(params.quoteCurrency.toId(), 16, params.tokenId), 0, 255, 16, 274), - y1: scale(getCircleCoord(params.baseCurrency.toId(), 16, params.tokenId), 0, 255, 100, 484), - x2: scale(getCircleCoord(params.quoteCurrency.toId(), 32, params.tokenId), 0, 255, 16, 274), - y2: scale(getCircleCoord(params.baseCurrency.toId(), 32, params.tokenId), 0, 255, 100, 484), - x3: scale(getCircleCoord(params.quoteCurrency.toId(), 48, params.tokenId), 0, 255, 16, 274), - y3: scale(getCircleCoord(params.baseCurrency.toId(), 48, params.tokenId), 0, 255, 100, 484) + color0: currencyToColorHex(uint256(uint160(params.quoteCurrency)), 136), + color1: currencyToColorHex(uint256(uint160(params.baseCurrency)), 136), + color2: currencyToColorHex(uint256(uint160(params.quoteCurrency)), 0), + color3: currencyToColorHex(uint256(uint160(params.baseCurrency)), 0), + x1: scale(getCircleCoord(uint256(uint160(params.quoteCurrency)), 16, params.tokenId), 0, 255, 16, 274), + y1: scale(getCircleCoord(uint256(uint160(params.baseCurrency)), 16, params.tokenId), 0, 255, 100, 484), + x2: scale(getCircleCoord(uint256(uint160(params.quoteCurrency)), 32, params.tokenId), 0, 255, 16, 274), + y2: scale(getCircleCoord(uint256(uint160(params.baseCurrency)), 32, params.tokenId), 0, 255, 100, 484), + x3: scale(getCircleCoord(uint256(uint160(params.quoteCurrency)), 48, params.tokenId), 0, 255, 16, 274), + y3: scale(getCircleCoord(uint256(uint160(params.baseCurrency)), 48, params.tokenId), 0, 255, 100, 484) }); return SVG.generateSVG(svgParams); diff --git a/src/libraries/SVG.sol b/src/libraries/SVG.sol index 90733ddc..2731a6ca 100644 --- a/src/libraries/SVG.sol +++ b/src/libraries/SVG.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; -import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; import {BitMath} from "@uniswap/v4-core/src/libraries/BitMath.sol"; import {Strings} from "openzeppelin-contracts/contracts/utils/Strings.sol"; diff --git a/src/libraries/SafeCurrencyMetadata.sol b/src/libraries/SafeCurrencyMetadata.sol index b220bf29..cc88ab84 100644 --- a/src/libraries/SafeCurrencyMetadata.sol +++ b/src/libraries/SafeCurrencyMetadata.sol @@ -2,30 +2,26 @@ pragma solidity ^0.8.0; import {IERC20Metadata} from "openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol"; -import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; import {AddressStringUtil} from "./AddressStringUtil.sol"; /// @title SafeCurrencyMetadata /// @notice can produce symbols and decimals from inconsistent or absent ERC20 implementations /// @dev Reference: https://github.com/Uniswap/solidity-lib/blob/master/contracts/libraries/SafeERC20Namer.sol library SafeCurrencyMetadata { - using CurrencyLibrary for Currency; - uint8 constant MAX_SYMBOL_LENGTH = 12; - /// @notice attempts to extract the token symbol. if it does not implement symbol, returns a symbol derived from the address - /// @param currency The currency + /// @notice attempts to extract the currency symbol. if it does not implement symbol, returns a symbol derived from the address + /// @param currency The currency address /// @param nativeLabel The native label - /// @return the token symbol - function currencySymbol(Currency currency, string memory nativeLabel) internal view returns (string memory) { - if (currency.isAddressZero()) { + /// @return the currency symbol + function currencySymbol(address currency, string memory nativeLabel) internal view returns (string memory) { + if (currency == address(0)) { return nativeLabel; } - address currencyAddress = Currency.unwrap(currency); - string memory symbol = callAndParseStringReturn(currencyAddress, IERC20Metadata.symbol.selector); + string memory symbol = callAndParseStringReturn(currency, IERC20Metadata.symbol.selector); if (bytes(symbol).length == 0) { // fallback to 6 uppercase hex of address - return addressToSymbol(currencyAddress); + return addressToSymbol(currency); } if (bytes(symbol).length > MAX_SYMBOL_LENGTH) { return truncateSymbol(symbol); @@ -34,14 +30,13 @@ library SafeCurrencyMetadata { } /// @notice attempts to extract the token decimals, returns 0 if not implemented or not a uint8 - /// @param currency The currency - /// @return the token decimals - function currencyDecimals(Currency currency) internal view returns (uint8) { - if (currency.isAddressZero()) { + /// @param currency The currency address + /// @return the currency decimals + function currencyDecimals(address currency) internal view returns (uint8) { + if (currency == address(0)) { return 18; } - (bool success, bytes memory data) = - Currency.unwrap(currency).staticcall(abi.encodeCall(IERC20Metadata.decimals, ())); + (bool success, bytes memory data) = currency.staticcall(abi.encodeCall(IERC20Metadata.decimals, ())); if (!success) { return 0; } diff --git a/test/PositionDescriptor.t.sol b/test/PositionDescriptor.t.sol index f3cd168d..c20465f0 100644 --- a/test/PositionDescriptor.t.sol +++ b/test/PositionDescriptor.t.sol @@ -11,9 +11,14 @@ import {PositionConfig} from "./shared/PositionConfig.sol"; import {PosmTestSetup} from "./shared/PosmTestSetup.sol"; import {ActionConstants} from "../src/libraries/ActionConstants.sol"; import {Base64} from "./base64.sol"; +import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; +import {SafeCurrencyMetadata} from "../src/libraries/SafeCurrencyMetadata.sol"; +import {AddressStringUtil} from "../src/libraries/AddressStringUtil.sol"; +import {Descriptor} from "../src/libraries/Descriptor.sol"; contract PositionDescriptorTest is Test, PosmTestSetup { using Base64 for string; + using CurrencyLibrary for Currency; address public WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; address public DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; @@ -118,10 +123,185 @@ contract PositionDescriptorTest is Test, PosmTestSetup { bytes memory data = vm.parseJson(json); Token memory token = abi.decode(data, (Token)); - assertEq(token.name, "Uniswap - 0.3% - TEST/TEST - 1.0060<>1.0121"); + // quote is currency1, base is currency0 + assertFalse(positionDescriptor.flipRatio(Currency.unwrap(key.currency0), Currency.unwrap(key.currency1))); + + string memory symbol0 = SafeCurrencyMetadata.currencySymbol(Currency.unwrap(currency0), nativeCurrencyLabel); + string memory symbol1 = SafeCurrencyMetadata.currencySymbol(Currency.unwrap(currency1), nativeCurrencyLabel); + string memory managerAddress = toHexString(address(manager)); + string memory currency0Address = toHexString(Currency.unwrap(currency0)); + string memory currency1Address = toHexString(Currency.unwrap(currency1)); + string memory id = uintToString(tokenId); + string memory hookAddress = address(key.hooks) == address(0) + ? "No Hook" + : string(abi.encodePacked("0x", toHexString(address(key.hooks)))); + string memory fee = Descriptor.feeToPercentString(key.fee); + string memory tickToDecimal0 = Descriptor.tickToDecimalString( + tickLower, + key.tickSpacing, + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency0)), + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency1)), + false + ); + string memory tickToDecimal1 = Descriptor.tickToDecimalString( + tickUpper, + key.tickSpacing, + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency0)), + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency1)), + false + ); + + assertEq( + token.name, + string( + abi.encodePacked( + "Uniswap - ", fee, " - ", symbol1, "/", symbol0, " - ", tickToDecimal0, "<>", tickToDecimal1 + ) + ) + ); + assertEq( + token.description, + string( + abi.encodePacked( + unicode"This NFT represents a liquidity position in a Uniswap v4 ", + symbol1, + "-", + symbol0, + " pool. The owner of this NFT can modify or redeem the position.\n\nPool Manager Address: ", + managerAddress, + "\n", + symbol1, + " Address: ", + currency1Address, + "\n", + symbol0, + " Address: ", + currency0Address, + "\nHook Address: ", + hookAddress, + "\nFee Tier: ", + fee, + "\nToken ID: ", + id, + "\n\n", + unicode"⚠️ DISCLAIMER: Due diligence is imperative when assessing this NFT. Make sure currency addresses match the expected currencies, as currency symbols may be imitated." + ) + ) + ); + } + + function test_native_tokenURI_succeeds() public { + (nativeKey,) = initPool(CurrencyLibrary.ADDRESS_ZERO, currency1, IHooks(address(0)), 3000, SQRT_PRICE_1_1); + int24 tickLower = int24(nativeKey.tickSpacing); + int24 tickUpper = int24(nativeKey.tickSpacing * 2); + uint256 amount0Desired = 100e18; + uint256 amount1Desired = 100e18; + uint256 liquidityToAdd = LiquidityAmounts.getLiquidityForAmounts( + SQRT_PRICE_1_1, + TickMath.getSqrtPriceAtTick(tickLower), + TickMath.getSqrtPriceAtTick(tickUpper), + amount0Desired, + amount1Desired + ); + + PositionConfig memory config = PositionConfig({poolKey: nativeKey, tickLower: tickLower, tickUpper: tickUpper}); + uint256 tokenId = lpm.nextTokenId(); + mintWithNative(SQRT_PRICE_1_1, config, liquidityToAdd, ActionConstants.MSG_SENDER, ZERO_BYTES); + + // The prefix length is calculated by converting the string to bytes and finding its length + uint256 prefixLength = bytes("data:application/json;base64,").length; + + string memory uri = positionDescriptor.tokenURI(lpm, tokenId); + // Convert the uri to bytes + bytes memory uriBytes = bytes(uri); + + // Slice the uri to get only the base64-encoded part + bytes memory base64Part = new bytes(uriBytes.length - prefixLength); + + for (uint256 i = 0; i < base64Part.length; i++) { + base64Part[i] = uriBytes[i + prefixLength]; + } + + // Decode the base64-encoded part + bytes memory decoded = Base64.decode(string(base64Part)); + string memory json = string(decoded); + + // decode json + bytes memory data = vm.parseJson(json); + Token memory token = abi.decode(data, (Token)); + + // quote is currency1, base is currency0 + assertFalse( + positionDescriptor.flipRatio(Currency.unwrap(nativeKey.currency0), Currency.unwrap(nativeKey.currency1)) + ); + + string memory symbol0 = + SafeCurrencyMetadata.currencySymbol(Currency.unwrap(nativeKey.currency0), nativeCurrencyLabel); + string memory symbol1 = + SafeCurrencyMetadata.currencySymbol(Currency.unwrap(nativeKey.currency1), nativeCurrencyLabel); + string memory managerAddress = toHexString(address(manager)); + string memory currency0Address = Currency.unwrap(nativeKey.currency0) == address(0) + ? "Native" + : toHexString(Currency.unwrap(nativeKey.currency0)); + string memory currency1Address = Currency.unwrap(nativeKey.currency1) == address(0) + ? "Native" + : toHexString(Currency.unwrap(nativeKey.currency1)); + string memory id = uintToString(tokenId); + string memory hookAddress = address(nativeKey.hooks) == address(0) + ? "No Hook" + : string(abi.encodePacked("0x", toHexString(address(nativeKey.hooks)))); + string memory fee = Descriptor.feeToPercentString(nativeKey.fee); + string memory tickToDecimal0 = Descriptor.tickToDecimalString( + tickLower, + nativeKey.tickSpacing, + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency0)), + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency1)), + false + ); + string memory tickToDecimal1 = Descriptor.tickToDecimalString( + tickUpper, + nativeKey.tickSpacing, + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency0)), + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency1)), + false + ); + + assertEq( + token.name, + string( + abi.encodePacked( + "Uniswap - ", fee, " - ", symbol1, "/", symbol0, " - ", tickToDecimal0, "<>", tickToDecimal1 + ) + ) + ); assertEq( token.description, - unicode"This NFT represents a liquidity position in a Uniswap v4 TEST-TEST pool. The owner of this NFT can modify or redeem the position.\n\nPool Manager Address: 0x2e234dae75c793f67a35089c9d99245e1c58470b\nTEST Address: 0xf62849f9a0b5bf2913b396098f7c7019b51a820a\nTEST Address: 0xc7183455a4c133ae270771860664b6b7ec320bb1\nHook Address: No Hook\nFee Tier: 0.3%\nToken ID: 1\n\n⚠️ DISCLAIMER: Due diligence is imperative when assessing this NFT. Make sure currency addresses match the expected currencies, as currency symbols may be imitated." + string( + abi.encodePacked( + unicode"This NFT represents a liquidity position in a Uniswap v4 ", + symbol1, + "-", + symbol0, + " pool. The owner of this NFT can modify or redeem the position.\n\nPool Manager Address: ", + managerAddress, + "\n", + symbol1, + " Address: ", + currency1Address, + "\n", + symbol0, + " Address: ", + currency0Address, + "\nHook Address: ", + hookAddress, + "\nFee Tier: ", + fee, + "\nToken ID: ", + id, + "\n\n", + unicode"⚠️ DISCLAIMER: Due diligence is imperative when assessing this NFT. Make sure currency addresses match the expected currencies, as currency symbols may be imitated." + ) + ) ); } @@ -146,4 +326,42 @@ contract PositionDescriptorTest is Test, PosmTestSetup { positionDescriptor.tokenURI(lpm, tokenId + 1); } + + // Helper functions for testing purposes + function toHexString(address account) internal pure returns (string memory) { + return toHexString(uint256(uint160(account)), 20); + } + + // different from AddressStringUtil.toHexString. this one is all lowercase hex and includes the 0x prefix + function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { + bytes memory buffer = new bytes(2 * length + 2); + buffer[0] = "0"; + buffer[1] = "x"; + for (uint256 i = 2 * length + 1; i > 1; --i) { + uint8 digit = uint8(value & 0xf); + buffer[i] = digit < 10 ? bytes1(digit + 48) : bytes1(digit + 87); // Lowercase hex (0x61 is 'a' in ASCII) + value >>= 4; + } + require(value == 0, "Hex length insufficient"); + return string(buffer); + } + + function uintToString(uint256 value) internal pure returns (string memory) { + if (value == 0) { + return "0"; + } + uint256 temp = value; + uint256 digits; + while (temp != 0) { + digits++; + temp /= 10; + } + bytes memory buffer = new bytes(digits); + while (value != 0) { + digits -= 1; + buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); + value /= 10; + } + return string(buffer); + } } diff --git a/test/libraries/SVG.t.sol b/test/libraries/SVG.t.sol index c322483e..915557cb 100644 --- a/test/libraries/SVG.t.sol +++ b/test/libraries/SVG.t.sol @@ -47,4 +47,11 @@ contract DescriptorTest is Test { result = SVG.isRare(2, 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB); assertFalse(result); } + + function test_substring_succeeds() public pure { + string memory result = SVG.substring("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", 0, 5); + assertEq(result, "0xC02"); + result = SVG.substring("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", 39, 42); + assertEq(result, "Cc2"); + } } diff --git a/test/position-managers/PositionManager.modifyLiquidities.t.sol b/test/position-managers/PositionManager.modifyLiquidities.t.sol index c805dd27..6f422ccf 100644 --- a/test/position-managers/PositionManager.modifyLiquidities.t.sol +++ b/test/position-managers/PositionManager.modifyLiquidities.t.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.24; import "forge-std/Test.sol"; import {IERC20} from "forge-std/interfaces/IERC20.sol"; +import {CustomRevert} from "@uniswap/v4-core/src/libraries/CustomRevert.sol"; import {PoolManager} from "@uniswap/v4-core/src/PoolManager.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; @@ -239,9 +240,11 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF // should revert because hook is not approved vm.expectRevert( abi.encodeWithSelector( - Hooks.Wrap__FailedHookCall.selector, + CustomRevert.WrappedError.selector, address(hookModifyLiquidities), - abi.encodeWithSelector(IPositionManager.NotApproved.selector, address(hookModifyLiquidities)) + IHooks.beforeSwap.selector, + abi.encodeWithSelector(IPositionManager.NotApproved.selector, address(hookModifyLiquidities)), + abi.encodeWithSelector(Hooks.HookCallFailed.selector) ) ); swap(key, true, -1e18, calls); @@ -260,9 +263,11 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF // should revert because hook is not approved vm.expectRevert( abi.encodeWithSelector( - Hooks.Wrap__FailedHookCall.selector, + CustomRevert.WrappedError.selector, address(hookModifyLiquidities), - abi.encodeWithSelector(IPositionManager.NotApproved.selector, address(hookModifyLiquidities)) + IHooks.beforeSwap.selector, + abi.encodeWithSelector(IPositionManager.NotApproved.selector, address(hookModifyLiquidities)), + abi.encodeWithSelector(Hooks.HookCallFailed.selector) ) ); swap(key, true, -1e18, calls); @@ -285,9 +290,11 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF // should revert because hook is not approved vm.expectRevert( abi.encodeWithSelector( - Hooks.Wrap__FailedHookCall.selector, + CustomRevert.WrappedError.selector, address(hookModifyLiquidities), - abi.encodeWithSelector(IPositionManager.NotApproved.selector, address(hookModifyLiquidities)) + IHooks.beforeSwap.selector, + abi.encodeWithSelector(IPositionManager.NotApproved.selector, address(hookModifyLiquidities)), + abi.encodeWithSelector(Hooks.HookCallFailed.selector) ) ); swap(key, true, -1e18, calls); @@ -306,9 +313,11 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF // should revert because hook is not approved vm.expectRevert( abi.encodeWithSelector( - Hooks.Wrap__FailedHookCall.selector, + CustomRevert.WrappedError.selector, address(hookModifyLiquidities), - abi.encodeWithSelector(IPositionManager.NotApproved.selector, address(hookModifyLiquidities)) + IHooks.beforeSwap.selector, + abi.encodeWithSelector(IPositionManager.NotApproved.selector, address(hookModifyLiquidities)), + abi.encodeWithSelector(Hooks.HookCallFailed.selector) ) ); swap(key, true, -1e18, calls); @@ -329,9 +338,11 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF // should revert because hook is re-entering modifyLiquiditiesWithoutUnlock vm.expectRevert( abi.encodeWithSelector( - Hooks.Wrap__FailedHookCall.selector, + CustomRevert.WrappedError.selector, address(hookModifyLiquidities), - abi.encodeWithSelector(ReentrancyLock.ContractLocked.selector) + IHooks.beforeAddLiquidity.selector, + abi.encodeWithSelector(ReentrancyLock.ContractLocked.selector), + abi.encodeWithSelector(Hooks.HookCallFailed.selector) ) ); lpm.modifyLiquidities(calls, _deadline); diff --git a/test/position-managers/PositionManager.notifier.t.sol b/test/position-managers/PositionManager.notifier.t.sol index 253afd96..401f5c3c 100644 --- a/test/position-managers/PositionManager.notifier.t.sol +++ b/test/position-managers/PositionManager.notifier.t.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.24; import "forge-std/Test.sol"; +import {CustomRevert} from "@uniswap/v4-core/src/libraries/CustomRevert.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; import {Position} from "@uniswap/v4-core/src/libraries/Position.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; @@ -510,9 +511,11 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup { vm.expectRevert( abi.encodeWithSelector( - INotifier.Wrap__SubscriptionReverted.selector, + CustomRevert.WrappedError.selector, address(revertSubscriber), - abi.encodeWithSelector(MockRevertSubscriber.TestRevert.selector, "notifySubscribe") + ISubscriber.notifySubscribe.selector, + abi.encodeWithSelector(MockRevertSubscriber.TestRevert.selector, "notifySubscribe"), + abi.encodeWithSelector(INotifier.SubscriptionReverted.selector) ) ); lpm.subscribe(tokenId, address(revertSubscriber), ZERO_BYTES); @@ -540,9 +543,11 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup { bytes memory calls = plan.finalizeModifyLiquidityWithSettlePair(config.poolKey); vm.expectRevert( abi.encodeWithSelector( - INotifier.Wrap__ModifyLiquidityNotificationReverted.selector, + CustomRevert.WrappedError.selector, address(revertSubscriber), - abi.encodeWithSelector(MockRevertSubscriber.TestRevert.selector, "notifyModifyLiquidity") + ISubscriber.notifyModifyLiquidity.selector, + abi.encodeWithSelector(MockRevertSubscriber.TestRevert.selector, "notifyModifyLiquidity"), + abi.encodeWithSelector(INotifier.ModifyLiquidityNotificationReverted.selector) ) ); lpm.modifyLiquidities(calls, _deadline); @@ -561,9 +566,11 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup { vm.expectRevert( abi.encodeWithSelector( - INotifier.Wrap__TransferNotificationReverted.selector, + CustomRevert.WrappedError.selector, address(revertSubscriber), - abi.encodeWithSelector(MockRevertSubscriber.TestRevert.selector, "notifyTransfer") + ISubscriber.notifyTransfer.selector, + abi.encodeWithSelector(MockRevertSubscriber.TestRevert.selector, "notifyTransfer"), + abi.encodeWithSelector(INotifier.TransferNotificationReverted.selector) ) ); lpm.transferFrom(alice, bob, tokenId); @@ -582,9 +589,11 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup { vm.expectRevert( abi.encodeWithSelector( - INotifier.Wrap__TransferNotificationReverted.selector, + CustomRevert.WrappedError.selector, address(revertSubscriber), - abi.encodeWithSelector(MockRevertSubscriber.TestRevert.selector, "notifyTransfer") + ISubscriber.notifyTransfer.selector, + abi.encodeWithSelector(MockRevertSubscriber.TestRevert.selector, "notifyTransfer"), + abi.encodeWithSelector(INotifier.TransferNotificationReverted.selector) ) ); lpm.safeTransferFrom(alice, bob, tokenId); @@ -603,9 +612,11 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup { vm.expectRevert( abi.encodeWithSelector( - INotifier.Wrap__TransferNotificationReverted.selector, + CustomRevert.WrappedError.selector, address(revertSubscriber), - abi.encodeWithSelector(MockRevertSubscriber.TestRevert.selector, "notifyTransfer") + ISubscriber.notifyTransfer.selector, + abi.encodeWithSelector(MockRevertSubscriber.TestRevert.selector, "notifyTransfer"), + abi.encodeWithSelector(INotifier.TransferNotificationReverted.selector) ) ); lpm.safeTransferFrom(alice, bob, tokenId, ""); @@ -678,9 +689,11 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup { // should revert since the pool manager is unlocked vm.expectRevert( abi.encodeWithSelector( - Hooks.Wrap__FailedHookCall.selector, + CustomRevert.WrappedError.selector, address(reenterHook), - abi.encodeWithSelector(IPositionManager.PoolManagerMustBeLocked.selector) + IHooks.beforeAddLiquidity.selector, + abi.encodeWithSelector(IPositionManager.PoolManagerMustBeLocked.selector), + abi.encodeWithSelector(Hooks.HookCallFailed.selector) ) ); lpm.modifyLiquidities(actions, _deadline); @@ -699,9 +712,11 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup { // should revert since the pool manager is unlocked vm.expectRevert( abi.encodeWithSelector( - Hooks.Wrap__FailedHookCall.selector, + CustomRevert.WrappedError.selector, address(reenterHook), - abi.encodeWithSelector(IPositionManager.PoolManagerMustBeLocked.selector) + IHooks.beforeAddLiquidity.selector, + abi.encodeWithSelector(IPositionManager.PoolManagerMustBeLocked.selector), + abi.encodeWithSelector(Hooks.HookCallFailed.selector) ) ); lpm.modifyLiquidities(actions, _deadline); @@ -720,9 +735,11 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup { // should revert since the pool manager is unlocked vm.expectRevert( abi.encodeWithSelector( - Hooks.Wrap__FailedHookCall.selector, + CustomRevert.WrappedError.selector, address(reenterHook), - abi.encodeWithSelector(IPositionManager.PoolManagerMustBeLocked.selector) + IHooks.beforeAddLiquidity.selector, + abi.encodeWithSelector(IPositionManager.PoolManagerMustBeLocked.selector), + abi.encodeWithSelector(Hooks.HookCallFailed.selector) ) ); lpm.modifyLiquidities(actions, _deadline); diff --git a/test/script/DeployPoolManager.t.sol b/test/script/DeployPoolManager.t.sol index fbb7df43..19159c26 100644 --- a/test/script/DeployPoolManager.t.sol +++ b/test/script/DeployPoolManager.t.sol @@ -15,7 +15,7 @@ contract DeployPoolManagerTest is Test { function test_run_poolManager() public { IPoolManager manager = deployer.run(); // Foundry sets a default sender in scripts. - address defaultSender = 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38; + address defaultSender = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; // Deployer is the owner. assertEq(_getOwner(manager), defaultSender); } diff --git a/test/script/DeployPoolMofifyLiquidityTest.t.sol b/test/script/DeployPoolMofifyLiquidityTest.t.sol index e4c67710..6da02e01 100644 --- a/test/script/DeployPoolMofifyLiquidityTest.t.sol +++ b/test/script/DeployPoolMofifyLiquidityTest.t.sol @@ -14,7 +14,7 @@ contract DeployPoolModifyLiquidityTestTest is Test { IPoolManager manager; function setUp() public { - manager = new PoolManager(); + manager = new PoolManager(address(this)); deployer = new DeployPoolModifyLiquidityTest(); } diff --git a/test/script/DeployPoolSwapTest.t.sol b/test/script/DeployPoolSwapTest.t.sol index 2feb0aaa..de9ca350 100644 --- a/test/script/DeployPoolSwapTest.t.sol +++ b/test/script/DeployPoolSwapTest.t.sol @@ -14,7 +14,7 @@ contract DeployPoolSwapTestTest is Test { IPoolManager manager; function setUp() public { - manager = new PoolManager(); + manager = new PoolManager(address(this)); deployer = new DeployPoolSwapTest(); }