@morpho-org/evm-simulation 5.0.1 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +6 -4
  2. package/lib/cjs/errors.d.ts +17 -2
  3. package/lib/cjs/errors.js +19 -3
  4. package/lib/cjs/index.d.ts +2 -2
  5. package/lib/cjs/index.js +2 -1
  6. package/lib/cjs/params.d.ts +20 -1
  7. package/lib/cjs/requirements/requirements.js +2 -1
  8. package/lib/cjs/simulate/backends/eth-simulate-v1.d.ts +26 -34
  9. package/lib/cjs/simulate/backends/eth-simulate-v1.js +35 -74
  10. package/lib/cjs/simulate/backends/index.d.ts +1 -1
  11. package/lib/cjs/simulate/backends/index.js +1 -2
  12. package/lib/cjs/simulate/backends/parse-response.d.ts +1 -0
  13. package/lib/cjs/simulate/backends/parse-response.js +4 -2
  14. package/lib/cjs/simulate/backends/resolve-pinned-block.d.ts +6 -12
  15. package/lib/cjs/simulate/backends/resolve-pinned-block.js +3 -4
  16. package/lib/cjs/simulate/pipeline/bundles-retention.d.ts +3 -3
  17. package/lib/cjs/simulate/pipeline/bundles-retention.js +6 -6
  18. package/lib/cjs/simulate/pipeline/resolve-chain.d.ts +5 -1
  19. package/lib/cjs/simulate/pipeline/resolve-chain.js +12 -1
  20. package/lib/cjs/simulate/request/parse-request.d.ts +2 -1
  21. package/lib/cjs/simulate/request/parse-request.js +21 -0
  22. package/lib/cjs/simulate/run-simulation.js +9 -12
  23. package/lib/cjs/simulate/simulate.d.ts +30 -19
  24. package/lib/cjs/simulate/simulate.js +30 -19
  25. package/lib/cjs/types.d.ts +15 -0
  26. package/lib/esm/errors.d.ts +17 -2
  27. package/lib/esm/errors.js +17 -2
  28. package/lib/esm/index.d.ts +2 -2
  29. package/lib/esm/index.js +1 -1
  30. package/lib/esm/params.d.ts +20 -1
  31. package/lib/esm/requirements/requirements.js +2 -1
  32. package/lib/esm/simulate/backends/eth-simulate-v1.d.ts +26 -34
  33. package/lib/esm/simulate/backends/eth-simulate-v1.js +37 -75
  34. package/lib/esm/simulate/backends/index.d.ts +1 -1
  35. package/lib/esm/simulate/backends/index.js +1 -1
  36. package/lib/esm/simulate/backends/parse-response.d.ts +1 -0
  37. package/lib/esm/simulate/backends/parse-response.js +4 -2
  38. package/lib/esm/simulate/backends/resolve-pinned-block.d.ts +6 -12
  39. package/lib/esm/simulate/backends/resolve-pinned-block.js +3 -4
  40. package/lib/esm/simulate/pipeline/bundles-retention.d.ts +3 -3
  41. package/lib/esm/simulate/pipeline/bundles-retention.js +6 -6
  42. package/lib/esm/simulate/pipeline/resolve-chain.d.ts +5 -1
  43. package/lib/esm/simulate/pipeline/resolve-chain.js +13 -2
  44. package/lib/esm/simulate/request/parse-request.d.ts +2 -1
  45. package/lib/esm/simulate/request/parse-request.js +21 -0
  46. package/lib/esm/simulate/run-simulation.js +10 -13
  47. package/lib/esm/simulate/simulate.d.ts +30 -19
  48. package/lib/esm/simulate/simulate.js +30 -19
  49. package/lib/esm/types.d.ts +15 -0
  50. package/package.json +4 -4
@@ -4,11 +4,11 @@ import type { SimulationConfig } from "../types.js";
4
4
  /**
5
5
  * Simulate a bundle of EVM transactions.
6
6
  *
7
- * Parses and normalizes the request → resolves the chain identity → resolves
8
- * a single pinned block → resolves quoted-asset metadata → plans state reads
9
- * and the execution → executes once through `eth_simulateV1` under the full
10
- * timeout budget (simulation with in-block state reads → response parsing →
11
- * reorg check) → derives ERC20/WETH9 transfers and net asset changes from the
7
+ * Parses and normalizes the request → resolves a single pinned block (skipped
8
+ * when `params.block` is supplied) → resolves quoted-asset metadata → plans
9
+ * state reads and the execution → executes once through `eth_simulateV1` under
10
+ * the full timeout budget (simulation with in-block state reads → response
11
+ * parsing) → derives ERC20/WETH9 transfers and net asset changes from the
12
12
  * user calls only → decodes quoted balances/positions → runs slippage checks
13
13
  * → asserts no funds are retained by standalone `bundles` periphery contracts
14
14
  * → returns the result. The caller reads whichever fields they need:
@@ -37,10 +37,13 @@ import type { SimulationConfig } from "../types.js";
37
37
  * separating gas from economic effects. Monad nodes reject `false`, so Monad
38
38
  * simulations send `true`; its simulated block charges no gas either way.
39
39
  *
40
- * @param config - Required per-chain `eth_simulateV1` URL, optional logger, and
41
- * the overall timeout budget.
40
+ * @param config - Required per-chain `eth_simulateV1` URL, optional per-chain
41
+ * `blockOverrides.gasLimit` and `parentHashCheck`, optional logger, and the
42
+ * overall timeout budget.
42
43
  * @param params - Per-call simulation input.
43
- * @param params.chainId - Chain id the bundle targets; must match the endpoint.
44
+ * @param params.chainId - Chain id the bundle targets. Sent on every call inside
45
+ * `eth_simulateV1`, so nodes that check it reject a wrong-chain endpoint;
46
+ * there is no separate `eth_chainId` lookup.
44
47
  * @param params.transactions - The bundle's transactions, in execution order.
45
48
  * All must share the same `from`.
46
49
  * @param params.mode - `"final"` (default) or `"preview"`.
@@ -50,9 +53,16 @@ import type { SimulationConfig } from "../types.js";
50
53
  * than `"pending"`.
51
54
  * Defaults to `latest` (`finalized` on Monad, whose `latest` block is not
52
55
  * final), resolved exactly once.
56
+ * @param params.block - Optional caller-supplied state block (`number`,
57
+ * `hash`, `timestamp`). Skips the block lookup, so a simulation without
58
+ * asset metadata reads makes a single `eth_simulateV1` request. Cannot be
59
+ * combined with `blockNumber`.
53
60
  * @throws {SimulationValidationError} for invalid input (mixed senders, bad
54
61
  * addresses, empty transactions, malformed authorizations, final-mode
55
- * authorizations, malformed limits, unknown fields, a `"pending"` block tag, or share quotes for
62
+ * authorizations, malformed limits, unknown fields, a `"pending"` block tag,
63
+ * a malformed `block` or one combined with `blockNumber`, a
64
+ * `blockOverrides.gasLimit` that is not a positive bigint, a `parentHashCheck`
65
+ * that is not a boolean, or share quotes for
56
66
  * `blueSupplyCollateral` / `blueWithdrawCollateral`).
57
67
  * @throws {ConsumerLimitViolationError} when a declared `limits` bound is
58
68
  * violated by the observed effects.
@@ -66,20 +76,21 @@ import type { SimulationConfig } from "../types.js";
66
76
  * @throws {InvalidSimulationResponseError} when the node response cannot be
67
77
  * trusted (bad shape, call-count mismatch, block that is neither the pinned
68
78
  * state block nor its immediate successor, a successor with a mismatched
69
- * `parentHash`, a block timestamp earlier than the pinned block's, a
70
- * malformed per-call result, a quoted balance/position read whose non-empty
71
- * return data cannot be decoded, a state-block hash that changed or a pinned
72
- * block that vanished mid-flight, or an
73
- * endpoint whose `eth_chainId` differs from `params.chainId`; chain identity
74
- * is checked before any block lookup).
79
+ * `parentHash` (unless `parentHashCheck` is off; off by default on Stable,
80
+ * chain 988), a block timestamp earlier than the pinned block's, a
81
+ * malformed per-call result, or a quoted balance/position read whose
82
+ * non-empty return data cannot be decoded).
83
+ * @throws {InvalidChainIdError} when the node rejects the request `chainId`
84
+ * because the endpoint serves another chain (a subclass of
85
+ * `InvalidSimulationResponseError` sharing its `name`/`code`;
86
+ * `instanceof InvalidChainIdError` tells them apart). Never bypassable.
75
87
  * @throws {BlacklistViolationError} when the simulation leaves value retained
76
88
  * beyond the dust threshold by a `bundles` periphery contract
77
- * (VaultExitBundlesV1, VaultBundlesV1, BlueBundlesV1, MidnightBundlesV1).
89
+ * (VaultExitBundlesV1, VaultBundlesV1, BlueBundlesV1, MidnightBundlesV2).
78
90
  * Never bypassable.
79
91
  * @throws {ExternalServiceError} when the RPC is unavailable within the
80
- * timeout budget or returns a malformed JSON-RPC envelope. Chain-id
81
- * mismatches and a state block without number/hash are reported as
82
- * `InvalidSimulationResponseError`.
92
+ * timeout budget or returns a malformed JSON-RPC envelope. A looked-up state
93
+ * block without number/hash is reported as `InvalidSimulationResponseError`.
83
94
  * @returns A frozen {@link VerifiedSimulationResult} carrying the normalized
84
95
  * `simulationTxs`, per-tx `calls` (aligned 1:1), parsed `transfers` (each
85
96
  * stamped with `txIdx`), per-account net `assetChanges`, and per-operation
@@ -3,11 +3,11 @@ import { runSimulation } from "./run-simulation.js";
3
3
  /**
4
4
  * Simulate a bundle of EVM transactions.
5
5
  *
6
- * Parses and normalizes the request → resolves the chain identity → resolves
7
- * a single pinned block → resolves quoted-asset metadata → plans state reads
8
- * and the execution → executes once through `eth_simulateV1` under the full
9
- * timeout budget (simulation with in-block state reads → response parsing →
10
- * reorg check) → derives ERC20/WETH9 transfers and net asset changes from the
6
+ * Parses and normalizes the request → resolves a single pinned block (skipped
7
+ * when `params.block` is supplied) → resolves quoted-asset metadata → plans
8
+ * state reads and the execution → executes once through `eth_simulateV1` under
9
+ * the full timeout budget (simulation with in-block state reads → response
10
+ * parsing) → derives ERC20/WETH9 transfers and net asset changes from the
11
11
  * user calls only → decodes quoted balances/positions → runs slippage checks
12
12
  * → asserts no funds are retained by standalone `bundles` periphery contracts
13
13
  * → returns the result. The caller reads whichever fields they need:
@@ -36,10 +36,13 @@ import { runSimulation } from "./run-simulation.js";
36
36
  * separating gas from economic effects. Monad nodes reject `false`, so Monad
37
37
  * simulations send `true`; its simulated block charges no gas either way.
38
38
  *
39
- * @param config - Required per-chain `eth_simulateV1` URL, optional logger, and
40
- * the overall timeout budget.
39
+ * @param config - Required per-chain `eth_simulateV1` URL, optional per-chain
40
+ * `blockOverrides.gasLimit` and `parentHashCheck`, optional logger, and the
41
+ * overall timeout budget.
41
42
  * @param params - Per-call simulation input.
42
- * @param params.chainId - Chain id the bundle targets; must match the endpoint.
43
+ * @param params.chainId - Chain id the bundle targets. Sent on every call inside
44
+ * `eth_simulateV1`, so nodes that check it reject a wrong-chain endpoint;
45
+ * there is no separate `eth_chainId` lookup.
43
46
  * @param params.transactions - The bundle's transactions, in execution order.
44
47
  * All must share the same `from`.
45
48
  * @param params.mode - `"final"` (default) or `"preview"`.
@@ -49,9 +52,16 @@ import { runSimulation } from "./run-simulation.js";
49
52
  * than `"pending"`.
50
53
  * Defaults to `latest` (`finalized` on Monad, whose `latest` block is not
51
54
  * final), resolved exactly once.
55
+ * @param params.block - Optional caller-supplied state block (`number`,
56
+ * `hash`, `timestamp`). Skips the block lookup, so a simulation without
57
+ * asset metadata reads makes a single `eth_simulateV1` request. Cannot be
58
+ * combined with `blockNumber`.
52
59
  * @throws {SimulationValidationError} for invalid input (mixed senders, bad
53
60
  * addresses, empty transactions, malformed authorizations, final-mode
54
- * authorizations, malformed limits, unknown fields, a `"pending"` block tag, or share quotes for
61
+ * authorizations, malformed limits, unknown fields, a `"pending"` block tag,
62
+ * a malformed `block` or one combined with `blockNumber`, a
63
+ * `blockOverrides.gasLimit` that is not a positive bigint, a `parentHashCheck`
64
+ * that is not a boolean, or share quotes for
55
65
  * `blueSupplyCollateral` / `blueWithdrawCollateral`).
56
66
  * @throws {ConsumerLimitViolationError} when a declared `limits` bound is
57
67
  * violated by the observed effects.
@@ -65,20 +75,21 @@ import { runSimulation } from "./run-simulation.js";
65
75
  * @throws {InvalidSimulationResponseError} when the node response cannot be
66
76
  * trusted (bad shape, call-count mismatch, block that is neither the pinned
67
77
  * state block nor its immediate successor, a successor with a mismatched
68
- * `parentHash`, a block timestamp earlier than the pinned block's, a
69
- * malformed per-call result, a quoted balance/position read whose non-empty
70
- * return data cannot be decoded, a state-block hash that changed or a pinned
71
- * block that vanished mid-flight, or an
72
- * endpoint whose `eth_chainId` differs from `params.chainId`; chain identity
73
- * is checked before any block lookup).
78
+ * `parentHash` (unless `parentHashCheck` is off; off by default on Stable,
79
+ * chain 988), a block timestamp earlier than the pinned block's, a
80
+ * malformed per-call result, or a quoted balance/position read whose
81
+ * non-empty return data cannot be decoded).
82
+ * @throws {InvalidChainIdError} when the node rejects the request `chainId`
83
+ * because the endpoint serves another chain (a subclass of
84
+ * `InvalidSimulationResponseError` sharing its `name`/`code`;
85
+ * `instanceof InvalidChainIdError` tells them apart). Never bypassable.
74
86
  * @throws {BlacklistViolationError} when the simulation leaves value retained
75
87
  * beyond the dust threshold by a `bundles` periphery contract
76
- * (VaultExitBundlesV1, VaultBundlesV1, BlueBundlesV1, MidnightBundlesV1).
88
+ * (VaultExitBundlesV1, VaultBundlesV1, BlueBundlesV1, MidnightBundlesV2).
77
89
  * Never bypassable.
78
90
  * @throws {ExternalServiceError} when the RPC is unavailable within the
79
- * timeout budget or returns a malformed JSON-RPC envelope. Chain-id
80
- * mismatches and a state block without number/hash are reported as
81
- * `InvalidSimulationResponseError`.
91
+ * timeout budget or returns a malformed JSON-RPC envelope. A looked-up state
92
+ * block without number/hash is reported as `InvalidSimulationResponseError`.
82
93
  * @returns A frozen {@link VerifiedSimulationResult} carrying the normalized
83
94
  * `simulationTxs`, per-tx `calls` (aligned 1:1), parsed `transfers` (each
84
95
  * stamped with `txIdx`), per-account net `assetChanges`, and per-operation
@@ -3,6 +3,21 @@ import type { Address, Hex } from "viem";
3
3
  export interface ChainSimulationConfig {
4
4
  /** JSON-RPC URL supporting `eth_simulateV1`. Required for every configured chain. */
5
5
  readonly simulateV1Url: string;
6
+ /**
7
+ * Block overrides forwarded to `eth_simulateV1` as the simulated block's
8
+ * `blockOverrides`. Omitted fields leave the node's defaults untouched.
9
+ */
10
+ readonly blockOverrides?: {
11
+ /** Gas limit of the simulated block. Omitted: no gas limit override is sent. */
12
+ readonly gasLimit?: bigint;
13
+ };
14
+ /**
15
+ * Whether a simulated successor block's `parentHash` must equal the pinned
16
+ * state block hash. Block number and timestamp checks always run.
17
+ * Omitted: on everywhere except Stable (988), whose nodes report a
18
+ * `parentHash` that never matches the pinned block.
19
+ */
20
+ readonly parentHashCheck?: boolean;
6
21
  }
7
22
  /**
8
23
  * Top-level configuration for `simulate`.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@morpho-org/evm-simulation",
3
3
  "description": "EVM simulation engine for Morpho transactions.",
4
- "version": "5.0.1",
4
+ "version": "6.0.0",
5
5
  "author": "Morpho Association <contact@morpho.org>",
6
6
  "repository": {
7
7
  "type": "git",
@@ -21,9 +21,9 @@
21
21
  "lib"
22
22
  ],
23
23
  "dependencies": {
24
- "@morpho-org/blue-sdk": "^7.2.0",
25
- "@morpho-org/morpho-sdk": "^6.6.0",
26
- "@morpho-org/morpho-ts": "^3.2.1"
24
+ "@morpho-org/blue-sdk": "^8.0.0",
25
+ "@morpho-org/morpho-sdk": "^7.0.0",
26
+ "@morpho-org/morpho-ts": "^4.0.0"
27
27
  },
28
28
  "peerDependencies": {
29
29
  "viem": "^2.0.0"