Qian V2 Contracts
Onchain token launch with permanently locked liquidity and DEX routing (Uniswap v3 + v4). No admin keys, no mint/blacklist. MIT licensed. Deployed addresses in README.
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Qian Exchange - https://qian.ag
|
||||
pragma solidity ^0.8.24;
|
||||
|
||||
import "./IPoolManager.sol";
|
||||
|
||||
/**
|
||||
* @title IConfigurableHook
|
||||
* @notice Generic interface for hooks that can be configured by the factory
|
||||
* @dev All hooks that want to be auto-configured by QianFactoryV4 must implement this interface
|
||||
*
|
||||
* This allows the factory to remain hook-agnostic - new hooks can be added
|
||||
* without modifying the factory contract. Each hook:
|
||||
* 1. Defines its own config format (decoded from bytes)
|
||||
* 2. Validates its own constraints (tax limits, thresholds, etc.)
|
||||
* 3. Stores per-pool configuration
|
||||
*
|
||||
* Example config encoding:
|
||||
* - AutoBuyBurnHook: abi.encode(uint16 buyTaxBps, uint16 sellTaxBps, uint256 threshold)
|
||||
* - QianTaxHook: abi.encode(uint16 buyTaxBps, uint16 sellTaxBps, uint16 snipeStartBps, uint16 snipeEndBps, uint32 snipeDecaySeconds)
|
||||
* - FutureHook: abi.encode(param1, param2, param3, ...)
|
||||
*/
|
||||
interface IConfigurableHook {
|
||||
/**
|
||||
* @notice Configure the hook for a newly deployed token's pool
|
||||
* @param poolId The pool identifier (keccak256 of PoolKey)
|
||||
* @param tokenAddress The token address being configured
|
||||
* @param config Hook-specific configuration data (abi.encoded)
|
||||
* @dev Called by factory during deployCoin(). Must validate and store config.
|
||||
* Should revert if already configured (immutability) or invalid params.
|
||||
*/
|
||||
function configureHook(
|
||||
bytes32 poolId,
|
||||
address tokenAddress,
|
||||
bytes calldata config
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @notice Get the pool ID from a PoolKey
|
||||
* @param key The pool key
|
||||
* @return poolId The computed pool identifier
|
||||
*/
|
||||
function getPoolId(PoolKey calldata key) external pure returns (bytes32);
|
||||
|
||||
/**
|
||||
* @notice Check if a pool has been configured for this hook
|
||||
* @param poolId The pool identifier
|
||||
* @return True if the pool is configured and enabled
|
||||
*/
|
||||
function isConfigured(bytes32 poolId) external view returns (bool);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Qian Exchange - https://qian.ag
|
||||
pragma solidity ^0.8.24;
|
||||
|
||||
/// @notice Currency type for Uniswap V4
|
||||
/// Wraps an address to represent a token or native ETH
|
||||
type Currency is address;
|
||||
|
||||
/// @notice Currency library for V4
|
||||
library CurrencyLibrary {
|
||||
/// @notice Wrap an address as Currency
|
||||
function wrap(address token) internal pure returns (Currency) {
|
||||
return Currency.wrap(token);
|
||||
}
|
||||
|
||||
/// @notice Unwrap Currency to address
|
||||
function unwrap(Currency currency) internal pure returns (address) {
|
||||
return Currency.unwrap(currency);
|
||||
}
|
||||
|
||||
/// @notice Native ETH currency
|
||||
function native() internal pure returns (Currency) {
|
||||
return Currency.wrap(address(0));
|
||||
}
|
||||
|
||||
/// @notice Check if currency is native ETH
|
||||
function isNative(Currency currency) internal pure returns (bool) {
|
||||
return Currency.unwrap(currency) == address(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Qian Exchange - https://qian.ag
|
||||
pragma solidity ^0.8.24;
|
||||
|
||||
/// @notice Optional interface for hooks to expose fee configuration
|
||||
/// This allows the factory/fee collector to understand hook fee behavior
|
||||
interface IHookFeeConfig {
|
||||
/// @notice Get the fee split configuration
|
||||
/// @return platformBps Platform fee in basis points (out of 10000)
|
||||
/// @return hookBps Hook fee in basis points (out of 10000)
|
||||
/// @return creatorBps Creator fee in basis points (out of 10000)
|
||||
/// @dev Sum should equal 10000
|
||||
function getFeeSplit() external view returns (uint256 platformBps, uint256 hookBps, uint256 creatorBps);
|
||||
|
||||
/// @notice Get hook name/identifier
|
||||
function getHookName() external view returns (string memory);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Qian Exchange - https://qian.ag
|
||||
pragma solidity ^0.8.24;
|
||||
|
||||
import "./IPoolManager.sol";
|
||||
|
||||
/// @notice Swap parameters for hook callbacks
|
||||
struct SwapParams {
|
||||
bool zeroForOne;
|
||||
int256 amountSpecified;
|
||||
uint160 sqrtPriceLimitX96;
|
||||
}
|
||||
|
||||
/// @notice Uniswap V4 Hooks interface
|
||||
/// Hooks can implement various callbacks to customize pool behavior
|
||||
interface IHooks {
|
||||
/// @notice Called before a pool is initialized
|
||||
function beforeInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96) external returns (bytes4);
|
||||
|
||||
/// @notice Called after a pool is initialized
|
||||
function afterInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96, int24 tick) external returns (bytes4);
|
||||
|
||||
/// @notice Called before a swap
|
||||
function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata hookData) external returns (bytes4, BeforeSwapDelta, uint24);
|
||||
|
||||
/// @notice Called after a swap
|
||||
function afterSwap(address sender, PoolKey calldata key, SwapParams calldata params, BalanceDelta delta, bytes calldata hookData) external returns (bytes4, int128);
|
||||
|
||||
/// @notice Called before liquidity is added
|
||||
function beforeAddLiquidity(address sender, PoolKey calldata key, ModifyLiquidityParams calldata params, bytes calldata hookData) external returns (bytes4);
|
||||
|
||||
/// @notice Called after liquidity is added
|
||||
function afterAddLiquidity(address sender, PoolKey calldata key, ModifyLiquidityParams calldata params, BalanceDelta delta, BalanceDelta feesAccrued, bytes calldata hookData) external returns (bytes4, BalanceDelta);
|
||||
|
||||
/// @notice Called before liquidity is removed
|
||||
function beforeRemoveLiquidity(address sender, PoolKey calldata key, ModifyLiquidityParams calldata params, bytes calldata hookData) external returns (bytes4);
|
||||
|
||||
/// @notice Called after liquidity is removed
|
||||
function afterRemoveLiquidity(address sender, PoolKey calldata key, ModifyLiquidityParams calldata params, BalanceDelta delta, BalanceDelta feesAccrued, bytes calldata hookData) external returns (bytes4, BalanceDelta);
|
||||
|
||||
/// @notice Called before a donate
|
||||
function beforeDonate(address sender, PoolKey calldata key, uint256 amount0, uint256 amount1, bytes calldata hookData) external returns (bytes4);
|
||||
|
||||
/// @notice Called after a donate
|
||||
function afterDonate(address sender, PoolKey calldata key, uint256 amount0, uint256 amount1, bytes calldata hookData) external returns (bytes4);
|
||||
}
|
||||
|
||||
/// @notice Before swap delta type - encodes (specifiedDelta, unspecifiedDelta)
|
||||
type BeforeSwapDelta is int256;
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.24;
|
||||
|
||||
import "./ICurrency.sol";
|
||||
import "./IHooks.sol";
|
||||
|
||||
// BalanceDelta is a packed int256 where:
|
||||
// - Upper 128 bits = amount0 (int128)
|
||||
// - Lower 128 bits = amount1 (int128)
|
||||
type BalanceDelta is int256;
|
||||
|
||||
/// @notice Library for getting amount0/amount1 from BalanceDelta
|
||||
library BalanceDeltaLibrary {
|
||||
function amount0(BalanceDelta balanceDelta) internal pure returns (int128 _amount0) {
|
||||
assembly ("memory-safe") {
|
||||
_amount0 := sar(128, balanceDelta)
|
||||
}
|
||||
}
|
||||
|
||||
function amount1(BalanceDelta balanceDelta) internal pure returns (int128 _amount1) {
|
||||
assembly ("memory-safe") {
|
||||
_amount1 := signextend(15, balanceDelta)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @notice PoolKey identifies a V4 pool
|
||||
struct PoolKey {
|
||||
Currency currency0;
|
||||
Currency currency1;
|
||||
uint24 fee;
|
||||
int24 tickSpacing;
|
||||
IHooks hooks;
|
||||
}
|
||||
|
||||
/// @notice Parameters for modifyLiquidity
|
||||
struct ModifyLiquidityParams {
|
||||
int24 tickLower;
|
||||
int24 tickUpper;
|
||||
int256 liquidityDelta;
|
||||
bytes32 salt;
|
||||
}
|
||||
|
||||
/// @notice Interface for Uniswap V4 PoolManager
|
||||
interface IPoolManager {
|
||||
/// @notice Initialize the state for a given pool
|
||||
function initialize(PoolKey memory key, uint160 sqrtPriceX96) external returns (int24 tick);
|
||||
|
||||
/// @notice Modify the liquidity for the given pool
|
||||
function modifyLiquidity(PoolKey memory key, ModifyLiquidityParams memory params, bytes calldata hookData)
|
||||
external
|
||||
returns (BalanceDelta callerDelta, BalanceDelta feesAccrued);
|
||||
|
||||
/// @notice All interactions on the contract that account deltas require unlocking
|
||||
function unlock(bytes calldata data) external returns (bytes memory);
|
||||
|
||||
/// @notice Sync the currency to its current balance in the PoolManager
|
||||
function sync(Currency currency) external;
|
||||
|
||||
/// @notice Settle the currency, paying what is owed
|
||||
function settle() external payable returns (uint256 paid);
|
||||
|
||||
/// @notice Take currency from the PoolManager
|
||||
/// @param currency The currency to take
|
||||
/// @param to The address to receive the currency
|
||||
/// @param amount The amount to take
|
||||
function take(Currency currency, address to, uint256 amount) external;
|
||||
|
||||
/// @notice Execute a swap
|
||||
/// @param key The pool key
|
||||
/// @param params The swap parameters
|
||||
/// @param hookData Any data to be passed to hooks
|
||||
function swap(PoolKey memory key, SwapParams memory params, bytes calldata hookData)
|
||||
external
|
||||
returns (BalanceDelta swapDelta);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Qian Exchange - https://qian.ag
|
||||
pragma solidity ^0.8.24;
|
||||
|
||||
/// @notice Interface for the callback executed when an address unlocks the pool manager
|
||||
interface IUnlockCallback {
|
||||
/// @notice Called by the pool manager on `msg.sender` when the manager is unlocked
|
||||
/// @param data The data that was passed to the call to unlock
|
||||
/// @return Any data that you want to be returned from the unlock call
|
||||
function unlockCallback(bytes calldata data) external returns (bytes memory);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Qian Exchange - https://qian.ag
|
||||
pragma solidity ^0.8.24;
|
||||
|
||||
interface IWETH {
|
||||
function deposit() external payable;
|
||||
function withdraw(uint256 amount) external;
|
||||
function transfer(address to, uint256 amount) external returns (bool);
|
||||
function transferFrom(address from, address to, uint256 amount) external returns (bool);
|
||||
function approve(address spender, uint256 amount) external returns (bool);
|
||||
function balanceOf(address account) external view returns (uint256);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user