diff --git a/.forge-snapshots/PositionManager_permit.snap b/.forge-snapshots/PositionManager_permit.snap index ef9de9e8..227e327e 100644 --- a/.forge-snapshots/PositionManager_permit.snap +++ b/.forge-snapshots/PositionManager_permit.snap @@ -1 +1 @@ -79064 \ No newline at end of file +79076 \ No newline at end of file diff --git a/src/PositionManager.sol b/src/PositionManager.sol index de5a2f76..d5721e34 100644 --- a/src/PositionManager.sol +++ b/src/PositionManager.sol @@ -130,7 +130,7 @@ contract PositionManager is ) BaseActionsRouter(_poolManager) Permit2Forwarder(_permit2) - ERC721Permit_v4("Uniswap V4 Positions NFT", "UNI-V4-POSM") + ERC721Permit_v4("Uniswap v4 Positions NFT", "UNI-V4-POSM") Notifier(_unsubscribeGasLimit) { tokenDescriptor = _tokenDescriptor; diff --git a/src/V4Router.sol b/src/V4Router.sol index b33d8d90..0aaf7715 100644 --- a/src/V4Router.sol +++ b/src/V4Router.sol @@ -18,7 +18,7 @@ import {Actions} from "./libraries/Actions.sol"; import {ActionConstants} from "./libraries/ActionConstants.sol"; /// @title UniswapV4Router -/// @notice Abstract contract that contains all internal logic needed for routing through Uniswap V4 pools +/// @notice Abstract contract that contains all internal logic needed for routing through Uniswap v4 pools /// @dev the entry point to executing actions in this contract is calling `BaseActionsRouter._executeActions` /// An inheriting contract should call _executeActions at the point that they wish actions to be executed abstract contract V4Router is IV4Router, BaseActionsRouter, DeltaResolver { diff --git a/src/libraries/CurrencyRatioSortOrder.sol b/src/libraries/CurrencyRatioSortOrder.sol index 6114c1f9..d9d9d442 100644 --- a/src/libraries/CurrencyRatioSortOrder.sol +++ b/src/libraries/CurrencyRatioSortOrder.sol @@ -1,6 +1,10 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; +/// @title CurrencyRatioSortOrder +/// @notice Provides constants for sorting currencies when displaying price ratios +/// Currencies given larger values will be in the numerator of the price ratio +/// @dev Reference: https://github.com/Uniswap/v3-periphery/blob/main/contracts/libraries/TokenRatioSortOrder.sol library CurrencyRatioSortOrder { int256 constant NUMERATOR_MOST = 300; int256 constant NUMERATOR_MORE = 200; diff --git a/src/libraries/Descriptor.sol b/src/libraries/Descriptor.sol index 9af53218..831fd81a 100644 --- a/src/libraries/Descriptor.sol +++ b/src/libraries/Descriptor.sol @@ -5,6 +5,7 @@ import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.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"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {Base64} from "@openzeppelin/contracts/utils/Base64.sol"; import {SVG} from "./SVG.sol"; @@ -46,12 +47,12 @@ library Descriptor { string memory descriptionPartOne = generateDescriptionPartOne( escapeQuotes(params.quoteCurrencySymbol), escapeQuotes(params.baseCurrencySymbol), - addressToString(params.poolManager), - addressToString(Currency.unwrap(params.quoteCurrency)) + addressToString(params.poolManager) ); string memory descriptionPartTwo = generateDescriptionPartTwo( params.tokenId.toString(), escapeQuotes(params.baseCurrencySymbol), + addressToString(Currency.unwrap(params.quoteCurrency)), addressToString(Currency.unwrap(params.baseCurrency)), addressToString(params.hooks), feeToPercentString(params.fee) @@ -111,18 +112,16 @@ library Descriptor { /// @param quoteCurrencySymbol The symbol of the quote currency /// @param baseCurrencySymbol The symbol of the base currency /// @param poolManager The address of the pool manager - /// @param quoteCurrency The address of the quote currency /// @return The first part of the description function generateDescriptionPartOne( string memory quoteCurrencySymbol, string memory baseCurrencySymbol, - string memory poolManager, - string memory quoteCurrency + string memory poolManager ) private pure returns (string memory) { // displays quote currency first, then base currency return string( abi.encodePacked( - "This NFT represents a liquidity position in a Uniswap V4 ", + "This NFT represents a liquidity position in a Uniswap v4 ", quoteCurrencySymbol, "-", baseCurrencySymbol, @@ -131,10 +130,7 @@ library Descriptor { "\\nPool Manager Address: ", poolManager, "\\n", - quoteCurrencySymbol, - " Address: ", - quoteCurrency, - "\\n" + quoteCurrencySymbol ) ); } @@ -142,6 +138,7 @@ library Descriptor { /// @notice Generates the second part of the description for a Uniswap v4 NFTs /// @param tokenId The token ID /// @param baseCurrencySymbol The symbol of the base currency + /// @param quoteCurrency The address of the quote currency /// @param baseCurrency The address of the base currency /// @param hooks The address of the hooks contract /// @param feeTier The fee tier of the pool @@ -149,12 +146,16 @@ library Descriptor { function generateDescriptionPartTwo( string memory tokenId, string memory baseCurrencySymbol, + string memory quoteCurrency, string memory baseCurrency, string memory hooks, string memory feeTier ) private pure returns (string memory) { return string( abi.encodePacked( + ' Address: ', + quoteCurrency, + "\\n", baseCurrencySymbol, " Address: ", baseCurrency, @@ -402,6 +403,9 @@ library Descriptor { /// @param fee fee amount /// @return fee as a decimal string with percent sign function feeToPercentString(uint24 fee) internal pure returns (string memory) { + if (fee == LPFeeLibrary.DYNAMIC_FEE_FLAG) { + return "Dynamic"; + } if (fee == 0) { return "0%"; } diff --git a/src/libraries/SVG.sol b/src/libraries/SVG.sol index 9e860ea2..24d71282 100644 --- a/src/libraries/SVG.sol +++ b/src/libraries/SVG.sol @@ -53,12 +53,6 @@ library SVG { /// @param params The SVGParams struct containing the parameters for the SVG /// @return svg The SVG string associated with the NFT function generateSVG(SVGParams memory params) internal pure returns (string memory svg) { - /* - address: "0xe8ab59d3bcde16a29912de83a90eb39628cfc163", - msg: "Forged in SVG for Uniswap in 2021 by 0xe8ab59d3bcde16a29912de83a90eb39628cfc163", - sig: "0x2df0e99d9cbfec33a705d83f75666d98b22dea7c1af412c584f7d626d83f02875993df740dc87563b9c73378f8462426da572d7989de88079a382ad96c57b68d1b", - version: "2" - */ return string( abi.encodePacked( generateSVGDefs(params), diff --git a/test/position-managers/Permit.t.sol b/test/position-managers/Permit.t.sol index ea3a9c6d..392fc17e 100644 --- a/test/position-managers/Permit.t.sol +++ b/test/position-managers/Permit.t.sol @@ -64,7 +64,7 @@ contract PermitTest is Test, PosmTestSetup { keccak256( abi.encode( keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"), - keccak256("Uniswap V4 Positions NFT"), // storage is private on EIP712.sol so we need to hardcode these + keccak256("Uniswap v4 Positions NFT"), // storage is private on EIP712.sol so we need to hardcode these block.chainid, address(lpm) )