Spark Spell 2026-07-16 Security Review

Summary

All spell actions match the July 16, 2026 proposal and nothing is done beyond it. The Robinhood and X Layer contracts the spell activates were deployed by EOAs rather than governance, so we additionally verified their bytecode against the audited releases and double-checked all deployer-set roles and configuration. All checks passed.

Deployment verification

Robinhood

❯ forge verify-bytecode 0xfD2fD4B046136B540A56C11c75ac679AE7d1dB24 ALMProxy --rpc-url $RH_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract ALMProxy at address 0xfD2fD4B046136B540A56C11c75ac679AE7d1dB24
Creation code matched with status partial
Runtime code matched with status partial
❯ forge verify-bytecode 0x5c1fDE9d4C7f1BF4bc5dEAA2a7752e56232c68a0 RateLimits  --rpc-url $RH_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract RateLimits at address 0x5c1fDE9d4C7f1BF4bc5dEAA2a7752e56232c68a0
Creation code matched with status partial
Runtime code matched with status partial
❯ export FOUNDRY_LIBRARIES="src/libraries/LayerZeroLib.sol:LayerZeroLib:0x7A492eCbAB494dA77eee1ca3CFd879E6980b0503"
❯ forge verify-bytecode 0xcf8d58A6eeF2a1cae2Ce69bC463b1178FB76bA1E ForeignController --rpc-url $RH_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract ForeignController at address 0xcf8d58A6eeF2a1cae2Ce69bC463b1178FB76bA1E
Creation code matched with status partial
Runtime code matched with status partial
❯ forge verify-bytecode 0x7A492eCbAB494dA77eee1ca3CFd879E6980b0503 LayerZeroLib --rpc-url $RH_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract LayerZeroLib at address 0x7A492eCbAB494dA77eee1ca3CFd879E6980b0503
Creation code matched with status partial
Error: Runtime code did not match - this may be due to varying compiler settings
❯ forge verify-bytecode 0xc12B1e59c5E337d5Acd2b4f0A9a27d9E5D7387E8 ArbitrumReceiver --rpc-url $RH_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract ArbitrumReceiver at address 0xc12B1e59c5E337d5Acd2b4f0A9a27d9E5D7387E8
Creation code matched with status partial
Runtime code matched with status partial
❯ forge verify-bytecode 0x826AEaeee9233fA8Ba199518dd8621A5962b1D02 Executor --rpc-url $RH_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract Executor at address 0x826AEaeee9233fA8Ba199518dd8621A5962b1D02
Creation code matched with status partial
Runtime code matched with status partial
❯ forge verify-bytecode 0xAEa9f5dE56e6C20383a1fcC2C3629Dca0A92cE41 ALMProxyFreezable --rpc-url $RH_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract ALMProxyFreezable at address 0xAEa9f5dE56e6C20383a1fcC2C3629Dca0A92cE41
Creation code matched with status partial
Runtime code matched with status partial
❯ forge verify-bytecode 0x797c58C9779D46a437D8f57908D6d56371A55F02 SparkVault --rpc-url $RH_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract SparkVault at address 0x797c58C9779D46a437D8f57908D6d56371A55F02
Creation code matched with status partial
Runtime code matched with status partial

X Layer

❯ forge verify-bytecode 0x83A914C361bB729EB6BEBC8C7bA993667A0E6Df8 ALMProxy --rpc-url $XL_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract ALMProxy at address 0x83A914C361bB729EB6BEBC8C7bA993667A0E6Df8
Creation code matched with status partial
Runtime code matched with status partial
❯ forge verify-bytecode 0x7F7E2286983994c4403Cf2B86758cE0e7bA666a8 RateLimits --rpc-url $XL_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract RateLimits at address 0x7F7E2286983994c4403Cf2B86758cE0e7bA666a8
Creation code matched with status partial
Runtime code matched with status partial
❯ export FOUNDRY_LIBRARIES="src/libraries/LayerZeroLib.sol:LayerZeroLib:0xa44a27901ee51d657f59c75a61521e332cdc2e2e"
❯ forge verify-bytecode 0xf9187C99Ee842beABE8e2e346d958315BFc9331f ForeignController --rpc-url $XL_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract ForeignController at address 0xf9187C99Ee842beABE8e2e346d958315BFc9331f
Creation code matched with status partial
Runtime code matched with status partial
❯ forge verify-bytecode 0xA44A27901Ee51d657f59c75a61521E332cDC2E2E LayerZeroLib --rpc-url $XL_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract LayerZeroLib at address 0xA44A27901Ee51d657f59c75a61521E332cDC2E2E
Creation code matched with status partial
Error: Runtime code did not match - this may be due to varying compiler settings
❯ forge verify-bytecode 0x4bd50B9c00Ae19e8B59723F27645C7A5cCe7a4A0 OptimismReceiver --rpc-url $XL_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract OptimismReceiver at address 0x4bd50B9c00Ae19e8B59723F27645C7A5cCe7a4A0
Creation code matched with status partial
Runtime code matched with status partial
❯ forge verify-bytecode 0xCF5af6F53ceC74B791cb4182aC778ca9CD323510 Executor --rpc-url $XL_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract Executor at address 0xCF5af6F53ceC74B791cb4182aC778ca9CD323510
Creation code matched with status partial
Runtime code matched with status partial
❯ forge verify-bytecode 0x9449ed367C60ea757544fd990B57e1C2D0Ec3A94 ALMProxyFreezable --rpc-url $XL_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract ALMProxyFreezable at address 0x9449ed367C60ea757544fd990B57e1C2D0Ec3A94
[⠔] Compiling...
No files changed, compilation skipped
Creation code matched with status partial
Runtime code matched with status partial
❯ forge verify-bytecode 0xdCe929A335C75a1676EF5957A4D7a3b928C48820 SparkVault --rpc-url $XL_RPC --verifier-url $VERIFIER_URL
Verifying bytecode for contract SparkVault at address 0xdCe929A335C75a1676EF5957A4D7a3b928C48820
Creation code matched with status partial
Runtime code matched with status partial

Configuration & permissions verification

Robinhood

Roles setup (pre-spell)

Configuration (pre-spell)

Roles setup (spell changes)

Configuration (spell changes)

X Layer

Roles setup (pre-spell)

Configuration (pre-spell)

Roles setup (spell changes)

Configuration (spell changes)

  • No configuration changes on X Layer

Ethereum

Roles setup (spell changes)

  • No permanent role changes. Two roles are granted and revoked within the same spell execution (for the Grove USDS transfer)

Configuration (spell changes)

Transfers (spell changes)

All amounts are in USDS

  • Treasury transfers (sent from Ethereum.SPARK_PROXY)
  • USDS transfer to Grove:
    • recipient: GROVE_ALM_PROXY
    • amount is computed at execution time: syrupUSDC.convertToAssets(85,943,747.637271e6) * 1e12, i.e. the USDS value of 85,943,747.637271 SYRUP_USDC shares at the exchange rate
    • USDS is minted to Ethereum.ALM_PROXY via mintUSDS and transferred to Grove via doCall, using temporary RELAYER / CONTROLLER role grants revoked in the same transaction
  • SparkLend reserves claim (recurring item, in the SparkPayloadEthereum base contract)

Development Stage Checklist

Preparation

No commits were made between 17b5536303705b088f6a5d0b60fc1fdcbee7e7d6 https://github.com/sparkdotfi/spark-spells/commit/17b5536303705b088f6a5d0b60fc1fdcbee7e7d6 and 20510f7 initial commit of the new Spell (branch feat/sc-1573-spell-20260716)

  • LIST every commit since the last externally reviewed spell:
  • No security-related changes are present beyond the spell’s intended scope.
  • Verify solc version matches the Prime Agent protocol standard based on prior contracts.

Spell Description & Comments

  • Spell PR has clear description.
  • Spell contract has a clear description.
  • Every significant action and parameter change are clearly commented in the code.
  • Every significant action has valid source url (forum post, poll, atlas).
  • Every parameter change is clearly commented with before/after values. note:
    rateLimits.setRateLimitData(MORPHO_VAULT_V2_USDT_DEPOSIT_KEY,  0, 0);
    rateLimits.setRateLimitData(MORPHO_VAULT_V2_USDT_WITHDRAW_KEY, 0, 0);
    no before comment

Proposed changes

  • LIST every forum post proposing changes for this particular Prime Agent, particular target date:

  • Verify spell content matches the combined scope of the forum posts listed above.

    From forum post / proposal:

    • [Robinhood Chain] Spark Liquidity Layer - Activate SLL and Spark Savings Infrastructure
    • [X Layer] Spark Savings - Deploy spUSDT
    • [Ethereum] Spark Liquidity Layer - Enable USDG Bridging to Robinhood Chain
    • [Ethereum] Spark Liquidity Layer - Enable USDT Bridging to X Layer
    • [Ethereum] Spark Liquidity Layer - Deactivate Deprecated USDT Morpho V2 Vault
    • [Ethereum] Spark Treasury - USDS Transfer to Spark Foundation for Incentives
    • [Ethereum] Spark Treasury - USDS Transfer to Spark Assets Foundation for Anchorage Fees
    • [Ethereum] Spark Treasury - Transfer USDS to Grove Recurring Items
    • [Ethereum] SparkLend - Claim SparkLend Reserves (Exec)
    • [Ethereum] Spark Treasury - Grants for Spark Foundation and Spark Assets Foundation (Exec)
    • [Ethereum] Spark Treasury - Transfer USDS for Buybacks (Exec)

    From SparkEthereum_20260716.sol:

    • Spark Liquidity Layer:
      • Deactivate Old USDT Morpho V2 Vault.
      • Enable USDT Bridging to X Layer.
      • Enable USDG Bridging to Robinhood Chain.
      • Transfer USDS to Grove.
    • Spark Treasury:
      • USDS Transfer to Spark Foundation for Incentives.
      • USDS Transfer to Spark Assets Foundation for Anchorage Fees.
      • Grants for Spark Foundation and Spark Assets Foundation (Exec).
      • Transfer USDS for Buybacks (Exec).

    From SparkRobinhood_20260716.sol:

    • Spark Liquidity Layer - Activate SLL and Spark Savings Infrastructure.

    From SparkXLayer_20260716.sol:

    • Spark Savings - Deploy spUSDT.
  • Verify forum posts contain all new addresses directly or indirectly used in the spell, their constructor arguments and rate limits. – not in the post: USDT_OFT, LZ_ENDPOINT_XLAYER

  • IF the Prime Agent spell introduces a major change that can affect external parties, suggest Governance Facilitators to set Core Spell office hours to true.

Contract Structure & Code Quality

  • The only external non-view function in the spell contract is execute().
    • SparkEthereum_20260716.sol: no external functions present
    • SparkRobinhood_20260716.sol: function grantRole(bytes32 role, address account) external; → execute() in parent contract
    • SparkXLayer_20260716.sol:
      function grantRole(bytes32 role, address account) external; → execute() in parent contract
  • There are no methods that can modify contract state after deployment.
  • No unused imports, interfaces, methods, or variables.
    • SparkEthereum_20260716.sol
      • imports
      • interfaces — none declared
      • methods — none declared
      • variables
    • SparkRobinhood_20260716.sol
      • interfaces
      • methods
      • variables
    • SparkXLayer_20260716.sol
      • imports
      • interfaces
      • methods
      • variables — none declared
  • All function visibility modifiers are explicitly declared.
    • SparkEthereum_20260716.sol
    • SparkRobinhood_20260716.sol
    • SparkXLayer_20260716.sol
  • No redundant code or commented-out functionality.
  • Addresses must be fetched from the relevant protocol’s address registry (e.g., spark-address-registry, bloom-address-registry) IF they are present there, OTHERWISE defined as constant and have trusted source (e.g., when onboarding new contracts).
    • SparkEthereum_20260716.sol — Ethereum
    • SparkRobinhood_20260716.sol — Robinhood
      • OLD_FREEZER_RELAYER_SETTER, 0x59C85fe4385403e93877e48e5521f2F02B150359, https://forum.skyeco.com/t/technical-scope-spark-savings-usdg-spusdg-deployment-on-robinhood-chain/28031#p-106756-trusted-addresses-8
      • ALM_RELAYER_MULTISIG, 0x0ca8f938Aba2214eA11eb451e795A8ef7B720C18, spark-address-registry/Robinhood.sol
      • ALM_BACKSTOP_RELAYER_MULTISIG, 0x52CC27896e641Cbe88F0aD36480839961A47CdF8, spark-address-registry/Robinhood.sol
      • ALM_FREEZER_MULTISIG, 0x2d5Aa449FB8C5646C81BC3C1D2034c2d37F17099, spark-address-registry/Robinhood.sol
      • ALM_CONTROLLER, 0xcf8d58A6eeF2a1cae2Ce69bC463b1178FB76bA1E, spark-address-registry/Robinhood.sol
      • ALM_PROXY_FREEZABLE, 0xAEa9f5dE56e6C20383a1fcC2C3629Dca0A92cE41, spark-address-registry/Robinhood.sol
      • SPARK_VAULT_V2_SPUSDG, 0xde770c84FE66E063336b31737cFE9790f18c4087, spark-address-registry/Robinhood.sol
      • PAXOS_USDG_DEPOSIT, 0x17C0F5345d1144fdF670D14719077be3842E5087, spark-address-registry/Robinhood.sol
      • USDG, 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168, spark-address-registry/Robinhood.sol
      • ALM_RATE_LIMITS, 0x5c1fDE9d4C7f1BF4bc5dEAA2a7752e56232c68a0, spark-address-registry/Robinhood.sol
    • SparkXLayer_20260716.sol — XLayer
      • ALM_RELAYER_MULTISIG, 0x8a25A24EDE9482C4Fc0738F99611BE58F1c839AB, spark-address-registry/XLayer.sol
      • ALM_BACKSTOP_RELAYER_MULTISIG, 0x9330edE0Fc6E3E0D47Ebf3C145efd569796aC7F5, spark-address-registry/XLayer.sol
      • ALM_FREEZER_MULTISIG, 0x90D8c80C028B4C09C0d8dcAab9bbB057F0513431, spark-address-registry/XLayer.sol

StarGuard execution

  • IF a StarGuard module is onboarded for this Prime Agent, the following additional checks are done:
    • The spell exposes view-only interface function isExecutable() external view returns (bool result). https://github.com/sparkdotfi/spark-spells/blob/32d0504c18115873369eaf1028abc0ce90a9df3f/src/SparkPayloadEthereum.sol#L183
    • isExecutable either simply returns true or implements additional logic communicated via the relevant forum post (e.g., by describing “earliest launch date” or “office hours” logic, etc).
    • The test ensures the spell is executable before expiration (i.e. isExecutable outputs true before StarGuard.maxDelay() is passed).
    • Third-party actors can not take advantage of the fact that Spell will be executed in a later block than the Core spell, otherwise suggest direct execution.

On-boarding New Contracts

No new implementation contracts are deployed by this spell. The spell configures existing Spark SLL, X Layer, Robinhood, and treasury components.

Dependency checks

Interfaces

  • No unused static interfaces.
  • Declared static interface is not present in standard libraries, OTHERWISE should be imported from there.
  • Interface matches the deployed contract.
  • Each static interface declares only functions actually used in the spell code.

Variable Declarations

Deployment & Execution Security

  • No selfdestruct() operations in the spell.
  • No delegatecall() to untrusted contracts.
  • No use of tx.origin for authorization.
  • No external calls that could revert and fail the entire spell execution.
  • No loops with unbounded gas consumption.
  • No timestamp-dependent logic that could cause issues across the GSM delay.
  • All math operations use safe math libraries or are checked for overflow/underflow.
  • No unchecked return values from external calls.

Access Control

  • Spell execution cannot be front-run by malicious actors.
  • No privileged functions accessible by unauthorized users.

Parameter Changes & Protocol Integration

  • Prime Agent protocol invariants are maintained after spell execution.
  • All parameter changes use the appropriate helper functions IF available.
  • Parameter changes match the Executive Sheet or the corresponding Atlas edit exactly.
  • Spell interacts correctly with existing protocol components.
  • Proper error handling for all external interactions.

Testing

  • LIST each spell action and corresponding tests

    • [Robinhood Chain] Spark Liquidity Layer - Activate SLL and Spark Savings Infrastructure
      • SparkEthereum_20260716_SLLTests.test_ROBINHOOD_roleChanges()
      • SparkEthereum_20260716_SLLTests.test_Robinhood_ALMProxyFreezableConfiguration()
      • SparkEthereum_20260716_SLLTests.test_ROBINHOOD_sll_enableUsdgTransferToPaxosDeposit()
      • SparkEthereum_20260716_SLLTests.test_ROBINHOOD_sll_spUSDGPaxosRoundTrip()
    • [Ethereum] Spark Liquidity Layer - Enable USDG Bridging to Robinhood Chain
      • SparkEthereum_20260716_SLLTests.test_ETHEREUM_sll_enableUsdgTransferToPaxosDeposit()
      • SparkEthereum_20260716_SLLTests.test_ROBINHOOD_sll_spUSDGPaxosRoundTrip()
    • [X Layer] Spark Savings - Deploy spUSDT
      • SparkEthereum_20260716_SLLTests.test_XLAYER_ALMProxyFreezableConfiguration()
      • SparkEthereum_20260716_SLLTests.test_XLAYER_sll_spUSDT_usdt0RoundTrip()
      • XLayerConfigTests.test_postDeployState()
      • XLayerConfigTests.test_vault_config()
      • XLayerConfigTests.test_rateLimits_config()
      • XLayerConfigTests.test_controller_config()
      • XLayerConfigTests.test_executor_config()
      • XLayerConfigTests.test_receiver_config()
      • XLayerConfigTests.test_almProxyFreezable_config()
      • XLayerE2ETests.test_boundary_depositCap()
      • XLayerE2ETests.test_settingVsr_failsAboveMaxVsrBoundary()
      • XLayerCrosschainE2ETests.test_crosschainE2E_setVsrBounds()
    • [Ethereum] Spark Liquidity Layer - Enable USDT Bridging to X Layer
      • SparkEthereum_20260716_SLLTests.test_ETHEREUM_sll_enableUSDTBridgingToXLayer()
      • SparkEthereum_20260716_SLLTests.test_XLAYER_sll_spUSDT_usdt0RoundTrip()
    • [Ethereum] Spark Liquidity Layer - Deactivate Deprecated USDT Morpho V2 Vault
      • SparkEthereum_20260716_SLLTests.test_ETHEREUM_sll_deactivateOldMorphoUsdtVault()
    • [Ethereum] Spark Treasury - USDS Transfer to Spark Foundation for Incentives
      • SparkEthereum_20260716_SpellTests.test_ETHEREUM_sparkTreasury_transfers()
    • [Ethereum] Spark Treasury - USDS Transfer to Spark Assets Foundation for Anchorage Fees
      • SparkEthereum_20260716_SpellTests.test_ETHEREUM_sparkTreasury_transfers()
    • [Ethereum] Spark Liquidity Layer - Transfer USDS to Grove
      • SparkEthereum_20260716_SpellTests.test_ETHEREUM_sll_transferUsdsToGrove()
    • [Ethereum] SparkLend - Claim SparkLend Reserves (Exec)
      • SpellTests.test_ETHEREUM_sparkLend_withdrawAllReserves()
    • [Ethereum] Spark Treasury - Grants for Spark Foundation and Spark Assets Foundation (Exec)
      • SparkEthereum_20260716_SpellTests.test_ETHEREUM_sparkTreasury_transfers()
    • [Ethereum] Spark Treasury - Transfer USDS for Buybacks (Exec)
      • SparkEthereum_20260716_SpellTests.test_ETHEREUM_sparkTreasury_transfers()
  • All actions are covered by tests.

  • Integration tests verify the end-to-end execution flow.

  • Gas tests ensure execution is possible within the existing block gas limit.

  • All tests are passing in CI at 8f599b459490e458338efe2061e7c30865691535. - except test_ETHEREUM_PayloadsConfigured() which is intended

  • All tests listed above are not skipped.

  • All tests are passing locally at 8f599b459490e458338efe2061e7c30865691535: – except test_ETHEREUM_PayloadsConfigured() which is intended

❯ forge test
[⠒] Compiling...
No files changed, compilation skipped

Ran 2 tests for src/proposals/20260716/XLayer_20260716.t.sol:XLayerE2ETests
[PASS] test_boundary_depositCap() (gas: 397453)
[PASS] test_settingVsr_failsAboveMaxVsrBoundary() (gas: 50132)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 1.87s (7.26ms CPU time)

Ran 7 tests for src/proposals/20260716/XLayer_20260716.t.sol:XLayerConfigTests
[PASS] test_almProxyFreezable_config() (gas: 21746)
[PASS] test_controller_config() (gas: 20473)
[PASS] test_executor_config() (gas: 22791)
[PASS] test_postDeployState() (gas: 171415)
[PASS] test_rateLimits_config() (gas: 50502)
[PASS] test_receiver_config() (gas: 7310)
[PASS] test_vault_config() (gas: 59991)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 1.88s (14.79ms CPU time)

Ran 1 test for src/proposals/20260716/XLayer_20260716.t.sol:XLayerCrosschainE2ETests
[PASS] test_crosschainE2E_setVsrBounds() (gas: 2338488)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 39.57s (34.78s CPU time)

Ran 15 tests for src/proposals/20260716/Spell_20260716.t.sol:SparkEthereum_20260716_SpellTests
[SKIP] test_ARBITRUM_ONE_PayloadBytecodeMatches() (gas: 0)
[SKIP] test_AVALANCHE_PayloadBytecodeMatches() (gas: 0)
[SKIP] test_BASE_PayloadBytecodeMatches() (gas: 0)
[PASS] test_ETHEREUM_PayloadBytecodeMatches() (gas: 2942272)
[FAIL: Mainnet payload not matching deployed payload: 0x0000000000000000000000000000000000000000 != 0xc7183455a4C133Ae270771860664b6B7ec320bB1] test_ETHEREUM_PayloadsConfigured() (gas: 67436)
[PASS] test_ETHEREUM_SparkProxyStorage() (gas: 62821894)
[PASS] test_ETHEREUM_sll_transferUsdsToGrove() (gas: 62709678)
[PASS] test_ETHEREUM_sparkLend_withdrawAllReserves() (gas: 64413378)
[PASS] test_ETHEREUM_sparkTreasury_transfers() (gas: 62673280)
[SKIP] test_GNOSIS_PayloadBytecodeMatches() (gas: 0)
[SKIP] test_OPTIMISM_PayloadBytecodeMatches() (gas: 0)
[PASS] test_ROBINHOOD_PayloadBytecodeMatches() (gas: 718756)
[SKIP] test_UNICHAIN_PayloadBytecodeMatches() (gas: 0)
[PASS] test_XLAYER_PayloadBytecodeMatches() (gas: 220077)
[PASS] test_officeHours() (gas: 55292)
Suite result: FAILED. 8 passed; 1 failed; 6 skipped; finished in 78.14s (7.26s CPU time)

Warning: the following cheatcode(s) are deprecated and will be removed in future versions:
  revertTo(uint256): replaced by `revertToState`
  snapshot(): replaced by `snapshotState`
Ran 16 tests for src/proposals/20260716/Spell_20260716.t.sol:SparkEthereum_20260716_SLLTests
[PASS] test_ARBITRUM_E2E_sparkLiquidityLayer() (gas: 775799107)
[PASS] test_AVALANCHE_E2E_sparkLiquidityLayer() (gas: 314007287)
[PASS] test_BASE_E2E_sparkLiquidityLayer() (gas: 607682780)
[PASS] test_E2E_sparkLiquidityLayerCCTPCrossChainSetup() (gas: 4394270355)
[PASS] test_ETHEREUM_E2E_sparkLiquidityLayer() (gas: 2304608390)
[PASS] test_ETHEREUM_sll_deactivateOldMorphoUsdtVault() (gas: 62768764)
[PASS] test_ETHEREUM_sll_enableUSDTBridgingToXLayer() (gas: 62715421)
[PASS] test_ETHEREUM_sll_enableUsdgTransferToPaxosDeposit() (gas: 62932743)
[PASS] test_OPTIMISM_E2E_sparkLiquidityLayer() (gas: 400715283)
[PASS] test_ROBINHOOD_roleChanges() (gas: 62472117)
[PASS] test_ROBINHOOD_sll_enableUsdgTransferToPaxosDeposit() (gas: 62607509)
[PASS] test_ROBINHOOD_sll_spUSDGPaxosRoundTrip() (gas: 62954462)
[PASS] test_Robinhood_ALMProxyFreezableConfiguration() (gas: 62419449)
[PASS] test_UNICHAIN_E2E_sparkLiquidityLayer() (gas: 361710264)
[PASS] test_XLAYER_ALMProxyFreezableConfiguration() (gas: 62410426)
[PASS] test_XLAYER_sll_spUSDT_usdt0RoundTrip() (gas: 83597918)
Suite result: ok. 16 passed; 0 failed; 0 skipped; finished in 78.84s (50.46s CPU time)

Warning: the following cheatcode(s) are deprecated and will be removed in future versions:
  revertTo(uint256): replaced by `revertToState`
  snapshot(): replaced by `snapshotState`
Ran 14 tests for src/proposals/20260716/Spell_20260716.t.sol:SparkEthereum_20260716_SparklendTests
[PASS] test_ETHEREUM_AllReservesSeeded() (gas: 62867011)
[PASS] test_ETHEREUM_CapAutomator() (gas: 89235750)
[PASS] test_ETHEREUM_E2E_sparkLend() (gas: 4147021024)
[PASS] test_ETHEREUM_FreezerMom() (gas: 180207199)
[PASS] test_ETHEREUM_FreezerMom_Multisig() (gas: 142882417)
[PASS] test_ETHEREUM_Oracles() (gas: 65583606)
[PASS] test_ETHEREUM_RewardsConfiguration() (gas: 63548487)
[PASS] test_ETHEREUM_SpellExecutionDiff() (gas: 253236260)
[PASS] test_ETHEREUM_TokenImplementationsMatch() (gas: 63055607)
[SKIP] test_GNOSIS_AllReservesSeeded() (gas: 0)
[SKIP] test_GNOSIS_E2E_sparkLend() (gas: 0)
[SKIP] test_GNOSIS_Oracles() (gas: 0)
[SKIP] test_GNOSIS_SpellExecutionDiff() (gas: 0)
[SKIP] test_GNOSIS_TokenImplementationsMatch() (gas: 0)
Suite result: ok. 9 passed; 0 failed; 5 skipped; finished in 98.05s (51.34s CPU time)

Ran 6 test suites in 98.10s (298.35s CPU time): 43 tests passed, 1 failed, 11 skipped (55 total tests)

Failing tests:
Encountered 1 failing test in src/proposals/20260716/Spell_20260716.t.sol:SparkEthereum_20260716_SpellTests
[FAIL: Mainnet payload not matching deployed payload: 0x0000000000000000000000000000000000000000 != 0xc7183455a4C133Ae270771860664b6B7ec320bB1] test_ETHEREUM_PayloadsConfigured() (gas: 67436)

Encountered a total of 1 failing tests, 43 tests succeeded

Deployment Stage Checklist

  • Both reviewers gave explicit “Good to deploy”.
  • A new comment in the PR contains link to the deployed spell(s) and Tenderly vnet(s). – No Tenderly simulation
  • The comment also contains codehash of the deployed mainnet spell. – No comment with codehash
  • The codehash matches one produced locally from the reviewed source code
❯ strip_meta() { python3 -c "
import sys; b = bytes.fromhex(sys.stdin.read().strip().removeprefix('0x'))
print(b[:len(b)-2-int.from_bytes(b[-2:],'big')].hex())"; }

❯ cast code 0xC1090e8fEE666868622a2F1e870185F944108Ee2 --rpc-url $ETH_RPC | strip_meta | cast keccak
0x8c61353a0e3fe95114c3f34b40524e4923eb3f898d911ee4222ccbe4ad18e2f3

❯ cast call --rpc-url $ETH_RPC --create $(forge inspect SparkEthereum_20260716 bytecode) | strip_meta | cast keccak
0x8c61353a0e3fe95114c3f34b40524e4923eb3f898d911ee4222ccbe4ad18e2f3
❯ forge verify-bytecode 0xC1090e8fEE666868622a2F1e870185F944108Ee2 SparkEthereum_20260716 --rpc-url $ETH_RPC
Verifying bytecode for contract SparkEthereum_20260716 at address 0xC1090e8fEE666868622a2F1e870185F944108Ee2
Creation code matched with status partial
Runtime code matched with status partial

❯ forge verify-bytecode 0xE7933ffE5D03f0c0100456cE2E41d911db70Afa4 SparkRobinhood_20260716 --rpc-url $RH_RPC --verifier-url $RH_VERIFIER_URL
Verifying bytecode for contract SparkRobinhood_20260716 at address 0xE7933ffE5D03f0c0100456cE2E41d911db70Afa4
Creation code matched with status partial
Runtime code matched with status partial

❯ forge verify-bytecode 0x03801438834a9127088b4F2Cba02F42F8a600036 SparkXLayer_20260716 --rpc-url $XL_RPC --verifier-url $XL_VERIFIER_URL --ignore runtime

Verifying bytecode for contract SparkXLayer_20260716 at address 0x03801438834a9127088b4F2Cba02F42F8a600036
Creation code matched with status full
  • Etherscan settings (optimizer, EVM version, license) match local ones.
  • Every spell is deployed using standard CREATE (not CREATE2).
  • Tests are updated to execute against the deployed spell(s).
  • No test is skipped after deployment
  • All tests are passing in CI at 5889042930bcbc0aa2d2652a328a14199dfa50c9
    • currently tests are not passed in CI
  • All tests are passing locally at 5889042930bcbc0aa2d2652a328a14199dfa50c9:
❯ forge test
[⠢] Compiling...
No files changed, compilation skipped

Ran 2 tests for src/proposals/20260716/XLayer_20260716.t.sol:XLayerE2ETests
[PASS] test_boundary_depositCap() (gas: 397453)
[PASS] test_settingVsr_failsAboveMaxVsrBoundary() (gas: 50132)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.46s (3.25ms CPU time)

Ran 7 tests for src/proposals/20260716/XLayer_20260716.t.sol:XLayerConfigTests
[PASS] test_almProxyFreezable_config() (gas: 21746)
[PASS] test_controller_config() (gas: 20473)
[PASS] test_executor_config() (gas: 22791)
[PASS] test_postDeployState() (gas: 171415)
[PASS] test_rateLimits_config() (gas: 50502)
[PASS] test_receiver_config() (gas: 7310)
[PASS] test_vault_config() (gas: 59991)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 2.46s (6.13ms CPU time)

Ran 1 test for src/proposals/20260716/XLayer_20260716.t.sol:XLayerCrosschainE2ETests
[PASS] test_crosschainE2E_setVsrBounds() (gas: 2338488)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 42.70s (37.38s CPU time)

Ran 15 tests for src/proposals/20260716/Spell_20260716.t.sol:SparkEthereum_20260716_SpellTests
[SKIP] test_ARBITRUM_ONE_PayloadBytecodeMatches() (gas: 0)
[SKIP] test_AVALANCHE_PayloadBytecodeMatches() (gas: 0)
[SKIP] test_BASE_PayloadBytecodeMatches() (gas: 0)
[PASS] test_ETHEREUM_PayloadBytecodeMatches() (gas: 2942339)
[PASS] test_ETHEREUM_PayloadsConfigured() (gas: 77685)
[PASS] test_ETHEREUM_SparkProxyStorage() (gas: 76016715)
[PASS] test_ETHEREUM_sll_transferUsdsToGrove() (gas: 75899149)
[PASS] test_ETHEREUM_sparkLend_withdrawAllReserves() (gas: 77661084)
[PASS] test_ETHEREUM_sparkTreasury_transfers() (gas: 75862087)
[SKIP] test_GNOSIS_PayloadBytecodeMatches() (gas: 0)
[SKIP] test_OPTIMISM_PayloadBytecodeMatches() (gas: 0)
[PASS] test_ROBINHOOD_PayloadBytecodeMatches() (gas: 721256)
[SKIP] test_UNICHAIN_PayloadBytecodeMatches() (gas: 0)
[PASS] test_XLAYER_PayloadBytecodeMatches() (gas: 222577)
[PASS] test_officeHours() (gas: 55324)
Suite result: ok. 9 passed; 0 failed; 6 skipped; finished in 77.37s (19.22s CPU time)

Warning: the following cheatcode(s) are deprecated and will be removed in future versions:
  snapshot(): replaced by `snapshotState`
  revertTo(uint256): replaced by `revertToState`
Ran 16 tests for src/proposals/20260716/Spell_20260716.t.sol:SparkEthereum_20260716_SLLTests
[PASS] test_ARBITRUM_E2E_sparkLiquidityLayer() (gas: 814491533)
[PASS] test_AVALANCHE_E2E_sparkLiquidityLayer() (gas: 340108770)
[PASS] test_BASE_E2E_sparkLiquidityLayer() (gas: 650280742)
[PASS] test_E2E_sparkLiquidityLayerCCTPCrossChainSetup() (gas: 4574858060)
[PASS] test_ETHEREUM_E2E_sparkLiquidityLayer() (gas: 2356718611)
[PASS] test_ETHEREUM_sll_deactivateOldMorphoUsdtVault() (gas: 75965477)
[PASS] test_ETHEREUM_sll_enableUSDTBridgingToXLayer() (gas: 75907471)
[PASS] test_ETHEREUM_sll_enableUsdgTransferToPaxosDeposit() (gas: 76138402)
[PASS] test_OPTIMISM_E2E_sparkLiquidityLayer() (gas: 430741182)
[PASS] test_ROBINHOOD_roleChanges() (gas: 75665148)
[PASS] test_ROBINHOOD_sll_enableUsdgTransferToPaxosDeposit() (gas: 75806373)
[PASS] test_ROBINHOOD_sll_spUSDGPaxosRoundTrip() (gas: 76166801)
[PASS] test_Robinhood_ALMProxyFreezableConfiguration() (gas: 75611744)
[PASS] test_UNICHAIN_E2E_sparkLiquidityLayer() (gas: 390307180)
[PASS] test_XLAYER_ALMProxyFreezableConfiguration() (gas: 75602476)
[PASS] test_XLAYER_sll_spUSDT_usdt0RoundTrip() (gas: 100721743)
Suite result: ok. 16 passed; 0 failed; 0 skipped; finished in 87.87s (35.63s CPU time)

Warning: the following cheatcode(s) are deprecated and will be removed in future versions:
  revertTo(uint256): replaced by `revertToState`
  snapshot(): replaced by `snapshotState`
Ran 14 tests for src/proposals/20260716/Spell_20260716.t.sol:SparkEthereum_20260716_SparklendTests
[PASS] test_ETHEREUM_AllReservesSeeded() (gas: 76056671)
[PASS] test_ETHEREUM_CapAutomator() (gas: 106603709)
[PASS] test_ETHEREUM_E2E_sparkLend() (gas: 4170611299)
[PASS] test_ETHEREUM_FreezerMom() (gas: 200969692)
[PASS] test_ETHEREUM_FreezerMom_Multisig() (gas: 161640094)
[PASS] test_ETHEREUM_Oracles() (gas: 78777761)
[PASS] test_ETHEREUM_RewardsConfiguration() (gas: 76776995)
[PASS] test_ETHEREUM_SpellExecutionDiff() (gas: 278194784)
[PASS] test_ETHEREUM_TokenImplementationsMatch() (gas: 76245267)
[SKIP] test_GNOSIS_AllReservesSeeded() (gas: 0)
[SKIP] test_GNOSIS_E2E_sparkLend() (gas: 0)
[SKIP] test_GNOSIS_Oracles() (gas: 0)
[SKIP] test_GNOSIS_SpellExecutionDiff() (gas: 0)
[SKIP] test_GNOSIS_TokenImplementationsMatch() (gas: 0)
Suite result: ok. 9 passed; 0 failed; 5 skipped; finished in 103.62s (41.87s CPU time)

Ran 6 test suites in 103.69s (316.49s CPU time): 44 tests passed, 0 failed, 11 skipped (55 total tests)