Spark Spell 2026-05-07 Security Review

Summary

Overall, we consider the spell to be ready for deployment and safe.

Deployment and state verification

[Ethereum/Avalanche] Spark Liquidity Layer - Update Bridge DVN Configuration

  • Correct endpoint and ULN addresses used:
    • Ethereum send side: SEND_ULN_302 = 0xbB2Ea70C9E858123480642Cf96acbcCE1372dCe1 (source)
    • Avalanche receive side: RECEIVE_ULN_302 = 0xbf3521d309642FA9B1c91A08609505BA09752c61 (source)
    • LAYERZERO_ENDPOINT_V2 = 0x1a44076050125825900e736c501f859c50fE728c (same on both chains)
  • Correct EIDs: Avalanche (30106) on send side, Ethereum (30101) on receive side
  • Correct threshold: 4 of 7 (optionalDVNThreshold: 4, optionalDVNCount: 7)
  • requiredDVNCount: 255 (NIL_DVN_COUNT) correctly overrides any default required DVNs
  • All 7 DVN addresses on both chains match the official LayerZero DVN registry for the correct providers: Horizen, LayerZero Labs, Nethermind, Deutsche Telekom, Canary, Luganodes, P2P (source)
  • DVN addresses correctly sorted in ascending order on both chains (required by LayerZero)
  • Tests passed:
    • SparkEthereum_20260507_SLLTests.test_AVALANCHE_sll_updateBridgeDvnConfiguration()
    • SparkEthereum_20260507_SLLTests.test_ETHEREUM_sll_updateBridgeDvnConfiguration()
    • SparkEthereum_20260507_SLLTests.test_ETHEREUM_attack_sendLibraryUnchanged()
    • SparkEthereum_20260507_SLLTests.test_AVALANCHE_attack_receiveLibraryUnchanged()

Overall status: safe

[Avalanche] Spark Liquidity Layer - Offboard Aave Avalanche USDC

  • Correct aToken used: Avalanche.ATOKEN_CORE_USDC
  • Rate limits:
    • ATOKEN_CORE_USDC_DEPOSIT_KEY:
      • maxAmount: 0
      • slope: 0
    • ATOKEN_CORE_USDC_WITHDRAW_KEY:
      • maxAmount: 0
      • slope: 0
  • Test passed: SparkEthereum_20260507_SLLTests.test_AVALANCHE_sll_deactivateAaveCoreUsdc()

Overall status: safe

[Ethereum] Spark Liquidity Layer - Update Spark Blue Chip USDT Morpho Vault

Deactivating old Morpho Vault V2 USDT integration

  • Correct old vault address: Ethereum.MORPHO_VAULT_V2_USDT = 0xc7CDcFDEfC64631ED6799C95e3b110cd42F2bD22
  • Rate limits correspond to the proposal:
    • OLD_MORPHO_VAULT_V2_USDT_DEPOSIT_KEY:
      • maxAmount: 0
      • slope: 0
    • OLD_MORPHO_VAULT_V2_USDT_WITHDRAW_KEY:
      • maxAmount: Unlimited
      • slope: 0
  • Any withdrawal or redemption from the old vault will revert after spell execution, despite the withdrawal rate limit being set to unlimited. Funds remaining in the old vault will be locked until the deposit rate limit is reconfigured. More details: PR discussion

Overall status: Spark team decided to cancel deactivating old Morpho vault, so it is safe

Onboarding new Morpho Vault V2 USDT integration

  • Correct new vault address: 0xb0c424116172B55CbB6dD3136F5989F7959e5B91
  • New vault onboarded with: depositMax = 100M USDT, depositSlope = 1B/day, withdrawMax = unlimited, maxExchangeRate = 1M USDT / share
  • Both vaults confirmed as MorphoVaultV2 via factory check
  • Old vault state:
    • adapterRegistry: ZERO_ADDRESS
    • adapters: 0x7481968709B8f155652D42ebf468b22945907dC2
    • adaptersLength: 1
    • asset: 0xdAC17F958D2ee523a2206206994597C13D831ec7
    • curator: 0x0f963A8A8c01042B69054e787E5763ABbB0646A3
    • decimals: 18
    • firstTotalAssets: 0
    • lastUpdate: 1777487687
    • liquidityAdapter: 0x7481968709B8f155652D42ebf468b22945907dC2
    • managementFee: 0
    • managementFeeRecipient: ZERO_ADDRESS
    • maxRate: 63419583967
    • name: Spark Blue Chip USDT Vault
    • owner: 0x3300f198988e4C9C63F75dF86De36421f06af8c4
    • performanceFee: 100000000000000000
    • performanceFeeRecipient: 0x1601843c5E9bC251A3272907010AFa41Fa18347E
    • receiveAssetsGate: ZERO_ADDRESS
    • receiveSharesGate: ZERO_ADDRESS
    • sendAssetsGate: ZERO_ADDRESS
    • sendSharesGate: ZERO_ADDRESS
    • symbol: sparkUSDTbc
  • New vault state:
    • adapterRegistry: 0x3696c5eAe4a7Ffd04Ea163564571E9CD8Ed9364e
    • adapters: 0xEF4cB7e87f212F128f0b24cf35861E52B3C78A6a
    • adaptersLength: 1 (matches with old vault)
    • asset: 0xdAC17F958D2ee523a2206206994597C13D831ec7 (matches with old vault)
    • curator: 0x0f963A8A8c01042B69054e787E5763ABbB0646A3 (matches with old vault)
    • decimals: 18 (matches with old vault)
    • firstTotalAssets: 0 (matches with old vault)
    • liquidityAdapter: 0xEF4cB7e87f212F128f0b24cf35861E52B3C78A6a
    • managementFee: 0 (matches with old vault)
    • managementFeeRecipient: 0x1601843c5E9bC251A3272907010AFa41Fa18347E
    • maxRate: 63419583650
    • name: Spark Blue Chip USDT Vault (matches with old vault)
    • owner: 0x3300f198988e4C9C63F75dF86De36421f06af8c4 (matches with old vault)
    • performanceFee: 100000000000000000 (matches with old vault)
    • performanceFeeRecipient: 0x1601843c5E9bC251A3272907010AFa41Fa18347E (matches with old vault)
    • receiveAssetsGate: ZERO_ADDRESS (matches with old vault)
    • receiveSharesGate: ZERO_ADDRESS (matches with old vault)
    • sendAssetsGate: ZERO_ADDRESS (matches with old vault)
    • sendSharesGate: ZERO_ADDRESS (matches with old vault)
    • symbol: sparkUSDTbc (matches with old vault)
  • Although the proposal states that vaults are equivalent, there are some differences:
    • marketIds order in the adapter differs between the old and new vault
      • status: no functional impact; the adapter uses marketIds only in realAssets() to sum assets across markets
    • adapterRegistry in the old vault was set to address(0), while in the new vault it is set to 0x3696c5eAe4a7Ffd04Ea163564571E9CD8Ed9364e (Morpho Registry, source)
      • status: beneficial change, required for Morpho frontend listing
    • managementFeeRecipient in the old vault was set to address(0), while in the new vault it is set to 0x1601843c5E9bC251A3272907010AFa41Fa18347E (ALM_PROXY)
      • status: no functional impact; managementFee is 0 on both vaults
    • maxRate in the old vault was set to 63419583967, while in the new vault it is set to 63419583650
      • status: negligible difference of 317 out of ~6.34e10
    • liquidityData in the old vault points to the wstETH/USDT market, while in the new vault it points to the sUSDS/USDT market
      • status: Spark team confirmed that sUSDS/USDT is the correct market
  • Tests passed:
    • SparkEthereum_20260507_SLLTests.test_ETHEREUM_sll_onboardNewMorphoVaultV2Usdt()
    • SparkEthereum_20260507_SLLTests.test_ETHEREUM_sll_switchMorphoVaultV2Usdt()
    • SparkEthereum_20260507_SLLTests.test_ETHEREUM_sll_newMorphovaultUIListingRequirements()
    • SparkEthereum_20260507_SLLTests.test_ETHEREUM_sll_adapterConfigMatch()

Overall status: safe

[Ethereum] Spark Liquidity Layer - Offboard Aave Core USDT

  • Correct aToken used: Ethereum.ATOKEN_CORE_USDT
  • Rate limits:
    • ATOKEN_CORE_USDT_DEPOSIT_KEY:
      • maxAmount: 0
      • slope: 0
    • ATOKEN_CORE_USDT_WITHDRAW_KEY:
      • maxAmount: 0
      • slope: 0
  • Test passed: SparkEthereum_20260507_SLLTests.test_ETHEREUM_sll_deactivateAaveCoreUsdt()

Overall status: safe

[Ethereum] SparkLend - Update LBTC Parameters

  • Correct token used: Ethereum.LBTC
  • Correct cap automator address: SparkLend.CAP_AUTOMATOR
  • Current supply cap config:
    • max: 10000
    • gap: 500
    • increaseCooldown: 43200
  • Update:
    • max: 5000
    • gap: 200
    • increaseCooldown: 43200
  • Test passed: SparkEthereum_20260507_SparklendTests.test_ETHEREUM_sparkLend_lbtcCapAutomatorUpdates()

Overall status: safe

[Ethereum] SparkLend - Update WBTC Parameters

  • Correct token used: Ethereum.WBTC
  • Correct cap automator address: SparkLend.CAP_AUTOMATOR = 0x4C1341636721b8B687647920B2E9481f3AB1F2eE
  • Current supply cap config:
    • max: 3000
    • gap: 500
    • increaseCooldown: 43200
  • Update:
    • max: 30000
    • gap: 500
    • increaseCooldown: 43200
  • Test passed: SparkEthereum_20260507_SparklendTests.test_ETHEREUM_sparkLend_wbtcCapAutomatorUpdates()

Overall status: safe

[Ethereum] SparkLend - Claim SparkLend Reserves

  • Implemented in base class SparkPayloadEthereum.execute(), runs automatically for every Ethereum spell

Overall status: safe

[Ethereum] Spark Treasury - Monthly Grants for Spark Foundation and Spark Assets Foundation

  • Correct token used: Ethereum.USDS
  • Correct recipient address for Spark Foundation: Ethereum.SPARK_FOUNDATION_MULTISIG
  • Correct recipient address for Spark Asset Foundation: Ethereum.SPARK_ASSET_FOUNDATION_MULTISIG
  • Correct amounts: 1,100,000 USDS and 100,000 USDS
  • Test passed: SparkEthereum_20260507_SpellTests.test_ETHEREUM_sparkTreasury_transfers()

Overall status: safe

[Ethereum] Spark Treasury - Transfer Excess USDS from SubDAO Proxy for SPK Buybacks

  • Correct token used: Ethereum.USDS
  • Correct recipient address: Ethereum.ALM_OPS_MULTISIG
  • Correct amount: 326,945 USDS (SPK_BUYBACKS_AMOUNT = 326_945e18)
  • Test passed: SparkEthereum_20260507_SpellTests.test_ETHEREUM_sparkTreasury_transfers()

Overall status: safe