Skip to content

♻️ app: replace proposal simulation with simulate blocks, batch contract reads#907

Merged
cruzdanilo merged 4 commits intomainfrom
sim
Mar 25, 2026
Merged

♻️ app: replace proposal simulation with simulate blocks, batch contract reads#907
cruzdanilo merged 4 commits intomainfrom
sim

Conversation

@cruzdanilo
Copy link
Copy Markdown
Member

@cruzdanilo cruzdanilo commented Mar 24, 2026


Open with Devin

Summary by CodeRabbit

  • New Features

    • Multi-block simulation support for end-to-end proposal + execute previews.
  • Improvements

    • Unified/simplified proposal simulation API used across repay, roll, send and swap flows.
    • Broadened simulation availability (removed prior bytecode gating); UI surfaces simulation errors and disables actions when appropriate.
    • Multicall/chain metadata support for more reliable chain behavior.
  • Chores

    • Updated gas benchmark snapshots, spelling list, and release metadata entries.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 24, 2026

🦋 Changeset detected

Latest commit: ce222ba

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 24, 2026

Walkthrough

Refactors proposal simulation to batch contract reads and simulate consecutive blocks via a new useSimulateBlocks hook; updates chain config to include multicall3 contract metadata; removes bytecode gating from several UI components; updates fork etching and gas snapshots; adds two Changesets for @exactly/mobile.

Changes

Cohort / File(s) Summary
Changeset Entries
.changeset/bold-ram-dig.md, .changeset/tidy-geese-batch.md
Added two patch changesets for @exactly/mobile describing simulate-proposal API flattening and replacement with simulate blocks.
Chain Configuration
common/wagmi.config.ts
Widened generated chain export/type to include contracts.multicall3.address; runtime chain content assigns multicall3.address for anvil.
Test Infrastructure
contracts/test/Fork.t.sol, contracts/script/ExaAccountFactory.s.sol
Replaced etchCreate3() with etchCanonical(); etching now includes MULTICALL3_ADDRESS bytecode and adjusted script usage.
Gas Snapshots & Spelling
contracts/.gas-snapshot, cspell.json
Updated recorded gas metrics; added "multicall" to cspell dictionary.
Simulation Hook (Core)
src/utils/useSimulateProposal.ts
Rewrote hook to batch reads via useReadContracts, encode calldata with new helpers, and simulate propose+execute as consecutive blocks; API now returns { request, isPending, error } and accepts optional chain.contracts.multicall3.
Wagmi Simulation Utility
src/utils/wagmi/useSimulateBlocks.ts
Added useSimulateBlocks hook that wraps viem/actions simulateBlocks with React Query integration, chainId/config overrides, and caching.
UI Components
src/components/pay/Repay.tsx, src/components/roll-debt/RollDebt.tsx, src/components/send-funds/Amount.tsx, src/components/swaps/Swaps.tsx
Removed bytecode gating, switched callers to the new useSimulateProposal return shape (request, error, isPending), adjusted enablement conditions and mutation calls, and stopped returning zeroAddress for some swap lookups.

Sequence Diagram(s)

sequenceDiagram
    participant UI as UI Component
    participant Hook as useSimulateProposal
    participant RC as useReadContracts
    participant SB as useSimulateBlocks
    participant Viem as Viem Actions

    UI->>Hook: call with proposal params
    Hook->>RC: batch-read plugins, delay, nonces, timestamp, previewer assets
    RC->>Viem: readContracts (multicall)
    Viem-->>RC: returns read results
    RC-->>Hook: read results
    Hook->>SB: call simulateBlocks with propose + execute calldata (blockOverrides.time = timestamp + delay)
    SB->>Viem: simulateBlocks
    Viem-->>SB: simulation results
    SB-->>Hook: simulation result / error
    Hook-->>UI: returns { request, isPending, error }
    UI->>Viem: execute mutation using request
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • itofarina
  • dieguezguille
  • franm91
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main architectural changes: refactoring proposal simulation to use simulate blocks and batching contract reads via multicall3.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sim

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly overhauls the client-side proposal simulation mechanism, transitioning to viem's simulateBlocks for more precise and efficient on-chain interaction previews. It also introduces batched contract data fetching to optimize performance and integrates multicall3 into the local development setup for enhanced testing capabilities. These changes collectively improve the reliability and speed of transaction simulations across the application.

Highlights

  • Simulation Logic Refactor: The useSimulateProposal hook was refactored to leverage viem's simulateBlocks action, replacing the previous useSimulateContract with manual state overrides. This change streamlines the simulation process and enhances its accuracy by simulating both the proposal and its execution in a single, atomic block.
  • Batched Contract Reads: Multiple contract reads within useSimulateProposal (e.g., getInstalledPlugins, delay, queueNonces, getCurrentBlockTimestamp, assets) are now batched using useReadContracts. This optimization reduces network requests and improves data fetching efficiency.
  • Multicall3 Integration for Anvil: The local Anvil development environment now includes the multicall3 contract. The wagmi.config.ts was updated to configure its address, and Fork.t.sol was modified to etch the multicall3 bytecode, enabling more robust local testing.
  • Simplified useSimulateProposal Usage: Client-side components such as Repay.tsx, RollDebt.tsx, Amount.tsx, and Swaps.tsx now directly consume the request property from the refactored useSimulateProposal hook, simplifying their integration and reducing boilerplate.
  • Dynamic CrossRepayAtMaturity Encoding: The CrossRepayAtMaturity proposal data encoding in useSimulateProposal now conditionally includes the marketOut parameter based on the plugin's version, ensuring compatibility with different plugin versions and supporting new features.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist
Copy link
Copy Markdown

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

@sentry
Copy link
Copy Markdown

sentry bot commented Mar 24, 2026

Codecov Report

❌ Patch coverage is 79.48718% with 24 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.60%. Comparing base (d62c2a3) to head (ce222ba).
⚠️ Report is 4 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/utils/useSimulateProposal.ts 75.82% 22 Missing ⚠️
contracts/script/ExaAccountFactory.s.sol 0.00% 1 Missing ⚠️
src/components/pay/Repay.tsx 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #907      +/-   ##
==========================================
+ Coverage   71.46%   71.60%   +0.14%     
==========================================
  Files         225      226       +1     
  Lines        8165     8199      +34     
  Branches     2605     2634      +29     
==========================================
+ Hits         5835     5871      +36     
+ Misses       2103     2101       -2     
  Partials      227      227              
Flag Coverage Δ
e2e 71.59% <79.48%> (+0.14%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cruzdanilo
Copy link
Copy Markdown
Member Author

/gemini review

gemini-code-assist[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

sentry[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 7 additional findings in Devin Review.

Open in Devin Review

coderabbitai[bot]

This comment was marked as resolved.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (2)
src/utils/useSimulateProposal.ts (1)

117-131: ⚠️ Potential issue | 🟡 Minor

Use semver comparison instead of string comparison for version checks.

String comparison for versions like pluginMetadata.version < "0.0.4" will fail for multi-digit components (e.g., "0.0.10" would incorrectly compare as less than "0.0.4"). The semver library is available in the project.

🛡️ Proposed fix using semver
+import semver from "semver";
+
 // At line 101
-marketOut: pluginMetadata.version >= "1.1.0" ? proposal.marketOut : undefined,
+marketOut: semver.gte(pluginMetadata.version, "1.1.0") ? proposal.marketOut : undefined,

 // At lines 117-119
-proposal.proposalType === ProposalType.Withdraw &&
-    pluginMetadata?.version !== undefined &&
-    pluginMetadata.version < "0.0.4"
+proposal.proposalType === ProposalType.Withdraw &&
+    pluginMetadata?.version !== undefined &&
+    semver.lt(pluginMetadata.version, "0.0.4")
.changeset/bold-ram-dig.md (1)

1-5: 🧹 Nitpick | 🔵 Trivial

Consider making this changeset empty or user-facing.

This describes internal API refactoring ("flatten simulate-proposal api") that users won't notice. Either convert to an empty changeset (just --- separators) or reframe as user-facing benefit (e.g., "♻️ improve proposal transaction reliability").


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: cf290269-3c8d-490a-b190-f02071af9662

📥 Commits

Reviewing files that changed from the base of the PR and between 2702ae1 and ce222ba.

📒 Files selected for processing (7)
  • .changeset/bold-ram-dig.md
  • cspell.json
  • src/components/pay/Repay.tsx
  • src/components/roll-debt/RollDebt.tsx
  • src/components/send-funds/Amount.tsx
  • src/components/swaps/Swaps.tsx
  • src/utils/useSimulateProposal.ts

@cruzdanilo cruzdanilo merged commit ce222ba into main Mar 25, 2026
16 checks passed
@cruzdanilo cruzdanilo deleted the sim branch March 25, 2026 02:46
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.

1 participant