Spark Spell 2026-06-04 Security Review

Summary

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

Deployment and state verification

[Ethereum] SparkLend - Deprecate BTC e-mode

  • Correct assets: Ethereum.CBBTC and Ethereum.LBTC
  • Correctly sets emode category to 0 for both assets via POOL_CONFIGURATOR.setAssetEModeCategory()
  • Tests passed:
    • SparkEthereum_20260604_SparklendTests.test_ETHEREUM_sparkLend_deprecateBTCeMode()
    • SparkEthereum_20260604_SparklendTests.test_ETHEREUM_btcEmodeBorrowDeprecationE2E()
    • SparkEthereum_20260604_SparklendTests.test_ETHEREUM_btcEmodeBorrowPositionLiquidatableAfterDeprecationE2E()

Overall status: safe

[Ethereum] SparkLend - Update WBTC Oracle to Use Killswitch

  • Already implemented in the March 12, 2026 spell

Overall status: safe

[Ethereum] SparkLend - Update Cap Automator Parameters

  • Correct cap automator address: SparkLend.CAP_AUTOMATOR = 0x4C1341636721b8B687647920B2E9481f3AB1F2eE
  • Correct assets used: WETH, wstETH, weETH, WBTC, cbBTC
  • All increaseCooldown values correctly changed from 12 hours -> 4 hours
  • WETH supply cap config:
    • max: MAX_VALID_SUPPLY_CAP (Unlimited) <- from 2000000
    • gap: 100000 <- from 150000
    • cooldown: 4 hours <- from 12 hours
  • WETH borrow cap config:
    • max: MAX_VALID_BORROW_CAP (Unlimited) <- from 1000000
    • gap: 10000 <- from 20000
    • cooldown: 4 hours <- from 12 hours
  • wstETH supply cap config:
    • max: MAX_VALID_SUPPLY_CAP (Unlimited) <- from 2000000
    • gap: 50000 <- unchanged
    • cooldown: 4 hours <- from 12 hours
  • weETH supply cap config:
    • max: 500000 <- unchanged
    • gap: 10000 <- unchanged
    • cooldown: 4 hours <- from 12 hours
  • WBTC supply cap config:
    • max: 50000 <- from 30000
    • gap: 500 <- unchanged
    • cooldown: 4 hours <- from 12 hours
  • WBTC borrow cap config:
    • max: 50000 <- from 1
    • gap: 100 <- from 1
    • cooldown: 4 hours <- from 12 hours
  • cbBTC supply cap config:
    • max: 50000 <- from 20000
    • gap: 500 <- unchanged
    • cooldown: 4 hours <- from 12 hours
  • cbBTC borrow cap config:
    • max: 50000 <- from 10000
    • gap: 100 <- from 50
    • cooldown: 4 hours <- from 12 hours
  • Tests passed:
    • SparkEthereum_20260604_SparklendTests.test_ETHEREUM_CapAutomator()
    • SparkEthereum_20260604_SparklendTests.test_ETHEREUM_sparkLend_wethCapAutomatorUpdates()
    • SparkEthereum_20260604_SparklendTests.test_ETHEREUM_sparkLend_wstethCapAutomatorUpdates()
    • SparkEthereum_20260604_SparklendTests.test_ETHEREUM_sparkLend_weethCapAutomatorUpdates()
    • SparkEthereum_20260604_SparklendTests.test_ETHEREUM_sparkLend_wbtcCapAutomatorUpdates()
    • SparkEthereum_20260604_SparklendTests.test_ETHEREUM_sparkLend_cbbtcCapAutomatorUpdates()

Overall status: safe

[Ethereum] SparkLend - Update Parameters for Deprecated Assets

  • Correct tokens used: rsETH, ezETH, tBTC, rETH
  • Parameters match proposal
    • rsETH (Ethereum.RSETH):
      • LTV: 0%
      • LT: 70%
    • ezETH (Ethereum.EZETH):
      • LTV: 0%
      • LT: 70%
    • tBTC (Ethereum.TBTC):
      • LTV: 0%
      • LT: 70%
    • rETH (Ethereum.RETH):
      • LTV: KEEP_CURRENT
      • LT: 70%
  • Test passed:
    • SparkEthereum_20260604_SparklendTests.test_ETHEREUM_sparkLend_updateParamsForDeprecatedAssets()

Overall status: safe

[Ethereum] SparkLend - Increase USDC and USDT Reserve Factors

  • Correct tokens: Ethereum.USDC and Ethereum.USDT
  • USDC:
    • Reserve factor before: 1%
    • Reserve factor after: 10%
  • USDT:
    • Reserve factor before: 1%
    • Reserve factor after: 10%
  • Test passed:
    • SparkEthereum_20260604_SparklendTests.test_ETHEREUM_sparkLend_reserveFactor()

Overall status: safe

[Sky Core] Spark Allocator Vault - Increase gap and Reduce ttl

  • This is executed via the Sky Core infrastructure

Overall status: safe

[Ethereum] Spark Liquidity Layer - Update Rate Limits

Anchorage USDC

  • Key constructed via makeAddressAddressKey(LIMIT_ASSET_TRANSFER, Ethereum.USDC, Ethereum.ANCHORAGE_USAT_USDT_DEPOSIT)
  • maxAmount: 50,000,000 USDC (50_000_000e6) <- from 5,000,000
  • slope: 250,000,000 USDC/day (250_000_000e6 / 1 days) <- from 50,000,000/day
  • Test passed: SparkEthereum_20260604_SLLTests.test_ETHEREUM_updateAnchorageRateLimits()

Uniswap v4 USDT/USDS swap

  • Pool ID: 0x3b1b1f2e775a6db1664f8e7d59ad568605ea2406312c11aef03146c0cf89d5b9
  • Key constructed via makeBytes32Key(LIMIT_UNISWAP_V4_SWAP, USDT_USDS_POOL_ID)
  • maxAmount: 25,000,000 USDS (25_000_000e18) <- from 5,000,000
  • slope: 250,000,000 USDS/day (250_000_000e18 / 1 days) <- from 50,000,000/day
  • maxSlippage: 0.2% (0.998e18) - pre-existing value, not changed by this spell
  • Test passed: SparkEthereum_20260604_SLLTests.test_ETHEREUM_sll_uniswapUsdtUsdsRateLimit()

USDS Mint

  • Key: MainnetController.LIMIT_USDS_MINT()
  • maxAmount: 1,000,000,000 USDS (1_000_000_000e18) <- from 500,000,000
  • slope: 1,000,000,000 USDS/day (1_000_000_000e18 / 1 days) <- from 500,000,000/day
  • Test passed: SparkEthereum_20260604_SLLTests.test_ETHEREUM_increaseUSDSMintRateLimit()

USDC PSM swap

  • Key: MainnetController.LIMIT_USDS_TO_USDC()
  • maxAmount: 1,000,000,000 USDC (1_000_000_000e6) <- from 500,000,000
  • slope: 1,000,000,000 USDC/day (1_000_000_000e6 / 1 days) <- from 300,000,000/day
  • Test passed: SparkEthereum_20260604_SLLTests.test_ETHEREUM_increaseSwapUSDSToUSDCRateLimit()

Overall status: safe

[Ethereum] Spark Liquidity Layer - Update ALM Proxy Freezable

  • New ALM Proxy Freezable address: 0xe5c6318456a7Cb6f74f93B4eee4616dB5fcef699
  • New ALM Proxy Freezable code corresponds to diamond-pau v1.12.0-rc.4 release
  • Roles granted on new proxy: ALLOCATOR_ROLE -> ALM_RELAYER_MULTISIG, ALM_BACKSTOP_RELAYER_MULTISIG; FREEZER_ROLE -> ALM_FREEZER_MULTISIG
  • DEFAULT_ADMIN_ROLE pre-assigned to Ethereum.SPARK_PROXY
  • Migrations (revoke old -> grant new):
    • SparkLend.CAP_AUTOMATOR -> UPDATE_ROLE
    • Ethereum.SPARK_VAULT_V2_SPUSDC -> SETTER_ROLE
    • Ethereum.SPARK_VAULT_V2_SPUSDT -> SETTER_ROLE
    • Ethereum.SPARK_VAULT_V2_SPETH -> SETTER_ROLE
    • Ethereum.SPARK_VAULT_V2_SPPYUSD -> SETTER_ROLE
    • Ethereum.MORPHO_VAULT_USDS -> isAllocator
    • Ethereum.MORPHO_VAULT_USDC_BC -> isAllocator
  • USDT v2 Morpho vaults intentionally excluded: migration handled by curator framework
  • Tests passed:
    • SparkEthereum_20260604_SLLTests.test_ETHEREUM_ALMProxyFreezableConfiguration()
    • SparkEthereum_20260604_SLLTests.test_ETHEREUM_roleChanges()
    • SparkEthereum_20260604_SLLTests.test_ETHEREUM_sparkVaultSetterRoleChanges()

Overall status: safe

[Avalanche] Spark Liquidity Layer - Update ALM Proxy Freezable

  • New ALM Proxy Freezable address: 0x93c81ADc7F98FdBC8C7a15eCBeD312c8F6adbcB3
  • New ALM Proxy Freezable code corresponds to diamond-pau v1.12.0-rc.4 release
  • Roles granted on new proxy: ALLOCATOR_ROLE -> ALM_RELAYER_MULTISIG, ALM_BACKSTOP_RELAYER_MULTISIG; FREEZER_ROLE -> ALM_FREEZER_MULTISIG
  • DEFAULT_ADMIN_ROLE pre-assigned to Avalanche.SPARK_EXECUTOR
  • Migrations (revoke old -> grant new):
    • Avalanche.SPARK_VAULT_V2_SPUSDC -> SETTER_ROLE
  • Tests passed:
    • SparkEthereum_20260604_SLLTests.test_AVALANCHE_sparkVaultSetterRoleChanges()
    • SparkEthereum_20260604_SLLTests.test_AVALANCHE_ALMProxyFreezableConfiguration()

Overall status: safe

[Base] Spark Liquidity Layer - Update ALM Proxy Freezable

  • New ALM Proxy Freezable address: 0x92d7B06e5844e67174AE9E86bdCb06428482DDF9
  • New ALM Proxy Freezable code corresponds to diamond-pau v1.12.0-rc.4 release
  • Roles granted on new proxy: ALLOCATOR_ROLE -> ALM_RELAYER_MULTISIG, ALM_BACKSTOP_RELAYER_MULTISIG; FREEZER_ROLE -> ALM_FREEZER_MULTISIG
  • DEFAULT_ADMIN_ROLE pre-assigned to Base.SPARK_EXECUTOR
  • Migrations (revoke old -> grant new):
    • Base.MORPHO_VAULT_SUSDC -> isAllocator
  • Tests passed:
    • SparkEthereum_20260604_SLLTests.test_BASE_morphoVaultAllocatorRoleChanges()
    • SparkEthereum_20260604_SLLTests.test_BASE_ALMProxyFreezableConfiguration()

Overall status: safe

[Ethereum] SparkLend - Claim SparkLend Reserves (Exec)

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

Overall status: safe

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

  • Correct token: Ethereum.USDS
  • Correct recipient address: Ethereum.ALM_OPS_MULTISIG = 0x2E1b01adABB8D4981863394bEa23a1263CBaeDfC
  • Correct amount: 663,354 USDS (SPK_BUYBACKS_AMOUNT = 663_354e18)
  • Test passed: SparkEthereum_20260604_SpellTests.test_ETHEREUM_sparkTreasury_transfers()

Overall status: safe