编译器
0.8.20+commit.a1b79de6
文件 1 的 24:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 2 的 24:DoubleEndedQueue.sol
pragma solidity ^0.8.20;
library DoubleEndedQueue {
error QueueEmpty();
error QueueFull();
error QueueOutOfBounds();
struct Uint256Deque {
uint128 _begin;
uint128 _end;
mapping(uint128 index => uint256) _data;
}
function pushBack(Uint256Deque storage deque, uint256 value) internal {
unchecked {
uint128 backIndex = deque._end;
if (backIndex + 1 == deque._begin) revert QueueFull();
deque._data[backIndex] = value;
deque._end = backIndex + 1;
}
}
function popBack(
Uint256Deque storage deque
) internal returns (uint256 value) {
unchecked {
uint128 backIndex = deque._end;
if (backIndex == deque._begin) revert QueueEmpty();
--backIndex;
value = deque._data[backIndex];
delete deque._data[backIndex];
deque._end = backIndex;
}
}
function pushFront(Uint256Deque storage deque, uint256 value) internal {
unchecked {
uint128 frontIndex = deque._begin - 1;
if (frontIndex == deque._end) revert QueueFull();
deque._data[frontIndex] = value;
deque._begin = frontIndex;
}
}
function popFront(
Uint256Deque storage deque
) internal returns (uint256 value) {
unchecked {
uint128 frontIndex = deque._begin;
if (frontIndex == deque._end) revert QueueEmpty();
value = deque._data[frontIndex];
delete deque._data[frontIndex];
deque._begin = frontIndex + 1;
}
}
function front(
Uint256Deque storage deque
) internal view returns (uint256 value) {
if (empty(deque)) revert QueueEmpty();
return deque._data[deque._begin];
}
function back(
Uint256Deque storage deque
) internal view returns (uint256 value) {
if (empty(deque)) revert QueueEmpty();
unchecked {
return deque._data[deque._end - 1];
}
}
function at(
Uint256Deque storage deque,
uint256 index
) internal view returns (uint256 value) {
if (index >= length(deque)) revert QueueOutOfBounds();
unchecked {
return deque._data[deque._begin + uint128(index)];
}
}
function clear(Uint256Deque storage deque) internal {
deque._begin = 0;
deque._end = 0;
}
function length(Uint256Deque storage deque) internal view returns (uint256) {
unchecked {
return uint256(deque._end - deque._begin);
}
}
function empty(Uint256Deque storage deque) internal view returns (bool) {
return deque._end == deque._begin;
}
}
文件 3 的 24:ERC20Events.sol
pragma solidity ^0.8.20;
library ERC20Events {
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
event Transfer(address indexed from, address indexed to, uint256 amount);
}
文件 4 的 24:ERC333.sol
pragma solidity ^0.8.9;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {ERC404} from "../ERC404/ERC404.sol";
import {ERC5169} from "stl-contracts/ERC/ERC5169.sol";
import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
import {PoolAddress} from "../utils/PoolAddress.sol";
import {TickMath} from "../utils/TickMath.sol";
import {PoolData} from "../structs/PoolData.sol";
import {MintParams, IncreaseLiquidityParams, DecreaseLiquidityParams, CollectParams} from "../structs/PositionParams.sol";
import {ExactInputSingleParams} from "../structs/RouterParams.sol";
abstract contract ERC333 is Ownable, ERC404, ERC5169 {
event Initialize(PoolData poolData);
event ReceiveTax(uint256 value);
event ERC20Burn(uint256 value);
event RefundETH(address sender, uint256 value);
using Strings for uint256;
string constant _JSON_FILE = ".json";
uint256 public mintSupply = 10000;
uint24 public taxPercent = 80000;
address public initialMintRecipient;
bool public initialized;
PoolData public currentPoolData;
int24 public tickThreshold;
int24 public currentTick;
uint256 public mintTimestamp;
uint256 public totalTax;
address public positionManagerAddress;
address public swapRouterAddress;
uint32 constant TWAP_INTERVAL = 30 minutes;
event BaseUriUpdate(string uri);
string public baseURI;
constructor(
address initialOwner_,
address initialMintRecipient_,
uint256 mintSupply_,
uint24 taxPercent_,
string memory name_,
string memory sym_,
uint8 decimals_,
uint8 ratio_
) ERC404(name_, sym_, decimals_, ratio_) Ownable(initialOwner_) {
mintSupply = mintSupply_;
taxPercent = taxPercent_;
initialMintRecipient = initialMintRecipient_;
_setERC721TransferExempt(initialMintRecipient_, true);
_mintERC20(initialMintRecipient_, mintSupply * units, false);
}
function supportsInterface(
bytes4 interfaceId
) public view override(ERC5169, ERC404) returns (bool) {
return
ERC5169.supportsInterface(interfaceId) ||
ERC404.supportsInterface(interfaceId);
}
function _authorizeSetScripts(
string[] memory
) internal view override(ERC5169) onlyOwner {}
function initialize() external payable virtual;
function _initialize(
uint160 sqrtPriceX96,
uint24 fee,
address quoteToken,
uint256 quoteTokenAmount,
uint16 observationCardinalityNext,
address positionManagerAddress_,
address swapRouterAddress_
) internal virtual onlyOwner {
require(!initialized, "has initialized");
positionManagerAddress = positionManagerAddress_;
swapRouterAddress = swapRouterAddress_;
currentPoolData.quoteToken = quoteToken;
currentPoolData.fee = fee;
currentPoolData.sqrtPriceX96 = sqrtPriceX96;
(address token0, address token1) = (address(this), quoteToken);
(uint256 amount0, uint256 amount1) = (
balanceOf[address(this)],
quoteTokenAmount
);
if (token0 > token1) {
(token0, token1) = (token1, token0);
(amount0, amount1) = (amount1, amount0);
}
_approveUniswap(token0, type(uint256).max);
_approveUniswap(token1, type(uint256).max);
int24 tickSpacing;
(
currentPoolData.poolAddress,
currentTick,
tickSpacing
) = _initializePool(token0, token1, fee, sqrtPriceX96);
require(
currentPoolData.poolAddress != address(0) && tickSpacing != 0,
"initialize pool failed"
);
tickThreshold = currentTick;
if (_thisIsToken0()) {
currentPoolData.tickLower = (tickThreshold / tickSpacing) * tickSpacing;
if (tickThreshold < 0) {
currentPoolData.tickLower -= tickSpacing;
}
currentPoolData.tickUpper =
(TickMath.MAX_TICK / tickSpacing) *
tickSpacing;
} else {
currentPoolData.tickUpper = (tickThreshold / tickSpacing) * tickSpacing;
if (tickThreshold > 0) {
currentPoolData.tickUpper += tickSpacing;
}
currentPoolData.tickLower =
(TickMath.MIN_TICK / tickSpacing) *
tickSpacing;
}
if (observationCardinalityNext > 0) {
bool success = _initializeObservations(
currentPoolData.poolAddress,
observationCardinalityNext
);
require(success, "initialize observations failed");
}
(
currentPoolData.positionId,
currentPoolData.liquidity,
,
) = _initializeLiquidity(
token0,
token1,
fee,
amount0,
amount1,
currentPoolData.tickLower,
currentPoolData.tickUpper,
address(this)
);
require(currentPoolData.positionId != 0, "initialize liquidity failed");
mintTimestamp = block.timestamp;
initialized = true;
emit Initialize(currentPoolData);
}
function _getCurrentTokenTick() internal virtual returns (int24) {
if (!initialized) {
return tickThreshold;
}
(bool success0, bytes memory data0) = currentPoolData
.poolAddress
.staticcall(abi.encodeWithSelector(0x3850c7bd));
if (!success0) {
return tickThreshold;
}
(, int24 tick, uint16 index, uint16 cardinality, , , ) = abi.decode(
data0,
(uint160, int24, uint16, uint16, uint16, uint8, bool)
);
uint32 delta = TWAP_INTERVAL;
if (uint32(block.timestamp - mintTimestamp) < delta) {
return tick;
}
uint32[] memory secondsTwapIntervals = new uint32[](2);
secondsTwapIntervals[0] = delta;
secondsTwapIntervals[1] = 0;
(bool success, bytes memory data) = currentPoolData
.poolAddress
.staticcall(
abi.encodeWithSelector(0x883bdbfd, secondsTwapIntervals)
);
if (!success) {
return tick;
}
(int56[] memory tickCumulatives, ) = abi.decode(
data,
(int56[], uint160[])
);
int56 tickCumulativesDelta = tickCumulatives[1] - tickCumulatives[0];
tick = int24(tickCumulativesDelta / int56(uint56(delta)));
if (
tickCumulativesDelta < 0 &&
(tickCumulativesDelta % int56(uint56(delta)) != 0)
) tick--;
return tick;
}
function _approveUniswap(
address token,
uint256 amount
) internal virtual returns (bool) {
if (amount == 0) {
return true;
}
if (token == address(this)) {
allowance[address(this)][positionManagerAddress] = amount;
allowance[address(this)][swapRouterAddress] = amount;
return true;
}
(bool success0, ) = token.call(
abi.encodeWithSelector(0x095ea7b3, positionManagerAddress, amount)
);
(bool success1, ) = token.call(
abi.encodeWithSelector(0x095ea7b3, swapRouterAddress, amount)
);
return success0 && success1;
}
function _initializePool(
address token0,
address token1,
uint24 fee,
uint160 sqrtPriceX96
)
internal
virtual
returns (address poolAddress, int24 tick, int24 tickSpacing)
{
(bool success0, bytes memory data0) = positionManagerAddress.call(
abi.encodeWithSelector(
0x13ead562,
token0,
token1,
fee,
sqrtPriceX96
)
);
if (!success0) {
return (address(0), 0, 0);
}
poolAddress = abi.decode(data0, (address));
(bool success1, bytes memory data1) = poolAddress.staticcall(
abi.encodeWithSelector(0x3850c7bd)
);
if (!success1) {
return (address(0), 0, 0);
}
(, tick, , , , , ) = abi.decode(
data1,
(uint160, int24, uint16, uint16, uint16, uint8, bool)
);
(bool success2, bytes memory data2) = poolAddress.staticcall(
abi.encodeWithSelector(0xd0c93a7c)
);
if (!success2) {
return (address(0), 0, 0);
}
tickSpacing = abi.decode(data2, (int24));
}
function _initializeObservations(
address poolAddress,
uint16 observationCardinalityNext
) internal virtual returns (bool) {
(bool success, ) = poolAddress.call(
abi.encodeWithSelector(0x32148f67, observationCardinalityNext)
);
return success;
}
function _initializeLiquidity(
address token0,
address token1,
uint24 fee,
uint256 amount0,
uint256 amount1,
int24 tickLower,
int24 tickUpper,
address recipient
)
internal
virtual
returns (
uint256 positionId,
uint128 liquidity,
uint256 amount0Used,
uint256 amount1Used
)
{
MintParams memory params = MintParams({
token0: token0,
token1: token1,
fee: fee,
tickLower: tickLower,
tickUpper: tickUpper,
amount0Desired: amount0,
amount1Desired: amount1,
amount0Min: 0,
amount1Min: 0,
recipient: recipient,
deadline: block.timestamp
});
(bool success, bytes memory data) = positionManagerAddress.call(
abi.encodeWithSelector(0x88316456, params)
);
if (success) {
(positionId, liquidity, amount0Used, amount1Used) = abi.decode(
data,
(uint256, uint128, uint256, uint256)
);
}
}
function _exactInputSingle(
address tokenIn,
address tokenOut,
address recipient,
uint256 amountIn
) internal virtual returns (uint256 amountOut) {
ExactInputSingleParams memory params = ExactInputSingleParams({
tokenIn: tokenIn,
tokenOut: tokenOut,
fee: currentPoolData.fee,
recipient: recipient,
amountIn: amountIn,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0,
deadline: block.timestamp
});
(bool success, bytes memory data) = swapRouterAddress.call(
abi.encodeWithSelector(0x414bf389, params)
);
if (success) {
amountOut = abi.decode(data, (uint256));
}
}
function _increaseLiquidity(
uint256 positionId,
uint256 amount0,
uint256 amount1
)
internal
virtual
returns (uint128 liquidity, uint256 amount0Used, uint256 amount1Used)
{
IncreaseLiquidityParams memory params = IncreaseLiquidityParams({
tokenId: positionId,
amount0Desired: amount0,
amount1Desired: amount1,
amount0Min: 0,
amount1Min: 0,
deadline: block.timestamp
});
(bool success, bytes memory data) = positionManagerAddress.call(
abi.encodeWithSelector(0x219f5d17, params)
);
if (success) {
(liquidity, amount0Used, amount1Used) = abi.decode(
data,
(uint128, uint256, uint256)
);
}
}
function _decreaseLiquidity(
uint256 positionId,
uint128 liquidity
) internal virtual returns (uint256 amount0, uint256 amount1) {
DecreaseLiquidityParams memory params = DecreaseLiquidityParams({
tokenId: positionId,
liquidity: liquidity,
amount0Min: 0,
amount1Min: 0,
deadline: block.timestamp
});
(bool success, bytes memory data) = positionManagerAddress.call(
abi.encodeWithSelector(0x0c49ccbe, params)
);
if (success) {
(amount0, amount1) = abi.decode(data, (uint256, uint256));
}
}
function _collect(
uint256 positionId,
address recipient
) internal virtual returns (uint256 amount0, uint256 amount1) {
CollectParams memory params = CollectParams({
tokenId: positionId,
recipient: recipient,
amount0Max: type(uint128).max,
amount1Max: type(uint128).max
});
(bool success, bytes memory data) = positionManagerAddress.call(
abi.encodeWithSelector(0xfc6f7865, params)
);
if (success) {
(amount0, amount1) = abi.decode(data, (uint256, uint256));
}
}
function _thisIsToken0() internal returns(bool) {
return (address(this) < currentPoolData.quoteToken);
}
function _getTaxOrBurned(
address from_,
address to_,
uint256 value_
) internal virtual returns (uint256 tax, bool burned) {
if (
msg.sender == initialMintRecipient ||
msg.sender == swapRouterAddress ||
from_ == address(this) ||
to_ == address(currentPoolData.poolAddress)
) {
return (0, false);
}
currentTick = _getCurrentTokenTick();
if (_thisIsToken0()) {
if (currentTick > tickThreshold) {
tax = (value_ * taxPercent) / 1000000;
} else if (currentTick < tickThreshold) {
burned = true;
} else {
}
} else {
if (currentTick < tickThreshold) {
tax = (value_ * taxPercent) / 1000000;
} else if (currentTick > tickThreshold) {
burned = true;
} else {
}
}
}
function _transferWithTax(
address from_,
address to_,
uint256 value_
) public virtual returns (bool) {
(uint256 tax, bool burned) = _getTaxOrBurned(from_, to_, value_);
if (burned) {
_transferERC20WithERC721(from_, address(0), value_);
_refundETH(to_, value_);
totalSupply -= value_;
emit ERC20Burn(value_);
} else if (tax > 0) {
_transferERC20WithERC721(from_, to_, value_ - tax);
_transferERC20WithERC721(from_, address(this), tax);
totalTax += tax;
emit ReceiveTax(tax);
} else {
_transferERC20WithERC721(from_, to_, value_);
}
return true;
}
function swapAndLiquify(uint256 amount) external virtual onlyOwner {
require(
amount <= ((balanceOf[address(this)] * 2) / 3),
"amount is too large"
);
uint256 quoteAmount = swapTokensForQuote(amount);
if (quoteAmount > 0) {
addLiquidity(balanceOf[address(this)], quoteAmount / 2);
}
}
function liquifyAndCollect(uint128 liquidity) external virtual onlyOwner {
require(
liquidity <= (currentPoolData.liquidity),
"liquidity is too large"
);
if (liquidity > 0) {
subLiquidity(liquidity);
}
_collect(currentPoolData.positionId, initialMintRecipient);
}
function swapTokensForQuote(uint256 tokenAmount) private returns (uint256) {
return
_exactInputSingle(
address(this),
currentPoolData.quoteToken,
address(this),
tokenAmount
);
}
function addLiquidity(uint256 thisAmount, uint256 quoteAmount) private {
(address token0, address token1) = (
address(this),
currentPoolData.quoteToken
);
(uint256 amount0, uint256 amount1) = (thisAmount, quoteAmount);
if (token0 > token1) {
(token0, token1) = (token1, token0);
(amount0, amount1) = (amount1, amount0);
}
uint128 liquidity;
(liquidity, amount0, amount1) = _increaseLiquidity(
currentPoolData.positionId,
amount0,
amount1
);
if (liquidity > 0) {
currentPoolData.liquidity += liquidity;
}
}
function subLiquidity(uint128 liquidity) private {
(uint256 amount0, uint256 amount1) = _decreaseLiquidity(
currentPoolData.positionId,
liquidity
);
if (amount0 > 0 || amount1 > 0) {
currentPoolData.liquidity -= liquidity;
}
}
function transfer(
address to_,
uint256 value_
) public override returns (bool) {
if (to_ == address(0)) {
revert InvalidRecipient();
}
return _transferWithTax(msg.sender, to_, value_);
}
function transferFrom(
address from_,
address to_,
uint256 valueOrId_
) public override returns (bool) {
if (from_ == address(0)) {
revert InvalidSender();
}
if (to_ == address(0)) {
revert InvalidRecipient();
}
if (valueOrId_ <= _minted) {
uint256 id = valueOrId_;
if (from_ != _getOwnerOf(id)) {
revert Unauthorized();
}
if (
msg.sender != from_ &&
!isApprovedForAll[from_][msg.sender] &&
msg.sender != getApproved[id]
) {
revert Unauthorized();
}
_transferERC20(from_, to_, units);
_transferERC721(from_, to_, id);
} else {
uint256 value = valueOrId_;
uint256 allowed = allowance[from_][msg.sender];
if (allowed != type(uint256).max) {
allowance[from_][msg.sender] = allowed - value;
}
return _transferWithTax(from_, to_, value);
}
return true;
}
function _refundETH(address account, uint256 value) internal virtual {
if (account == address(0)) {
revert InvalidSender();
}
(bool success0, bytes memory data0) = currentPoolData
.quoteToken
.staticcall(abi.encodeWithSelector(0x70a08231, address(this)));
if (!success0) {
return;
}
uint256 totalWETHAmount = abi.decode(data0, (uint256));
uint256 wethAmount = (value * totalWETHAmount) / totalSupply;
(bool success, ) = currentPoolData.quoteToken.call(
abi.encodeWithSelector(0xa9059cbb, account, wethAmount)
);
if (success) {
emit RefundETH(account, wethAmount);
}
}
}
文件 5 的 24:ERC404.sol
pragma solidity ^0.8.20;
import {IERC404} from "./interfaces/IERC404.sol";
import {ERC721Receiver} from "./lib/ERC721Receiver.sol";
import {DoubleEndedQueue} from "./lib/DoubleEndedQueue.sol";
import {IERC165} from "./lib/interfaces/IERC165.sol";
import {ERC721Events} from "./lib/ERC721Events.sol";
import {ERC20Events} from "./lib/ERC20Events.sol";
abstract contract ERC404 is IERC404 {
using DoubleEndedQueue for DoubleEndedQueue.Uint256Deque;
DoubleEndedQueue.Uint256Deque private _storedERC721Ids;
string public name;
string public symbol;
uint8 public immutable decimals;
uint256 public immutable units;
uint256 public totalSupply;
uint256 internal _minted;
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
mapping(uint256 => address) public getApproved;
mapping(address => mapping(address => bool)) public isApprovedForAll;
mapping(uint256 => uint256) internal _ownedData;
mapping(address => uint256[]) internal _owned;
mapping(address => bool) public erc721TransferExempt;
mapping(address => uint256) public nonces;
uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;
uint256 private constant _BITMASK_OWNED_INDEX = ((1 << 96) - 1) << 160;
constructor(
string memory name_,
string memory symbol_,
uint8 decimals_,
uint8 ratio_
) {
name = name_;
symbol = symbol_;
if (decimals_ < 18) {
revert DecimalsTooLow();
}
decimals = decimals_;
units = 10 ** decimals * ratio_;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = _computeDomainSeparator();
}
function ownerOf(
uint256 id_
) public view virtual returns (address erc721Owner) {
erc721Owner = _getOwnerOf(id_);
if (id_ > _minted || id_ == 0 || erc721Owner == address(0)) {
revert NotFound();
}
}
function owned(
address owner_
) public view virtual returns (uint256[] memory) {
return _owned[owner_];
}
function erc721BalanceOf(
address owner_
) public view virtual returns (uint256) {
return _owned[owner_].length;
}
function erc20BalanceOf(
address owner_
) public view virtual returns (uint256) {
return balanceOf[owner_];
}
function erc20TotalSupply() public view virtual returns (uint256) {
return totalSupply;
}
function erc721TotalSupply() public view virtual returns (uint256) {
return _minted;
}
function erc721TokensBankedInQueue() public view virtual returns (uint256) {
return _storedERC721Ids.length();
}
function tokenURI(uint256 id_) public view virtual returns (string memory);
function approve(
address spender_,
uint256 valueOrId_
) public virtual returns (bool) {
if (valueOrId_ <= _minted && valueOrId_ > 0) {
uint256 id = valueOrId_;
address erc721Owner = _getOwnerOf(id);
if (
msg.sender != erc721Owner &&
!isApprovedForAll[erc721Owner][msg.sender]
) {
revert Unauthorized();
}
getApproved[id] = spender_;
emit ERC721Events.Approval(erc721Owner, spender_, id);
} else {
if (spender_ == address(0)) {
revert InvalidSpender();
}
uint256 value = valueOrId_;
allowance[msg.sender][spender_] = value;
emit ERC20Events.Approval(msg.sender, spender_, value);
}
return true;
}
function setApprovalForAll(
address operator_,
bool approved_
) public virtual {
if (operator_ == address(0)) {
revert InvalidOperator();
}
isApprovedForAll[msg.sender][operator_] = approved_;
emit ApprovalForAll(msg.sender, operator_, approved_);
}
function transferFrom(
address from_,
address to_,
uint256 valueOrId_
) public virtual returns (bool) {
if (from_ == address(0)) {
revert InvalidSender();
}
if (to_ == address(0)) {
revert InvalidRecipient();
}
if (valueOrId_ <= _minted) {
uint256 id = valueOrId_;
if (from_ != _getOwnerOf(id)) {
revert Unauthorized();
}
if (
msg.sender != from_ &&
!isApprovedForAll[from_][msg.sender] &&
msg.sender != getApproved[id]
) {
revert Unauthorized();
}
_transferERC20(from_, to_, units);
_transferERC721(from_, to_, id);
} else {
uint256 value = valueOrId_;
uint256 allowed = allowance[from_][msg.sender];
if (allowed != type(uint256).max) {
allowance[from_][msg.sender] = allowed - value;
}
_transferERC20WithERC721(from_, to_, value);
}
return true;
}
function transfer(
address to_,
uint256 value_
) public virtual returns (bool) {
if (to_ == address(0)) {
revert InvalidRecipient();
}
return _transferERC20WithERC721(msg.sender, to_, value_);
}
function safeTransferFrom(
address from_,
address to_,
uint256 id_
) public virtual {
transferFrom(from_, to_, id_);
if (
to_.code.length != 0 &&
ERC721Receiver(to_).onERC721Received(msg.sender, from_, id_, "") !=
ERC721Receiver.onERC721Received.selector
) {
revert UnsafeRecipient();
}
}
function safeTransferFrom(
address from_,
address to_,
uint256 id_,
bytes calldata data_
) public virtual {
transferFrom(from_, to_, id_);
if (
to_.code.length != 0 &&
ERC721Receiver(to_).onERC721Received(
msg.sender,
from_,
id_,
data_
) !=
ERC721Receiver.onERC721Received.selector
) {
revert UnsafeRecipient();
}
}
function permit(
address owner_,
address spender_,
uint256 value_,
uint256 deadline_,
uint8 v_,
bytes32 r_,
bytes32 s_
) public virtual {
if (deadline_ < block.timestamp) {
revert PermitDeadlineExpired();
}
if (value_ <= _minted && value_ > 0) {
revert InvalidApproval();
}
if (spender_ == address(0)) {
revert InvalidSpender();
}
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner_,
spender_,
value_,
nonces[owner_]++,
deadline_
)
)
)
),
v_,
r_,
s_
);
if (recoveredAddress == address(0) || recoveredAddress != owner_) {
revert InvalidSigner();
}
allowance[recoveredAddress][spender_] = value_;
}
emit ERC20Events.Approval(owner_, spender_, value_);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return
block.chainid == INITIAL_CHAIN_ID
? INITIAL_DOMAIN_SEPARATOR
: _computeDomainSeparator();
}
function supportsInterface(
bytes4 interfaceId
) public view virtual returns (bool) {
return
interfaceId == type(IERC404).interfaceId ||
interfaceId == type(IERC165).interfaceId;
}
function _computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
function calculateERC721Transfers(
address from_,
uint256 value_
) public view returns (uint256[] memory tokenIds) {
uint256 erc20BalanceOfSenderBefore = erc20BalanceOf(from_);
if (!erc721TransferExempt[from_]) {
uint256 nftsToTransfer = value_ / units;
uint256 fractionalAmount = value_ % units;
if (
(erc20BalanceOfSenderBefore - fractionalAmount) / units <
(erc20BalanceOfSenderBefore / units)
) {
nftsToTransfer++;
}
if (nftsToTransfer > 0) {
tokenIds = new uint256[](nftsToTransfer);
for (uint256 i = 0; i < nftsToTransfer; i++) {
uint256 indexOfLastToken = _owned[from_].length - (1 + i);
tokenIds[i] = _owned[from_][indexOfLastToken];
}
}
}
}
function _transferERC20(
address from_,
address to_,
uint256 value_
) internal virtual {
if (from_ == address(0)) {
totalSupply += value_;
} else {
balanceOf[from_] -= value_;
}
unchecked {
balanceOf[to_] += value_;
}
emit ERC20Events.Transfer(from_, to_, value_);
}
function _transferERC721(
address from_,
address to_,
uint256 id_
) internal virtual {
if (from_ != address(0)) {
delete getApproved[id_];
uint256 updatedId = _owned[from_][_owned[from_].length - 1];
if (updatedId != id_) {
uint256 updatedIndex = _getOwnedIndex(id_);
_owned[from_][updatedIndex] = updatedId;
_setOwnedIndex(updatedId, updatedIndex);
}
_owned[from_].pop();
}
if (to_ != address(0)) {
_setOwnerOf(id_, to_);
_owned[to_].push(id_);
_setOwnedIndex(id_, _owned[to_].length - 1);
} else {
delete _ownedData[id_];
}
emit ERC721Events.Transfer(from_, to_, id_);
}
function _transferERC20WithERC721(
address from_,
address to_,
uint256 value_
) internal virtual returns (bool) {
uint256 erc20BalanceOfSenderBefore = erc20BalanceOf(from_);
uint256 erc20BalanceOfReceiverBefore = erc20BalanceOf(to_);
_transferERC20(from_, to_, value_);
bool isFromERC721TransferExempt = erc721TransferExempt[from_];
bool isToERC721TransferExempt = erc721TransferExempt[to_];
if (isFromERC721TransferExempt && isToERC721TransferExempt) {
} else if (isFromERC721TransferExempt) {
uint256 tokensToRetrieveOrMint = (balanceOf[to_] / units) -
(erc20BalanceOfReceiverBefore / units);
for (uint256 i = 0; i < tokensToRetrieveOrMint; i++) {
_retrieveOrMintERC721(to_);
}
} else if (isToERC721TransferExempt) {
uint256 tokensToWithdrawAndStore = (erc20BalanceOfSenderBefore /
units) - (balanceOf[from_] / units);
for (uint256 i = 0; i < tokensToWithdrawAndStore; i++) {
_withdrawAndStoreERC721(from_);
}
} else {
uint256 nftsToTransfer = value_ / units;
for (uint256 i = 0; i < nftsToTransfer; i++) {
uint256 indexOfLastToken = _owned[from_].length - 1;
uint256 tokenId = _owned[from_][indexOfLastToken];
_transferERC721(from_, to_, tokenId);
}
uint256 fractionalAmount = value_ % units;
if (
(erc20BalanceOfSenderBefore - fractionalAmount) / units <
(erc20BalanceOfSenderBefore / units)
) {
_withdrawAndStoreERC721(from_);
}
if (
(erc20BalanceOfReceiverBefore + fractionalAmount) / units >
(erc20BalanceOfReceiverBefore / units)
) {
_retrieveOrMintERC721(to_);
}
}
return true;
}
function _mintERC20(
address to_,
uint256 value_,
bool mintCorrespondingERC721s_
) internal virtual {
if (to_ == address(0)) {
revert InvalidRecipient();
}
_transferERC20(address(0), to_, value_);
if (mintCorrespondingERC721s_) {
uint256 nftsToRetrieveOrMint = value_ / units;
for (uint256 i = 0; i < nftsToRetrieveOrMint; i++) {
_retrieveOrMintERC721(to_);
}
}
}
function _retrieveOrMintERC721(address to_) internal virtual {
if (to_ == address(0)) {
revert InvalidRecipient();
}
uint256 id;
if (!DoubleEndedQueue.empty(_storedERC721Ids)) {
id = _storedERC721Ids.popBack();
} else {
_minted++;
id = _minted;
}
address erc721Owner = _getOwnerOf(id);
if (erc721Owner != address(0)) {
revert AlreadyExists();
}
_transferERC721(erc721Owner, to_, id);
}
function _withdrawAndStoreERC721(address from_) internal virtual {
if (from_ == address(0)) {
revert InvalidSender();
}
uint256 id = _owned[from_][_owned[from_].length - 1];
_transferERC721(from_, address(0), id);
_storedERC721Ids.pushFront(id);
}
function _setERC721TransferExempt(
address target_,
bool state_
) internal virtual {
if (erc20BalanceOf(target_) >= units && !state_) {
revert CannotRemoveFromERC721TransferExempt();
}
erc721TransferExempt[target_] = state_;
}
function _getOwnerOf(
uint256 id_
) internal view virtual returns (address ownerOf_) {
uint256 data = _ownedData[id_];
assembly {
ownerOf_ := and(data, _BITMASK_ADDRESS)
}
}
function _setOwnerOf(uint256 id_, address owner_) internal virtual {
uint256 data = _ownedData[id_];
assembly {
data := add(
and(data, _BITMASK_OWNED_INDEX),
and(owner_, _BITMASK_ADDRESS)
)
}
_ownedData[id_] = data;
}
function _getOwnedIndex(
uint256 id_
) internal view virtual returns (uint256 ownedIndex_) {
uint256 data = _ownedData[id_];
assembly {
ownedIndex_ := shr(160, data)
}
}
function _setOwnedIndex(uint256 id_, uint256 index_) internal virtual {
uint256 data = _ownedData[id_];
if (index_ > _BITMASK_OWNED_INDEX >> 160) {
revert OwnedIndexOverflow();
}
assembly {
data := add(
and(data, _BITMASK_ADDRESS),
and(shl(160, index_), _BITMASK_OWNED_INDEX)
)
}
_ownedData[id_] = data;
}
}
文件 6 的 24:ERC5169.sol
pragma solidity ^0.8.16;
import "./IERC5169.sol";
abstract contract ERC5169 is IERC5169 {
string[] private _scriptURI;
function scriptURI() external view override returns (string[] memory) {
return _scriptURI;
}
function setScriptURI(string[] memory newScriptURI) external override {
_authorizeSetScripts(newScriptURI);
_scriptURI = newScriptURI;
emit ScriptUpdate(newScriptURI);
}
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC5169).interfaceId;
}
function _authorizeSetScripts(string[] memory newScriptURI) internal virtual;
}
文件 7 的 24:ERC721Events.sol
pragma solidity ^0.8.20;
library ERC721Events {
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
event Approval(
address indexed owner,
address indexed spender,
uint256 indexed id
);
event Transfer(
address indexed from,
address indexed to,
uint256 indexed id
);
}
文件 8 的 24:ERC721Receiver.sol
pragma solidity ^0.8.20;
abstract contract ERC721Receiver {
function onERC721Received(
address,
address,
uint256,
bytes calldata
) external virtual returns (bytes4) {
return ERC721Receiver.onERC721Received.selector;
}
}
文件 9 的 24:FullMath.sol
pragma solidity ^0.8.4;
library FullMath {
function mulDiv(
uint256 a,
uint256 b,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(a, b, not(0))
prod0 := mul(a, b)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
require(denominator > 0);
assembly {
result := div(prod0, denominator)
}
return result;
}
require(denominator > prod1);
uint256 remainder;
assembly {
remainder := mulmod(a, b, denominator)
}
assembly {
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
}
assembly {
prod0 := div(prod0, twos)
}
assembly {
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inv = (3 * denominator) ^ 2;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
result = prod0 * inv;
return result;
}
}
function mulDivRoundingUp(
uint256 a,
uint256 b,
uint256 denominator
) internal pure returns (uint256 result) {
result = mulDiv(a, b, denominator);
if (mulmod(a, b, denominator) > 0) {
require(result < type(uint256).max);
result++;
}
}
}
文件 10 的 24:IERC165.sol
pragma solidity ^0.8.20;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 11 的 24:IERC404.sol
pragma solidity ^0.8.20;
import {IERC165} from "../lib/interfaces/IERC165.sol";
interface IERC404 is IERC165 {
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
event Approval(
address indexed owner,
address indexed spender,
uint256 indexed id
);
event Transfer(address indexed from, address indexed to, uint256 amount);
error NotFound();
error InvalidId();
error AlreadyExists();
error InvalidRecipient();
error InvalidSender();
error InvalidSpender();
error InvalidOperator();
error UnsafeRecipient();
error NotERC721TransferExempt();
error Unauthorized();
error InsufficientAllowance();
error DecimalsTooLow();
error CannotRemoveFromERC721TransferExempt();
error PermitDeadlineExpired();
error InvalidSigner();
error InvalidApproval();
error OwnedIndexOverflow();
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint256);
function erc20TotalSupply() external view returns (uint256);
function erc721TotalSupply() external view returns (uint256);
function balanceOf(address owner_) external view returns (uint256);
function erc721BalanceOf(address owner_) external view returns (uint256);
function erc20BalanceOf(address owner_) external view returns (uint256);
function erc721TransferExempt(
address account_
) external view returns (bool);
function isApprovedForAll(
address owner_,
address operator_
) external view returns (bool);
function allowance(
address owner_,
address spender_
) external view returns (uint256);
function owned(address owner_) external view returns (uint256[] memory);
function ownerOf(uint256 id_) external view returns (address erc721Owner);
function tokenURI(uint256 id_) external view returns (string memory);
function approve(
address spender_,
uint256 valueOrId_
) external returns (bool);
function setApprovalForAll(address operator_, bool approved_) external;
function transferFrom(
address from_,
address to_,
uint256 valueOrId_
) external returns (bool);
function transfer(address to_, uint256 amount_) external returns (bool);
function erc721TokensBankedInQueue() external view returns (uint256);
function safeTransferFrom(address from_, address to_, uint256 id_) external;
function safeTransferFrom(
address from_,
address to_,
uint256 id_,
bytes calldata data_
) external;
function DOMAIN_SEPARATOR() external view returns (bytes32);
function permit(
address owner_,
address spender_,
uint256 value_,
uint256 deadline_,
uint8 v_,
bytes32 r_,
bytes32 s_
) external;
}
文件 12 的 24:IERC5169.sol
pragma solidity ^0.8.16;
interface IERC5169 {
event ScriptUpdate(string[]);
function scriptURI() external view returns (string[] memory);
function setScriptURI(string[] memory) external;
}
文件 13 的 24:IERC721.sol
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 14 的 24:IERC721Metadata.sol
pragma solidity ^0.8.20;
import {IERC721} from "../IERC721.sol";
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 15 的 24:Math.sol
pragma solidity ^0.8.20;
library Math {
error MathOverflowedMulDiv();
enum Rounding {
Floor,
Ceil,
Trunc,
Expand
}
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
return a / b;
}
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0 = x * y;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (0 - denominator);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}
文件 16 的 24:Ownable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 17 的 24:PoolAddress.sol
pragma solidity >=0.5.0;
library PoolAddress {
bytes32 internal constant POOL_INIT_CODE_HASH =
0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;
struct PoolKey {
address token0;
address token1;
uint24 fee;
}
function getPoolKey(
address tokenA,
address tokenB,
uint24 fee
) internal pure returns (PoolKey memory) {
if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA);
return PoolKey({ token0: tokenA, token1: tokenB, fee: fee });
}
function computeAddress(address factory, PoolKey memory key)
internal
pure
returns (address pool)
{
require(key.token0 < key.token1);
pool = address(
uint160(
uint256(
keccak256(
abi.encodePacked(
hex"ff",
factory,
keccak256(abi.encode(key.token0, key.token1, key.fee)),
POOL_INIT_CODE_HASH
)
)
)
)
);
}
}
文件 18 的 24:PoolData.sol
pragma solidity ^0.8.9;
struct PoolData {
address poolAddress;
address quoteToken;
uint24 fee;
uint256 positionId;
uint160 sqrtPriceX96;
int24 tickLower;
int24 tickUpper;
uint128 liquidity;
}
文件 19 的 24:PositionParams.sol
pragma solidity ^0.8.9;
struct MintParams {
address token0;
address token1;
uint24 fee;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
address recipient;
uint256 deadline;
}
struct IncreaseLiquidityParams {
uint256 tokenId;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
struct DecreaseLiquidityParams {
uint256 tokenId;
uint128 liquidity;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
struct CollectParams {
uint256 tokenId;
address recipient;
uint128 amount0Max;
uint128 amount1Max;
}
文件 20 的 24:RouterParams.sol
pragma solidity ^0.8.9;
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
文件 21 的 24:SignedMath.sol
pragma solidity ^0.8.20;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
return uint256(n >= 0 ? n : -n);
}
}
}
文件 22 的 24:Strings.sol
pragma solidity ^0.8.20;
import {Math} from "./math/Math.sol";
import {SignedMath} from "./math/SignedMath.sol";
library Strings {
bytes16 private constant HEX_DIGITS = "0123456789abcdef";
uint8 private constant ADDRESS_LENGTH = 20;
error StringsInsufficientHexLength(uint256 value, uint256 length);
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toStringSigned(int256 value) internal pure returns (string memory) {
return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
uint256 localValue = value;
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = HEX_DIGITS[localValue & 0xf];
localValue >>= 4;
}
if (localValue != 0) {
revert StringsInsufficientHexLength(value, length);
}
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
}
}
文件 23 的 24:TickMath.sol
pragma solidity ^0.8.4;
library TickMath {
int24 internal constant MIN_TICK = -887272;
int24 internal constant MAX_TICK = -MIN_TICK;
uint160 internal constant MIN_SQRT_RATIO = 4295128739;
uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;
function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {
uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));
require(absTick <= uint256(int256(MAX_TICK)), "T");
uint256 ratio = absTick & 0x1 != 0
? 0xfffcb933bd6fad37aa2d162d1a594001
: 0x100000000000000000000000000000000;
if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;
if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;
if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;
if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;
if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;
if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;
if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;
if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;
if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;
if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;
if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;
if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;
if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;
if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;
if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;
if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;
if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;
if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;
if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;
if (tick > 0) ratio = type(uint256).max / ratio;
sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));
}
function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {
require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, "R");
uint256 ratio = uint256(sqrtPriceX96) << 32;
uint256 r = ratio;
uint256 msb = 0;
assembly {
let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(5, gt(r, 0xFFFFFFFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(4, gt(r, 0xFFFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(3, gt(r, 0xFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(2, gt(r, 0xF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(1, gt(r, 0x3))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := gt(r, 0x1)
msb := or(msb, f)
}
if (msb >= 128) r = ratio >> (msb - 127);
else r = ratio << (127 - msb);
int256 log_2 = (int256(msb) - 128) << 64;
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(63, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(62, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(61, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(60, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(59, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(58, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(57, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(56, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(55, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(54, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(53, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(52, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(51, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(50, f))
}
int256 log_sqrt10001 = log_2 * 255738958999603826347141;
int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);
int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);
tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96
? tickHi
: tickLow;
}
}
文件 24 的 24:WHO404.sol
pragma solidity ^0.8.9;
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {ERC333} from "./ERC333/ERC333.sol";
import {FullMath} from "./utils/FullMath.sol";
contract WHO404 is ERC333 {
using Strings for uint256;
string private constant __NAME = "WHO404";
string private constant __SYM = "WHO";
uint256 private constant __MINT_SUPPLY = 1000;
uint24 private constant __TAX_PERCENT = 80000;
uint8 private constant __DECIMALS = 18;
uint8 private constant __RATIO = 100;
address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
constructor(
address initialOwner_,
address initialMintRecipient_
)
ERC333(
initialOwner_,
initialMintRecipient_,
__MINT_SUPPLY,
__TAX_PERCENT,
__NAME,
__SYM,
__DECIMALS,
__RATIO
)
{
baseURI = "https://who404.wtf/assets/";
}
function initialize() external payable override onlyOwner {
address positionManagerAddress = 0xC36442b4a4522E871399CD717aBDD847Ab11FE88;
address swapRouterAddress = 0xE592427A0AEce92De3Edee1F18E0157C05861564;
if (msg.value > 0) {
depositETH(msg.value);
}
uint160 sqrtPriceX96 = (address(this) < WETH)
? 1372272028650297984479657984
: 4574240095500993129133247561728;
uint256 quoteTokenAmount = _getWETHAtSqrtPriceX96(sqrtPriceX96);
uint256 wethAmount = balanceOfWETH();
require(wethAmount >= quoteTokenAmount, "weth amount is too low");
_initialize(
sqrtPriceX96,
3000,
WETH,
quoteTokenAmount,
60,
positionManagerAddress,
swapRouterAddress
);
}
function balanceOfWETH() internal returns (uint256 amount) {
(bool success, bytes memory data) = WETH.staticcall(
abi.encodeWithSelector(0x70a08231, address(this))
);
if (success) {
amount = abi.decode(data, (uint256));
}
}
function depositETH(uint256 amount) internal returns (bool) {
(bool success, ) = WETH.call{value: amount}(
abi.encodeWithSelector(0xd0e30db0)
);
return success;
}
function _getWETHAtSqrtPriceX96(
uint160 sqrtPriceX96
) private view returns (uint256 quoteAmount) {
uint256 thisAmount = balanceOf[address(this)];
if (sqrtPriceX96 <= type(uint128).max) {
uint256 ratioX192 = uint256(sqrtPriceX96) * sqrtPriceX96;
quoteAmount = address(this) < WETH
? FullMath.mulDiv(ratioX192, thisAmount, 1 << 192)
: FullMath.mulDiv(1 << 192, thisAmount, ratioX192);
} else {
uint256 ratioX128 = FullMath.mulDiv(
sqrtPriceX96,
sqrtPriceX96,
1 << 64
);
quoteAmount = address(this) < WETH
? FullMath.mulDiv(ratioX128, thisAmount, 1 << 128)
: FullMath.mulDiv(1 << 128, thisAmount, ratioX128);
}
}
function tokenURI(uint256 id) public view override returns (string memory) {
uint8 seed = uint8(bytes1(keccak256(abi.encodePacked(id))));
string memory image;
string memory color;
if (seed <= 64) {
image = "0.png";
color = "Red";
} else if (seed <= 128) {
image = "1.png";
color = "Blue";
} else if (seed <= 192) {
image = "2.png";
color = "Green";
} else {
image = "3.png";
color = "Purple";
}
return
string(
abi.encodePacked(
'{"name": "WHO404 NFT#',
Strings.toString(id),
'","description":"A collection of ',
Strings.toString(mintSupply),
" pots of liquidity that tokenizes decentralized reserve currency idea for the IQ50, #ERC333.",
'","external_url":"https://who404.wtf/","image":"',
baseURI,
image,
'","attributes":[{"trait_type":"Color","value":"',
color,
'"}]}'
)
);
}
receive() external payable {
depositETH(msg.value);
}
}
{
"compilationTarget": {
"contracts/WHO404.sol": "WHO404"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"initialOwner_","type":"address"},{"internalType":"address","name":"initialMintRecipient_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyExists","type":"error"},{"inputs":[],"name":"CannotRemoveFromERC721TransferExempt","type":"error"},{"inputs":[],"name":"DecimalsTooLow","type":"error"},{"inputs":[],"name":"InsufficientAllowance","type":"error"},{"inputs":[],"name":"InvalidApproval","type":"error"},{"inputs":[],"name":"InvalidId","type":"error"},{"inputs":[],"name":"InvalidOperator","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidSender","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidSpender","type":"error"},{"inputs":[],"name":"NotERC721TransferExempt","type":"error"},{"inputs":[],"name":"NotFound","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"OwnedIndexOverflow","type":"error"},{"inputs":[],"name":"PermitDeadlineExpired","type":"error"},{"inputs":[],"name":"QueueEmpty","type":"error"},{"inputs":[],"name":"QueueFull","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"UnsafeRecipient","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"uri","type":"string"}],"name":"BaseUriUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"ERC20Burn","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"poolAddress","type":"address"},{"internalType":"address","name":"quoteToken","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"uint256","name":"positionId","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint128","name":"liquidity","type":"uint128"}],"indexed":false,"internalType":"struct PoolData","name":"poolData","type":"tuple"}],"name":"Initialize","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"ReceiveTax","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"RefundETH","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string[]","name":"","type":"string[]"}],"name":"ScriptUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"_transferWithTax","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"valueOrId_","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"calculateERC721Transfers","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentPoolData","outputs":[{"internalType":"address","name":"poolAddress","type":"address"},{"internalType":"address","name":"quoteToken","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"uint256","name":"positionId","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint128","name":"liquidity","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentTick","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"erc20BalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc20TotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"erc721BalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc721TokensBankedInQueue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc721TotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"erc721TransferExempt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialMintRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"liquidity","type":"uint128"}],"name":"liquifyAndCollect","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"owned","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"erc721Owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"},{"internalType":"uint256","name":"deadline_","type":"uint256"},{"internalType":"uint8","name":"v_","type":"uint8"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"s_","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"positionManagerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"id_","type":"uint256"},{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"scriptURI","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator_","type":"address"},{"internalType":"bool","name":"approved_","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string[]","name":"newScriptURI","type":"string[]"}],"name":"setScriptURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"swapAndLiquify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapRouterAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxPercent","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tickThreshold","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"valueOrId_","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"units","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]