SinjohTraditionalHook
RobinhoodSinjohTraditionalHook is a Uniswap v4 hook on Robinhood Chain. Runs code on every swap. Can take tokens from swaps. Sets its own swap fee. Can block LP withdrawals. Gates who can add liquidity. Runs at pool creation. Handles donations to LPs.
- Contract name
- SinjohTraditionalHook
How this hook works
Trading taxA trading tax hook. It sets its own trading fee, takes a tax on trades and keeps rewards to claim.
Sets its own trading fee
It sets the pool’s trading fee itself instead of using a fixed one.
The code that does this (completeGraduation):function completeGraduation(PoolId poolId, uint256 tokenId, uint128 liquidity) external onlyFactory { Graduation storage g = _graduations[poolId]; Phase phase = phaseOf(poolId); if (phase != Phase.Swept) revert WrongPhase(phase); (g.graduated, g.graduatedAt, g.liquidity, g.tokenId) = (true, uint64(block.timestamp), liquidity, tokenId); FutureMarket storage f = _future[poolId]; if (f.kind != LaunchKind.Curve) { // Owner decision (27 October 2026): a slot pool's tax model starts at actual graduation. f.modelStart = uint64(block.timestamp); emit ModelStarted(poolId, uint64(block.timestamp)); } if (_isPoolCurve(poolId)) poolManager.updateDynamicLPFee(_poolKey(_markets[poolId]), LP_FEE); SinjohTraditionalToken(_markets[poolId].token).notifyGraduation(); if (_pairedBacking[poolId]) { ISinjohPairedToken(_markets[poolId].backing).notifyPairedGraduation(poolId); } emit Graduated(poolId, tokenId, liquidity, uint64(block.timestamp)); }Takes a tax on trades
On top of the normal pool fee, it keeps part of each trade as a tax. Buys and sells can be taxed differently.
The code that does this (beforeSwap):function _beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata) internal override returns (bytes4, BeforeSwapDelta, uint24) { PoolId poolId = key.toId(); // A module's own swap in the window the root opened for it on this pool (trusted transient state, never hook // data): uncharged here, its flows are charged per direction through `chargeModule` and reconciled at close. address window = WINDOW_MODULE_SLOT.asAddress().tload(); if (window != address(0)) { if (sender != window || WINDOW_POOL_SLOT.asBytes32().tload() != PoolId.unwrap(poolId)) { revert SwapReentered(); } if (MODULE_SWAP_SLOT.asBoolean().tload()) revert SwapReentered(); MODULE_SWAP_SLOT.asBoolean().tstore(true); return (IHooks.beforeSwap.selector, toBeforeSwapDelta(0, 0), 0); } if (SWAP_LOCK_SLOT.asBoolean().tload() || _reentrancyGuardEntered()) revert SwapReentered(); if (!_graduations[poolId].graduated) { if (!_isPoolCurve(poolId) || phaseOf(poolId) != Phase.Curve) revert WrongPhase(phaseOf(poolId)); SWAP_LOCK_SLOT.asBoolean().tstore(true); CURVE_SWAP_SLOT.asBoolean().tstore(true); return _beforeCurveSwap(sender, key, params); } // Pending module flow settles before the trade's pre-trade state is read. _runModules(key, Hooks.BEFORE_SWAP_FLAG); SWAP_LOCK_SLOT.asBoolean().tstore(true); ISinjohHook.Market storage m = _markets[poolId]; bool buy = params.zeroForOne != m.tokenIsCurrency0; bool exactInput = params.amountSpecified < 0; // …Rewards to claim
It keeps track of what people have earned, and they claim it themselves.
The code that does this (redeemVaultClaims):function redeemVaultClaims(PoolId poolId, uint256 amount) external { ISinjohHook.Market storage m = _market(poolId); if (msg.sender != m.vault) revert NotVault(msg.sender); // The callback returns nothing. // slither-disable-next-line unused-return poolManager.unlock(abi.encode(OP_REDEEM, abi.encode(poolId, amount))); }Rules for adding or removing liquidity
It decides who can add or remove liquidity, or when.
The code that does this (beforeAddLiquidity):function _beforeAddLiquidity(address sender, PoolKey calldata key, ModifyLiquidityParams calldata, bytes calldata) internal override returns (bytes4) { _beforeLiquidity(sender, key, Hooks.BEFORE_ADD_LIQUIDITY_FLAG); return IHooks.beforeAddLiquidity.selector; }Only approved callers create pools
New pools with this hook can only be created by approved callers, for example its own factory or launcher.
The code that does this (beforeInitialize):function _beforeInitialize(address sender, PoolKey calldata key, uint160) internal view override returns (bytes4) { PoolId poolId = key.toId(); _market(poolId); Phase phase = phaseOf(poolId); if (_isPoolCurve(poolId) && phase == Phase.Curve) { if (sender != curveOf[poolId]) revert NotCurve(); } else { if (sender != factory) revert NotFactory(); if (phase != Phase.Swept) revert WrongPhase(phase); } return IHooks.beforeInitialize.selector; }Anyone can trigger payouts
Anyone can collect the fees it has built up, so nobody has to wait on the hook developer.
The code that does this (collectPlatform):function collectPlatform(PoolId[] calldata poolIds) external nonReentrant { address recipient = ISinjohSettings(settings).feeRecipient(); Payment[] memory payments = new Payment[](poolIds.length); for (uint256 i; i < poolIds.length; ++i) { ISinjohHook.Market storage m = _market(poolIds[i]); uint256 curvePaid = _curvePlatform(poolIds[i]); uint256 amount = m.platformBucket; m.platformBucket = 0; payments[i] = Payment(poolIds[i], _backingOf(m), recipient, amount, m.backingIsSinjohToken); emit PlatformCollected(poolIds[i], recipient, amount + curvePaid); } _pay(payments); }
Who controls it: The code itself can’t be changed. The hook developer can call: execute takeover. The pool creator can change: fee destination, sell surcharge. The pool creator can also call: adopt module, adopt decision module, remove module, lower static rates, switch to static, propose creator and 4 more.
Based on the hook’s published code.
What it can do
Its code executes inside each trade in pools that use it.
It can take or add tokens during a swap. Fees, burns and custom curves work this way, and so do scams.
Pools using it let the hook choose the swap fee instead of a fixed tier.
It runs before liquidity is removed, so it can delay or refuse LP exits.
It checks every deposit before it goes in.
It runs when a pool is created, often to lock in that pool’s settings.
It runs when someone donates tokens to the pool’s LPs.
Hook history
Across all its pools, the hook handled a trade: $0.0000825.
- Handled a trade 2 times, worth $0.0000825
Latest transactions
- 0xe9edec7f…2352ca block 110,701,128
- 0x600464f1…e7f7c5 block 110,701,058
- Started the model 1 time
- Registered a curve 1 time
Settings changes: set up the future (1 time).
Counted from what the hook recorded on-chain across all its pools, for every action in its published code, plus token transfers in and out of it. Dollar values count the amounts paid in ETH, stablecoins, BNB and BTC, at today’s prices.