veil.protocol

Documentation

Everything, written down.

What the protocol does, what it will not do, what it costs, and what is still untrue. Every number here is read out of the contracts rather than repeated from memory.

What this is

Two crypto projects agree to work together. Instead of announcing it, each one buys some of the other's token on the open market and locks it here for a term they agree between themselves. Neither can take it out early without paying for it.

That is the whole mechanism. There is no clever part, no swap, no yield on what is locked, and nothing that needs a price feed to work.

What it changes is exposure. Once you are holding their token, a partner who goes quiet, rugs or simply fails costs you money rather than credibility. Anyone can check that you were holding, from when, for how long, and how it ended.

Each one of these agreements is called a Veil.

Why it exists

Every project has a partners page. None of them cost anything to make, which is exactly why nobody believes them, and three months later nobody remembers who actually did the work.

The usual answers to that are worse. An escrow needs someone to decide whether the work was done, and that person becomes a judge with an opinion. A milestone contract needs an oracle for facts that are not on any chain. Both put a referee in the middle of a relationship that was supposed to be between two parties.

A Veil settles a different question. It never asks whether the work was good. It only records who committed capital, for how long, and whether they saw the term out. That is a fact, and facts are the only thing a contract can settle honestly.

The limit of this, stated up front

A Veil is a costly signal, not collateral. At small sizes walking away is cheap. It filters out theatre. It does not make betrayal impossible, and it should never be sold as if it does.

The two ways in

A direct Veil

You already know who you want. You name them, buy their token, and lock it. They mirror it on the terms you published, and the term starts the moment their transaction confirms. If they never answer, the offer expires and your deposit comes home in full.

An open call

You do not know who yet. You publish what you are looking for and deposit nothing, because until somebody answers there is no counterparty token to buy. Anyone may answer, and answering means they buy your token and lock it before you have chosen anybody.

You say how many partners you want, from one to fifty. Each one you accept becomes its own separate agreement, funded and bonded on its own, with its own term running from the moment you accepted it. One call does not mean one clock.

The call keeps taking answers until every place is filled or you close it. Accepting somebody is never a rejection of the rest: every other application stays pending and can be withdrawn in full, at any moment, whatever you do or fail to do.

The rule that does not change between them

Whoever wants the partnership pays before the other side has agreed to anything. On a direct Veil that is the proposer. On an open call it is the applicant. Which is why a call with ten answers is ten projects who each put money down.

The life of a Veil

Awaiting

One side has funded and locked. The other has not answered yet. The deposit can be reclaimed once the deadline passes.

Under term

Both sides funded. Nothing can be withdrawn, for any reason, by anyone, until the term ends.

Unwinding

Past the term and releasing linearly across the release window. Neither side can speed it up.

Closed

Fully released, expired, or ended early. The record stays either way.

The terms you choose

SettingWhat it doesRange
TermHow long neither side can withdraw anything7 to 730 days
Release windowHow long the linear unlock takes afterwards1 to 180 days
Acceptance windowHow long a direct proposal waits for an answerup to 30 days
Call windowHow long an open call keeps taking answersup to 90 days
PartnersHow many places an open call has1 to 50

Release is linear, never a cliff

When the term ends, nothing unlocks at once. Both positions release evenly across the release window, so a Veil ending cannot dump two charts in a single block. This is not configurable, because the version of this product with a cliff would be actively harmful to the projects using it.

What you agreed to

The text of the agreement lives off-chain. Only its keccak256 hash is stored on-chain, which means the words can be proven later but never quietly rewritten. Either side may flag it delivered. That flag moves no money and it never has to.

Ending one early

Nothing traps anyone. Either side may end an active Veil at any moment before the term is up. The consequence is written into the instrument rather than argued about afterwards.

  • Both holdings go home. Every locked token returns in full, immediately, to whoever bought it.
  • Whoever leaves forfeits their bond. Half goes to the side they walked out on, half is burned.
  • Whoever stayed keeps theirs. Staying was never the thing that costs.
  • The address stays on it. brokenBy is written into the Veil and never cleared.

The split is fixed when the Veil is made and no later change to the protocol can reach it. On an open call it is fixed when the application is made, which is the earliest moment anybody committed anything.

Why there is no penalty beyond the bond

A larger penalty would need someone to decide whether leaving was justified, and that is the referee this whole design exists without. The bond is what somebody agreed to lose in advance, and the record of having lost it is the rest.

What the contract guarantees

Each of these is enforced by code rather than promised by anyone, and each has a test that proves it.

  • Nobody can take your tokens. There is no sweep, no rescue and no withdraw function anywhere in the vault. The only paths out pay the rightful party.
  • Nobody can block a withdrawal. Creation of new Veils can be paused. Claims cannot. There is a test that pauses the contract and then successfully claims.
  • Terms cannot change after you commit. The bond token and the break split are pinned onto each Veil at the moment it is made, so no later configuration change touches a live agreement.
  • Deposits are measured on arrival. A token that takes a cut on transfer is credited for what actually landed, never for what was requested.
  • An answer to an open call is never trapped. A pending application can be withdrawn in full at any moment, regardless of the call's status or deadline.
  • Accepting one answer rejects none of the others. It fills one place. Everyone else keeps their tokens, their bond, and their right to walk away with both.

What it refuses to do

Most of the design is refusal. These are not missing features.

  • It never judges the work. No arbiter, no dispute process, no vote. The protocol cannot tell whether two posts were good, and pretending otherwise would make it a court.
  • It never swaps. Both sides acquire the other's token themselves, on the open market, at whatever price they get. The vault holds; it does not trade.
  • It has no price feed. Nothing in the contract knows what anything is worth, which is why the fee is flat and not a percentage of value.
  • It has no governance. Nobody wants to vote on a protocol with forty Veils in it.
  • It mints nothing to pay anyone. Holder rewards come out of real trades and real fees. Nothing is created to fund them.

Fees, and where they go

A flat fee per side, payable in the chain's native currency or in VEIL at a discount. Flat rather than a percentage, because a percentage of locked value needs a price and the contract deliberately has no way to learn one.

On an open call the fee is charged once, to the maker, at posting, however many partners the call ends up taking. Applicants pay no protocol fee to answer: they are already committing capital, and taxing the answers would thin the very pool an open call exists to reach.

Every fee splits three ways

WhereWhat forShare
Buyback, burnedBuys VEIL on the open market and burns it40%
MarketingETH, straight to the marketing wallet40%
Buyback, to holdersBuys VEIL on the open market and shares it out to holders20%

Nothing here is a privileged action. Anyone may call distribute() on the splitter, and buyback() on either buyback contract. Each buyback runs at most once a day, spends at most a fifth of what it holds, and never moves the price more than 1%, so it cannot be timed or traded around. Neither buyback has an owner.

The split can be fixed for good with lockSplit(). Until then the owner can change it, which is stated here rather than discovered later.

The token

$VEIL has two jobs inside the protocol, and both fall out of the mechanism rather than being bolted on: it pays the fee at a discount, and it is the bond you lose if you walk. Around those sits a small tax on trades.

It pays the fee, cheaper

The fee is payable in VEIL at a discount. Nobody is forced to touch the token; the product works entirely without it.

It is the bond you lose if you walk

Both sides post one. End a Veil early and you forfeit it, half to the side you left and half burned. This needs no arbiter, because whether you ended it before the agreed date is a fact rather than a judgement.

The tax on trades

2% on every buy and every sell against the pool, taken in VEIL and split in the same transaction:

WhereHowOf the tax
BurnedDestroyed on the spot, so the supply falls as volume grows40%
HoldersPaid in VEIL to every holder, pro rata20%
MarketingSold for ETH in small pieces, sent to the marketing wallet40%

The ceiling is 3%, and it is a constant the owner cannot raise, which is the usual way a tax token turns out to be a trap. The tax can be locked for good; after that the rate, the split and every exemption are fixed. One thing stays possible after the lock: a new pool holding VEIL can be marked as a market, so nobody can dodge the tax by trading in a second pool. An ordinary wallet can never be marked.

Moving tokens between your own wallets is not taxed. Neither is the protocol: taxing a bond going in and coming back would mean honouring an agreement costs money while walking away costs nothing, so the vault, the splitter and both buybacks never pay it.

How the marketing share is sold

It collects in the token and is sold during sells, never during buys: a pool is locked for the whole of its own swap, so selling into it inside a buy is impossible. Each sale is at most 0.3% of the pool, one per block, and the ETH goes straight to the marketing wallet. A sale that fails is skipped and tried again later; it can never make somebody else's trade fail. Because a sell can carry one small sale in front of it, set 3 to 4% slippage when trading.

How holder rewards work

Every wallet holding VEIL earns its share of the holder part of the tax, and of the protocol's buyback for holders. Rewards land in the wallet with its next transfer, or can be claimed at any time with claimRewards(). Nobody earns from their own trade.

Some addresses never earn: the pool, because a pool whose balance grows by itself can be drained by anyone; the protocol's contracts, because they hold other people's money; and the treasury, because it starts with the whole supply and would otherwise collect most of it. Rewards are only shared once at least 1,000,000 VEIL is held by earning wallets in total. Below that they wait and are paid out with the next distribution, which keeps the arithmetic safe whatever anyone holds.

Supply

A fixed supply of one billion, minted once at deployment. There is no mint function, so supply can only ever go down: through the burn on every trade, the daily buyback, and forfeited bonds. The allocation is published with its wallet addresses before launch.

On timing, plainly

The token is worth nothing without Veils flowing through the protocol. The buyback is a credibility mechanism long before it is ever a price mechanism, and anybody who tells you otherwise is selling you something.

The bond can only be switched on once VEIL is actually tradeable. Before that, a non-zero bond would make the protocol unusable, since it pulls a token nobody can buy. It starts at zero and is turned on later, in public, with one transaction.

Who is who

A project can publish a name, a ticker, a logo and links by signing a message with the address it operates under. That is the only thing the signature proves.

What "signed" means, and what it does not

It means that wallet produced a signature proving it controls that address. It is not a statement that the project is real, solvent or honest, and the API returns that caveat inside the payload so no interface can quietly upgrade it into a trust badge.

Nothing verifies that a token belongs to the project offering it either. A call can name any ERC-20 as "your token". Nobody can be robbed that way, because an applicant may always withdraw and an accepted Veil returns each side's own deposit, but a call can misrepresent what it is offering. Read the token address, not the name beside it.

Security

The contracts are not audited by a third party. Do not commit capital you cannot afford to lose until they are.

The critical bug found before publication

In review we found that bonds were refunded using a mutable setting rather than the value recorded on the Veil itself. Pointing that setting at another token mid-term would have made a claim revert, which would have locked a user's holdings for good, and pointing it at nothing would have stranded the bond silently.

That broke the protocol's own second guarantee, so it was fixed before anything was published: the bond token and break split are now written into each Veil when it is made and never read from configuration again. Three tests attempt exactly that attack and fail to land it.

What has been checked

  • 131 contract tests, covering every state, both routes in, owner limits, hostile tokens, the tax, the rewards and both buybacks.
  • Every attack we could think of written as a test against the real Uniswap V2 code, from bricking the rewards to blocking the launch pool.
  • 51 backend checks, including signature replay, tampering, and every refusal path.
  • The full launch rehearsed on a local chain and on the Robinhood testnet: deploy, pool, tax, trades, buybacks, fees.
  • A reorg lag of twelve confirmations, so the indexer cannot silently lose events.

Known limitations, stated plainly

  • Not audited. See above. This is the first thing that should change.
  • The owner can change the fee and tax settings until they are locked. lockTax() and lockSplit() fix them for good, and neither can reach fees already paid or any locked position.
  • The treasury is exempt from the tax at launch, because it has to add the liquidity. That exemption is revoked before the tax is locked.
  • A fee-on-transfer token means the receiving side gets less than the number they saw. The shortfall is recorded on-chain and visible, but it cannot be undone after acceptance.
  • Answering an open call ties up capital with no promise of being picked. It can always be withdrawn, so it is not at risk of being taken, but it sits idle while the maker decides.
  • The backend is a convenience, never an authority. The chain is the source of truth. Delete the database and the indexer rebuilds it from the deploy block. Nothing financial depends on any off-chain record.

For developers

The contracts are public and so is everything around them. The chain is the only thing that settles anything; the indexer and the API exist so a browser does not have to scan logs.

The contract surface

CallWhat it does
proposePactName a counterparty and fund your side
acceptPactMirror it and start the term
cancelExpiredProposalReclaim a deposit nobody answered
postOfferPublish an open call with a number of places
applyToOfferAnswer one by funding first
withdrawApplicationTake a pending answer back, always available
acceptApplicationFill one place and start that term
closeOfferStop taking answers early
claimTake whatever has vested; can never be paused
breakPactEnd early and forfeit the bond
flagCompletedRecord that you consider it delivered; moves no money

Reading the board

GET /api/pacts?status=active
GET /api/pacts/:id
GET /api/offers?status=open
GET /api/offers/:id
GET /api/parties/:address/pacts
GET /api/stats

Share cards

Every Veil and every call renders its own image, engraved from its own number with the same arithmetic the board uses, so a posted link shows the instrument itself.

/v/:id            a Veil, with preview tags
/c/:id            a call, with preview tags
/cards/veil/:id.png
/cards/call/:id.png

Running it

npm install
npm test          # 76 contract tests
npm run smoke     # 51 backend checks
npm start         # API and the board on :8787

Status

Where this actually is

Not audited. Do not put money through these contracts that you cannot afford to lose. Nothing here is investment advice and none of it is a promise of return.

The protocol is built and tested. What happens next, in order: contracts deployed and verified, the first Veils made by hand with people we know, a real audit, and only then anything about a token.

Progress is posted weekly, including the weeks where nothing worked. When a Veil is ended early and somebody forfeits their bond, that gets posted the same way the successes do.

Words used here

WordMeaning
VeilOne agreement. Two parties, two locked positions, one term.
Open callA published request for partners that anybody may answer.
ApplicationAn answer to a call, funded by the applicant before any choice is made.
PlaceOne partner slot on a call. A call has between one and fifty.
TermThe stretch during which nothing can be withdrawn.
Release windowHow long the linear unlock takes once the term is over.
BondWhat each side stands to forfeit by ending a Veil early.
ScopeWhat two parties agreed. Kept off-chain, hashed on-chain.
BriefWhat a call is asking for. Same arrangement as a scope.
SealThe engraving belonging to one instrument, cut from its own number.

If something here disagrees with the contracts, the contracts are right and this page is a bug. Every figure on it was read out of the code rather than remembered.