Skip to main content

ERC-8004 & ZK Proofs

This layer ensures every Zyfai Agent action is independently verifiable.

By anchoring Zero-Knowledge Proofs (ZKPs) of correct execution to an on-chain identity via the ERC-8004 standard, Zyfai provides cryptographic, non-repudiable proof of honest operation, establishing the trust layer for the agentic economy.

Why This Model?

Trust must be proven, not promised. ZK Proofs allow anyone to verify the correctness of a computation without revealing sensitive strategy details, preventing front-running. ERC-8004 provides the standard ledger to record these proofs, building a public, auditable reputation for each Agent that enables future Agent-to-Agent communication.

How It Works

  1. Deterministic Execution: A Zyfai Agent's logic is a deterministic set of rules, guaranteeing the same input always produces the same, verifiable output.
  2. Proof Generation: For each rebalance, the system generates a ZK proof. This proof cryptographically attests that the Agent's action was the exclusive correct output of its rules.
  3. Simple, Standalone Verification: A dedicated verifier contract checks this proof, returning a definitive "yes" or "no" on the transaction's integrity.
  4. Onchain Anchoring via ERC-8004: The ZK proof is permanently linked to the Agent's unique onchain identity in the ERC-8004 Validation Registry. This creates a tamper-proof history of verified actions, building a reputation over time.

For Institutions

This elevates audit and compliance. Institutions can cryptographically verify that an Agent has complied with its mandate. It shifts the basis of delegation to mathematically verified onchain evidence, significantly reducing counterparty risk and enabling trust at scale.


Technical Implementation

ERC-8004 ZK Validation Quick Reference

Contract Addresses

Base Sepolia (Chain ID: 84532)

IdentityRegistry:      0x8004A818BFB912233c491871b3d84c89A494BD9e
ReputationRegistry: 0x8004B663056A597Dffe9eCcC1965A193B7388713
RebalancerVerifier: 0x07A1Dc74Ec0C2F3F9e605Ad464A048099793be09

Ethereum Sepolia (Chain ID: 11155111)

IdentityRegistry:      0x8004A818BFB912233c491871b3d84c89A494BD9e
ReputationRegistry: 0x8004B663056A597Dffe9eCcC1965A193B7388713
RebalancerVerifier: 0x752AC7b1b6707399b989a6c5c68EADfcE041eE7C

Circuit Constraints

#ConstraintFormulaPurpose
1Liquidityliquidity * 85 > zyfiTvl * 100Sufficient liquidity
2TVLpoolTvl * 1e6 > amount * 400Max 25% allocation
3APYnewApy > oldApy + 10 OR edge cases0.1%+ improvement
4APY StabilityapyStable7Days == 17-day stability
5TVL StabilitytvlStable == 1Pool stability

Input Scaling

FieldScalingExample
Liquidity, TVL×100$100,000.00 → 10000000
APY×100008.0952% → 80952
AmountToken units2.00519 USDC → 2005190
Booleans0 or 1Stable → 1

Public Signals Order (15 signals)

[
liquidity,// 1. Available liquidity (×100)
zyfiTvl,// 2. Zyfai TVL (×100)
amount,// 3. Rebalancer amount (token units)
poolTvl,// 4. Pool TVL (×100)
newApy,// 5. New APY (×10000)
apyStable7Days,// 6. APY stable? (0/1)
tvlStable,// 7. TVL stable? (0/1)
oldApy,// 8. Old APY (×10000)
oldLiquidity,// 9. Old liquidity (×100)
oldZyfiTvl,// 10. Old Zyfai TVL (×100)
oldTvlStable,// 11. Old TVL stable? (0/1)
oldUtilizationStable,// 12. Old utilization stable? (0/1)
oldCollateralHealth,// 13. Old collateral healthy? (0/1)
oldZyfiTVLCheck,// 14. Old Zyfai TVL check? (0/1)
supportsCurrentPool,// 15. Current pool supported? (0/1)
];

Workflow Diagram

Example Proof

IPFSView Full Proof

Data:

{
"publicSignals":[
"125570357",// $1,255,703.57 liquidity
"10226",// $102.26 Zyfai TVL
"2005190",// 2.00519 USDC
"1016077651",// $10,160,776.51 pool TVL
"80952",// 8.0952% APY
"1",
"1",// APY & TVL stable
"0",
"0",
"0",// No old opportunity
"1",
"1",
"1",
"1",
"1"// All checks pass
],
"verifierAddress":"0x07A1Dc74Ec0C2F3F9e605Ad464A048099793be09",
"chainId":84532
}

📖Resources
Need help?
Zero-Knowledge Circuit Deep Dive

Circuit Overview

The Zyfai Rebalancer Validation Circuit (rebalancer-validation.circom) is a Circom 2.x circuit that validates DeFi rebalancing opportunities against backend constraints using zero-knowledge proofs. The circuit implements the core validation logic from Zyfai's backend, ensuring opportunities meet all safety and performance criteria.

Circuit Properties

  • Language: Circom 2.0.0+
  • Proof System: Groth16 (efficient on-chain verification)
  • Curve: bn128 (bn254)
  • Constraints: ~100-200 (includes comparison circuits from circomlib)
  • Public Signals: 15 (all inputs are public)
  • Private Signals: None (transparency-focused implementation)

Public Inputs

The circuit has 15 public input signals organized into three categories:

New Opportunity Data (7 signals)

These signals describe the rebalancing opportunity being evaluated:

SignalDescriptionScalingExample
liquidityAvailable liquidity in the pool×100 (2 decimals)10000000 = $100,000.00
zyfiTvlCurrent Zyfai TVL in the pool×100 (2 decimals)500000 = $5,000.00
amountRebalancer deposit amountToken smallest unit1000000 = 1 USDC (6 decimals)
poolTvlTotal pool TVL×100 (2 decimals)10000000 = $100,000.00
newApyNew opportunity APY×10000 (4 decimals)54352 = 5.4352%
apyStable7DaysAPY stable over 7 daysBoolean (0 or 1)1 = stable
tvlStableTVL is stableBoolean (0 or 1)1 = stable

Old Opportunity Data (7 signals)

These signals describe the previous opportunity (if any) for comparison and edge case handling:

SignalDescriptionScalingDefault
oldApyPrevious opportunity APY×10000 (4 decimals)0 = no old opportunity
oldLiquidityOld opportunity liquidity×100 (2 decimals)0 = no old opportunity
oldZyfiTvlOld opportunity Zyfai TVL×100 (2 decimals)0 = no old opportunity
oldTvlStableOld opportunity TVL stableBoolean (0 or 1)1 = defaults to stable
oldUtilizationStableOld opportunity utilization stableBoolean (0 or 1)1 = defaults to stable
oldCollateralHealthOld opportunity collateral healthyBoolean (0 or 1)1 = defaults to healthy
oldZyfiTVLCheckOld opportunity passes Zyfai TVL checkBoolean (0 or 1)1 = defaults to pass

User Preferences (1 signal)

SignalDescriptionScalingExample
supportsCurrentPoolCurrent pool is in user's preferencesBoolean (0 or 1)1 = supported

Validation Constraints

The circuit enforces 5 core validation rules that all must pass for a valid proof:

1. Available Liquidity Check

Ruleliquidity * 0.85 > zyfiTvl

Purpose: Ensures sufficient liquidity to cover the rebalancing amount.

Implementation:

// Avoid floating point: liquidity * 85 > zyfiTvl * 100
signal liquidityLeft <== liquidity * 85;
signal liquidityRight <== zyfiTvl * 100;

component liquidityCheck = GreaterThan(252);
liquidityCheck.in[0] <== liquidityLeft;
liquidityCheck.in[1] <== liquidityRight;

Example:

liquidity = 10,000,000 (scaled: $100,000.00)
zyfiTvl = 500,000 (scaled: $5,000.00)

Check: 10,000,000 × 85 = 850,000,000 > 500,000 × 100 = 50,000,000 ✓

2. TVL Constraint

RulepoolTvl * 1e6 > amount * 400

Purpose: Prevents excessive allocation. Ensures rebalancer is at most 25% of pool TVL.

Mathamount * (100 / 25) = amount * 4, scaled by 100: poolTvl * 1e6 > amount * 400

Implementation:

signal tvlLeft <== poolTvl * 1000000;
signal tvlRight <== amount * 400;

component tvlCheck = GreaterThan(252);
tvlCheck.in[0] <== tvlLeft;
tvlCheck.in[1] <== tvlRight;

3. APY Performance Check (with Edge Cases)

RulenewApy > oldApy + 10 OR edge cases

Purpose: Requires meaningful yield improvement (0.1%+) unless bypassed by edge cases.

Edge Cases (APY check bypassed if ANY are true):

  1. No Old OpportunityoldApy == 0 (first deposit or no previous opportunity)
  2. Rebalancing from Problematic PoolshouldRebalanceFromOld == 1 (computed internally)
  3. Pool No Longer SupportedsupportsCurrentPool == 0 (user preferences changed)

shouldRebalanceFromOld Computation:

shouldRebalanceFromOld = enoughLiquidity && (
!oldZyfiTVLCheck ||
!oldTvlStable ||
oldLiquidityIsLow ||
!oldUtilizationStable ||
!oldCollateralHealth
)

Where:
- enoughLiquidity = oldLiquidity * 1e6 >= amount
- oldLiquidityIsLow = oldLiquidity * 0.85 < oldZyfiTvl

Implementation:

// Base APY check: newApy > oldApy + 10 (0.1% improvement)
signal apyThreshold <== oldApy + 10;
component apyCheck = GreaterThan(252);
apyCheck.in[0] <== newApy;
apyCheck.in[1] <== apyThreshold;

// Edge case 1: No old opportunity
component oldApyIsZero = IsEqual();
oldApyIsZero.in[0] <== oldApy;
oldApyIsZero.in[1] <== 0;

// Edge case 2: shouldRebalanceFromOld (computed internally)
// ... (see circuit code for full implementation)

// Edge case 3: Pool no longer supported
signal notSupportsCurrentPool <== 1 - supportsCurrentPool;

// APY check passes if ANY are true (OR logic)
signal apyCheckOrSkip <== apyCheckValue + oldApyIsZeroValue +
shouldRebalanceFromOldValue + notSupportsCurrentPool;

component apyCheckFinal = GreaterThan(252);
apyCheckFinal.in[0] <== apyCheckOrSkip;
apyCheckFinal.in[1] <== 0;

Example:

newApy = 120,000 (12.0000%)
oldApy = 100,000 (10.0000%)
supportsCurrentPool = 1

Check: 120,000 > 100,000 + 10 = 100,010 ✓
Result: 2% improvement exceeds 0.1% threshold

4. APY Stability Check

RuleapyStable7Days == 1

Purpose: Ensures APY has been stable over the past 7 days (prevents volatile pools).

Implementation:

component apyStabilityCheck = IsEqual();
apyStabilityCheck.in[0] <== apyStable7Days;
apyStabilityCheck.in[1] <== 1;

Example:

apyStable7Days = 1

Check: 1 == 1 ✓
Result: APY is stable

5. TVL Stability Check

RuletvlStable == 1

Purpose: Verifies pool TVL is stable (prevents pools with unstable liquidity).

Implementation:

component tvlStabilityCheck = IsEqual();
tvlStabilityCheck.in[0] <== tvlStable;
tvlStabilityCheck.in[1] <== 1;

Example:

tvlStable = 1

Check: 1 == 1 ✓
Result: TVL is stable

Constraint Composition

All 5 checks are combined using AND logic (all must pass):

signal check12 <== liquidityCheckValue * tvlCheckValue;
signal check34 <== apyCheckFinalValue * apyStabilityCheckValue;
signal check5 <== tvlStabilityCheckValue;
signal check1234 <== check12 * check34;
signal finalCheck <== check1234 * check5;

// Enforce all checks must pass
finalCheck === 1;

If any constraint fails, witness generation fails and no proof can be generated.

Example Input

{
"liquidity":100000000,
"zyfiTvl":500000,
"amount":1000000,
"poolTvl":100000000,
"newApy":120000,
"apyStable7Days":1,
"tvlStable":1,
"oldApy":100000,
"oldLiquidity":8000000,
"oldZyfiTvl":400000,
"oldTvlStable":1,
"oldUtilizationStable":1,
"oldCollateralHealth":1,
"oldZyfiTVLCheck":1,
"supportsCurrentPool":1
}

Example Output

{
"isValid":1 (or0)
}

Off-chain Checks

More checks are in done off-chain which are not a part of the zk circuit but the above covers all the basic checks that're being proven on-chain.

Security Considerations

Current Implementation

  • ✅ All inputs are public signals (transparency-focused)
  • ✅ Boolean validation prevents malformed inputs
  • ✅ Circom 2.x syntax with explicit public input declaration
  • ✅ Comparison circuits from audited circomlib
  • ✅ Edge case handling for APY checks

Performance Metrics

OperationTimeGas Cost
Circuit Compilation~30s-
Witness Generation~100ms-
Proof Generation~500ms-
Off-Chain Verification~50ms-
On-Chain Verification~50ms-