// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {
BalanceDelta,
BalanceDeltaLibrary,
BeforeSwapDelta,
BeforeSwapDeltaLibrary,
Currency,
CurrencyLibrary,
IHooks,
IPoolManager,
LPFeeLibrary,
ModifyLiquidityParams,
PoolId,
PoolIdLibrary,
PoolKey,
SwapParams,
TickMath
} from "./v4/V4Types.sol";
import {PumpRobinToken} from "./PumpRobinToken.sol";
import {IWETH} from "./interfaces/IWETH.sol";
/**
* @title PumpRobinHook
* @notice Uniswap v4 hook: 2% WETH fee on every swap (1% creator / 1% platform),
* optional 99% anti-snipe on buys for 15 minutes, LP locked forever.
* @dev Deploy via CREATE2 so `uint160(address) & 0x3FFF == 0x2ECC`.
*/
contract PumpRobinHook is Ownable {
using SafeERC20 for IERC20;
using PoolIdLibrary for PoolKey;
using CurrencyLibrary for Currency;
using BalanceDeltaLibrary for BalanceDelta;
using BeforeSwapDeltaLibrary for BeforeSwapDelta;
uint256 internal constant FEE_BPS = 200;
uint256 internal constant ANTI_SNIPE_BPS = 9_900;
uint256 internal constant BPS_DENOM = 10_000;
uint256 public constant PLATFORM_FLUSH_WEI = 0.012 ether;
int24 internal constant TICK_SPACING = 60;
int24 internal constant MIN_TICK = -887220;
int24 internal constant MAX_TICK = 887220;
IPoolManager public immutable poolManager;
address public immutable WETH;
address public immutable platformFeeRecipient;
address public factory;
struct PoolConfig {
address bondingCurve;
address creator;
address token;
uint128 pendingCreator;
uint128 pendingPlatform;
bool minted;
}
mapping(PoolId => PoolConfig) public pools;
mapping(address => PoolId) public poolIdForToken;
event FactorySet(address indexed factory);
event PoolRegistered(PoolId indexed poolId, address indexed token, address indexed creator);
event PoolMinted(PoolId indexed poolId, address currency0, address currency1);
event HookFeeTaken(PoolId indexed poolId, uint256 amount, bool antiSnipe);
event CreatorFeesClaimed(address indexed creator, address indexed token, uint256 amount);
event PlatformFeesFlushed(address indexed platform, address indexed token, uint256 amount);
constructor(
IPoolManager poolManager_,
address weth_,
address platformFeeRecipient_,
address initialOwner
) Ownable(initialOwner) {
require(address(poolManager_) != address(0) && weth_ != address(0), "Bad infra");
require(platformFeeRecipient_ != address(0), "Bad platform");
poolManager = poolManager_;
WETH = weth_;
platformFeeRecipient = platformFeeRecipient_;
}
receive() external payable {}
function setFactory(address factory_) external onlyOwner {
require(factory_ != address(0), "Bad factory");
factory = factory_;
emit FactorySet(factory_);
}
function register(PoolId poolId, address bondingCurve, address token, address creator) external {
require(msg.sender == factory, "Only factory");
require(bondingCurve != address(0) && token != address(0) && creator != address(0), "Bad args");
PoolConfig storage config = pools[poolId];
require(config.bondingCurve == address(0), "Registered");
config.bondingCurve = bondingCurve;
config.creator = creator;
config.token = token;
poolIdForToken[token] = poolId;
emit PoolRegistered(poolId, token, creator);
}
function pendingCreatorFees(address token) external view returns (uint256) {
return pools[poolIdForToken[token]].pendingCreator;
}
function pendingPlatformFees(address token) external view returns (uint256) {
return pools[poolIdForToken[token]].pendingPlatform;
}
function claimCreatorFees(address token) external {
PoolId poolId = poolIdForToken[token];
PoolConfig storage config = pools[poolId];
require(msg.sender == config.creator, "Not creator");
uint256 amt = config.pendingCreator;
require(amt > 0, "Nothing to claim");
config.pendingCreator = 0;
_payEth(config.creator, amt);
emit CreatorFeesClaimed(config.creator, token, amt);
}
function flushPlatformFees(address token) public {
PoolId poolId = poolIdForToken[token];
PoolConfig storage config = pools[poolId];
uint256 amt = config.pendingPlatform;
require(amt >= PLATFORM_FLUSH_WEI, "Below $30");
config.pendingPlatform = 0;
_payEth(platformFeeRecipient, amt);
emit PlatformFeesFlushed(platformFeeRecipient, token, amt);
}
/// @notice Permissionless: send platform WETH to the collector once ~$30 has accrued.
function sweep(address token) external {
if (pools[poolIdForToken[token]].pendingPlatform >= PLATFORM_FLUSH_WEI) {
flushPlatformFees(token);
}
}
function beforeInitialize(address sender, PoolKey calldata key, uint160) external view returns (bytes4) {
require(key.tickSpacing == TICK_SPACING, "Tick spacing");
require(sender == pools[key.toId()].bondingCurve, "Init");
return this.beforeInitialize.selector;
}
function beforeAddLiquidity(
address,
PoolKey calldata key,
ModifyLiquidityParams calldata params,
bytes calldata
) external view returns (bytes4) {
if (params.tickLower != MIN_TICK || params.tickUpper != MAX_TICK) revert("LP locked");
if (pools[key.toId()].minted) revert("LP locked");
return this.beforeAddLiquidity.selector;
}
function afterAddLiquidity(
address,
PoolKey calldata key,
ModifyLiquidityParams calldata,
BalanceDelta,
BalanceDelta,
bytes calldata
) external returns (bytes4, BalanceDelta) {
PoolId poolId = key.toId();
pools[poolId].minted = true;
emit PoolMinted(poolId, Currency.unwrap(key.currency0), Currency.unwrap(key.currency1));
return (this.afterAddLiquidity.selector, BalanceDeltaLibrary.ZERO_DELTA);
}
function beforeRemoveLiquidity(
address,
PoolKey calldata,
ModifyLiquidityParams calldata,
bytes calldata
) external pure returns (bytes4) {
revert("LP locked");
}
function beforeSwap(
address sender,
PoolKey calldata key,
SwapParams calldata params,
bytes calldata
) external returns (bytes4, BeforeSwapDelta, uint24) {
require(msg.sender == address(poolManager), "PM");
PoolConfig storage config = pools[key.toId()];
if (sender == config.bondingCurve) {
return (this.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, LPFeeLibrary.OVERRIDE_FEE_FLAG);
}
bool exactIn = params.amountSpecified < 0;
Currency specified = exactIn
? (params.zeroForOne ? key.currency0 : key.currency1)
: (params.zeroForOne ? key.currency1 : key.currency0);
if (Currency.unwrap(specified) == WETH) {
if (!exactIn) revert("No exact-out WETH");
uint256 feeBps = _buyFeeBps(config.token);
uint256 base = uint256(-params.amountSpecified);
uint256 fee = Math.mulDiv(base, feeBps, BPS_DENOM);
if (fee == 0) {
return (this.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, LPFeeLibrary.OVERRIDE_FEE_FLAG);
}
poolManager.take(specified, address(this), fee);
_accountFee(config, fee, feeBps == ANTI_SNIPE_BPS);
emit HookFeeTaken(key.toId(), fee, feeBps == ANTI_SNIPE_BPS);
return (
this.beforeSwap.selector,
BeforeSwapDeltaLibrary.toBeforeSwapDelta(SafeCast.toInt128(int256(fee)), 0),
LPFeeLibrary.OVERRIDE_FEE_FLAG
);
}
return (this.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, LPFeeLibrary.OVERRIDE_FEE_FLAG);
}
function afterSwap(
address sender,
PoolKey calldata key,
SwapParams calldata params,
BalanceDelta delta,
bytes calldata
) external returns (bytes4, int128) {
require(msg.sender == address(poolManager), "PM");
PoolConfig storage config = pools[key.toId()];
if (sender == config.bondingCurve) {
return (this.afterSwap.selector, 0);
}
bool exactIn = params.amountSpecified < 0;
Currency unspecified = exactIn
? (params.zeroForOne ? key.currency1 : key.currency0)
: (params.zeroForOne ? key.currency0 : key.currency1);
if (Currency.unwrap(unspecified) != WETH) {
return (this.afterSwap.selector, 0);
}
int128 wethAmount = Currency.unwrap(key.currency0) == WETH ? delta.amount0() : delta.amount1();
if (wethAmount == 0) return (this.afterSwap.selector, 0);
uint256 base = uint256(int256(wethAmount > 0 ? wethAmount : -wethAmount));
uint256 fee = Math.mulDiv(base, FEE_BPS, BPS_DENOM);
if (fee == 0) return (this.afterSwap.selector, 0);
poolManager.take(unspecified, address(this), fee);
_accountFee(config, fee, false);
emit HookFeeTaken(key.toId(), fee, false);
return (this.afterSwap.selector, SafeCast.toInt128(int256(fee)));
}
function _buyFeeBps(address token) internal view returns (uint256) {
if (token == address(0)) return FEE_BPS;
try PumpRobinToken(token).isAntiSnipeActive() returns (bool active) {
return active ? ANTI_SNIPE_BPS : FEE_BPS;
} catch {
return FEE_BPS;
}
}
function _accountFee(PoolConfig storage config, uint256 fee, bool antiSnipe) internal {
if (antiSnipe) {
config.pendingPlatform += SafeCast.toUint128(fee);
} else {
uint256 creatorShare = fee / 2;
uint256 platformShare = fee - creatorShare;
config.pendingCreator += SafeCast.toUint128(creatorShare);
config.pendingPlatform += SafeCast.toUint128(platformShare);
}
}
function _payEth(address to, uint256 wethAmt) internal {
IWETH(WETH).withdraw(wethAmt);
(bool ok, ) = to.call{value: wethAmt}("");
require(ok, "ETH send");
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "poolManager_",
"type": "address",
"internalType": "contract IPoolManager"
},
{
"name": "weth_",
"type": "address",
"internalType": "address"
},
{
"name": "platformFeeRecipient_",
"type": "address",
"internalType": "address"
},
{
"name": "initialOwner",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "nonpayable"
},
{
"name": "MathOverflowedMulDiv",
"type": "error",
"inputs": []
},
{
"name": "OwnableInvalidOwner",
"type": "error",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "OwnableUnauthorizedAccount",
"type": "error",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "SafeCastOverflowedIntDowncast",
"type": "error",
"inputs": [
{
"name": "bits",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "value",
"type": "int256",
"internalType": "int256"
}
]
},
{
"name": "SafeCastOverflowedUintDowncast",
"type": "error",
"inputs": [
{
"name": "bits",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "CreatorFeesClaimed",
"type": "event",
"inputs": [
{
"name": "creator",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "token",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "FactorySet",
"type": "event",
"inputs": [
{
"name": "factory",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "HookFeeTaken",
"type": "event",
"inputs": [
{
"name": "poolId",
"type": "bytes32",
"indexed": true,
"internalType": "PoolId"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "antiSnipe",
"type": "bool",
"indexed": false,
"internalType": "bool"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferred",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "PlatformFeesFlushed",
"type": "event",
"inputs": [
{
"name": "platform",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "token",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "PoolMinted",
"type": "event",
"inputs": [
{
"name": "poolId",
"type": "bytes32",
"indexed": true,
"internalType": "PoolId"
},
{
"name": "currency0",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "currency1",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "PoolRegistered",
"type": "event",
"inputs": [
{
"name": "poolId",
"type": "bytes32",
"indexed": true,
"internalType": "PoolId"
},
{
"name": "token",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "creator",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "PLATFORM_FLUSH_WEI",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "WETH",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "afterAddLiquidity",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
},
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "Currency"
},
{
"name": "currency1",
"type": "address",
"internalType": "Currency"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "contract IHooks"
}
],
"internalType": "struct PoolKey"
},
{
"name": "",
"type": "tuple",
"components": [
{
"name": "tickLower",
"type": "int24",
"internalType": "int24"
},
{
"name": "tickUpper",
"type": "int24",
"internalType": "int24"
},
{
"name": "liquidityDelta",
"type": "int256",
"internalType": "int256"
},
{
"name": "salt",
"type": "bytes32",
"internalType": "bytes32"
}
],
"internalType": "struct ModifyLiquidityParams"
},
{
"name": "",
"type": "int256",
"internalType": "BalanceDelta"
},
{
"name": "",
"type": "int256",
"internalType": "BalanceDelta"
},
{
"name": "",
"type": "bytes",
"internalType": "bytes"
}
],
"outputs": [
{
"name": "",
"type": "bytes4",
"internalType": "bytes4"
},
{
"name": "",
"type": "int256",
"internalType": "BalanceDelta"
}
],
"stateMutability": "nonpayable"
},
{
"name": "afterSwap",
"type": "function",
"inputs": [
{
"name": "sender",
"type": "address",
"internalType": "address"
},
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "Currency"
},
{
"name": "currency1",
"type": "address",
"internalType": "Currency"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "contract IHooks"
}
],
"internalType": "struct PoolKey"
},
{
"name": "params",
"type": "tuple",
"components": [
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
},
{
"name": "amountSpecified",
"type": "int256",
"internalType": "int256"
},
{
"name": "sqrtPriceLimitX96",
"type": "uint160",
"internalType": "uint160"
}
],
"internalType": "struct SwapParams"
},
{
"name": "delta",
"type": "int256",
"internalType": "BalanceDelta"
},
{
"name": "",
"type": "bytes",
"internalType": "bytes"
}
],
"outputs": [
{
"name": "",
"type": "bytes4",
"internalType": "bytes4"
},
{
"name": "",
"type": "int128",
"internalType": "int128"
}
],
"stateMutability": "nonpayable"
},
{
"name": "beforeAddLiquidity",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
},
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "Currency"
},
{
"name": "currency1",
"type": "address",
"internalType": "Currency"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "contract IHooks"
}
],
"internalType": "struct PoolKey"
},
{
"name": "params",
"type": "tuple",
"components": [
{
"name": "tickLower",
"type": "int24",
"internalType": "int24"
},
{
"name": "tickUpper",
"type": "int24",
"internalType": "int24"
},
{
"name": "liquidityDelta",
"type": "int256",
"internalType": "int256"
},
{
"name": "salt",
"type": "bytes32",
"internalType": "bytes32"
}
],
"internalType": "struct ModifyLiquidityParams"
},
{
"name": "",
"type": "bytes",
"internalType": "bytes"
}
],
"outputs": [
{
"name": "",
"type": "bytes4",
"internalType": "bytes4"
}
],
"stateMutability": "view"
},
{
"name": "beforeInitialize",
"type": "function",
"inputs": [
{
"name": "sender",
"type": "address",
"internalType": "address"
},
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "Currency"
},
{
"name": "currency1",
"type": "address",
"internalType": "Currency"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "contract IHooks"
}
],
"internalType": "struct PoolKey"
},
{
"name": "",
"type": "uint160",
"internalType": "uint160"
}
],
"outputs": [
{
"name": "",
"type": "bytes4",
"internalType": "bytes4"
}
],
"stateMutability": "view"
},
{
"name": "beforeRemoveLiquidity",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
},
{
"name": "",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "Currency"
},
{
"name": "currency1",
"type": "address",
"internalType": "Currency"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "contract IHooks"
}
],
"internalType": "struct PoolKey"
},
{
"name": "",
"type": "tuple",
"components": [
{
"name": "tickLower",
"type": "int24",
"internalType": "int24"
},
{
"name": "tickUpper",
"type": "int24",
"internalType": "int24"
},
{
"name": "liquidityDelta",
"type": "int256",
"internalType": "int256"
},
{
"name": "salt",
"type": "bytes32",
"internalType": "bytes32"
}
],
"internalType": "struct ModifyLiquidityParams"
},
{
"name": "",
"type": "bytes",
"internalType": "bytes"
}
],
"outputs": [
{
"name": "",
"type": "bytes4",
"internalType": "bytes4"
}
],
"stateMutability": "pure"
},
{
"name": "beforeSwap",
"type": "function",
"inputs": [
{
"name": "sender",
"type": "address",
"internalType": "address"
},
{
"name": "key",
"type": "tuple",
"components": [
{
"name": "currency0",
"type": "address",
"internalType": "Currency"
},
{
"name": "currency1",
"type": "address",
"internalType": "Currency"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooks",
"type": "address",
"internalType": "contract IHooks"
}
],
"internalType": "struct PoolKey"
},
{
"name": "params",
"type": "tuple",
"components": [
{
"name": "zeroForOne",
"type": "bool",
"internalType": "bool"
},
{
"name": "amountSpecified",
"type": "int256",
"internalType": "int256"
},
{
"name": "sqrtPriceLimitX96",
"type": "uint160",
"internalType": "uint160"
}
],
"internalType": "struct SwapParams"
},
{
"name": "",
"type": "bytes",
"internalType": "bytes"
}
],
"outputs": [
{
"name": "",
"type": "bytes4",
"internalType": "bytes4"
},
{
"name": "",
"type": "int256",
"internalType": "BeforeSwapDelta"
},
{
"name": "",
"type": "uint24",
"internalType": "uint24"
}
],
"stateMutability": "nonpayable"
},
{
"name": "claimCreatorFees",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "factory",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "flushPlatformFees",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "pendingCreatorFees",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "pendingPlatformFees",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "platformFeeRecipient",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "poolIdForToken",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "PoolId"
}
],
"stateMutability": "view"
},
{
"name": "poolManager",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IPoolManager"
}
],
"stateMutability": "view"
},
{
"name": "pools",
"type": "function",
"inputs": [
{
"name": "",
"type": "bytes32",
"internalType": "PoolId"
}
],
"outputs": [
{
"name": "bondingCurve",
"type": "address",
"internalType": "address"
},
{
"name": "creator",
"type": "address",
"internalType": "address"
},
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "pendingCreator",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "pendingPlatform",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "minted",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "register",
"type": "function",
"inputs": [
{
"name": "poolId",
"type": "bytes32",
"internalType": "PoolId"
},
{
"name": "bondingCurve",
"type": "address",
"internalType": "address"
},
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "creator",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "renounceOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setFactory",
"type": "function",
"inputs": [
{
"name": "factory_",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "sweep",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "receive",
"stateMutability": "payable"
}
]0x6040608081526004908136101561001f575b5050361561001d575f80fd5b005b5f91823560e01c806301681a6214610c1a57806321d0ee7014610bec578063259982e514610ac45780632a8b5b2a1461093d5780635146fcd5146108f5578063575e24b41461086f5780635bb47808146107d1578063715018a614610777578063778b0c53146107525780638da5cb5b1461072a5780639f063efc14610642578063a0e62eb91461060a578063aa1802bc146105e8578063ad5c4648146105a4578063b47b2fb114610522578063b5217bb4146104ad578063c45a015514610484578063c598b2f914610435578063d6ae6e4414610321578063dc4c90d3146102dd578063dc98354e146101f9578063eb13554f146101b15763f2fde38b146101285750610011565b346101ad5760203660031901126101ad57610141610c75565b9061014a61177d565b6001600160a01b0391821692831561019757505082546001600160a01b0319811683178455167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b51631e4fbdf760e01b8152908101849052602490fd5b8280fd5b5050346101f557816003193601126101f557517f00000000000000000000000061f928cbbc9b65c404c3db42bde403d78954add96001600160a01b03168152602090f35b5080fd5b5082346102da5760e03660031901126102da57610214610c75565b9060a03660231901126102da576001600160a01b039060c435828116036102da576084358060020b8091036101f557603c036102a85784829161025e61025936610e7b565b611712565b81526002602052205416911603610280578151636e4c1aa760e11b8152602090f35b606491519062461bcd60e51b8252602081830152602482015263125b9a5d60e21b6044820152fd5b845162461bcd60e51b8152602081860152600c60248201526b5469636b2073706163696e6760a01b6044820152606490fd5b80fd5b5050346101f557816003193601126101f557517f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e409516001600160a01b03168152602090f35b508290346101f557602092836003193601126101ad576001600160a01b039384610349610c75565b16928385526003825282852054855260028252828520956001870181815416978833036104045760030180546001600160801b0381169485156103ce57507faa4ecfd5324d73e3b54d038b3ae8ac8f88866d49dc334dc1f02fe36e0f935748969798996103c39286926001600160801b0319169055611605565b54169351908152a380f35b875162461bcd60e51b8152908101879052601060248201526f4e6f7468696e6720746f20636c61696d60801b6044820152606490fd5b855162461bcd60e51b8152808501869052600b60248201526a2737ba1031b932b0ba37b960a91b6044820152606490fd5b5050346101f55760203660031901126101f5576020916001600160801b039060039083906001600160a01b03610469610c75565b16815282865281812054815260028652200154169051908152f35b5050346101f557816003193601126101f55760015490516001600160a01b039091168152602090f35b50346101ad5760203660031901126101ad578160c0938235815260026020522060018060a01b0391828254169360ff84600185015416946002850154169260038501549401541693815195865260208601528401526001600160801b038116606084015260801c6080830152151560a0820152f35b508290346101f5576101603660031901126101f55761053f610c75565b9160a03660231901126102da5760603660c31901126102da57610144359067ffffffffffffffff82116102da575061058a929161057e91369101610ca3565b505061012435906112cd565b82516001600160e01b03199092168252600f0b6020820152f35b5050346101f557816003193601126101f557517f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b03168152602090f35b5050346101f557816003193601126101f55760209051662aa1efb94e00008152f35b5050346101f55760203660031901126101f55760209181906001600160a01b03610632610c75565b1681526003845220549051908152f35b508290346101f5576101a03660031901126101f55761065f610c75565b5060a03660231901126101f55760803660c31901126101f5576101843567ffffffffffffffff81116101ad576106989036908301610ca3565b50506106a661025936610e7b565b8083526002602052838320909101805460ff191660011790556001600160a01b03602435818116919082900361072657604435908116809103610726577f4518920c2f225659d6dda9e860312f5f1af7cbe6ee8fd579c70b84cb456b923691859182519182526020820152a28151906327c18fbf60e21b82526020820152f35b8380fd5b5050346101f557816003193601126101f557905490516001600160a01b039091168152602090f35b83346102da5760203660031901126102da5761077461076f610c75565b610d35565b80f35b83346102da57806003193601126102da5761079061177d565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b50346101ad5760203660031901126101ad576107eb610c75565b6107f361177d565b6001600160a01b031691821561083e575050600180546001600160a01b031916821790557f1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b18280a280f35b906020606492519162461bcd60e51b8352820152600b60248201526a42616420666163746f727960a81b6044820152fd5b508290346101f5576101403660031901126101f55761088c610c75565b9160a03660231901126102da5760603660c31901126102da57610124359067ffffffffffffffff82116102da57606062ffffff866108d7876108d036888a01610ca3565b5050610f49565b9083949294519463ffffffff60e01b16855260208501521690820152f35b5050346101f55760203660031901126101f55760209160039082906001600160a01b03610920610c75565b1681528285528181205481526002855220015460801c9051908152f35b50346101ad5760803660031901126101ad576001600160a01b03602435818116938335929091859003610ac05760443593818516809503610abc5760643595828716809703610ab85782600154163303610a865780151580610a7d575b80610a74575b15610a46578488526002602052838820918254938416610a1657506001600160a01b0319928316178155600181018054831687179055600201805490911684179055828552600360205284208190557ffafdbdd88ac30f0aa936e576be61816ea751908540523fa81b80c4a406ad7bec8480a480f35b606490602086519162461bcd60e51b8352820152600a602482015269149959da5cdd195c995960b21b6044820152fd5b835162461bcd60e51b81526020818401526008602482015267426164206172677360c01b6044820152606490fd5b508615156109a0565b5085151561099a565b835162461bcd60e51b8152602081840152600c60248201526b4f6e6c7920666163746f727960a01b6044820152606490fd5b8780fd5b8680fd5b8580fd5b5082346102da57610ad436610cd1565b5050909150620d89b319610ae782610e07565b60020b1490811591610bcf575b50610bb85760a0813603126101f557835190610b0f82610e15565b610b1881610c8f565b8252610b2660208201610c8f565b60208301528481013562ffffff81168103610726578583015260608101358060020b8103610726576060830152608001356001600160a01b03811681036101ad5760ff92610b7b838793608088960152611712565b8152600260205220015416610b9b57815163259982e560e01b8152602090f35b905162461bcd60e51b8152908190610bb4908201610ef4565b0390fd5b835162461bcd60e51b815280610bb4818601610ef4565b620d89b491506020610be19101610e07565b60020b141585610af4565b5090346101ad57610bb49250610c0136610cd1565b50505050505191829162461bcd60e51b83528201610ef4565b5050346101f55760203660031901126101f557662aa1efb94e00006003610c3f610c75565b6001600160a01b0381168552602082815284862054865260029052928420015460801c1015610c6c575080f35b61077490610d35565b600435906001600160a01b0382168203610c8b57565b5f80fd5b35906001600160a01b0382168203610c8b57565b9181601f84011215610c8b5782359167ffffffffffffffff8311610c8b5760208381860195010111610c8b57565b90610160600319830112610c8b576004356001600160a01b0381168103610c8b579160a0602319820112610c8b57602491608060c319830112610c8b5760c491610144359067ffffffffffffffff8211610c8b57610d3191600401610ca3565b9091565b60018060a01b0380911690815f52600360205260405f20545f526002602052600360405f200180548060801c92662aa1efb94e00008410610dd6577f018ab89a03392690616364a92de4c708840145f22adb3a8fb020d55a93ae043a926001600160801b036020931690557f00000000000000000000000061f928cbbc9b65c404c3db42bde403d78954add9610dcb8582611605565b6040519485521692a3565b60405162461bcd60e51b8152602060048201526009602482015268042656c6f77202433360bc1b6044820152606490fd5b358060020b8103610c8b5790565b60a0810190811067ffffffffffffffff821117610e3157604052565b634e487b7160e01b5f52604160045260245ffd5b67ffffffffffffffff8111610e3157604052565b90601f8019910116810190811067ffffffffffffffff821117610e3157604052565b60a0906023190112610c8b5760405190610e9482610e15565b6001600160a01b03826024358281168103610c8b5781526044358281168103610c8b57602082015260643562ffffff81168103610c8b5760408201526084358060020b8103610c8b57606082015260a4359182168203610c8b5760800152565b6060906020815260096020820152681314081b1bd8dad95960ba1b60408201520190565b15610f1f57565b60405162461bcd60e51b8152602060048201526002602482015261504d60f01b6044820152606490fd5b906001600160a01b037f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951811690610f81338314610f18565b610f8d61025936610e7b565b935f94855260026020526040928386209183808454169116146112b75760e4359086821293845f146112835760c435801515810361126f571561127357602435818116810361126f575b945b817f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad73168287161461101d57506315d7892d60e21b9796624000009650945050505050565b9794959715611237576110359060028501541661155e565b91600160ff1b8114611223578261104d9186036117a8565b94851561120a57813b15611206578751630b0d9c0960e01b81526001600160a01b03919091166004820152306024820152604481018690529084908290606490829084905af180156111fc57906126ac92916111ed575b501491821561114f575061113a939461111c7f4df0f885588f3e4064a51769477ad350e7c8e7c53d3db9763e1850448a65da57926110f360036110e688611889565b920191825460801c6115ea565b81546001600160801b031660809190911b6fffffffffffffffffffffffffffffffff1916179055565b61112861025936610e7b565b928151908582526020820152a26118bc565b60801b906315d7892d60e21b91906240000090565b8360011c808503918583116111d957507f4df0f885588f3e4064a51769477ad350e7c8e7c53d3db9763e1850448a65da57926110f361113a9798936111cb600361119b6111d496611889565b9401938454906111b56001600160801b03918284166115ea565b16906001600160801b0319161791828555611889565b9060801c6115ea565b61111c565b634e487b7160e01b81526011600452602490fd5b6111f690610e45565b5f6110a4565b87513d86823e3d90fd5b8480fd5b506315d7892d60e21b9650929462400000945092505050565b634e487b7160e01b85526011600452602485fd5b875162461bcd60e51b815260206004820152601160248201527009cde40caf0c2c6e85adeeae840ae8aa89607b1b6044820152606490fd5b8880fd5b6044358181168114610fd7578880fd5b60c435801515810361126f57156112a757604435818116810361126f575b94610fd9565b60243581811681146112a1578880fd5b506315d7892d60e21b9493624000009350915050565b906001600160a01b03907f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e409518216611305338214610f18565b61131161025936610e7b565b915f92835260026020526040832094848087541691161461149e578260e435125f1461152a5760c4358015158103610726571561151a576044358481168103610726575b935b807f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad73169081818716036115055760243590811680910361120657036114fd5760801d5b80600f0b9081156114e957838213156114b1576113bb91505b600f0b611822565b92831561149e57813b156101ad57604051630b0d9c0960e01b81526001600160a01b03919091166004820152306024820152604481018490529082908290606490829084905af1801561149357611484575b508160011c9283830390838211611470576110f3611436926111cb600361119b61146599611889565b7f4df0f885588f3e4064a51769477ad350e7c8e7c53d3db9763e1850448a65da57604061112861025936610e7b565b63b47b2fb160e01b91565b634e487b7160e01b5f52601160045260245ffd5b61148d90610e45565b5f61140d565b6040513d84823e3d90fd5b5063b47b2fb160e01b9491935090915050565b506f7fffffffffffffffffffffffffffffff1981146114d5576113bb9083036113b3565b634e487b7160e01b83526011600452602483fd5b5063b47b2fb160e01b959294509192505050565b600f0b61139a565b5063b47b2fb160e01b96939550929350505050565b6024358481168114611355578380fd5b60c4358015158103610726571561154e576024358481168103610726575b93611357565b6044358481168114611548578380fd5b6001600160a01b031680156115e4576020600491604051928380926387f86db760e01b82525afa80915f916115aa575b509061159a575060c890565b156115a5576126ac90565b60c890565b6020813d82116115dc575b816115c260209383610e59565b810103126101f557519081151582036102da57505f61158e565b3d91506115b5565b5060c890565b9190916001600160801b038080941691160191821161147057565b7f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad736001600160a01b031690813b15610c8b576040518092632e1a7d4d60e01b82528160245f958680948960048401525af18015611707576116f4575b508180809481935af1903d156116ee573d9067ffffffffffffffff82116116da576040519161169a601f8201601f191660200184610e59565b825260203d92013e5b156116aa57565b60405162461bcd60e51b8152602060048201526008602482015267115512081cd95b9960c21b6044820152606490fd5b634e487b7160e01b81526041600452602490fd5b506116a3565b61170090929192610e45565b905f611661565b6040513d85823e3d90fd5b6040516020810191608060018060a01b039182815116855282602082015116604085015262ffffff6040820151166060850152606081015160020b8285015201511660a082015260a0815260c0810181811067ffffffffffffffff821117610e315760405251902090565b5f546001600160a01b0316330361179057565b60405163118cdaa760e01b8152336004820152602490fd5b90808202905f1981840990828083109203918083039214611817576127109082821115611805577fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e91940990828211900360fc1b910360041c170290565b60405163227bc15360e01b8152600490fd5b505061271091500490565b60c881025f1960c8830981808210910390808203911461187f57612710818111156118055760c87fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e91940990828211900360fc1b910360041c170290565b5061271091500490565b6001600160801b039081811161189d571690565b604490604051906306dfcc6560e41b8252608060048301526024820152fd5b9081600f0b918083036118cc5750565b6044906040519063327269a760e01b8252608060048301526024820152fdfea26469706673582212207fd7ed5f1a494cab0f099a322eff41e1515aba303553ebd30551e062e1514ccc64736f6c63430008140033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| no token holdings | ||||
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| no token transfers for this address yet | |||||||||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0x6a5ca9…7c8026 | 1 day agoSun, 16 Aug 2026 11:28:47 UTC | 0x451892…9236 | [0] 0xed6b61d3f4cb…321075bf data: 0x000000000000000000…0905a91c |
| 0x6a5ca9…7c8026 | 1 day agoSun, 16 Aug 2026 11:28:47 UTC | 0xfafdbd…7bec | [0] 0xed6b61d3f4cb…321075bf [1] 0x000000000000…0905a91c [2] 0x000000000000…fdedd090 |
| 0xe3b695…67f92a | 1 day agoSun, 16 Aug 2026 11:03:13 UTC | 0x1edf3a…41b1 | [0] 0x000000000000…c85fb42b |
| 0xede22c…e37347 | 1 day agoSun, 16 Aug 2026 11:02:08 UTC | 0x8be007…57e0 | [0] 0x000000000000…00000000 [1] 0x000000000000…2c0c444d |
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0xe3b695…67f92a | setFactory | 37,924,829 | 1 day agoSun, 16 Aug 2026 11:03:13 UTC | 0xf3b4…444d | IN | PumpRobinHook | $0.000 ETH | 0.00000103 |
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| 37,924,171 | 1 day agoSun, 16 Aug 2026 11:02:08 UTC | 0xede22c…e37347 | CREATE2 | optimized_routeFill921336808 | 0x4e59…956c | IN | 0xdbac…2ecc | 0 ETH |