KaleidofiDocs

Networks

Multichain deployment map

What has to exist on a chain before the app can point at it: our contracts, the external dependencies, and what must be verified per deployment.

4 sectionsSource docs/MULTICHAIN_DEPLOYMENT_MAP.md

What has to exist on each chain before the app can point at it, derived by reading the contracts and deploy scripts.

Deploy targets are already wired in smart-contract/hardhat.config.js:

networkchainIdcompilernotes
abstractMainnet2741zksolczkSync stack
abstractTestnet11124zksolczkSync stack
ethereum1solc
sepolia11155111solc
base8453solc
baseTestnet84532solc
bsc56solcnative BNB
bscTestnet97solcnative tBNB
robinhood4663solc
robinhoodTestnet46630solc
arcTestnet5042002solcnative currency is USDC, 18 decimals

1. Deployed per chain (ours)#

Diamond coreDiamond, DiamondCutFacet, DiamondInit, then cut in: DiamondLoupeFacet, OwnershipFacet, ProtocolFacet, AgentPermissionFacet.

AgentPermissionFacet is what bounds Luca on-chain (per-agent spend budgets and token allowlists that hold even if the frontend is bypassed). It was written but historically never cut in. It must be in the facet list or the agent has no on-chain limits at all.

DEX V3KaleidoSwapV3Factory, SwapRouter, NFTDescriptor, NonfungibleTokenPositionDescriptor, NonfungiblePositionManager, Quoter. The last four take WETH9 as a constructor argument, so the wrapped native must exist first.

StablecoinkfUSD, kafUSD, YieldTreasury (+ mock USDT/USDe on testnets).

StakingKLDVaultV2, StKLD, and the KLD token itself.

OraclePythPriceOracle, which takes Pyth's own contract address as a constructor argument.

Testnet onlyFaucet.

2. External per chain (not ours)#

whatwhy it is per-chain
Wrapped nativeWETH on Ethereum, WBNB on BNB, WPOL on Polygon; on Arc it wraps USDC. Not derivable from the native symbol.
Pyth contractDifferent address on every chain. Note the price feed ids (ETH_USD etc. in constant.sol) are global and do not vary.
USDCCanonical where it exists; a mock on testnets that lack one.

3. Derived, must be verified per deployment#

POOL_INIT_CODE_HASH — the highest-risk value in the whole deploy.

The V3 periphery derives pool addresses via CREATE2 from this constant instead of asking the factory, and the swap callback authenticates msg.sender against the derived address. The hash is a property of the compiled bytecode, and Kaleido targets two compilers: zksolc for Abstract, solc for every other chain. Identical source produces different bytecode under each.

A wrong value does not fail at deploy. The factory still creates pools. It breaks at the first swap, against an address holding no code.

Run smart-contract/scripts/verify-pool-init-hash.js per deployment and record the result in the registry.

4. Post-deploy configuration#

Deployment alone leaves the protocol inert. Required wiring:

  • setPythOracle(oracle)
  • addCollateralToken(token, priceFeedId) per accepted collateral
  • addLoanableToken(token, priceFeedId) per loanable asset
  • setSwapRouter(router)
  • setFeeVault, setBPS, setLiquidityBps
  • YieldTreasury: grant YIELD_SOURCE_ROLE to kfUSD, register kfUSD as a yield source, add supported yield assets
  • kfUSD: set YieldTreasury, enable auto-transfer, configure collaterals
  • kafUSD: set YieldTreasury, configure supported assets, cooldown