TabirView on GitHub

[ Confidential liquidation protection ]

Keep the Loan.
Hide the Rules.

A Chainlink CRE workflow that holds a leveraged ETH/USDC position out of liquidation — with the protection policy sealed inside a TEE.

HandlerInTee · sudden crash
tickpriceHF afteractionrationale
00$2,0001.40deposit 1.29 vETH
01$1,7001.61deposit 2.22 vETH
02$1,6251.54hold
03$1,4501.51deposit 0.89 vETH
survived · 3 actions · loan intactreserve left 0.60 vETH

[ Our approach ]

A public protection policy is an attackable one. Tabir keeps a leveraged position out of liquidation while preserving as much of the loan as possible — and seals every threshold inside a TEE, so no one can probe it to drain your reserve.

CRETEEETH
Built on Chainlink CRE Confidential Workflows

89.65

Average rubric score

0/11

Scenarios liquidated

81.95

Worst-scenario score

[ 01 ]

$1,442

The instant gap the HF 1.40 floor survives — deeper than any published path, with no warning at all.

[ 02 ]

Sudden crash

$2,000 → $1,700 → $1,625 → $1,450

liquidated without action

survived · 3 actions · 87.24

[ 03 ]

Temporary wick

$2,000 → $1,750 → $1,620 → $1,900

liquidated without action

survived · 2 actions · 91.31

[ 04 ]

Two-stage decline

$2,000 → $1,750 → $1,650 → $1,650 → $1,500

liquidated without action

survived · 2 actions · 91.31

One Strategy,
Two Consumers

The enclave and the simulator import the same decide(), so every number on this page describes the code that actually ships.

[ Layer 01 ]

Strategy Core

01decide(state, history, params)
02 hf = healthFactor(…)
03 projected = projectPrice(…)
04 if hf < floor or projected ≤ trigger
05 return deposit ?? repay
06 return hold

Pure TypeScript, integer math, compiles to WASM.

[ Layer 02 ]

Confidential Enclave

floorHf
minHfTrigger
targetHf
reactionWindow
repayUnlockHf
→ DONdeposit 1.29 vETH

Thresholds load from the Vault DON, inside the TEE only.

[ Layer 03 ]

Simulator & Scorer

Tabir Repay-first

Replica of the published rubric, across eleven price paths.

[ The strategy ]

Deposit First.
Repay Last.

repay() is charged twice — loan continuity and capital efficiency. deposit() is charged once. So Tabir carries an always-maintained floor in collateral, projects where the decline is heading, and unlocks repay only when free vETH can no longer carry the position.

Read the Strategy

Measured across 11 paths, assuming the liquidation sweep beats our transaction.

20/20

Loan continuity on every published path

1.40

Health-factor floor, held before the next move arrives

42.3%

Of the emergency reserve consumed, on average

[ The enclave boundary ]

What Goes In Stays In.
Only the Action Comes Out.

If your protection rules are public, an adversary can push price just far enough to trigger a costly defence — again and again — draining your reserve without ever needing to liquidate you. The veil removes that attack surface.

Every threshold, the velocity model, the time-to-liquidation estimate and the budget rationing run inside HandlerInTee. None of it is logged, reported, or readable on-chain.

01

Sealed inside

HandlerInTee

What to do and how much — never why. The DON receives “deposit 1.29 vETH”, not the floor, the projection, or the buffer that produced it.

02

Only the action crosses

Action + amount

A tick that holds runs the same enclave path as a tick that acts. If the workflow fired only when acting, its timing alone would leak the thresholds.

03

Uniform execution

Hold looks like act

[ Results ]

Three Policies, One Suite

Five published price paths and six synthetic ones, scored against our replica of the challenge rubric — assuming the liquidation sweep lands before our transaction.

Do nothing

50.00/100 avg

Sit the position out and hope.

  • 10 of 11 scenarios liquidated
  • Worst scenario 42.50
  • No reserve spent
See Every Path

Tabir

89.65/100 avg

Deposit-first, pre-positioned, sealed.

  • 0 of 11 scenarios liquidated
  • Worst scenario 81.95
  • 42.3% of reserve consumed
  • Policy sealed inside a TEE
See Every Path

Repay-first baseline

61.94/100 avg

One static threshold, repay whatever it can.

  • 7 of 11 scenarios liquidated
  • Worst scenario 42.50
  • 4.3% of reserve consumed
  • Thresholds public and probeable
See Every Path
ScenarioSourceDo nothingRepay-firstTabirTabir actions
Gradual declinePublished48.0092.6589.393
Sudden crashPublished45.0045.0087.243
Temporary wickPublished45.0045.0091.312
Two-stage declinePublished44.0044.0091.312
Safe volatilityPublished44.0044.0091.312
Deep sustained declineSynthetic45.7187.9481.956
Three-stage grindSynthetic42.5042.5091.312
Instant gap downSynthetic45.0045.0083.753
Double wick recoverySynthetic43.3343.3391.312
Sawtooth drift downSynthetic47.5091.9092.102
Benign flatSynthetic100.00100.0095.212

✕ marks a liquidation. Confidentiality counts as the declared 15 for every policy, and intervention discipline uses our own proxy curve — the rubric publishes no formula for it. Chainlink runs its own scenarios after the deadline; these are paths we chose.

[ FAQ ]

Questions Worth Asking

What is Tabir?+

A Chainlink CRE workflow built for the Automated Liquidation Protection Challenge. It watches a leveraged vETH/vUSD position on Sepolia and deposits collateral — or, as a last resort, repays debt — to keep it out of liquidation while preserving as much of the open loan as possible.

Why does the policy need a TEE?+

Because a visible policy can be probed. With the thresholds on-chain, an adversary can nudge price just past them, repeatedly, and bleed the emergency reserve dry without ever liquidating the position. Sealing the policy removes that attack surface regardless of how good the formula is.

Why deposit instead of repay?+

The rubric charges repay() against loan continuity (20%) and capital efficiency (15%); deposit() touches only capital efficiency. Repay's small edge in health factor per dollar is nowhere near the points it destroys, so it stays locked until free vETH runs out.

What if the liquidation sweep lands before our transaction?+

We assume it does. The organisers update the price and then sweep, and we cannot verify which lands first — so the policy carries an HF 1.40 floor at all times, sized to survive the next adverse move before it arrives.

Are these numbers real?+

They are computed when this page is built, by running the same decide() the enclave ships through our scenario engine and rubric scorer. They come from paths we chose — Chainlink runs its own after the deadline — which is why the policy is tuned for the worst scenario rather than the average.

Why the name?+

Tabir is Indonesian for veil.

[ Under the veil ]

Read the Build

Every decision, and every number, lives in the repo.

Put Your Position
Behind the Veil.

Built for ETHGlobal ETHOnline 2026 and Chainlink's Automated Liquidation Protection Challenge.

View on GitHub