Claim Deployer Fees
Withdraw your accrued share of post-graduation swap fees. Two steps: someone distributes, then you withdraw.
Why it is two calls
Swap fees accumulate in pendingFees[token] undivided. Nothing is credited to you until distributeFees(token) runs and splits them. That call is permissionless — anyone can trigger it, including you — but it is not automatic, so a token with plenty of trading volume can still show a zero deployer balance simply because nobody has distributed recently.
const HOOK_ABI = [
"function distributeFees(address token)",
"function withdrawDeployerFees(address token)",
"function deployerBalance(address token) view returns (uint256)",
"function getPendingFees(address token) view returns (uint256)",
"function canDistribute(address token) view returns (bool)",
"function getTokenInfo(address token) view returns (address deployer, uint256 positionId)"
];
const hook = new ethers.Contract(HOOK_ADDRESS, HOOK_ABI, signer);from web3 import Web3
HOOK_ABI = json.load(open("PrimaryHook.abi.json"))
w3 = Web3(Web3.HTTPProvider(RPC_URL))
acct = w3.eth.account.from_key(PRIVATE_KEY)
hook = w3.eth.contract(address=HOOK_ADDRESS, abi=HOOK_ABI)
def send(fn):
"""Build, sign and broadcast — used throughout these examples."""
tx = fn.build_transaction({
"from": acct.address,
"nonce": w3.eth.get_transaction_count(acct.address),
})
signed = acct.sign_transaction(tx)
return w3.eth.wait_for_transaction_receipt(
w3.eth.send_raw_transaction(signed.raw_transaction)
)Step 1 — Distribute
if (await hook.canDistribute(token)) {
await (await hook.distributeFees(token)).wait();
}if hook.functions.canDistribute(token).call():
send(hook.functions.distributeFees(token))On Gnosis there is an extra step first — V3 fees sit inside the position until pulled out:
// Gnosis only
await (await manager.collectFees(token)).wait();
await (await manager.distributeFees(token)).wait();# Gnosis only
send(manager.functions.collectFees(token))
send(manager.functions.distributeFees(token))Step 2 — Withdraw
const balance = await hook.deployerBalance(token);
if (balance > 0n) {
await (await hook.withdrawDeployerFees(token)).wait();
}balance = hook.functions.deployerBalance(token).call()
if balance > 0:
send(hook.functions.withdrawDeployerFees(token))The withdrawal pays out the full balance; there is no partial withdrawal. Only the address currently registered as deployer can call it.
Your share
| Chain family | Deployer | Protocol | Reinvested |
|---|---|---|---|
| V4 family | 30% | 10% | 60% |
| Gnosis | 40% | 20% | 40% |
V3 pays fees in both currencies. The deployer and protocol shares come exclusively from the native side; token-side fees go into a separate bucket and are burned or paired back into liquidity, never sold. Your 40% is 40% of the native fees, not of total fee value.
Distribution may be partial
The reinvest swap is bounded by the MEV cap, so a single distributeFees call may process only part of the pending balance. The rest carries forward and is picked up next time. This is normal — it is not a failure, and repeated calls will drain the backlog. A large accumulated balance on a thin pool may need several calls.
Checking a token's position
const [pending, credited, info] = await Promise.all([
hook.getPendingFees(token), // undistributed
hook.deployerBalance(token), // credited, withdrawable
hook.getTokenInfo(token) // (deployer, positionId)
]);
// Your eventual cut of `pending` is 30% (40% on Gnosis)pending = hook.functions.getPendingFees(token).call() # undistributed
credited = hook.functions.deployerBalance(token).call() # withdrawable
info = hook.functions.getTokenInfo(token).call() # (deployer, positionId)
# Your eventual cut of `pending` is 30% (40% on Gnosis)TokenTemplate.deployer() records the original launcher and is never updated. The authoritative current deployer — the one who can withdraw — is getTokenInfo(token).deployer on the hook. If a takeover succeeded, any balance you had not yet withdrawn was paid out to you during finalization; if that payment failed, it rolled into the balance the new team now owns.
Common reverts
| Revert | Cause |
|---|---|
Not deployer | Caller is not the currently registered deployer |
No fees | Nothing credited — distribute first |
No deployer fees for protocol token | $LP24 has no deployer share |
No position | Token has not graduated |
Pool too thin for any safe swap | Pool cannot absorb even a capped swap — wait for liquidity |