// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.14;
import "openzeppelin/contracts/utils/Base64.sol";
import "openzeppelin/contracts/utils/Strings.sol";
import "solmate/src/tokens/ERC20.sol";
import "../interfaces/IUniswapV3Pool.sol";
library NFTRenderer {
struct RenderParams {
address pool;
address owner;
int24 lowerTick;
int24 upperTick;
uint24 fee;
}
function render(RenderParams memory params)
internal
view
returns (string memory)
{
IUniswapV3Pool pool = IUniswapV3Pool(params.pool);
ERC20 token0 = ERC20(pool.token0());
ERC20 token1 = ERC20(pool.token1());
string memory symbol0 = token0.symbol();
string memory symbol1 = token1.symbol();
string memory image = string.concat(
""
);
string memory description = renderDescription(
symbol0,
symbol1,
params.fee,
params.lowerTick,
params.upperTick
);
string memory json = string.concat(
'{"name":"Uniswap V3 Position",',
'"description":"',
description,
'",',
'"image":"data:image/svg+xml;base64,',
Base64.encode(bytes(image)),
'"}'
);
return
string.concat(
"data:application/json;base64,",
Base64.encode(bytes(json))
);
}
////////////////////////////////////////////////////////////////////////////
//
// INTERNAL
//
////////////////////////////////////////////////////////////////////////////
function renderBackground(
address owner,
int24 lowerTick,
int24 upperTick
) internal pure returns (string memory background) {
bytes32 key = keccak256(abi.encodePacked(owner, lowerTick, upperTick));
uint256 hue = uint256(key) % 360;
background = string.concat(
'',
''
);
}
function renderTop(
string memory symbol0,
string memory symbol1,
uint24 fee
) internal pure returns (string memory top) {
top = string.concat(
'',
'',
symbol0,
"/",
symbol1,
""
'',
'',
feeToText(fee),
""
);
}
function renderBottom(int24 lowerTick, int24 upperTick)
internal
pure
returns (string memory bottom)
{
bottom = string.concat(
'',
'Lower tick: ',
tickToText(lowerTick),
"",
'',
'Upper tick: ',
tickToText(upperTick),
""
);
}
function renderDescription(
string memory symbol0,
string memory symbol1,
uint24 fee,
int24 lowerTick,
int24 upperTick
) internal pure returns (string memory description) {
description = string.concat(
symbol0,
"/",
symbol1,
" ",
feeToText(fee),
", Lower tick: ",
tickToText(lowerTick),
", Upper text: ",
tickToText(upperTick)
);
}
function feeToText(uint256 fee)
internal
pure
returns (string memory feeString)
{
if (fee == 500) {
feeString = "0.05%";
} else if (fee == 3000) {
feeString = "0.3%";
}
}
function tickToText(int24 tick)
internal
pure
returns (string memory tickString)
{
tickString = string.concat(
tick < 0 ? "-" : "",
tick < 0
? Strings.toString(uint256(uint24(-tick)))
: Strings.toString(uint256(uint24(tick)))
);
}
}