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:
Qian
2026-07-17 02:36:14 +00:00
commit 5f6db506c9
28 changed files with 2828 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
// ~ https://Qian.ag ~
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "../../interfaces/IPoolManager.sol";
import "../../interfaces/IHooks.sol";
import "../../errors/Errors.sol";
import { Hooks } from "./Hooks.sol";
/**
* @title GuardHook
* @notice Restricts pool initialization to the factory. A Qian PoolKey is derivable from
* a pending deployCoin, and v4's initialize is permissionless and reverts on an
* already-initialized pool, so without this anyone can front-run the initialize and the
* launch reverts.
*
* This is the hook for launches that want no hook behaviour: every swap-time flag is
* false, so the PoolManager never calls it on a trade. The creator's tax is the pool fee.
*
* Required hook flags: 0x2000 (beforeInitialize only). That is bit 13 — the SECOND byte
* of the address, not the last. A miner matching only the final byte will never find a
* valid salt.
*/
contract GuardHook is IHooks {
/// @notice Immutable: this hook has no admin functions and no owner. Deploy the
/// factory first, then this (an arg, not msg.sender — CREATE2 deploy).
address public immutable factory;
constructor(address _factory) {
if (_factory == address(0)) revert InvalidConfig();
factory = _factory;
}
// ------------------------------------------------ hook permissions
function getHookPermissions() external pure returns (Hooks.Permissions memory) {
return Hooks.Permissions({
beforeInitialize: true,
afterInitialize: false,
beforeAddLiquidity: false,
afterAddLiquidity: false,
beforeRemoveLiquidity: false,
afterRemoveLiquidity: false,
beforeSwap: false,
afterSwap: false,
beforeDonate: false,
afterDonate: false,
beforeSwapReturnDelta: false,
afterSwapReturnDelta: false,
afterAddLiquidityReturnDelta: false,
afterRemoveLiquidityReturnDelta: false
});
}
// ------------------------------------------------ the gate
function beforeInitialize(address sender, PoolKey calldata, uint160) external view returns (bytes4) {
if (sender != factory) revert Unauthorized();
return IHooks.beforeInitialize.selector;
}
// ------------------------------------------------ unused callbacks
// Every flag above is false, so the PoolManager never calls these. IHooks only.
function afterInitialize(address, PoolKey calldata, uint160, int24) external pure returns (bytes4) {
return IHooks.afterInitialize.selector;
}
function beforeSwap(address, PoolKey calldata, SwapParams calldata, bytes calldata)
external pure returns (bytes4, BeforeSwapDelta, uint24)
{
return (IHooks.beforeSwap.selector, BeforeSwapDelta.wrap(0), 0);
}
function afterSwap(address, PoolKey calldata, SwapParams calldata, BalanceDelta, bytes calldata)
external pure returns (bytes4, int128)
{
return (IHooks.afterSwap.selector, int128(0));
}
function beforeAddLiquidity(address, PoolKey calldata, ModifyLiquidityParams calldata, bytes calldata)
external pure returns (bytes4)
{
return IHooks.beforeAddLiquidity.selector;
}
function afterAddLiquidity(address, PoolKey calldata, ModifyLiquidityParams calldata, BalanceDelta, BalanceDelta, bytes calldata)
external pure returns (bytes4, BalanceDelta)
{
return (IHooks.afterAddLiquidity.selector, BalanceDelta.wrap(0));
}
function beforeRemoveLiquidity(address, PoolKey calldata, ModifyLiquidityParams calldata, bytes calldata)
external pure returns (bytes4)
{
return IHooks.beforeRemoveLiquidity.selector;
}
function afterRemoveLiquidity(address, PoolKey calldata, ModifyLiquidityParams calldata, BalanceDelta, BalanceDelta, bytes calldata)
external pure returns (bytes4, BalanceDelta)
{
return (IHooks.afterRemoveLiquidity.selector, BalanceDelta.wrap(0));
}
function beforeDonate(address, PoolKey calldata, uint256, uint256, bytes calldata) external pure returns (bytes4) {
return IHooks.beforeDonate.selector;
}
function afterDonate(address, PoolKey calldata, uint256, uint256, bytes calldata) external pure returns (bytes4) {
return IHooks.afterDonate.selector;
}
}
+26
View File
@@ -0,0 +1,26 @@
// ~ https://Qian.ag ~
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @notice Uniswap v4 hook permission flags, mirroring the canonical layout.
/// @dev Declarative only. v4 reads a hook's real permissions from the low 14 bits of its
/// address, not from this struct — if getHookPermissions() and the mined address disagree,
/// the address wins.
library Hooks {
struct Permissions {
bool beforeInitialize;
bool afterInitialize;
bool beforeAddLiquidity;
bool afterAddLiquidity;
bool beforeRemoveLiquidity;
bool afterRemoveLiquidity;
bool beforeSwap;
bool afterSwap;
bool beforeDonate;
bool afterDonate;
bool beforeSwapReturnDelta;
bool afterSwapReturnDelta;
bool afterAddLiquidityReturnDelta;
bool afterRemoveLiquidityReturnDelta;
}
}