Bid Validation

Every path a bid takes through UmiaValidationHook, from configuration to each revert it can hit

The CCA calls UmiaValidationHook.validate on every bid, and validate is the only way a credential reaches the hook. These charts follow the contract branch by branch, so every revert a bid can hit appears once. Nodes that start with Revert name the error; rounded nodes let the bid through. For the hookData formats and the owner functions in detail, see Validation Hook.

The CCA wraps any revert from the hook as ValidationHookCallFailed(reason), so a failed bid carries the hook's error inside.

Setup and configuration

yes no Deploy UmiaValidationHook(owner, reclaim, signer)Unpaired, validate() allows every bid Create the CCA with this hook as its validationHookThe CCA's hook is immutable setCCA(cca), once, later calls are no-opsCaches the CCA step schedule, reverting on empty,misaligned, zero-length or more than 256 steps Configure steps: owner calls, in any order, at any time(see the table below) Optional, per step: multicall(requireStepNotStarted(step),the step's setters, setVerifyEveryBid(step, true)) Step already started, disabled,or without a proof or permit gate? Revert the whole batch:StepAlreadyStarted or NoGateConfigured The step verifies every bid Cleared by setVerifyEveryBid(step, false) at any time,or by disableStep / disableStepBatch
Owner callEffect
setCCA(cca)Pairs once and caches the CCA schedule. Later calls are no-ops.
enableStep / enableStepBatchTurns enforcement on and sets the step's providers, which are its proof gate. An empty list means no proof gate.
disableStep / disableStepBatchTurns enforcement off and clears the step's verify-every-bid flag.
setStepProviders / setStepProvidersBatchReplaces a step's providers.
addStepProviders / removeStepProvidersAdds or removes single providers. Removing one that is absent reverts ProviderNotFound.
enableStepPermit / disableStepPermitTurns a step's permit gate on or off.
setSigner(signer)Sets the permit signer. address(0) disables every permit.
setVerifyEveryBid(step, on)On only before the step starts, with the step enabled and gated. Off at any time.
setStepMaxBidAmount(step, amount)Per-wallet zk cap at a step. 0 means no cap.
setZkGlobalMaxBidAmount(amount)Auction-wide zk cap. 0 means no cap. Settable before pairing.
setMaxBidPrice(q96)Bid price cap, which must sit on the CCA tick grid. 0 means no cap.
unregister / unregisterBatchClears standing registration (see below).
clearIdentity(providerHash, identityHash)Frees an identity slot.
multicall(calls)Runs owner calls atomically. Leading with requireStepNotStarted(step) makes a late-mined batch revert.

Everything except setSigner, setZkGlobalMaxBidAmount, setCCA, clearIdentity and multicall reverts NoCCA before pairing.

Validating a bid

no yes no yes yes no no yes no yes neither yes no proof, permit or both yes no yes no yes no Anyone calls CCA.submitBid(maxPrice, amount, owner, hookData)The CCA calls validate(maxPrice, amount, owner, sender, hookData)sender pays, credentials and caps bind to owner Hook paired with a CCA? msg.sender is the paired CCA? maxBidPrice set andmaxPrice above it? Resolve the current step: the CCA's step,or a forward scan of the cached schedulewhen the CCA's step is stale at a boundary Current block inside a step? Step enabled? Which gates does the step have?proof gate: providers setpermit gate: permit enabled Step verifies every bid? Standing registration applies?step does not verify every bid, has a proof gate,and owner is registered at this or an earlier step hookData empty? Take the permit path?permit gate, and hookData starts 0x01or the step has no proof gate Revert CallerNotCCA Revert MaxBidPriceExceeded Revert NoGateConfigured Revert ServerPermitRequired (permit gate only),ProofRequired (proof gate only) or NotVerified (both gates) Enforce zk caps Allow Allow Allow Allow: public step Allow Permit path Proof path

Permit path

no yes yes no yes no no yes no yes Permit pathhookData = 0x01 + abi.encode(permitStep, nonce, deadline, signature) Payload well-formed?0x01 prefix, canonical ABI head, signature within the payload Current step or permitStep verifies every bid,and permitStep is not the current step? permitStep after the current step? permitStep has the permit gate, signer set,deadline not passed, nonce unused? EIP-712 ServerPermit(owner, permitStep, nonce, deadline, amount)signed by the signer? Burn the nonce, emit PermitConsumed Revert ServerPermitRequired Revert CredentialStepMismatch Revert PermitStepTooHigh Revert ServerPermitNotEnabled, SignerNotSet,ExpiredDeadline or PermitAlreadyUsed Revert InvalidSignature Allow, permit bids skip the zk caps

Proof path

no yes yes no yes no yes no Proof pathhookData = proofStep (32 bytes) + abi.encode(Reclaim.Proof) Payload is a proof?not 0x01, at least 32 bytes Current step or proofStep verifies every bid,and proofStep is not the current step? proofStep after the current step? Current step verifies every bid? Consume a bid proof at the current step(see proof checks) Register the owner from proofStep(see proof checks) Enforce zk caps Revert ProofRequired Revert CredentialStepMismatch Revert ProofStepTooHigh Allow

zk caps

Proof bids and bids covered by standing registration count toward both caps. Permit bids never do: the API enforces permit caps when it signs.

yes no yes no Enforce zk caps Global cap set, and auction-wide total + amount above it? Accrue the auction-wide total, even while uncapped,and emit ZkGlobalBidAccrued Step cap set, and the owner's step total + amount above it? Accrue the owner's step total (only while the step is capped) Revert ZkBidExceedsGlobalCap Revert ZkBidExceedsStepCap

Proof checks

A proof is either a registration proof, sent inline on an ordinary step, or a bid proof, sent inline on a step that verifies every bid. The signed context message tells them apart, so neither can stand in for the other.

Shared checks for both kinds yes no yes no no no yes no yes yes yes, bid proof yes, registration proof no yes no yes yes no no Bid proof: inline on a step that verifies every bid Registration proof: inline on an ordinary step Dated in the future? Older than 10 minutes? Signed context message is bid:CHAIN:AUCTION:STEP:AMOUNT:NONCEfor this chain, auction, step and amount? Signed context message is register:CHAIN:AUCTION:NONCEfor this chain and auction? Revert BidProofFromFuture Revert BidProofExpired Revert BidProofContextMismatch Revert RegistrationProofContextMismatch Bid proof already consumed? Revert ProofAlreadyUsed Mark it consumed, emit ProofVerifiedNever registers the wallet Registered from the proof's step, emit Registered and ProofVerifiedReusable: registration keeps no used-proof record contextAddress is the owner? The proof's step has providers,and the proof's providerHash is one of them? Identity (provider + extractedParameters)claimed by another wallet? Claim the identity for the owner on first use(skipped when the proof has no extractedParameters) Reclaim witness signatures valid?Stateless, no shared replay registry is written Revert ContextAddressMismatch Revert ProviderNotFound or ProviderHashMismatch Revert IdentityAlreadyClaimed Revert from the Reclaim verifier

Registration and unregistering

An ordinary proof-gated step registers the ownerthe first time their bid carries a valid registration proof Later bids at this and later ordinary proof-gated stepsneed no credential unregister(user) / unregisterBatch(users): owner, needs pairing Standing registration cleared The next bid needs a proof again. Any valid registration proof,including the earlier one, registers the wallet again Not cleared: the identity slot, consumed bid proofs,burned permit nonces, zk bid totals clearIdentity(providerHash, identityHash): owner Frees the identity slot so another wallet can claim it

Where credentials come from

The Hub picks hookData from the step's gates. A step that verifies every bid gets a new permit while the wallet's allowance covers the bid, and a new bid proof otherwise. An ordinary step gets nothing once the wallet is registered onchain, then a stored registration proof, then a permit.

opt [Registration proof on an ordinary step] alt [Server permit] [zkTLS proof] [Already registered, ordinary proof-gated step] POST /api/v1/hub/server-permit/sign (auction, step hint, amount, walletAddress) EIP-712 ServerPermit(wallet, step, nonce, deadline in 5 min, amount) submitBid(maxPrice, amount, owner, 0x01 + permit) POST /api/v1/hub/zktls/proof-request (provider, contextMessage, walletAddress) Signed Reclaim request with contextAddress = wallet Prove the account, contextMessage register:... or bid:... Reclaim proof POST /api/v1/hub/zktls/verify (stores registration proofs only) submitBid(maxPrice, amount, owner, proofStep + proof) submitBid(maxPrice, amount, owner, empty hookData) validate(maxPrice, amount, owner, sender, hookData) Returns, or reverts and the bid fails walletAddress must be linked in Privy (a read at most 30 s old, outage returns 503),screening, server-resolved step, cap policy, live onchain gate check walletAddress must be one of the caller's linked wallets Wallet (Hub) Umia API Reclaim CCA UmiaValidationHook

Views

ViewAnswer
authorizesWithoutCredential(step, user)False out of range. True on a disabled step. False on a step that verifies every bid. Otherwise isVerified(step, user) when the step has a proof gate, else true only when it has no permit gate.
isVerified(step, user)Whether the user is registered at step or an earlier step.
verifiesEveryBid(step)The step's verify-every-bid flag.
isStepEnabled(step) / isStepPermitEnabled(step) / getStepProviders(step)The step's gates.
expirationBlock()End block of the highest gated step, meaning enabled with providers, a permit gate or verify every bid. 0 when no step is gated.
getSteps() / cca() / signer() / maxBidPrice()The cached schedule and settings.
stepMaxBidAmount(step) / zkBidTotal(wallet, step) / zkGlobalMaxBidAmount() / zkGlobalBidTotal()zk caps and running totals.
isPermitNonceUsed(nonce) / identityOwner(providerHash, identityHash)Burned permit nonces and identity slots.
requireStepNotStarted(step)Reverts StepAlreadyStarted once the step has started.
supportsInterface(id)CCA validation-hook introspection, IUmiaValidationHook, IMaxBidPriceValidationHook, IGatedValidationHook and IVerifyEveryBidHook.