Tranche Whitelist — call flow (grant / revoke propagation) Source of truth = hub TranchePermissions precompile · one spoke Whitelist contract per chain, mirrored per productId · grant and revoke share the path TX 1hub · ProductAdmin signs TX 2target spoke · relayer signs dashed= Socket event (colour = originating tx) · ✂ = tx boundary HUB chain (Bifrost) TX 1 — ProductAdmin signs · one grant call (record + propagate, atomic) 👤ProductAdmin TranchePermissions 0x…0202 Precompile source of truth — TrancheInvestor Orchestrator (Hub) one global — sends on behalf calls Hooks.request CCCP V2 (Hub) Hooks · Vault · Socket, collectively registers Socket request Investment Pallet pallet-tranche-permissions Msg — WHITELIST (asset 0 · tag 9) productId · vault(chain_id·address) · who · action(Grant=0 | Revoke=1) — sent only to vault chains 1-1 grant_permission (TrancheInvestor · who · vault) 1-2 propagation trigger precompile calls directly (old Gateway pattern) 1-3 request sends WHITELIST · asset 0 Relayers watches Socket events → ⅔+ signatures → submits Poll_Submit{msg, sigs, option} off-chain (tx boundary ✂) target SPOKE chain (where the vault lives) TX 2 — relayer signs · propagation applied ShareToken S/J 1404 hook — on transfer and claim Whitelist Module one per chain · tracked per productId mirror of the hub record CCCP V2 (Spoke) poll → hands to receiveMessage 2-2 receiveMessage(WHITELIST) → grant / revoke per productId isValidAddress The hub pallet is the record — a failed spoke update converges on retry, and failing closed is the safe direction for a transfer restriction · revoke takes the same path · a hub-issued product registers locally with no propagation Socket(WHITELIST) event ✂ 2-1 poll