Skip to content

Functions

DISCLAIMER // NFA // DYOR

This analysis is based on observations of the contract behavior. We are not smart contract security experts. This document aims to explain what the contract appears to do based on the code. It should not be considered a comprehensive security audit or financial advice. Always verify critical information independently and consult with blockchain security professionals for important decisions.

⊙ generated by robots | curated by humans

METADATA
Contract Address 0x00000000...1da8dB (etherscan)
Network Ethereum Mainnet
Analysis Date 2026-07-03

Function Selectors

SELECTOR FUNCTION SIGNATURE CATEGORY
0x8be3ad21 wrap(bytes32,uint256,bytes32) User
0x717fd7f2 settle(bytes,bytes,bytes[]) User
0x0b36171c attestBitcoinStateProven(bytes,bytes) User
createPairAndSettle createPairAndSettle(bytes32,bytes32,uint32,bytes,bytes,bytes[]) User
createPair createPair(bytes32,bytes32,uint32,uint8,bytes32,uint32) User
createPairAndAddLiquidityPublic createPairAndAddLiquidityPublic(bytes32,bytes32,uint32,uint256,uint256,uint256,uint64,address) User
swapPublic swapPublic(bytes32,bytes32,uint32,uint256,uint256,uint64,address) User
removeLiquidityPublicFrom removeLiquidityPublicFrom(bytes32,bytes32,uint32,uint256,uint256,uint256,uint64,address,address) User
shieldShares shieldShares(bytes32,uint256,bytes32) User
approveLpOperator approveLpOperator(address) User
farmEscrow farmEscrow(address,bytes32,uint256,address) User
0x0339e3f3 registerWrappedAuto(address,bytes32) User
registerWrapped registerWrapped(address,uint256,bytes32,string,string,uint8) User
registerMinted registerMinted(address,string,string,uint8) User
assets assets(bytes32) View
pools pools(bytes32) View
escrow escrow(bytes32) View
currentRoot currentRoot() View
nextLeafIndex nextLeafIndex() View
depositStatus depositStatus(bytes32) View
localAssetOf localAssetOf(bytes32) View
canonicalTokenFor canonicalTokenFor(bytes32) View
pendingBtcCall pendingBtcCall(bytes32) View
farmTreasury farmTreasury(address) View
cbtcBackingSats cbtcBackingSats() View
cbtcLockVBtc cbtcLockVBtc(bytes32) View
cbtcLockSpent cbtcLockSpent(bytes32) View
cbtcLockRedeemed cbtcLockRedeemed(bytes32) View
cbtcMinted cbtcMinted(bytes32) View
CBTC_ZK_ASSET_ID CBTC_ZK_ASSET_ID() View

Note: only the four selectors actually observed on-chain (wrap, settle, attestBitcoinStateProven, registerWrappedAuto) are shown as raw hashes; the remaining signatures are listed by name (derive the selector with cast sig).


Summary

CATEGORY COUNT
Total Functions 30
User Functions 14
Admin Functions 0
View Functions 16

User Functions

Function: settle(bytes publicValues, bytes proofBytes, bytes[] memos)

The single proof entrypoint. Verifies one SP1 proof against the immutable PROGRAM_VKEY, decodes the versioned PublicValues, and applies every effect the guest attested: spend nullifiers, append note/lock/CDP leaves, consume deposits, run AMM swaps and LP moves, open/close/liquidate/top-up CDP positions, mint cBTC against reflected locks, record cross-chain burns, and pay withdrawals + settler fees. All amount/conservation/range checking happened in the guest; the contract enforces roots, one-shot gates, reserve floors, and the public boundary.

ATTRIBUTE VALUE
Selector 0x717fd7f2
Parameters publicValues (ABI-encoded PublicValues), proofBytes (SP1 proof), memos (one encrypted memo per leaf, data-availability only)
Access External, nonReentrant, non-payable
FLAG OBSERVATION
Membership may be proven against an Ethereum root or a relay-attested Bitcoin root (cross-lane). Bitcoin-homed value exits must record the source nullifier for reverse reflection, or bridge.
Chain-bound: pv.chainBinding must equal keccak(chainid, address(this)), so a proof cannot be replayed onto another deployment.
No-inflation floor re-checked on-chain: evmNullifiersSpent ≤ nextLeafIndex (ReserveFloorBreach).
The contract trusts the guest's conservation/range math entirely; on-chain checks are structural gates + defense-in-depth floors, not a re-derivation of the cryptography.
Settler fees (pv.fees) are paid to msg.sender — a third-party relayer model; a self-prover sets none.
CONDITION REQUIREMENT
Valid proof SP1_VERIFIER.verifyProof(PROGRAM_VKEY, publicValues, proofBytes)
Version pv.version == PV_VERSION (1)
Chain binding pv.chainBinding == CHAIN_BINDING
Not expired pv.deadline == 0 || block.timestamp <= pv.deadline
Known roots spendRoot, lockSetRoot, cdpPositionRoot, bitcoinBurnRoot, bitcoinSpentRoot must each be a known/current root when the corresponding effect is present
Memos cover leaves memos.length >= pv.leaves.length
STEP ACTION
1 Verify SP1 proof; decode PublicValues; check version/chain/deadline
2 Resolve home lane (Ethereum vs Bitcoin root); enforce btcHomed value-exit rules
3 Mark each nullifier spent (revert on repeat); emit NullifiersSpent
4 Apply adaptor lock spends/appends; CDP mint/topup/close/liquidate via controllers; cBTC mint gates
5 Consume deposits; process bridge mints (one per burn nullifier); append note leaves; advance root
6 Pay withdrawals + settler fees; record cross-outs; apply AMM swap and LP pre→post reserves
VARIABLE CHANGE
nullifierSpent / lockSpent / cdpPositionSpent set true per spent id
nextLeafIndex, currentRoot, everKnownRoot advanced by appended leaves
escrow / canonical ERC-20 supply decreased/minted on payouts
pools[*].reserve*, .totalShares set to proven post-state
bridgeMinted, depositStatus, bitcoinConsumed*, crossOut*, cbtcMinted updated per effect
CONDITION REVERT MESSAGE
Bad proof (SP1 verifier reverts)
Wrong version / chain BadVersion / ChainMismatch
Reused nullifier NullifierAlreadySpent
Unknown / stale root UnknownRoot / StaleBitcoin*Root / UnknownLockRoot / UnknownCdpRoot
Inflation floor tripped ReserveFloorBreach
Escrow short InsufficientEscrow
function settle(bytes calldata publicValues, bytes calldata proofBytes, bytes[] calldata memos)
    external
    nonReentrant
{
    _settle(publicValues, proofBytes, memos);
}
// _settle: SP1_VERIFIER.verifyProof(PROGRAM_VKEY, ...); decode PublicValues; check version,
// chainBinding, deadline; resolve EVM vs Bitcoin home lane; spend nullifiers; apply lock/CDP/cBTC
// effects; consume deposits; bridge-mint gates; append leaves + advance root; pay withdrawals/fees;
// record cross-outs; apply AMM swap + LP pre→post reserve transitions. (~450 lines; see source.)

Function: wrap(bytes32 assetId, uint256 amount, bytes32 commit)

Public deposit boundary. Escrows amount of the asset's underlying (transfer-in an external ERC-20, escrow native ETH via msg.value, or burn a pool-minted canonical ERC-20) and records a pending deposit keyed by depositId = keccak(assetId, value, commit), where commit = keccak(Cx‖Cy‖owner). The note is inserted into the tree only when a later settle consumes the deposit and proves the commitment opens to value = amount/unitScale.

ATTRIBUTE VALUE
Selector 0x8be3ad21
Parameters assetId, amount (underlying units), commit (note commitment digest)
Access External, payable, nonReentrant
FLAG OBSERVATION
Only the digest reaches the chain — the note's nullifier stays externally uncomputable, so the later spend is unlinkable.
Amount must be a whole multiple of unitScale and fit u64 after scaling (AmountNotAligned / ValueOutOfRange) — binds the note's value to the escrow so it can never claim more than was deposited.
Fee-on-transfer tokens are rejected by a realized-delta check (FeeOnTransferUnsupported).
CONDITION REQUIREMENT
Registered asset _assets[assetId].registered
ETH coverage native ETH: msg.value == amount; else msg.value == 0
Fresh deposit id depositStatus[depositId] == 0
VARIABLE CHANGE
depositStatus[depositId] 0 → 1 (pending)
escrow[assetId] += amount (escrow assets) or canonical ERC-20 burned (pool-minted)
CONDITION REVERT MESSAGE
Not registered NotRegistered
ETH mismatch EthValueMismatch
Duplicate deposit DepositExists
Misaligned / oversize amount AmountNotAligned / ValueOutOfRange
function wrap(bytes32 assetId, uint256 amount, bytes32 commit) external payable nonReentrant {
    AssetStore storage a = _assets[assetId];
    if (!a.registered) revert NotRegistered();
    uint256 value = _amountToValue(amount, a.unitScale);
    bytes32 depositId = keccak256(abi.encodePacked(assetId, value, commit));
    _registerDeposit(depositId);
    if (a.underlying == address(0)) { if (msg.value != amount) revert EthValueMismatch(); }
    else if (msg.value != 0) revert EthValueMismatch();
    _moveInUnderlying(a, assetId, amount);
    emit Wrap(depositId, assetId, amount);
}

Function: attestBitcoinStateProven(bytes publicValues, bytes proofBytes)

The trustless Bitcoin-state import. Verifies an SP1 "reflection" proof against BITCOIN_RELAY_VKEY, then advances the reflected Bitcoin roots (pool note root → knownBitcoinRoot; spent-nullifier root; bridge-burn root), the reflection digest chain, cBTC backing/locks, and any etch-authenticated asset metadata. Roots are anchored to canonical Bitcoin via the BitcoinLightRelay and matured REFLECTION_CONFIRMATIONS (6) deep. No trusted oracle — the proof is the sole authority.

ATTRIBUTE VALUE
Selector 0x0b36171c
Parameters publicValues (ABI-encoded BitcoinRelayPublicValues), proofBytes
Access External, nonReentrant, non-payable
FLAG OBSERVATION
Append-only digest chain: priorDigest == knownReflectionDigest, height non-decreasing — a stale proof cannot roll the spent set backward.
Non-zero sentinel roots enforced (ZeroBitcoinPoolRoot, StaleBitcoin*Root) so an empty tree can never be marked canonical.
Freshness gates tie the folded fast-lane consume count and cross-out count to the current on-chain counters (ConsumedCountStale).
Soundness depends entirely on the off-chain reflection guest pinned by BITCOIN_RELAY_VKEY and on the BitcoinLightRelay's honesty about the canonical tip.
CONDITION REQUIREMENT
Reflection enabled BITCOIN_RELAY_VKEY != 0
Valid proof SP1_VERIFIER.verifyProof(BITCOIN_RELAY_VKEY, ...)
Continues chain r.priorDigest == knownReflectionDigest, r.newDigest != 0
Matured anchor prev == prior tip; tip is a matured ancestor of RELAY.tip()
VARIABLE CHANGE
knownBitcoinRoot[poolRoot] set true
knownBitcoinSpentRoot / knownBitcoinBurnRoot / knownReflectionDigest advanced
lastRelayHeight, lastReflectionBlockHash, cbtcBackingSats advanced
cbtcLockVBtc/Commitment/Spent/Redeemed, pendingBtcCall, localAssetOf updated per folded effect
CONDITION REVERT MESSAGE
Reflection off ZeroVKey
Stale digest/height StaleReflectionDigest / StaleRelayProof
Zero/omitted root ZeroBitcoinPoolRoot / StaleBitcoinSpentRoot / StaleBitcoinBurnRoot
Unanchored to Bitcoin UnanchoredReflection
Wrong reflected eth pool WrongEthPool
function attestBitcoinStateProven(bytes calldata publicValues, bytes calldata proofBytes)
    external nonReentrant
{
    if (BITCOIN_RELAY_VKEY == bytes32(0)) revert ZeroVKey();
    SP1_VERIFIER.verifyProof(BITCOIN_RELAY_VKEY, publicValues, proofBytes);
    BitcoinRelayPublicValues memory r = abi.decode(publicValues, (BitcoinRelayPublicValues));
    // mode-B eth pool gate; digest continuity; height non-decrease; non-zero sentinel roots;
    // fast-lane + cross-out freshness; _anchorReflection(prev, tip); advance roots/digest/backing;
    // fold cBTC locks; auto-register etch metadata; record pending Bitcoin calls. (see source)
}

Function: createPairAndAddLiquidityPublic(bytes32 assetA, bytes32 assetB, uint32 feeBps, uint256 amountA, uint256 amountB, uint256 minSharesOut, uint64 deadline, address to)

Public (non-shielded) liquidity provisioning. Lazily creates the canonical (assetA, assetB, feeBps) pool if absent, escrows both legs from public ERC-20/ETH funds, sets/updates reserves, and credits public LP shares to to. First add mints isqrt(vA·vB) with MINIMUM_LIQUIDITY locked; later adds are proportional (limiting-leg rule) with the off-ratio excess refunded.

ATTRIBUTE VALUE
Selector derive via cast sig
Parameters asset pair, fee tier, amounts, min-shares slippage, deadline, recipient
Access External, payable, nonReentrant
FLAG OBSERVATION
Shares public here vs a confidential note via shieldShares; both share pools[poolId].totalShares.
Reserves bounded to u64; excess leg refunded, never donated.
CONDITION REVERT MESSAGE
Same asset / unregistered SameAsset / NotRegistered
ETH mismatch EthValueMismatch
Below min shares SlippageExceeded
Dust first add InsufficientLiquidity
function createPairAndAddLiquidityPublic(bytes32 assetA, bytes32 assetB, uint32 feeBps,
    uint256 amountA, uint256 amountB, uint256 minSharesOut, uint64 deadline, address to)
    external payable nonReentrant returns (uint256 sharesMinted) { /* see source */ }

Function: swapPublic(bytes32 assetIn, bytes32 assetOut, uint32 feeBps, uint256 amountIn, uint256 minAmountOut, uint64 deadline, address to)

Public constant-product swap against the pool's public reserves (no privacy — the amount is revealed; the confidential OP_SWAP hides it). out = floor(reserveOut·vIn·γ / (reserveIn·10000 + vIn·γ)), γ = 10000 − feeBps; k can only increase.

ATTRIBUTE VALUE
Selector derive via cast sig
Parameters in/out assets, fee tier, amountIn, minAmountOut, deadline, recipient
Access External, payable, nonReentrant
CONDITION REVERT MESSAGE
Uninitialised pool PoolNotInit
Zero/over output InsufficientLiquidity
k decreased ConstantProductDecreased
Below min out SlippageExceeded
function swapPublic(bytes32 assetIn, bytes32 assetOut, uint32 feeBps, uint256 amountIn,
    uint256 minAmountOut, uint64 deadline, address to)
    external payable nonReentrant returns (uint256 amountOut) { /* see source */ }

Function: removeLiquidityPublicFrom(bytes32 assetA, bytes32 assetB, uint32 feeBps, uint256 shares, uint256 minAmountA, uint256 minAmountB, uint64 deadline, address owner, address to)

Burns public LP shares and withdraws proportional reserves to to. If owner != msg.sender, the caller must be an LP operator approved by owner. Can never remove the locked MINIMUM_LIQUIDITY.

ATTRIBUTE VALUE
Selector derive via cast sig
Access External, nonReentrant
FLAG OBSERVATION
Operator delegation is all-or-nothing: an approved operator may remove any amount to an operator-chosen to. Approve only trusted routers.
function removeLiquidityPublicFrom(bytes32 assetA, bytes32 assetB, uint32 feeBps, uint256 shares,
    uint256 minAmountA, uint256 minAmountB, uint64 deadline, address owner, address to)
    external nonReentrant returns (uint256 amountLo, uint256 amountHi) { /* see source */ }

Function: createPair(...) / createPairAndSettle(...)

createPair(assetA, assetB, feeBps, rcptPrefix, rcptX, protocolFeeBps) creates an empty confidential AMM pool slot (one per canonical pair + fee; optional fee-switch recipient). createPairAndSettle(assetA, assetB, feeBps, publicValues, proofBytes, memos) lazily creates the slot then runs _settle in one tx so a single proof both founds and seeds the pool.

ATTRIBUTE VALUE
Access External; createPairAndSettle is nonReentrant
FLAG OBSERVATION
Front-run resistant: a front-run only registers the empty slot; the first funder becomes founder, so the pair cannot be captured.
Swap fee capped at MAX_POOL_FEE_BPS (10%); protocolFeeBps < 10000.
function createPair(bytes32 assetA, bytes32 assetB, uint32 feeBps, uint8 rcptPrefix,
    bytes32 rcptX, uint32 protocolFeeBps) external returns (bytes32 poolId);
function createPairAndSettle(bytes32 assetA, bytes32 assetB, uint32 feeBps,
    bytes calldata publicValues, bytes calldata proofBytes, bytes[] calldata memos)
    external nonReentrant;

Function: shieldShares(bytes32 poolId, uint256 shares, bytes32 commit)

Opt-in privacy for an LP position: burns the caller's public LP shares and records a pending deposit that the existing OP_WRAP settle consumes into a confidential LP-share note. totalShares is unchanged (a form change only); the note is spendable only via OP_LP_REMOVE.

ATTRIBUTE VALUE
Access External, nonReentrant
function shieldShares(bytes32 poolId, uint256 shares, bytes32 commit)
    external nonReentrant returns (bytes32 depositId) { /* burns public shares, registers deposit */ }

Function: farmEscrow(address controller, bytes32 rewardAsset, uint256 amount, address to)

Fund (amount > 0) or wind down (amount == 0) a farm controller's escrow-backed reward treasury. Funding pins one escrow reward asset per controller; recovery returns exactly the budget not backing outstanding reward notes to the funding controller.

ATTRIBUTE VALUE
Access External, nonReentrant
FLAG OBSERVATION
Recovery is gated to the controller that funded (msg.sender), and can never reach another farm's backing.
Native/pool-minted assets are rejected as escrow reward assets (those are mint-mode).
function farmEscrow(address controller, bytes32 rewardAsset, uint256 amount, address to)
    external nonReentrant returns (uint256 out) { /* fund or recover, see source */ }

Function: approveLpOperator(address operator)

Approves an all-or-nothing operator to removeLiquidityPublicFrom the caller's public LP shares. Pass address(0) to revoke.

ATTRIBUTE VALUE
Access External
FLAG OBSERVATION
The setApprovalForAll model — the operator may remove any amount to any recipient. Approve only trusted contracts.
function approveLpOperator(address operator) external { lpOperator[msg.sender] = operator; }

Function: registerWrapped(...) / registerWrappedAuto(...) / registerMinted(...)

Permissionless asset registration.

  • registerWrapped(underlying, unitScale, crossChainLink, name, symbol, decimals) — register an external ERC-20 as an escrow-backed confidential asset (crossChainLink must be 0).
  • registerWrappedAuto(underlying, crossChainLink) — same, reading the token's decimals() and deriving unitScale = 10^(decimals − min(decimals,8)) on-chain.
  • registerMinted(canonicalErc20, name, symbol, tacitDecimals) — register a local pool-minted asset whose canonical ERC-20 this pool mints/burns (mint authority must be this pool).
ATTRIBUTE VALUE
Selector registerWrappedAuto = 0x0339e3f3
Access External, nonReentrant
FLAG OBSERVATION
A permissionless caller can never set a bridged cross-chain link: escrow assets reject a non-zero link (CrossChainEscrow); pool-minted links must match the token's committed ASSET_ID; native ETH's link is constructor-pinned.
The bridged-resolution link that a bridged unwrap uses is set only by the guest-proven attest_meta path, so a scale/token cannot be poisoned.
CONDITION REVERT MESSAGE
Already registered AlreadyRegistered
Link on escrow asset CrossChainEscrow
Link/token mismatch CrossChainTokenMismatch / CrossChainLinkTaken
Not this pool's minter PoolNotMinter
Bad decimals/scale BadDecimals / AmountNotAligned
function registerWrapped(address underlying, uint256 unitScale, bytes32 crossChainLink,
    string calldata name_, string calldata symbol_, uint8 decimals_)
    external nonReentrant returns (bytes32 assetId);
function registerWrappedAuto(address underlying, bytes32 crossChainLink)
    external nonReentrant returns (bytes32 assetId);
function registerMinted(address canonicalErc20, string calldata name_, string calldata symbol_,
    uint8 tacitDecimals) external nonReentrant returns (bytes32 assetId);

View Functions

Function: assets(bytes32 assetId)

Returns the asset registry tuple (registered, underlying, unitScale, crossChainLink, poolMinted, decimals). name/symbol are not stored — read them from the AssetRegistered event.

ATTRIBUTE VALUE
Access External, view
function assets(bytes32 assetId) external view
    returns (bool, address, uint256, bytes32, bool, uint8);

Function: pools(bytes32 poolId)

Returns the AMM pool tuple (init, assetA, assetB, reserveA, reserveB, feeBps, totalShares) for a canonical (pair, fee) slot.

function pools(bytes32 poolId) external view
    returns (bool, bytes32, bytes32, uint256, uint256, uint32, uint256);

Function: canonicalTokenFor(bytes32 assetId) / localAssetOf(bytes32)

canonicalTokenFor resolves an asset id (native or shared Bitcoin-side) to the canonical ERC-20 the pool recognizes, or address(0) — the source of truth for "is this the real token?" (impostors are never pool-registered). localAssetOf maps a shared Bitcoin-side id to this pool's local registry key.

function canonicalTokenFor(bytes32 assetId) external view returns (address);
function localAssetOf(bytes32) external view returns (bytes32); // public mapping getter

Function: shielded-pool & escrow views

Read-only accessors over pool state.

  • currentRoot() — the latest note-tree root.
  • nextLeafIndex() — total note leaves ever created.
  • escrow(bytes32 assetId) — escrowed underlying for an asset.
  • depositStatus(bytes32 depositId) — 0 none / 1 pending / 2 consumed.
  • farmTreasury(address controller) — a farm's funded, undistributed budget.
function currentRoot() external view returns (bytes32);
function nextLeafIndex() external view returns (uint256);
function escrow(bytes32) external view returns (uint256);        // public mapping getter
function depositStatus(bytes32) external view returns (uint8);   // public mapping getter
function farmTreasury(address) external view returns (uint256);  // public mapping getter

Function: cBTC views

Read-only cBTC (confidential Bitcoin) state, all advanced by reflection.

  • cbtcBackingSats() — Σ live self-custody cBTC.zk lock sats (the off-pool buffer reads it).
  • cbtcLockVBtc(outpoint) / cbtcLockSpent / cbtcLockRedeemed / cbtcMinted — per-lock registry + one-shot mint gate.
  • CBTC_ZK_ASSET_ID() — the fixed keccak256("tacit-cbtc-zk-lock-v1") domain constant.
  • pendingBtcCall(callId) — a recorded value-free Bitcoin-authorized call commitment (fired by a separate executor).
function cbtcBackingSats() external view returns (uint256);
function cbtcLockVBtc(bytes32) external view returns (uint64);
function cbtcLockSpent(bytes32) external view returns (bool);
function cbtcLockRedeemed(bytes32) external view returns (bool);
function cbtcMinted(bytes32) external view returns (bool);
function CBTC_ZK_ASSET_ID() external view returns (bytes32);
function pendingBtcCall(bytes32) external view returns (bytes32);