Skip to main content

GhostVault Contract

The production architecture replaces the generic Chainlink Compliant Private Transfer vault with a purpose built GhostVault smart contract. This contract adds protocol specific logic for collateral locking, DON authorized fund movements, and on chain settlement verification.

note

The GhostVault is the production design target. The current implementation uses Chainlink's generic vault at 0xE588a6c73933BFD66Af9b4A07d48bcE59c0D2d13.

Contract Responsibilities

FunctionDescription
deposit(token, amount)Accept ERC20 deposits into the vault
withdraw(token, amount)Allow withdrawals up to unlocked balance
onReport(report, signatures)Process DON signed reports for fund movements
lockedBalances[user][token]Track soft locked collateral and lend positions

Soft Locking Mechanism

The GhostVault introduces a lockedBalances mapping that prevents users from withdrawing funds that are committed to active protocol operations:

mapping(address => mapping(address => uint256)) public lockedBalances;

function withdraw(address token, uint256 amount) external {
uint256 available = balances[msg.sender][token] - lockedBalances[msg.sender][token];
require(amount <= available, "Insufficient unlocked balance");
// ... execute withdrawal
}

Locks are incremented when:

  • A lender confirms a deposit (their lending amount is locked)
  • A borrower submits a borrow intent (their collateral is locked)

Locks are decremented when:

  • A lend intent is cancelled
  • A borrow intent is cancelled
  • A loan is repaid
  • A loan is liquidated

Lock operations are executed via DON signed reports, ensuring that only the CRE (through threshold consensus) can modify lock state.

DON Report Processing

The onReport function is the sole entry point for protocol authorized fund movements:

function onReport(bytes calldata report, bytes[] calldata signatures) external {
// Verify DON threshold signatures
require(verifyDONSignatures(report, signatures), "Invalid DON signatures");

// Decode and execute operations
Operation[] memory ops = abi.decode(report, (Operation[]));
for (uint i = 0; i < ops.length; i++) {
executeOperation(ops[i]);
}
}

Each operation can be:

  • A private transfer between shielded addresses
  • A lock/unlock of user balances
  • A collateral seizure (for liquidations)

EIP 712 Typed Data

The production contract defines typed data structures for each protocol action:

TypeFieldsPurpose
LendBidlender, token, amount, encryptedRate, nonce, deadlineSubmit a lending position
BorrowRequestborrower, token, amount, encryptedMaxRate, collateralToken, collateralAmount, nonce, deadlineSubmit a borrow request
CancelIntentuser, intentId, nonce, deadlineCancel a lend or borrow intent

These typed data signatures are verified by the contract before forwarding to the CRE via the DON's HTTP proxy.

Differences from Generic Vault

FeatureGeneric VaultGhostVault
Collateral lockingNot supportedNative lockedBalances
Protocol specific operationsNoneLock, unlock, seize via DON report
Intent submissionOff chain onlyOn chain via EIP 712 + DON proxy
Withdrawal restrictionsNone (full balance available)Available = balance minus locked
Upgrade mechanismN/AUUPS proxy with timelock
Emergency controlsN/AGranular pause, circuit breaker

Access Control

The contract uses a minimal access control model:

RoleHeld ByPermissions
OwnerMultisig (3/5)Upgrade proxy, update DON config, emergency pause
DONChainlink DON addressSubmit reports via onReport
UsersAny addressDeposit, withdraw (unlocked), sign typed data

No admin can directly move user funds. All fund movements require valid DON signatures.