Spark Spell 2026-08-13 Security Review

Development Stage Checklist

Preparation

  • LIST every commit since the last externally reviewed spell:
    • No commits were made between c24ddf511b7454676a87ff8cb84e1aa12ee6073b (Spell 2026-07-16) and b9013b1cf9e94f88a82a776904a17ca043b76be8 initial commit of the 2026-08-13 Spell
  • 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.

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.
  • Verify forum posts contain all new addresses directly or indirectly used in the spell, their constructor arguments and rate limits.
  • 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().
  • There are no methods that can modify contract state after deployment.
  • No unused imports, interfaces, methods, or variables.
  • All function visibility modifiers are explicitly declared.
  • 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).
  • LIST every address used in the spell (defined as constant or fetched from the registry repo):
    • Ethereum.ALM_CONTROLLER
      • Matches valid external source (spark-alm-controller)
    • Ethereum.ALM_RATE_LIMITS
      • Matches valid external source (spark-alm-controller)
    • Ethereum.USDS
      • Matches valid external source (spark-alm-controller)
    • Ethereum.ALM_OPS_MULTISIG
      • Matches valid external source (spark-alm-controller)
    • USDS_USDG_POOL_ID = 0x28adc7179a8a83c3379955d59563c0fec33eadfa83946b447af289190ff5fcff
      • Matches valid external source (forum post)
    • RLUSD_USDS_POOL_ID = 0x9035721b23481db3888fd201b9c2b26dbc3af60258bca65e669f2ed98dc8eb4f
      • Matches valid external source (forum post)
    • CURVE_USDC_RLUSD = 0xD001aE433f254283FeCE51d4ACcE8c53263aa186
      • Matches valid external source (forum post)

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).
    • 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

  • LIST every new contract present in the spell:
    • No new implementation contracts are deployed by this spell

Dependency checks

  • LIST every submodule or any other imported code used in this spell:
    • spark-alm-controller imported at 984ec546fb2c98ed729ae91d2d73e97dedbf111f (v1.10.0)
      • The dependency commit matches audited commit.
      • The dependency commit matches the version of the deployed contracts. (if ALM contracts are updated, then dependency also needs to be updated and vice-versa: dependency shouldn’t be updated unless the ALM contracts are updated).

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

  • Every contract variable is declared as either constant or immutable.
  • Every precision variable (WAD, RAY, RAD, etc) match their expected value.
  • LIST every variable using precision (e18, e6, e..., WAD, RAY, RAD, etc):
    • USDS_SPK_BUYBACK_AMOUNT = 1_756_359e18
      • The precision matches provided source url.
  • Rates are expressed correctly (e.g. per / 1 days).
  • Rates match their source (e.g., forum post).
  • Timestamps are commented with the full UTC date and convert correctly.
  • Timestamps match their source (e.g., governance poll).

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.
    • IERC20(USDS).transfer(...) return value ignored, safe for USDS

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 (each line of code which changes a storage):
    • “Onboard Uniswap v4 USDG/USDS Pool” tested via test_ETHEREUM_sparkLiquidityLayer_onboardUniswapV4USDGUSDS(), test_ETHEREUM_uniswapV4PoolIdIntegrity()
      • The unit test ensures the new value was changed in the spell.
      • The end-to-end test is sufficient to ensure correctness the high-level goal behind this spell action.
    • “Onboard Uniswap v4 rlUSD/USDS Pool” tested via test_ETHEREUM_sparkLiquidityLayer_onboardUniswapV4RLUSDUSDS(), test_ETHEREUM_uniswapV4PoolIdIntegrity()
      • The unit test ensures the new value was changed in the spell.
      • The end-to-end test is sufficient to ensure correctness the high-level goal behind this spell action.
    • “Onboard Curve rlUSD/USDC for Swaps” tested via test_ETHEREUM_curvePoolOnboarding_USDCRLUSD()
      • The unit test ensures the new value was changed in the spell.
      • The end-to-end test is sufficient to ensure correctness the high-level goal behind this spell action.
    • “Claim SparkLend reserves” tested via test_ETHEREUM_sparkLend_withdrawAllReserves()
      • The unit test ensures the new value was changed in the spell.
    • “Transfer Excess USDS for Buybacks” tested via test_ETHEREUM_sparkTreasury_transferExcessUSDSForBuybacks()
      • The unit test ensures the new value was changed in the spell.
  • 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.
    • no such test
  • All tests are passing in CI at `23e8ebe83ca495615691e625f3a8816b64a85506.
  • All tests listed above are not skipped.
  • All tests are passing locally at 23e8ebe83ca495615691e625f3a8816b64a85506:
❯ forge test
[⠊] Compiling...
No files changed, compilation skipped

Ran 14 tests for src/proposals/20260813/Spell_20260813.t.sol:SparkEthereum_20260813_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: 2620803)
[PASS] test_ETHEREUM_PayloadsConfigured() (gas: 67524)
[PASS] test_ETHEREUM_SparkProxyStorage() (gas: 56054091)
[PASS] test_ETHEREUM_sparkLend_withdrawAllReserves() (gas: 57565717)
[PASS] test_ETHEREUM_sparkTreasury_transferExcessUSDSForBuybacks() (gas: 55900611)
[SKIP] test_GNOSIS_PayloadBytecodeMatches() (gas: 0)
[SKIP] test_OPTIMISM_PayloadBytecodeMatches() (gas: 0)
[SKIP] test_ROBINHOOD_PayloadBytecodeMatches() (gas: 0)
[SKIP] test_UNICHAIN_PayloadBytecodeMatches() (gas: 0)
[SKIP] test_XLAYER_PayloadBytecodeMatches() (gas: 0)
[PASS] test_officeHours() (gas: 55314)
Suite result: ok. 6 passed; 0 failed; 8 skipped; finished in 86.79s (911.67ms 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 11 tests for src/proposals/20260813/Spell_20260813.t.sol:SparkEthereum_20260813_SLLTests
[PASS] test_ARBITRUM_E2E_sparkLiquidityLayer() (gas: 741969507)
[PASS] test_AVALANCHE_E2E_sparkLiquidityLayer() (gas: 298153096)
[PASS] test_BASE_E2E_sparkLiquidityLayer() (gas: 599369171)
[PASS] test_E2E_sparkLiquidityLayerCCTPCrossChainSetup() (gas: 4251989001)
[PASS] test_ETHEREUM_E2E_sparkLiquidityLayer() (gas: 2765380757)
[PASS] test_ETHEREUM_curvePoolOnboarding_USDCRLUSD() (gas: 56536280)
[PASS] test_ETHEREUM_sparkLiquidityLayer_onboardUniswapV4RLUSDUSDS() (gas: 57753687)
[PASS] test_ETHEREUM_sparkLiquidityLayer_onboardUniswapV4USDGUSDS() (gas: 57441736)
[PASS] test_ETHEREUM_uniswapV4PoolIdIntegrity() (gas: 7773)
[PASS] test_OPTIMISM_E2E_sparkLiquidityLayer() (gas: 379581685)
[PASS] test_UNICHAIN_E2E_sparkLiquidityLayer() (gas: 349329656)
Suite result: ok. 11 passed; 0 failed; 0 skipped; finished in 92.94s (51.13s 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 14 tests for src/proposals/20260813/Spell_20260813.t.sol:SparkEthereum_20260813_SparklendTests
[PASS] test_ETHEREUM_AllReservesSeeded() (gas: 56102362)
[PASS] test_ETHEREUM_CapAutomator() (gas: 83299293)
[PASS] test_ETHEREUM_E2E_sparkLend() (gas: 4134343774)
[PASS] test_ETHEREUM_FreezerMom() (gas: 168786783)
[PASS] test_ETHEREUM_FreezerMom_Multisig() (gas: 132694589)
[PASS] test_ETHEREUM_Oracles() (gas: 57877395)
[PASS] test_ETHEREUM_RewardsConfiguration() (gas: 56759953)
[PASS] test_ETHEREUM_SpellExecutionDiff() (gas: 238594494)
[PASS] test_ETHEREUM_TokenImplementationsMatch() (gas: 56290958)
[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 105.99s (23.71s CPU time)

Ran 3 test suites in 106.03s (285.72s CPU time): 26 tests passed, 0 failed, 13 skipped (39 total tests)

Deployment Stage Checklist

Deployed Contract

  • 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 codehash comment
  • 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 0xc827237CB91Fa8E78B8dfA4F77838eDf924C04e9 --rpc-url $ETH_RPC | strip_meta | cast keccak
0xe7bf133cef2e2bb12911e7cf1dab7c5d5c66e4d0e47911e12528dfeb66d144c9

❯ cast call --rpc-url $ETH_RPC --create $(forge inspect SparkEthereum_20260813 bytecode) | strip_meta | cast keccak
0xe7bf133cef2e2bb12911e7cf1dab7c5d5c66e4d0e47911e12528dfeb66d144c9
❯ forge verify-bytecode 0xc827237CB91Fa8E78B8dfA4F77838eDf924C04e9 SparkEthereum_20260813 --rpc-url $ETH_RPC
Verifying bytecode for contract SparkEthereum_20260813 at address 0xc827237CB91Fa8E78B8dfA4F77838eDf924C04e9
Creation code matched with status full
Runtime 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 9939cb02801e17a9133f01f7215b2f7b16948cc2.
  • All tests are passing locally at 9939cb02801e17a9133f01f7215b2f7b16948cc2: