Skip to content

feat: Spell 2026-08-13 (SC-1605) - #182

Open
supercontracts wants to merge 8 commits into
masterfrom
feat/sc-1605-spell-20260813
Open

feat: Spell 2026-08-13 (SC-1605)#182
supercontracts wants to merge 8 commits into
masterfrom
feat/sc-1605-spell-20260813

Conversation

@supercontracts

@supercontracts supercontracts commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

2026-08-13 Spark Spell

Forum Post

https://forum.skyeco.com/t/august-13-2026-proposed-changes-to-spark-for-upcoming-spell/28135#p-106996-summary-1

Dependencies on Sky Core spell

None

Notes for Reviewers

None

Conditions for Spell Deployment

  • All spell-specific tests are passing.
  • All E2E tests are passing.
  • All newly deployed addresses have been reviewed and added to the spark-address-registry in a PR that has been merged.
  • All newly deployed addresses have been added to the Immunefi bug bounty program.
  • There is complete test coverage of all changes in the spell, including any relevant edge cases.
  • At least three approvals have been given from reviewers.
  • CODE_RABBIT.md comment has been posted, AI review performed.
  • Octane review performed.

Conditions for Spell Handoff to Sky

  • All spells payloads have been deployed and verified on Etherscan.
  • All spell-specific tests are passing (including spell bytecode verification).
  • All E2E tests are passing.
  • Spell caster is passing in CI.
  • At least three approvals have been given from reviewers on deployed spell.
  • Comment from at least three reviewers confirming address of mainnet spell payload.

Conditions for Spell Merge

  • Spell handoff performed to Sky team on Discord.
  • Spell handoff performed to Sky team on Signal.
  • Spell address confirmed to be correct in sky-ecosystem/spells-mainnet repo open PR through comments by at least three reviewers.
  • Sky deployed spell confirmed through a comment in this PR to contain correct Spark payload address by at least three reviewers.

Summary by CodeRabbit

  • New Features
    • Added July 16 Spark updates across Ethereum, Robinhood, and X Layer.
    • Enabled USDG and USDT bridging, updated transfer limits, and configured cross-chain recipients.
    • Updated liquidity-layer permissions and disabled deposits and withdrawals for the legacy USDT vault.
    • Added August 13 liquidity integrations for Uniswap V4 and Curve pools supporting USDG, USDS, and RLUSD.
    • Allocated excess USDS to support SPK buybacks and distributed treasury incentives and operational funds.

@octane-security-app

Copy link
Copy Markdown

Summary by Octane

New Contracts

  • SparkEthereum_20260813.sol: The smart contract onboards Uniswap and Curve pools for swaps, configures pool parameters, and transfers excess USDS for buybacks.

Updated Contracts

  • SparkLiquidityLayerTests.sol: The smart contract update includes new pool integrations, modified rate limits, and onboarded Uniswap and Curve integrations.

🔗 Commit Hash: b9013b1

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1d4cc3e2-8c6d-46ef-9e0f-94ca4021cb9c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Changes

Spark spell deployments

Layer / File(s) Summary
July payload execution
archive/20260716/SparkEthereum_20260716.sol, archive/20260716/SparkRobinhood_20260716.sol, archive/20260716/SparkXLayer_20260716.sol
Adds July payloads for roles, bridge limits, vault deactivation, treasury transfers, and Grove funding.
July spell validation
archive/20260716/Spell_20260716.t.sol
Tests role changes, cross-chain asset round trips, accrued interest, Grove funding, and treasury distributions.
X Layer configuration and bridge validation
archive/20260716/XLayer_20260716.t.sol
Tests X Layer configuration, vault boundaries, executor wiring, and cross-chain VSR-bound updates.
August liquidity-pool deployment and tests
src/proposals/20260813/SparkEthereum_20260813.sol, src/proposals/20260813/Spell_20260813.t.sol, diffs/...
Adds Uniswap V4 and Curve pool configuration, USDS buyback transfers, and related liquidity and swap tests.
Shared integration coverage
src/test-harness/SparkLiquidityLayerTests.sol
Updates pool identifiers, transfer integrations, withdrawal-limit assertions, and post-execution integration coverage.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: Priority: Medium, Status: Ready for Review

Suggested reviewers: lucas-manuel, deluca-mike, certora-spark-review

Poem

I’m a rabbit reviewing pools in the night,
Roles hop into place, and bridges shine bright.
USDS leaves a neat buyback trail,
VSR bounds cross the moonlit rail.
Tests thump softly: all paths align.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description includes the forum post, dependency status, review notes, and all deployment, handoff, and merge conditions, but omits the required Addresses section. Add the required Addresses section with each relevant address, network, and source of truth.
Out of Scope Changes check ⚠️ Warning The pull request includes July 16, 2026 archive contracts and tests that are unrelated to the August 13, 2026 spell objective. Remove the July 16 archive changes or document why they are required for SC-1605.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise, describes the August 13, 2026 spell, starts with a prefix, and ends with the required Linear issue identifier.
Linked Issues check ✅ Passed The changes add the August 13, 2026 Spark spell and supporting tests, which matches the stated objective of SC-1605.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sc-1605-spell-20260813

Comment @coderabbitai help to get the list of available commands.

@octane-security-app

Copy link
Copy Markdown

Overview

Vulnerabilities found: 1                                                                                
Warnings found: 3                                                                                

🔗 Commit Hash: b9013b1
🛡️ Octane Dashboard: All vulnerabilities

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Spell Caster

Inspect the impact of spell execution on forked networks:

Spell App URL RPC URL
SparkEthereum_20260813 🎇 App 🌎 RPC

Deployed from 9939cb0 on 2026-08-07T15:38:20.191Z

@supercontracts
supercontracts marked this pull request as ready for review August 4, 2026 08:27

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (7)
archive/20260716/SparkEthereum_20260716.sol (1)

52-52: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Rename LZ_ENDPOINT_XLAYER to reflect that it holds a LayerZero endpoint ID.

The value 30274 is a LayerZero endpoint ID (EID), not an endpoint address. The test file uses LZ_EID_XLAYER for the same concept. Use one term for the same concept.

♻️ Proposed rename
-    uint32 internal constant LZ_ENDPOINT_XLAYER = 30274;
+    uint32 internal constant LZ_EID_XLAYER = 30274;

Update the two usages on lines 80 and 85 accordingly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/SparkEthereum_20260716.sol` at line 52, Rename the constant
LZ_ENDPOINT_XLAYER to LZ_EID_XLAYER and update both references on lines 80 and
85 to use the renamed LayerZero endpoint ID symbol.
archive/20260716/XLayer_20260716.t.sol (3)

304-311: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

_assertUnlimitedRateLimit is never called.

No test in XLayerE2ETests calls this helper. The rateLimits member set on line 258 is also only read by this helper. The unlimited rate limits are already asserted in XLayerConfigTests.test_rateLimits_config on lines 163-184.

Either delete the helper, or add a test that uses it for the rate-limit keys not covered by test_rateLimits_config.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/XLayer_20260716.t.sol` around lines 304 - 311, Remove the
unused _assertUnlimitedRateLimit helper and the rateLimits member used only by
it, unless adding assertions for otherwise uncovered rate-limit keys in
XLayerE2ETests; avoid duplicating coverage already provided by
XLayerConfigTests.test_rateLimits_config.

402-403: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

L1_EXECUTOR is unused and the step comment names the wrong target.

Line 402 declares L1_EXECUTOR, but the call on line 461 targets Ethereum.SPARK_PROXY. The comment on line 458 states that L1_PAUSE_PROXY triggers L1_EXECUTOR, which does not match the code.

Delete the unused constant and correct the comment to name Ethereum.SPARK_PROXY.

♻️ Proposed fix
     // Ethereum mainnet governance contracts
-    address constant L1_EXECUTOR    = 0x3300f198988e4C9C63F75dF86De36421f06af8c4;
     address constant L1_PAUSE_PROXY = 0xBE8E3e3618f7474F8cB1d074A26afFef007E98FB;
-        // Step 3: L1_PAUSE_PROXY triggers L1_EXECUTOR to execute the crosschain payload.
+        // Step 3: L1_PAUSE_PROXY makes Ethereum.SPARK_PROXY execute the crosschain payload.

Also applies to: 458-464

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/XLayer_20260716.t.sol` around lines 402 - 403, Remove the
unused L1_EXECUTOR constant and update the step comment near the call to
identify Ethereum.SPARK_PROXY as the target, matching the actual invocation
while retaining L1_PAUSE_PROXY only where it is used.

88-89: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace the hardcoded RPC URL with a configured endpoint.

Three fork setups embed https://rpc.xlayer.tech directly. This bypasses the repository RPC configuration, so CI cannot point the tests at a private or archival node, and a public-endpoint outage fails the suite.

Use an alias resolved through foundry.toml rpc_endpoints, or read the URL from an environment variable with vm.envOr.

Run the following script to check how other tests in the repository resolve fork URLs:

#!/bin/bash
# Inspect declared RPC endpoints and existing fork-creation patterns.
fd -t f 'foundry.toml' --exec cat -n
rg -nP 'createSelectFork|createFork|rpcUrl' --iglob '*.sol' -C2 | head -80

Also applies to: 253-254, 425-429

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/XLayer_20260716.t.sol` around lines 88 - 89, Replace the
hardcoded https://rpc.xlayer.tech URL in all three fork setup blocks, including
setUp and the locations around the other referenced ranges, with the
repository’s configured RPC endpoint resolution. Reuse the established
foundry.toml rpc_endpoints alias or an environment-variable fallback via
vm.envOr, matching existing fork-creation patterns and preserving each fork’s
block number.
archive/20260716/Spell_20260716.t.sol (1)

235-238: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the tautological assertions.

Several assertions compare a value against the variable that was just assigned from it, so they always pass:

  • Line 237 compares usdt0XLayer.balanceOf(XLayer.ALM_PROXY) with xLayerProxyUsdt0Starting, assigned on line 235.
  • Lines 278-279 compare the two mainnet balances with ethProxyUsdtStarting and ethOFTUsdtStarting, assigned on lines 275-276.
  • Line 323 repeats the assertion already made on line 311 with no intervening state change.

Delete these lines. Keep the assertions that check a balance change.

Also applies to: 275-279, 323-324

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/Spell_20260716.t.sol` around lines 235 - 238, Remove the
tautological balance assertions in the test: the ALM proxy assertion using
xLayerProxyUsdt0Starting, the mainnet assertions using ethProxyUsdtStarting and
ethOFTUsdtStarting, and the duplicate assertion repeated after the earlier
check. Preserve assertions that verify actual balance changes, including the
vault balance assertion.
archive/20260716/SparkRobinhood_20260716.sol (1)

13-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Three files redeclare the ALM freezable proxy interface. src/interfaces/Interfaces.sol lines 15-21 already declare IALMProxyFreezableLike, but it lacks grantRole and revokeRole. Each new file works around that by declaring its own copy, so the same role surface now exists in four places with four different member sets. Extend the shared interface once, then import it.

  • archive/20260716/SparkRobinhood_20260716.sol#L13-L21: delete the local interface and add IALMProxyFreezableLike to the existing named import on line 11.
  • archive/20260716/SparkXLayer_20260716.sol#L6-L14: delete the local interface and import IALMProxyFreezableLike from ../../interfaces/Interfaces.sol.
  • archive/20260716/XLayer_20260716.t.sol#L41-L51: delete IXLayerALMProxyFreezable and use the shared IALMProxyFreezableLike, which already declares DEFAULT_ADMIN_ROLE, ALLOCATOR_ROLE, FREEZER_ROLE, and hasRole.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/SparkRobinhood_20260716.sol` around lines 13 - 21, Extend
the shared IALMProxyFreezableLike interface in src/interfaces/Interfaces.sol
with grantRole and revokeRole, then remove the duplicate local interfaces: in
archive/20260716/SparkRobinhood_20260716.sol lines 13-21, add
IALMProxyFreezableLike to the existing named import; in
archive/20260716/SparkXLayer_20260716.sol lines 6-14, import it from
../../interfaces/Interfaces.sol; and in archive/20260716/XLayer_20260716.t.sol
lines 41-51, delete IXLayerALMProxyFreezable and use the shared interface.
src/proposals/20260813/Spell_20260813.t.sol (1)

56-56: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reuse the inherited state-view constant and normalization helpers.

SparkLiquidityLayerTests already defines UNISWAP_V4_STATE_VIEW with the same address, and it already defines _toNormalizedAmount / _fromNormalizedAmount for address tokens. This contract inherits both. The local copies can drift from the harness values when the state view address or the decimal handling changes.

Use the inherited constant, and convert Currency to address at the call sites.

♻️ Proposed change
     uint256 internal constant USDG_BALANCES_SLOT_INDEX = 1;
     uint256 internal constant _V4_SWAP                 = 0x10;
-
-    address internal constant _STATE_VIEW = 0x7fFE42C4a5DEeA5b0feC41C94C136Cf115597227;
-    function _toNormalizedAmount(Currency currency, uint256 amount)
-        internal view returns (uint256 normalizedAmount)
-    {
-        return amount * 1e18 / (10 ** IERC20Metadata(Currency.unwrap(currency)).decimals());
-    }
-
-    function _fromNormalizedAmount(Currency currency, uint256 normalizedAmount) internal view returns (uint256 amount) {
-        return normalizedAmount * (10 ** IERC20Metadata(Currency.unwrap(currency)).decimals()) / 1e18;
-    }
+    function _toNormalizedAmount(Currency currency, uint256 amount)
+        internal view returns (uint256 normalizedAmount)
+    {
+        return _toNormalizedAmount(Currency.unwrap(currency), amount);
+    }
+
+    function _fromNormalizedAmount(Currency currency, uint256 normalizedAmount) internal view returns (uint256 amount) {
+        return _fromNormalizedAmount(Currency.unwrap(currency), normalizedAmount);
+    }

Then replace _STATE_VIEW with UNISWAP_V4_STATE_VIEW in _getCurrentTick (line 216).

Also applies to: 381-389

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/proposals/20260813/Spell_20260813.t.sol` at line 56, Remove the locally
defined _STATE_VIEW and reuse the inherited UNISWAP_V4_STATE_VIEW constant in
_getCurrentTick. Remove the local normalization helpers and use the inherited
_toNormalizedAmount and _fromNormalizedAmount helpers, converting Currency
values to address at their call sites.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@archive/20260716/Spell_20260716.t.sol`:
- Around line 87-102: Update test_ETHEREUM_sll_deactivateOldMorphoUsdtVault to
verify before _executeAllPayloadsAndBridges that Ethereum.ALM_PROXY holds zero
shares of OLD_MORPHO_VAULT_V2_USDT, using the vault’s established share-balance
query or an existing position-exited assertion.
- Around line 383-388: Update the interest derivation comment near the
USDT0XLayer assertion to use the exact FIVE_PCT_APY value, and align the
USDT0XLayer and Robinhood redemption assertions by using the same approximate
absolute comparison and tolerance for the calculated amount.

---

Nitpick comments:
In `@archive/20260716/SparkEthereum_20260716.sol`:
- Line 52: Rename the constant LZ_ENDPOINT_XLAYER to LZ_EID_XLAYER and update
both references on lines 80 and 85 to use the renamed LayerZero endpoint ID
symbol.

In `@archive/20260716/SparkRobinhood_20260716.sol`:
- Around line 13-21: Extend the shared IALMProxyFreezableLike interface in
src/interfaces/Interfaces.sol with grantRole and revokeRole, then remove the
duplicate local interfaces: in archive/20260716/SparkRobinhood_20260716.sol
lines 13-21, add IALMProxyFreezableLike to the existing named import; in
archive/20260716/SparkXLayer_20260716.sol lines 6-14, import it from
../../interfaces/Interfaces.sol; and in archive/20260716/XLayer_20260716.t.sol
lines 41-51, delete IXLayerALMProxyFreezable and use the shared interface.

In `@archive/20260716/Spell_20260716.t.sol`:
- Around line 235-238: Remove the tautological balance assertions in the test:
the ALM proxy assertion using xLayerProxyUsdt0Starting, the mainnet assertions
using ethProxyUsdtStarting and ethOFTUsdtStarting, and the duplicate assertion
repeated after the earlier check. Preserve assertions that verify actual balance
changes, including the vault balance assertion.

In `@archive/20260716/XLayer_20260716.t.sol`:
- Around line 304-311: Remove the unused _assertUnlimitedRateLimit helper and
the rateLimits member used only by it, unless adding assertions for otherwise
uncovered rate-limit keys in XLayerE2ETests; avoid duplicating coverage already
provided by XLayerConfigTests.test_rateLimits_config.
- Around line 402-403: Remove the unused L1_EXECUTOR constant and update the
step comment near the call to identify Ethereum.SPARK_PROXY as the target,
matching the actual invocation while retaining L1_PAUSE_PROXY only where it is
used.
- Around line 88-89: Replace the hardcoded https://rpc.xlayer.tech URL in all
three fork setup blocks, including setUp and the locations around the other
referenced ranges, with the repository’s configured RPC endpoint resolution.
Reuse the established foundry.toml rpc_endpoints alias or an
environment-variable fallback via vm.envOr, matching existing fork-creation
patterns and preserving each fork’s block number.

In `@src/proposals/20260813/Spell_20260813.t.sol`:
- Line 56: Remove the locally defined _STATE_VIEW and reuse the inherited
UNISWAP_V4_STATE_VIEW constant in _getCurrentTick. Remove the local
normalization helpers and use the inherited _toNormalizedAmount and
_fromNormalizedAmount helpers, converting Currency values to address at their
call sites.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f66e2a47-241c-40ae-9dca-34ee3bfd9644

📥 Commits

Reviewing files that changed from the base of the PR and between c24ddf5 and ed4780b.

📒 Files selected for processing (9)
  • archive/20260716/SparkEthereum_20260716.sol
  • archive/20260716/SparkRobinhood_20260716.sol
  • archive/20260716/SparkXLayer_20260716.sol
  • archive/20260716/Spell_20260716.t.sol
  • archive/20260716/XLayer_20260716.t.sol
  • diffs/20260813-Ethereum-0xC13e21B648A5Ee794902342038FF3aDAB66BE987-pre_20260813-Ethereum-0xC13e21B648A5Ee794902342038FF3aDAB66BE987-post.md
  • src/proposals/20260813/SparkEthereum_20260813.sol
  • src/proposals/20260813/Spell_20260813.t.sol
  • src/test-harness/SparkLiquidityLayerTests.sol

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

🧹 Nitpick comments (7)
archive/20260716/SparkEthereum_20260716.sol (1)

52-52: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Rename LZ_ENDPOINT_XLAYER to reflect that it holds a LayerZero endpoint ID.

The value 30274 is a LayerZero endpoint ID (EID), not an endpoint address. The test file uses LZ_EID_XLAYER for the same concept. Use one term for the same concept.

♻️ Proposed rename
-    uint32 internal constant LZ_ENDPOINT_XLAYER = 30274;
+    uint32 internal constant LZ_EID_XLAYER = 30274;

Update the two usages on lines 80 and 85 accordingly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/SparkEthereum_20260716.sol` at line 52, Rename the constant
LZ_ENDPOINT_XLAYER to LZ_EID_XLAYER and update both references on lines 80 and
85 to use the renamed LayerZero endpoint ID symbol.
archive/20260716/XLayer_20260716.t.sol (3)

304-311: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

_assertUnlimitedRateLimit is never called.

No test in XLayerE2ETests calls this helper. The rateLimits member set on line 258 is also only read by this helper. The unlimited rate limits are already asserted in XLayerConfigTests.test_rateLimits_config on lines 163-184.

Either delete the helper, or add a test that uses it for the rate-limit keys not covered by test_rateLimits_config.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/XLayer_20260716.t.sol` around lines 304 - 311, Remove the
unused _assertUnlimitedRateLimit helper and the rateLimits member used only by
it, unless adding assertions for otherwise uncovered rate-limit keys in
XLayerE2ETests; avoid duplicating coverage already provided by
XLayerConfigTests.test_rateLimits_config.

402-403: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

L1_EXECUTOR is unused and the step comment names the wrong target.

Line 402 declares L1_EXECUTOR, but the call on line 461 targets Ethereum.SPARK_PROXY. The comment on line 458 states that L1_PAUSE_PROXY triggers L1_EXECUTOR, which does not match the code.

Delete the unused constant and correct the comment to name Ethereum.SPARK_PROXY.

♻️ Proposed fix
     // Ethereum mainnet governance contracts
-    address constant L1_EXECUTOR    = 0x3300f198988e4C9C63F75dF86De36421f06af8c4;
     address constant L1_PAUSE_PROXY = 0xBE8E3e3618f7474F8cB1d074A26afFef007E98FB;
-        // Step 3: L1_PAUSE_PROXY triggers L1_EXECUTOR to execute the crosschain payload.
+        // Step 3: L1_PAUSE_PROXY makes Ethereum.SPARK_PROXY execute the crosschain payload.

Also applies to: 458-464

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/XLayer_20260716.t.sol` around lines 402 - 403, Remove the
unused L1_EXECUTOR constant and update the step comment near the call to
identify Ethereum.SPARK_PROXY as the target, matching the actual invocation
while retaining L1_PAUSE_PROXY only where it is used.

88-89: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace the hardcoded RPC URL with a configured endpoint.

Three fork setups embed https://rpc.xlayer.tech directly. This bypasses the repository RPC configuration, so CI cannot point the tests at a private or archival node, and a public-endpoint outage fails the suite.

Use an alias resolved through foundry.toml rpc_endpoints, or read the URL from an environment variable with vm.envOr.

Run the following script to check how other tests in the repository resolve fork URLs:

#!/bin/bash
# Inspect declared RPC endpoints and existing fork-creation patterns.
fd -t f 'foundry.toml' --exec cat -n
rg -nP 'createSelectFork|createFork|rpcUrl' --iglob '*.sol' -C2 | head -80

Also applies to: 253-254, 425-429

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/XLayer_20260716.t.sol` around lines 88 - 89, Replace the
hardcoded https://rpc.xlayer.tech URL in all three fork setup blocks, including
setUp and the locations around the other referenced ranges, with the
repository’s configured RPC endpoint resolution. Reuse the established
foundry.toml rpc_endpoints alias or an environment-variable fallback via
vm.envOr, matching existing fork-creation patterns and preserving each fork’s
block number.
archive/20260716/Spell_20260716.t.sol (1)

235-238: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the tautological assertions.

Several assertions compare a value against the variable that was just assigned from it, so they always pass:

  • Line 237 compares usdt0XLayer.balanceOf(XLayer.ALM_PROXY) with xLayerProxyUsdt0Starting, assigned on line 235.
  • Lines 278-279 compare the two mainnet balances with ethProxyUsdtStarting and ethOFTUsdtStarting, assigned on lines 275-276.
  • Line 323 repeats the assertion already made on line 311 with no intervening state change.

Delete these lines. Keep the assertions that check a balance change.

Also applies to: 275-279, 323-324

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/Spell_20260716.t.sol` around lines 235 - 238, Remove the
tautological balance assertions in the test: the ALM proxy assertion using
xLayerProxyUsdt0Starting, the mainnet assertions using ethProxyUsdtStarting and
ethOFTUsdtStarting, and the duplicate assertion repeated after the earlier
check. Preserve assertions that verify actual balance changes, including the
vault balance assertion.
archive/20260716/SparkRobinhood_20260716.sol (1)

13-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Three files redeclare the ALM freezable proxy interface. src/interfaces/Interfaces.sol lines 15-21 already declare IALMProxyFreezableLike, but it lacks grantRole and revokeRole. Each new file works around that by declaring its own copy, so the same role surface now exists in four places with four different member sets. Extend the shared interface once, then import it.

  • archive/20260716/SparkRobinhood_20260716.sol#L13-L21: delete the local interface and add IALMProxyFreezableLike to the existing named import on line 11.
  • archive/20260716/SparkXLayer_20260716.sol#L6-L14: delete the local interface and import IALMProxyFreezableLike from ../../interfaces/Interfaces.sol.
  • archive/20260716/XLayer_20260716.t.sol#L41-L51: delete IXLayerALMProxyFreezable and use the shared IALMProxyFreezableLike, which already declares DEFAULT_ADMIN_ROLE, ALLOCATOR_ROLE, FREEZER_ROLE, and hasRole.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/SparkRobinhood_20260716.sol` around lines 13 - 21, Extend
the shared IALMProxyFreezableLike interface in src/interfaces/Interfaces.sol
with grantRole and revokeRole, then remove the duplicate local interfaces: in
archive/20260716/SparkRobinhood_20260716.sol lines 13-21, add
IALMProxyFreezableLike to the existing named import; in
archive/20260716/SparkXLayer_20260716.sol lines 6-14, import it from
../../interfaces/Interfaces.sol; and in archive/20260716/XLayer_20260716.t.sol
lines 41-51, delete IXLayerALMProxyFreezable and use the shared interface.
src/proposals/20260813/Spell_20260813.t.sol (1)

56-56: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reuse the inherited state-view constant and normalization helpers.

SparkLiquidityLayerTests already defines UNISWAP_V4_STATE_VIEW with the same address, and it already defines _toNormalizedAmount / _fromNormalizedAmount for address tokens. This contract inherits both. The local copies can drift from the harness values when the state view address or the decimal handling changes.

Use the inherited constant, and convert Currency to address at the call sites.

♻️ Proposed change
     uint256 internal constant USDG_BALANCES_SLOT_INDEX = 1;
     uint256 internal constant _V4_SWAP                 = 0x10;
-
-    address internal constant _STATE_VIEW = 0x7fFE42C4a5DEeA5b0feC41C94C136Cf115597227;
-    function _toNormalizedAmount(Currency currency, uint256 amount)
-        internal view returns (uint256 normalizedAmount)
-    {
-        return amount * 1e18 / (10 ** IERC20Metadata(Currency.unwrap(currency)).decimals());
-    }
-
-    function _fromNormalizedAmount(Currency currency, uint256 normalizedAmount) internal view returns (uint256 amount) {
-        return normalizedAmount * (10 ** IERC20Metadata(Currency.unwrap(currency)).decimals()) / 1e18;
-    }
+    function _toNormalizedAmount(Currency currency, uint256 amount)
+        internal view returns (uint256 normalizedAmount)
+    {
+        return _toNormalizedAmount(Currency.unwrap(currency), amount);
+    }
+
+    function _fromNormalizedAmount(Currency currency, uint256 normalizedAmount) internal view returns (uint256 amount) {
+        return _fromNormalizedAmount(Currency.unwrap(currency), normalizedAmount);
+    }

Then replace _STATE_VIEW with UNISWAP_V4_STATE_VIEW in _getCurrentTick (line 216).

Also applies to: 381-389

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/proposals/20260813/Spell_20260813.t.sol` at line 56, Remove the locally
defined _STATE_VIEW and reuse the inherited UNISWAP_V4_STATE_VIEW constant in
_getCurrentTick. Remove the local normalization helpers and use the inherited
_toNormalizedAmount and _fromNormalizedAmount helpers, converting Currency
values to address at their call sites.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@archive/20260716/Spell_20260716.t.sol`:
- Around line 87-102: Update test_ETHEREUM_sll_deactivateOldMorphoUsdtVault to
verify before _executeAllPayloadsAndBridges that Ethereum.ALM_PROXY holds zero
shares of OLD_MORPHO_VAULT_V2_USDT, using the vault’s established share-balance
query or an existing position-exited assertion.
- Around line 383-388: Update the interest derivation comment near the
USDT0XLayer assertion to use the exact FIVE_PCT_APY value, and align the
USDT0XLayer and Robinhood redemption assertions by using the same approximate
absolute comparison and tolerance for the calculated amount.

---

Nitpick comments:
In `@archive/20260716/SparkEthereum_20260716.sol`:
- Line 52: Rename the constant LZ_ENDPOINT_XLAYER to LZ_EID_XLAYER and update
both references on lines 80 and 85 to use the renamed LayerZero endpoint ID
symbol.

In `@archive/20260716/SparkRobinhood_20260716.sol`:
- Around line 13-21: Extend the shared IALMProxyFreezableLike interface in
src/interfaces/Interfaces.sol with grantRole and revokeRole, then remove the
duplicate local interfaces: in archive/20260716/SparkRobinhood_20260716.sol
lines 13-21, add IALMProxyFreezableLike to the existing named import; in
archive/20260716/SparkXLayer_20260716.sol lines 6-14, import it from
../../interfaces/Interfaces.sol; and in archive/20260716/XLayer_20260716.t.sol
lines 41-51, delete IXLayerALMProxyFreezable and use the shared interface.

In `@archive/20260716/Spell_20260716.t.sol`:
- Around line 235-238: Remove the tautological balance assertions in the test:
the ALM proxy assertion using xLayerProxyUsdt0Starting, the mainnet assertions
using ethProxyUsdtStarting and ethOFTUsdtStarting, and the duplicate assertion
repeated after the earlier check. Preserve assertions that verify actual balance
changes, including the vault balance assertion.

In `@archive/20260716/XLayer_20260716.t.sol`:
- Around line 304-311: Remove the unused _assertUnlimitedRateLimit helper and
the rateLimits member used only by it, unless adding assertions for otherwise
uncovered rate-limit keys in XLayerE2ETests; avoid duplicating coverage already
provided by XLayerConfigTests.test_rateLimits_config.
- Around line 402-403: Remove the unused L1_EXECUTOR constant and update the
step comment near the call to identify Ethereum.SPARK_PROXY as the target,
matching the actual invocation while retaining L1_PAUSE_PROXY only where it is
used.
- Around line 88-89: Replace the hardcoded https://rpc.xlayer.tech URL in all
three fork setup blocks, including setUp and the locations around the other
referenced ranges, with the repository’s configured RPC endpoint resolution.
Reuse the established foundry.toml rpc_endpoints alias or an
environment-variable fallback via vm.envOr, matching existing fork-creation
patterns and preserving each fork’s block number.

In `@src/proposals/20260813/Spell_20260813.t.sol`:
- Line 56: Remove the locally defined _STATE_VIEW and reuse the inherited
UNISWAP_V4_STATE_VIEW constant in _getCurrentTick. Remove the local
normalization helpers and use the inherited _toNormalizedAmount and
_fromNormalizedAmount helpers, converting Currency values to address at their
call sites.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f66e2a47-241c-40ae-9dca-34ee3bfd9644

📥 Commits

Reviewing files that changed from the base of the PR and between c24ddf5 and ed4780b.

📒 Files selected for processing (9)
  • archive/20260716/SparkEthereum_20260716.sol
  • archive/20260716/SparkRobinhood_20260716.sol
  • archive/20260716/SparkXLayer_20260716.sol
  • archive/20260716/Spell_20260716.t.sol
  • archive/20260716/XLayer_20260716.t.sol
  • diffs/20260813-Ethereum-0xC13e21B648A5Ee794902342038FF3aDAB66BE987-pre_20260813-Ethereum-0xC13e21B648A5Ee794902342038FF3aDAB66BE987-post.md
  • src/proposals/20260813/SparkEthereum_20260813.sol
  • src/proposals/20260813/Spell_20260813.t.sol
  • src/test-harness/SparkLiquidityLayerTests.sol
🛑 Comments failed to post (2)
archive/20260716/Spell_20260716.t.sol (2)

87-102: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Confirm that the old USDT Morpho V2 vault holds no ALM proxy balance.

The payload sets the withdraw limit for OLD_MORPHO_VAULT_V2_USDT to 0. If Ethereum.ALM_PROXY still holds shares in that vault, the zeroed withdraw limit strands them, because LIMIT_4626_WITHDRAW gates the withdrawal path.

Add an assertion that the ALM proxy share balance is zero before execution, or confirm that the position was already exited.

💚 Proposed assertion
         _assertRateLimit(depositKey,  100_000_000e6,     1_000_000_000e6 / uint256(1 days));
         _assertRateLimit(withdrawKey, type(uint256).max, 0);
 
+        // No funds are stranded by zeroing the withdraw limit.
+        assertEq(IERC20(OLD_MORPHO_VAULT_V2_USDT).balanceOf(Ethereum.ALM_PROXY), 0);
+
         _executeAllPayloadsAndBridges();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    function test_ETHEREUM_sll_deactivateOldMorphoUsdtVault() external onChain(ChainIdUtils.Ethereum()) {
        SparkLiquidityLayerContext memory ctx = _getSparkLiquidityLayerContext();

        MainnetController controller = MainnetController(ctx.controller);

        bytes32 depositKey  = RateLimitHelpers.makeAddressKey(controller.LIMIT_4626_DEPOSIT(),  OLD_MORPHO_VAULT_V2_USDT);
        bytes32 withdrawKey = RateLimitHelpers.makeAddressKey(controller.LIMIT_4626_WITHDRAW(), OLD_MORPHO_VAULT_V2_USDT);

        _assertRateLimit(depositKey,  100_000_000e6,     1_000_000_000e6 / uint256(1 days));
        _assertRateLimit(withdrawKey, type(uint256).max, 0);

        // No funds are stranded by zeroing the withdraw limit.
        assertEq(IERC20(OLD_MORPHO_VAULT_V2_USDT).balanceOf(Ethereum.ALM_PROXY), 0);

        _executeAllPayloadsAndBridges();

        _assertRateLimit(depositKey,  0, 0);
        _assertRateLimit(withdrawKey, 0, 0);
    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/Spell_20260716.t.sol` around lines 87 - 102, Update
test_ETHEREUM_sll_deactivateOldMorphoUsdtVault to verify before
_executeAllPayloadsAndBridges that Ethereum.ALM_PROXY holds zero shares of
OLD_MORPHO_VAULT_V2_USDT, using the vault’s established share-balance query or
an existing position-exited assertion.

383-388: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix the derivation comment and align the two redemption assertions.

The comment on line 384 uses the rate 1.000000001547125957863212448. The constant FIVE_PCT_APY on line 72 is 1.000000001547125957863212167. The comment does not match the value used by the test.

The equivalent Robinhood assertion on line 534 uses assertApproxEqAbs(..., 1_001_337.610629e6, 1) for the same math, while line 386 uses exact equality against 1_001_337.610630e6. Use one form for both tests so a one-unit rounding difference does not make one test brittle.

💚 Proposed fix
         // 1m + 10 days of interest at 5% APY
-        // bc -l <<< 'scale=27; e( l(1.000000001547125957863212448)*(60*60*24*10) )'
+        // bc -l <<< 'scale=27; e( l(1.000000001547125957863212167)*(60*60*24*10) )'
         // 1.001337610630706965933736950
-        assertEq(usdt0XLayer.balanceOf(user), 1_001_337.610630e6);
+        assertApproxEqAbs(usdt0XLayer.balanceOf(user), 1_001_337.610630e6, 1);
         assertEq(vault.balanceOf(user),       0);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        // 1m + 10 days of interest at 5% APY
        // bc -l <<< 'scale=27; e( l(1.000000001547125957863212167)*(60*60*24*10) )'
        // 1.001337610630706965933736950
        assertApproxEqAbs(usdt0XLayer.balanceOf(user), 1_001_337.610630e6, 1);
        assertEq(vault.balanceOf(user),       0);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@archive/20260716/Spell_20260716.t.sol` around lines 383 - 388, Update the
interest derivation comment near the USDT0XLayer assertion to use the exact
FIVE_PCT_APY value, and align the USDT0XLayer and Robinhood redemption
assertions by using the same approximate absolute comparison and tolerance for
the calculated amount.

@TheMj0ln1r TheMj0ln1r left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, just few formats.

_assertRateLimit(withdrawPoolId, 0, 0);
_assertRateLimit(swapPoolId, 0, 0);

(int24 _tickLowerMin, int24 _tickUpperMax, uint24 _maxTickSpacing) = controller.uniswapV4TickLimits(USDG_USDS_POOL_ID);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after bracket. (Apply to entire file)

assertEq(controller.maxSlippages(address(uint160(uint256(USDG_USDS_POOL_ID)))), 0.999e18);

_assertRateLimit(depositPoolId, 10_000_000e18, 100_000_000e18 / uint256(1 days));
_assertRateLimit(withdrawPoolId, type(uint256).max, 0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra spaces

Comment thread src/proposals/20260813/Spell_20260813.t.sol
Comment thread src/proposals/20260813/Spell_20260813.t.sol
@unvariant-dev
unvariant-dev self-requested a review August 5, 2026 18:32
vm.revertTo(snapshot); // To allow swapping through higher liquidity below
} else {
// Deposit is disabled
assertEq(vars.depositAmounts[0], 0);

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good here

@lucas-manuel lucas-manuel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed spell, LGTM after these changes.

Comment thread src/proposals/20260813/SparkEthereum_20260813.sol Outdated
Comment thread src/proposals/20260813/Spell_20260813.t.sol Outdated
Comment thread src/proposals/20260813/Spell_20260813.t.sol Outdated
Comment thread src/proposals/20260813/Spell_20260813.t.sol Outdated
Comment thread src/proposals/20260813/SparkEthereum_20260813.sol Outdated
Comment thread src/test-harness/SparkLiquidityLayerTests.sol Outdated
Comment thread src/proposals/20260813/SparkEthereum_20260813.sol Outdated
Comment thread src/test-harness/SparkLiquidityLayerTests.sol Outdated
TheMj0ln1r
TheMj0ln1r previously approved these changes Aug 7, 2026

@TheMj0ln1r TheMj0ln1r left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving the Spell for deployment

  • Check forum post link - https://forum.skyeco.com/t/august-13-2026-proposed-changes-to-spark-for-upcoming-spell/28135/8
  • Check description for all payloads
  • Check poll links
  • Check spark-address-registry commit matches current HEAD
  • SLL - Uniswap V4 SLL Onboarding [Ethereum] - [1] - DONE
    • Verify Pool ID in Uniswap UI - USDG_USDS_POOL_ID=0x28adc7179a8a83c3379955d59563c0fec33eadfa83946b447af289190ff5fcff

    • Independently convert ticks to prices from forum post to validate correctness

      >>> (1.0001 ** -276_334) * 10**12
      0.9990031909716848
      >>> (1.0001 ** -276_314) * 10**12
      1.0010030965990384
    • Review all parameters in configureUniswapV4Pool against forum post

    • Review configureUniswapV4Pool function in SLLHelpers, ensuring that

      • Tick limits are set - -276_334 , -276_314
      • Max slippage is set - 0.999e18 (0.1%)
      • Rate limits are set
        • Deposit
          • maxAmount - 10_000_000e18
          • slope - 100_000_000e18/day
        • Withdraw
          • maxAmount - unlimited
          • slope - unlimited
        • Swap
          • maxAmount - 5_000_000e18
          • slope - 200_000_000e18/day
    • Review test - test_ETHEREUM_sparkLiquidityLayer_onboardUniswapV4USDGUSDS

      • Check rate limits have been set
      • Check maxSlippage has been set
      • Check tick limits have been set
      • Check that E2E testing is properly conducting deposit/withdraw/swap with proper state assertions and rate limit checks
  • SLL - Uniswap V4 SLL Onboarding [Ethereum] - [2] - DONE
    • Verify Pool ID in Uniswap UI - RLUSD_USDS_POOL_ID=0x9035721b23481db3888fd201b9c2b26dbc3af60258bca65e669f2ed98dc8eb4f

    • Independently convert ticks to prices from forum post to validate correctness

      >>> (1.0001 ** -10)
      0.9990005497800716
      >>> (1.0001 ** 10)
      1.001000450120021
    • Review all parameters in configureUniswapV4Pool against forum post

    • Review configureUniswapV4Pool function in SLLHelpers, ensuring that

      • Tick limits are set - -10, 10
      • Max slippage is set - 0.999e18 (0.1%)
      • Rate limits are set
        • Deposit
          • maxAmount - 10_000_000e18
          • slope - 50_000_000e18/day
        • Withdraw
          • maxAmount - unlimited
          • slope - unlimited
        • Swap
          • maxAmount - 5_000_000e18
          • slope - 100_000_000e18/day
    • Review test - test_ETHEREUM_sparkLiquidityLayer_onboardUniswapV4RLUSDUSDS

      • Check rate limits have been set
      • Check maxSlippage has been set
      • Check tick limits have been set
      • Check that E2E testing is properly conducting deposit/withdraw/swap with proper state assertions and rate limit checks
  • SLL - Curve SLL onboarding [Ethereum] - [3] - DONE
    • Check pool address against forum post - CURVE_RLUSD_USDC = 0xD001aE433f254283FeCE51d4ACcE8c53263aa186
    • Ensure that the pool is of type stableswap-ng (check curve.fi UI)
    • Check that pool address is verified
    • Ensure that the pool has been seeded with LP shares burned at address(1)
    • Ensure that maxSlippage is set according to forum post - 0.999e18
    • Check maxAmount against forum post - 5_000_000e18
    • Check slope against forum post - 25_000_000e18/day
    • Verify the precision of the rate limit is 1e18
    • Check rate limit before and after state in a test - test_ETHEREUM_curvePoolOnboarding_RLUSDUSDC
    • Ensure that _configureCurvePool helper function is used in spell
    • Ensure that _testCurveOnboarding helper test is used in test
  • Withdraw reserves [Ethereum] - [4] - DONE
    • Review SparkPayloadEthereum code for claiming all reserves
    • Ensure stablecoins go to ALMProxy and everything else goes to Liquidation multisig
    • Review that test decrements and increments funds from correct addresses for all reserves
  • Treasury Transfer [Ethereum] - [5] - DONE
    • Check receiver address against forum post or address registry - ALM_OPS_MULTISIG
    • Check amount against forum post - 1_756_359e18
    • Review that test decrements and increments funds from correct addresses - test_ETHEREUM_sparkTreasury_transferExcessUSDSForBuybacks

coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 7, 2026
lucas-manuel
lucas-manuel previously approved these changes Aug 7, 2026

@lucas-manuel lucas-manuel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to deploy.

  • Check forum post link - https://forum.skyeco.com/t/august-13-2026-proposed-changes-to-spark-for-upcoming-spell/28135/8
  • Check description for all payloads
  • Check poll links
  • Check spark-address-registry commit matches current HEAD
  • SLL - Uniswap V4 SLL Onboarding [Ethereum] - [1] DONE
    • Verify Pool ID in Uniswap UI - USDG_USDS_POOL_ID=0x28adc7179a8a83c3379955d59563c0fec33eadfa83946b447af289190ff5fcff

    • Verify pool is seeded through UI

    • Check pool token ordering through Etherscan and fee

    • Independently convert ticks to prices from forum post to validate correctness

      >>> (1.0001 ** -276_334) * 10**12
      0.9990031909716848
      >>> (1.0001 ** -276_314) * 10**12
      1.0010030965990384
    • Review all parameters in configureUniswapV4Pool against forum post

    • Review configureUniswapV4Pool function in SLLHelpers, ensuring that

      • Tick limits are set - -276_334 , -276_314
      • Max slippage is set - 0.999e18 (0.1%)
      • Rate limits are set
        • Deposit
          • maxAmount - 10_000_000e18
          • slope - 100_000_000e18/day
        • Withdraw
          • maxAmount - unlimited
          • slope - unlimited
        • Swap
          • maxAmount - 5_000_000e18
          • slope - 200_000_000e18/day
    • Review test - test_ETHEREUM_sparkLiquidityLayer_onboardUniswapV4USDGUSDS

      • Check rate limits have been set
      • Check maxSlippage has been set
      • Check tick limits have been set
      • Check that E2E testing is properly conducting deposit/withdraw/swap with proper state assertions and rate limit checks
  • SLL - Uniswap V4 SLL Onboarding [Ethereum] - [2] - DONE
    • Verify Pool ID in Uniswap UI - RLUSD_USDS_POOL_ID=0x9035721b23481db3888fd201b9c2b26dbc3af60258bca65e669f2ed98dc8eb4f

    • Verify pool is seeded through UI

    • Check pool token ordering through Etherscan and fee

    • Independently convert ticks to prices from forum post to validate correctness

      >>> (1.0001 ** -10)
      0.9990005497800716
      >>> (1.0001 ** 10)
      1.001000450120021
    • Review all parameters in configureUniswapV4Pool against forum post

    • Review configureUniswapV4Pool function in SLLHelpers, ensuring that

      • Tick limits are set - -10, 10
      • Max slippage is set - 0.999e18 (0.1%)
      • Rate limits are set
        • Deposit
          • maxAmount - 10_000_000e18
          • slope - 50_000_000e18/day
        • Withdraw
          • maxAmount - unlimited
          • slope - unlimited
        • Swap
          • maxAmount - 5_000_000e18
          • slope - 100_000_000e18/day
    • Review test - test_ETHEREUM_sparkLiquidityLayer_onboardUniswapV4RLUSDUSDS

      • Check rate limits have been set
      • Check maxSlippage has been set
      • Check tick limits have been set
      • Check that E2E testing is properly conducting deposit/withdraw/swap with proper state assertions and rate limit checks
  • SLL - Curve SLL onboarding [Ethereum] - [3] - DONE
    • Check pool address against forum post - CURVE_RLUSD_USDC = 0xD001aE433f254283FeCE51d4ACcE8c53263aa186
    • Check seeded
    • Ensure that the pool is of type stableswap-ng (check curve.fi UI)
    • Check that pool address is verified
    • Ensure that the pool has been seeded with LP shares burned at address(1)
    • Ensure that maxSlippage is set according to forum post - 0.999e18
    • Check maxAmount against forum post - 5_000_000e18
    • Check slope against forum post - 25_000_000e18/day
    • Verify the precision of the rate limit is 1e18
    • Check rate limit before and after state in a test - test_ETHEREUM_curvePoolOnboarding_RLUSDUSDC
    • Ensure that _configureCurvePool helper function is used in spell
    • Ensure that _testCurveOnboarding helper test is used in test
  • Withdraw reserves [Ethereum] - [4] - DONE
    • Review SparkPayloadEthereum code for claiming all reserves
    • Ensure stablecoins go to ALMProxy and everything else goes to Liquidation multisig
    • Review that test decrements and increments funds from correct addresses for all reserves
  • Treasury Transfer [Ethereum] - [5] - DONE
    • Check receiver address against forum post or address registry - ALM_OPS_MULTISIG
    • Check amount against forum post - 1_756_359e18
    • Review that test decrements and increments funds from correct addresses - test_ETHEREUM_sparkTreasury_transferExcessUSDSForBuybacks

Comment thread src/proposals/20260813/Spell_20260813.t.sol Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 7, 2026

@lucas-manuel lucas-manuel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving payload deployed at 0xc827237CB91Fa8E78B8dfA4F77838eDf924C04e9

@TheMj0ln1r TheMj0ln1r left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving spell deployment at 0xc827237CB91Fa8E78B8dfA4F77838eDf924C04e9

@unvariant-dev unvariant-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirming and approving the spell deployment at 0xc827237CB91Fa8E78B8dfA4F77838eDf924C04e9

Completed checklist for both the development and deployment stages: https://gist.github.com/unvariant-dev/9ec09866fed86c5b96b7f9d8e6035e20

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants