Loading…
Reading live on-chain state
Loading…
Reading live on-chain state
Read this before you trade
Walendria Protocol has no admin, no support desk, and no override switch. Every outcome is produced by the contracts exactly as written, executed by whoever presses the button — including you. This page is the definitive rulebook: what each role is allowed and expected to do, and every operation available to them, cross-referenced to the whitepaper sections that define it.
Four kinds of participants exist, and none of them need permission from anyone to act in their role.
| Role | What they are | What else they can do |
|---|---|---|
| Seller | Posts an Integrity Bond and creates a listing to sell something | Can also trade in their own dispute, submit evidence, or vote on a mutual close |
| Buyer | Pays for a listing and is owed the goods or service in return | Can also fund the Guilty side, trade, submit evidence, or claim a payout |
| Market participant | Anyone with a wallet — no relationship to the listing required | Trades Guilty/Innocent shares in any open dispute as a real bet, wins or loses real money |
| Anyone (permissionless) | Literally any address, connected or not to the dispute | Can call pokeSettlement, finalizeDispute, or finalizeExpiredSlot — the protocol never waits on a specific person |
pay() on the Settlement contract for a specific listing and slot.createListing reverts above it, and it can only be raised by a future redeployment at a new address, never an admin write.Being a “correct” buyer means understanding that the protocol only protects money that actually passed through it, and that you carry the responsibility of acting before the completion window closes.
Empty slot can be paid — Payment confirmed, Disputed, or Removed all mean that slot is no longer available to you.Settlement.pay(listingId, slotIndex), sending at least the full listing price. Send less and the entire call reverts — no partial payment, no partial state change. Send more and the excess is refunded automatically in the same transaction.finalizeExpiredSlot, which recycles the slot back to Empty so the seller can resell it — it does notreturn the seller's bond (that capital was never at risk and stays locked behind the slot). You can also finalize your own purchase early via confirmCompletiononce you're satisfied, which does the same thing before the window is up.fundGuiltySideto contribute toward half the listing price. Anyone else may also contribute — the instant the cumulative total reaches that threshold, the dispute opens automatically in that same transaction. Miss the window and this option disappears forever for that sale: the slot simply recycles for the seller's next buyer, with no dispute and no restitution. Funding below the threshold is never lost. If the window closes before the cumulative total reaches half the price, the dispute never opens, and every contributor can pull their exact contribution back with reclaimGuiltyFunding — it was locked while the window was live, not spent.mutualClose to resolve immediately instead of waiting on price discovery.IntegrityBond.claim()yourself once it's owed to you.SpectralMarket.redeem()to cash them out at up to $1 each — capped at whatever the market's pool still holds if a heavily-traded dispute left it short (Section 2.6.9).Being a correct seller means keeping enough bond posted, delivering within the window you agreed to, and understanding exactly what happens to your bond in either outcome.
extendWindow from the listing's slots page — works both before a buyer pays (pre-setting a longer window) and during a live sale. It only ever lengthens the window (never below the 72h floor, never shortens it), so it can only ever give the buyer more protection — a visible good-faith signal, at no cost but your own bond staying locked a little longer.finalizeExpiredSlot (or your buyer calling confirmCompletion early) recycles the slot back to Empty — ready for your next buyer, with its bond still locked behind it. You keep the 99.5% payment; the bond is not returned here, because it was never spent and stays put backing the slot for its next sale. This is the entire, correct happy path: the same slot resells indefinitely on this bond. When you actually want that capital back, reclaim it from any Empty slot with reduceSlots or closeListing.The self-dealing trap — and why it doesn't work
A tempting scheme: create a listing, pay yourself from a second wallet, then use that same second wallet to force a Guilty verdict — walking away with the 99.5% sale proceeds and the restitution payout, having only ever moved money to yourself.
This is mathematically blocked. Forcing price to the 93% resolution threshold from a neutral market costs strictly more capital than the 99.5% proceeds you'd have on hand to spend — a property derived directly from the LMSR cost curve (Section 2.6.9's H(p) boundary) and proven live on Chiado: a seller spending only their exact sale proceeds peaked at ~81.5%, nowhere near the 93% needed. The “attack” would require you to bring in more real money than you got back — at which point it isn't free money anymore, it's just you paying yourself restitution out of your own extra capital, minus gas. This ceiling is the load-bearing security property of the entire protocol, not an incidental detail.
Every on-chain action available across the protocol, in roughly the order they occur.
| Operation | Who can call it | Effect |
|---|---|---|
| deposit() | Anyone, on their own bond | Adds to Free IB |
| withdraw(amount) | The bond holder | Removes from Free IB only — Locked IB can never be withdrawn |
| createListing(price, slots, window) | Seller | Locks 1.5× price per slot; window ≥ 72h enforced; price capped at the protocol's per-transaction hardcap |
| reduceSlots / closeListing | Seller | Releases Locked IB for slots still Empty |
| extendWindow(listingId, slotIndex, newWindow) | Seller | Lengthens one slot's completion window — buyer-favorable, one-way (never shorter, never below 72h); works before or during a sale |
| pay(listingId, slotIndex) | Buyer | Confirms the slot, starts the window, pays seller 99.5% instantly |
| fundGuiltySide(listingId, slotIndex) | Anyone | Accumulates toward 0.5× price; opens the dispute automatically at threshold |
| reclaimGuiltyFunding(listingId, slotIndex, cycle) | Any Guilty-side funder | Refunds your exact contribution if the funding window closed before the 0.5× threshold ever opened a dispute |
| buy / sell | Anyone | Trades Guilty/Innocent shares in an open dispute — a real, priced bet |
| submitEvidence(...) | Buyer or Seller | Attaches IPFS-hosted evidence, visible to everyone |
| mutualClose(verdict) | Buyer and Seller, both, matching | Immediate resolution — only while no third party ever held shares |
| pokeSettlement(marketId) | Anyone | Resolves once 93%/1hr cumulative condition is met, even with zero trades since — pays the caller a small bounty from the case's own settlement surplus (can be zero for a quiet dispute) |
| finalizeDispute(listingId, slotIndex) | Anyone | Applies the Integrity Bond slash/unlock once the market has resolved |
| confirmCompletion(listingId, slotIndex) | The slot's buyer | Finalizes your own purchase early once satisfied — recycles the slot to Empty and waives your remaining dispute window |
| finalizeExpiredSlot(listingId, slotIndex) | Anyone | Recycles the slot to Empty for resale once the window passes with no dispute — the bond stays locked behind the slot (reclaim via reduceSlots/closeListing) |
| claim() | Whoever is owed restitution | Pulls a Guilty-verdict restitution payout from IntegrityBond |
| redeem(marketId) | Winning-side share holder | Pulls an up-to-$1-per-share payout from SpectralMarket, capped at the pool's remaining balance |
Every operation above has a button somewhere in this app — finalizeExpiredSlot and confirmCompletion on a listing's slots page, reclaimGuiltyFundingon the dispute page for any sale you funded below the threshold, and the rest where you'd expect them. Anything can also be called directly against the contract (a block explorer, or your own script) if you prefer — the protocol never depends on this site being the one to press the button.
pay() — this is never protected, and there is no recourse.This page describes the protocol exactly as coded and deployed — every rule above has a corresponding line of Solidity behind it, and the adversarial properties (no instant resolution, the mutual-close third-party lock, the self-dealing capital floor, permissionless poke resolution) have all been proven live on Gnosis Chiado, not just in local tests. See Articles for deeper technical write-ups on specific mechanisms.