Skip to content

Latest commit

 

History

History
381 lines (289 loc) · 9.76 KB

File metadata and controls

381 lines (289 loc) · 9.76 KB

VaultGuard E2E Demo (CLI)

This is the CLI-first end-to-end demo hub for VaultGuard. It’s designed for:

  • a smooth demo recording, and
  • judges running the project without guessing missing steps.

It covers:

  1. CRE workflow orchestration (simulate + broadcast)
  2. Custom PoRFeed onchain verification + state updates
  3. VaultGuard RiskMode gating (NORMAL → LIMITED → PAUSED → NORMAL)
  4. ACE policy enforcement (allowlist + min ticket + max volume)
  5. Optional AI tightening (healthy + calm/panic)
  6. Sepolia + Tenderly VTN runners

Demo Tip

The demo uses two terminals:

  • Terminal A — attestation server
  • Terminal B — workflow execution and user transactions

Demo Timeline

The CLI demo demonstrates the following vault lifecycle:

  1. Healthy reserves → NORMAL
  2. ACE policies enforced
  3. Reserve degradation → LIMITED
  4. Attestation staleness → PAUSED
  5. Optional AI tightening
  6. Recovery → NORMAL

CRE Execution Flow

sequenceDiagram
    participant Admin as Attestation Server
    participant CRE as Chainlink CRE Workflow
    participant PF as VaultGuardPoRFeed
    participant Vault as VaultGuard ERC4626
    participant ACE as Chainlink ACE
    participant User as Vault User

    Admin->>CRE: Serve signed EIP-712 attestation
    CRE->>PF: Broadcast verified report
    PF->>PF: Validate attestation<br/>Compute risk mode
    PF->>Vault: update risk state

    User->>Vault: deposit / withdraw / redeem
    Vault->>ACE: Evaluate policies
    ACE-->>Vault: Allow / Reject
    Vault-->>User: Execute or revert
Loading

This flow shows how VaultGuard connects off-chain attestations, CRE orchestration, PoR state updates, and ACE policy enforcement into one end-to-end system.


0) Requirements

Required Tools

Optional (only required if running the AI risk demo):

Clone this repo

git clone https://github.com/VitalR/cre-vaultguard.git
cd cre-vaultguard

Install dependencies

Install workflow dependencies:

bun install --cwd ./workflows

Install attestation server dependencies:

cd attestation-server && npm i

1) Environment setup

1.1 Sepolia .env (repo root)

Create .env in the repo root (same folder as Makefile) with at least:

RPC + addresses

  • SEPOLIA_URL
  • ASSET_ADDRESS
  • VAULT_ADDRESS
  • PORFEED_ADDRESS

Demo actors

  • ALLOWLIST_ADDRESS
  • ALLOWLIST_PK
  • NO_ALLOWLIST_ADDRESS
  • NO_ALLOWLIST_PK

Operator key (used for onchain admin toggles during demo)

  • CRE_ETH_PRIVATE_KEY

Amounts

  • AMT_OK (a normal deposit amount that should pass policies in NORMAL)
  • AMT_DUST (below min ticket; should revert)
  • AMT_MIN_OK (small withdraw amount allowed under LIMITED)

Optional (recommended for max-volume policy demo)

  • AMT_OVER (a deposit amount that exceeds the ACE max-volume cap; should revert)

Tip: store private keys only in local .env (never commit).

1.2 Tenderly .env.tenderly-vtn (repo root)

If you run Tenderly VTN:

  • RPC_URL (or TENDERLY_RPC)
  • same addresses/keys/amounts pattern as above
  • optionally: TENDERLY_MAX_AGE_SEC, TENDERLY_PAUSED_MAX_AGE_SEC

2) Start the attestation server

Terminal A:

make server-start
# or:
# cd attestation-server && npm run dev

Useful checks:

cd attestation-server && make debug
cd attestation-server && make latest
cd attestation-server && make state
cd attestation-server && make signals

3) Quick path (recommended): one command demo

Terminal B (repo root):

make demo
# or:
# bash scripts/demo.sh

This script performs:

  • baseline: healthy + AI OFF → NORMAL
  • ACE: allowlist + min ticket reverts
  • NORMAL deposit success
  • LIMITED: deposit blocked, withdraw allowed
  • PAUSED: deposits/withdraws blocked
  • optional AI calm/panic tightening
  • reset + redeem to clean state

4) Manual path (step-by-step)

4.1 Sanity check onchain state

make status
# and/or:
cast call $VAULT_ADDRESS "riskMode()(uint8)" --rpc-url $SEPOLIA_URL

4.2 Fund and approve demo users (once per run)

cast send $ASSET_ADDRESS "mint(address,uint256)" $ALLOWLIST_ADDRESS 1000000000   --rpc-url $SEPOLIA_URL --private-key $ALLOWLIST_PK
cast send $ASSET_ADDRESS "mint(address,uint256)" $NO_ALLOWLIST_ADDRESS 1000000000   --rpc-url $SEPOLIA_URL --private-key $NO_ALLOWLIST_PK

cast send $ASSET_ADDRESS "approve(address,uint256)" $VAULT_ADDRESS 2000000000   --rpc-url $SEPOLIA_URL --private-key $ALLOWLIST_PK
cast send $ASSET_ADDRESS "approve(address,uint256)" $VAULT_ADDRESS 2000000000   --rpc-url $SEPOLIA_URL --private-key $NO_ALLOWLIST_PK

5) Baseline: PoR → NORMAL

Terminal A:

make server-healthy
# (equivalent) cd attestation-server && make healthy

Terminal B:

make workflow-broadcast
cast call $VAULT_ADDRESS "riskMode()(uint8)" --rpc-url $SEPOLIA_URL

Expected: 0 (NORMAL).


6) ACE policy cases

6.1 Allowlist blocks non-allowlisted deposit

cast send $VAULT_ADDRESS "deposit(uint256,address)" $AMT_OK $NO_ALLOWLIST_ADDRESS   --rpc-url $SEPOLIA_URL --private-key $NO_ALLOWLIST_PK

Expected: revert (AllowPolicy).

6.2 Min ticket blocks dust deposit

cast send $VAULT_ADDRESS "deposit(uint256,address)" $AMT_DUST $ALLOWLIST_ADDRESS   --rpc-url $SEPOLIA_URL --private-key $ALLOWLIST_PK

Expected: revert (min ticket).

6.3 Max volume blocks oversized deposit (optional)

Set AMT_OVER in .env to exceed the configured ACE max-volume cap.

cast send $VAULT_ADDRESS "deposit(uint256,address)" $AMT_OVER $ALLOWLIST_ADDRESS   --rpc-url $SEPOLIA_URL --private-key $ALLOWLIST_PK

Expected: revert (max volume policy).

6.4 Happy deposit (NORMAL)

cast send $VAULT_ADDRESS "deposit(uint256,address)" $AMT_OK $ALLOWLIST_ADDRESS   --rpc-url $SEPOLIA_URL --private-key $ALLOWLIST_PK

7) PoR-driven RiskMode gating

7.1 LIMITED (deposits disabled, withdrawals allowed)

Terminal A:

make server-limited

Terminal B:

make workflow-broadcast
cast call $VAULT_ADDRESS "riskMode()(uint8)" --rpc-url $SEPOLIA_URL

Expected: 1 (LIMITED).

Deposit should revert:

cast send $VAULT_ADDRESS "deposit(uint256,address)" $AMT_OK $ALLOWLIST_ADDRESS   --rpc-url $SEPOLIA_URL --private-key $ALLOWLIST_PK

Withdraw should succeed:

cast send $VAULT_ADDRESS "withdraw(uint256,address,address)" $AMT_MIN_OK $ALLOWLIST_ADDRESS $ALLOWLIST_ADDRESS   --rpc-url $SEPOLIA_URL --private-key $ALLOWLIST_PK

7.2 PAUSED (everything blocked)

Terminal A:

make server-stale

Terminal B:

make workflow-broadcast
cast call $VAULT_ADDRESS "riskMode()(uint8)" --rpc-url $SEPOLIA_URL

Expected: 2 (PAUSED). Deposits/withdrawals should revert.


8) AI demo (optional)

8.1 Enable AI (PoRFeed + Vault)

make ai-on
# Equivalent explicit calls:
# cast send $PORFEED_ADDRESS "setAiEnabled(bool)" true --rpc-url $SEPOLIA_URL --private-key $CRE_ETH_PRIVATE_KEY
# cast send $VAULT_ADDRESS   "setAiEnabled(bool)" true --rpc-url $SEPOLIA_URL --private-key $CRE_ETH_PRIVATE_KEY

8.2 Healthy + calm (no tighten expected)

Terminal A:

make server-healthy-ai-calm

Terminal B:

make workflow-broadcast
cast call $VAULT_ADDRESS "riskMode()(uint8)" --rpc-url $SEPOLIA_URL

Expected: 0 (NORMAL).

8.3 Healthy + panic (tighten expected)

Terminal A:

make server-healthy-ai-panic

Terminal B:

make workflow-broadcast
cast call $VAULT_ADDRESS "riskMode()(uint8)" --rpc-url $SEPOLIA_URL

Expected: 1 (LIMITED) (or whatever your “tighten” outcome is configured to be).

8.4 Disable AI

make ai-off

When AI is disabled, workflow logs should include only: [AI] AI is disabled, skipping AI signals + OpenAI call.


9) Reset: back to NORMAL + redeem

Terminal A:

make server-healthy

Terminal B:

make workflow-broadcast
cast call $VAULT_ADDRESS "riskMode()(uint8)" --rpc-url $SEPOLIA_URL

Expected: 0 (NORMAL).

Redeem (policy cap per tx may apply):

cast send $VAULT_ADDRESS "redeem(uint256,address,address)" 50000000000000000000 $ALLOWLIST_ADDRESS $ALLOWLIST_ADDRESS   --rpc-url $SEPOLIA_URL --private-key $ALLOWLIST_PK
REMAINING=$(cast call $VAULT_ADDRESS "balanceOf(address)(uint256)" $ALLOWLIST_ADDRESS --rpc-url $SEPOLIA_URL | awk '{print $1}')
cast send $VAULT_ADDRESS "redeem(uint256,address,address)" $REMAINING $ALLOWLIST_ADDRESS $ALLOWLIST_ADDRESS   --rpc-url $SEPOLIA_URL --private-key $ALLOWLIST_PK

10) Tenderly Virtual TestNet (VTN)

Use the dedicated runner:

bash scripts/tenderly/demo.sh

Notes:

  • Fork timestamps can make “stale” behave differently; the Tenderly script may lower maxAgeSec temporarily to force PAUSED.
  • Ensure deployments/tenderly-vtn.json and .env.tenderly-vtn agree on RPC + addresses.

Troubleshooting

If riskMode doesn’t change after broadcast:

  • confirm server scenario: cd attestation-server && make state
  • confirm PoRFeed nonce increments:
    cast call $PORFEED_ADDRESS "lastNonce()(uint64)" --rpc-url $SEPOLIA_URL
  • confirm correct workflow target: --target=staging-settings vs --target=tenderly-vtn
  • confirm AI flags:
    cast call $PORFEED_ADDRESS "aiEnabled()(bool)" --rpc-url $SEPOLIA_URL
    cast call $VAULT_ADDRESS   "aiEnabled()(bool)" --rpc-url $SEPOLIA_URL