Skip to content

Commit

Permalink
Merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
hensha256 committed Oct 31, 2024
2 parents 2ee730f + 1a21920 commit 4673a21
Show file tree
Hide file tree
Showing 7 changed files with 262 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .forge-snapshots/positionDescriptor bytecode size.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
31738
31847
9 changes: 6 additions & 3 deletions src/PositionDescriptor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
33 changes: 16 additions & 17 deletions src/libraries/Descriptor.sol
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -23,8 +22,8 @@ library Descriptor {

struct ConstructTokenURIParams {
uint256 tokenId;
Currency quoteCurrency;
Currency baseCurrency;
address quoteCurrency;
address baseCurrency;
string quoteCurrencySymbol;
string baseCurrencySymbol;
uint8 quoteCurrencyDecimals;
Expand Down Expand Up @@ -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)
);
Expand Down Expand Up @@ -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,
Expand All @@ -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);
Expand Down
1 change: 0 additions & 1 deletion src/libraries/SVG.sol
Original file line number Diff line number Diff line change
@@ -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";
Expand Down
29 changes: 12 additions & 17 deletions src/libraries/SafeCurrencyMetadata.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down
Loading

0 comments on commit 4673a21

Please sign in to comment.