Skip to content

Commit 845f1b9

Browse files
Merge remote-tracking branch 'origin/main' into fix-2908-signer-context-columns
# Conflicts: # crates/test_fixtures/abis/RaindexV6.json # src/generated/candidate/GenericPoolRaindexV6ArbOrderTaker.sol # src/generated/candidate/GenericPoolRaindexV6FlashBorrower.sol # src/generated/candidate/RaindexV6.sol # src/generated/candidate/RouteProcessorRaindexV6ArbOrderTaker.sol
2 parents 8f06d3a + ae02ea5 commit 845f1b9

48 files changed

Lines changed: 896 additions & 506 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gas-snapshot‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ RaindexV6EnactTest:testRaindexEvalWriteStateDifferentOwnersNamespaced(address,ad
158158
RaindexV6EnactTest:testRaindexEvalWriteStateSequential() (gas: 556418)
159159
RaindexV6EnactTest:testRaindexEvalWriteStateSingle(address) (runs: 100, μ: 189480, ~: 189555)
160160
RaindexV6FlashBorrowerBadInitiatorTest:testOnFlashLoanBadInitiator(address) (runs: 5096, μ: 11005, ~: 11005)
161-
RaindexV6FlashBorrowerBadLenderApprovalTest:testBadLenderRevertsWithApproval() (gas: 4383922)
162161
RaindexV6FlashBorrowerFallbackTest:testFallbackAcceptsCalldata() (gas: 3149)
163162
RaindexV6FlashBorrowerFallbackTest:testFallbackAcceptsETHWithCalldata() (gas: 12730)
164163
RaindexV6FlashBorrowerFallbackTest:testFallbackAcceptsEmptyCalldata() (gas: 3113)

‎CLAUDE.md‎

Lines changed: 29 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ Read and follow @AGENTS.md.
22

33
# Merge / Publish / Deploy runbook
44

5-
Contract change chain: edit source → **deploy** the new bytecode to its new
6-
CREATE2 address → **merge**. Publishing to soldeer is a separate manual tag
7-
release (below), never a side effect of merging. All of it is routine and
8-
pre-authorized; don't stop to ask about address/codehash churn.
5+
Deploy repo: a source change regenerates `src/generated/candidate/` and merges
6+
without deploying. Deploying and publishing happen together at a release
7+
(below). `LibRaindexDeploy` is the candidate. The start-block, `networks.json`
8+
and `subgraph.yaml` tests read the released RaindexV6 from the newest entry of
9+
the generated `LibRaindexV6Released`. Address/codehash churn is routine; don't
10+
stop to ask about it.
911

1012
## Merging a PR
1113

@@ -28,41 +30,29 @@ pre-authorized; don't stop to ask about address/codehash churn.
2830
workflow re-runs and history rewrites are hook-blocked — these are the allowed
2931
equivalents; don't spell the blocked forms out or you'll trip those hooks.)
3032

31-
## Deploying a contract (the bytecode cascade)
33+
## Source changes
3234

33-
Any source change to a CREATE2/zoltu-deployed contract moves its on-chain
34-
address + codehash. Do the whole cascade without asking:
35+
Regenerate artifacts — run the `rainix-copy-artifacts` step sequence (see that
36+
workflow) in `nix develop github:rainlanguage/rainix#sol-shell`. Stage ALL
37+
changed artifacts or `git-clean` drifts red. Nothing is deployed.
3538

36-
1. Regenerate artifacts — run the `rainix-copy-artifacts` step sequence (see
37-
that workflow) in `nix develop github:rainlanguage/rainix#sol-shell`. Stage
38-
ALL changed artifacts or `git-clean` drifts red.
39-
2. Deploy each changed suite:
40-
`gh workflow run manual-sol-artifacts.yaml --ref <branch> -f suite=<x>`. One
41-
dispatch deploys all seven chains. **Never run two deploys concurrently** —
42-
they share one deployer EOA and race the nonce, leaving a partial deploy;
43-
serialize dispatches. A `completed/failure` run still deployed if the log has
44-
`ONCHAIN EXECUTION COMPLETE & SUCCESSFUL` — only etherscan `--verify` failed
45-
(cosmetic).
46-
3. If RaindexV6 moved, run `script/build-start-blocks.sh` — rewrites the
47-
`RAINDEX_START_BLOCK_*` constants, `subgraph/networks.json` and
48-
`subgraph/subgraph.yaml` (else `testIsStartBlock*` / `testNetworksJson*` /
49-
`testSubgraphYamlAddress` red). Uses foundry `rpc_endpoints` env vars,
50-
falling back to public archive RPCs.
51-
4. `testProdDeploy*` fork tests stay red until the new addresses have code
52-
on-chain; re-trigger PR CI with an empty commit after deploying.
53-
54-
## Publishing to soldeer (tag release)
39+
## Releasing (deploy + publish)
5540

56-
- Manual tag release via rainix `rainix-tag-release.yaml@main`
57-
(`package-release.yaml`, `sol-v*` tags). Merges to main do NOT publish.
58-
- To cut a release: deploy changed suites first, then one PR that runs
59-
`forge script ./script/Build.sol --sig 'cutRelease()'` — freezing the
60-
candidate pins as `src/generated/<tag>/` — and bumps
61-
`foundry.toml [external.package].version` to match. Merge, then push tag
62-
`sol-v<version>`.
63-
- The tag re-runs the fork suite and `release-guard` (version == tag, frozen dir
64-
present and byte-identical to `candidate/`, clean tree after regeneration, no
65-
later tag frozen), then publishes `raindex~<version>` and cuts the GitHub
66-
release.
67-
- `src/generated/<tag>/` snapshots are append-only — the
68-
`frozen-snapshots-append-only` gate reds any PR that edits or deletes one.
41+
1. Deploy each changed suite:
42+
`gh workflow run manual-sol-artifacts.yaml --ref main -f suite=<x>`. One
43+
dispatch deploys all seven chains. **Never run two deploys concurrently** —
44+
they share one deployer EOA and race the nonce; serialize dispatches. A
45+
`completed/failure` run still deployed if the log has
46+
`ONCHAIN EXECUTION COMPLETE & SUCCESSFUL` (only `--verify` failed).
47+
2. One PR: bump `foundry.toml [external.package].version`, run
48+
`forge script ./script/Build.sol --sig 'cutRelease()'` (freezes `candidate/`
49+
as `src/generated/<tag>/`), and if RaindexV6 moved run
50+
`script/build-start-blocks.sh` (`LibRaindexV6StartBlock`, `networks.json`,
51+
`subgraph.yaml`).
52+
3. Merge, then push tag `sol-v<version>`. Via rainix `rainix-tag-release.yaml`
53+
(`package-release.yaml`) it re-runs the fork suite and `release-guard`
54+
(version == tag, frozen dir byte-identical to `candidate/`, clean tree, no
55+
later tag frozen), then publishes `raindex-deploy~<version>`.
56+
57+
`src/generated/<tag>/` snapshots are append-only — the
58+
`frozen-snapshots-append-only` gate reds any PR that edits or deletes one.

‎crates/test_fixtures/abis/RaindexV6.json‎

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

‎foundry.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# `release-guard` checks it against the pushed `sol-v<version>` tag before
1212
# anything publishes.
1313
[external.package]
14-
name = "raindex"
14+
name = "raindex-deploy"
1515
version = "0.1.15"
1616

1717
[profile.default]

‎script/build-start-blocks.sh‎

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
# SPDX-License-Identifier: LicenseRef-DCL-1.0
33
# SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd
44

5-
# Refresh the RaindexV6 deploy-block bookkeeping after a redeploy.
5+
# Refresh the RaindexV6 deploy-block bookkeeping after a release.
66
#
7-
# Finds the exact block at which the currently-pinned RaindexV6 was deployed on
8-
# each mainnet by binary-searching `eth_getCode` over an archive RPC, then
9-
# rewrites the new per-chain blocks + the current pinned address into:
10-
# - the RAINDEX_START_BLOCK_* constants in src/lib/deploy/LibRaindexDeploy.sol
7+
# Finds the exact block at which the newest released RaindexV6 (the last entry
8+
# of LibRaindexV6Released) was deployed on each mainnet by binary-searching
9+
# `eth_getCode` over an archive RPC, then rewrites the new per-chain blocks +
10+
# that address into:
11+
# - the RAINDEX_START_BLOCK_* constants in src/lib/deploy/LibRaindexV6StartBlock.sol
1112
# - subgraph/networks.json (address + startBlock per network)
1213
# - subgraph/subgraph.yaml (data source address)
1314
#
@@ -19,10 +20,14 @@
1920
# tests.
2021
set -euo pipefail
2122

22-
LIB="src/lib/deploy/LibRaindexDeploy.sol"
23+
LIB="src/lib/deploy/LibRaindexV6StartBlock.sol"
24+
RELEASED="src/lib/LibRaindexV6Released.sol"
2325
NET="subgraph/networks.json"
2426
YAML="subgraph/subgraph.yaml"
25-
PTR="src/generated/candidate/RaindexV6.sol"
27+
TAG=$(grep -aoE 'storedDeployedAddress: RaindexV6_[A-Za-z0-9_]+_DEPLOYED_ADDRESS' "$RELEASED" | tail -1 \
28+
| sed -E 's/.*RaindexV6_(.+)_DEPLOYED_ADDRESS/\1/' || true)
29+
PTR="src/generated/${TAG}/RaindexV6.sol"
30+
[ -n "$TAG" ] && [ -f "$PTR" ] || { echo "could not read the newest released RaindexV6 snapshot from $RELEASED" >&2; exit 1; }
2631

2732
ARB_RPC="${ARBITRUM_RPC_URL:-https://arbitrum.drpc.org}"
2833
BASE_RPC="${BASE_RPC_URL:-https://mainnet.base.org}"

‎src/abstract/RaindexDeploySuites.sol‎

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ import {
1515
DEPLOYED_ADDRESS as TOFU_DECIMALS_ADDRESS,
1616
RUNTIME_CODE as TOFU_DECIMALS_RUNTIME_CODE
1717
} from "rain-tofu-erc20-decimals-deploy-0.1.3/src/generated/0_1_0/TOFUTokenDecimals.sol";
18-
import {
19-
DEPLOYED_ADDRESS as META_BOARD_ADDRESS,
20-
RUNTIME_CODE as META_BOARD_RUNTIME_CODE
21-
} from "rain-metadata-deploy-0.1.3/src/generated/0_1_1/MetaBoard.sol";
2218
import {
2319
CREATION_CODE as RAINDEX_CREATION_CODE_CANDIDATE,
2420
RUNTIME_CODE as RAINDEX_RUNTIME_CODE_CANDIDATE
@@ -73,14 +69,52 @@ abstract contract RaindexDeploySuites is RainDeploySuitesBase {
7369
return candidates;
7470
}
7571

76-
/// The code that must already be on a network before `RaindexV6` or
77-
/// `RaindexV6SubParser` can be broadcast there: the TOFU decimals reader
78-
/// and the metaboard.
72+
/// The TOFU decimals reader, which `RaindexV6` and every arb read token
73+
/// decimals through.
74+
/// @return The dependency.
75+
function tofuDecimalsDependency() internal pure returns (DeployDependency memory) {
76+
return DeployDependency({deployedAddress: TOFU_DECIMALS_ADDRESS, runtimeCode: TOFU_DECIMALS_RUNTIME_CODE});
77+
}
78+
79+
/// The candidate `RaindexV6`, the only raindex every arb accepts.
80+
/// @return The dependency.
81+
function raindexDependency() internal pure returns (DeployDependency memory) {
82+
return DeployDependency({
83+
deployedAddress: LibRaindexDeploy.RAINDEX_DEPLOYED_ADDRESS, runtimeCode: RAINDEX_RUNTIME_CODE_CANDIDATE
84+
});
85+
}
86+
87+
/// The code that must already be on a network before an arb can be
88+
/// broadcast there: the raindex it takes orders from and the TOFU
89+
/// decimals reader.
7990
/// @return The dependencies.
80-
function raindexDependencies() internal pure returns (DeployDependency[] memory) {
91+
function arbDependencies() internal pure returns (DeployDependency[] memory) {
8192
DeployDependency[] memory deps = new DeployDependency[](2);
82-
deps[0] = DeployDependency({deployedAddress: TOFU_DECIMALS_ADDRESS, runtimeCode: TOFU_DECIMALS_RUNTIME_CODE});
83-
deps[1] = DeployDependency({deployedAddress: META_BOARD_ADDRESS, runtimeCode: META_BOARD_RUNTIME_CODE});
93+
deps[0] = raindexDependency();
94+
deps[1] = tofuDecimalsDependency();
95+
return deps;
96+
}
97+
98+
/// `arbDependencies` plus the `RouteProcessor4` candidate the arb swaps
99+
/// through.
100+
/// @return The dependencies.
101+
function routeProcessorArbDependencies() internal pure returns (DeployDependency[] memory) {
102+
DeployDependency[] memory deps = new DeployDependency[](3);
103+
deps[0] = raindexDependency();
104+
deps[1] = tofuDecimalsDependency();
105+
deps[2] = DeployDependency({
106+
deployedAddress: LibRaindexDeploy.ROUTE_PROCESSOR_DEPLOYED_ADDRESS,
107+
runtimeCode: ROUTE_PROCESSOR_RUNTIME_CODE_CANDIDATE
108+
});
109+
return deps;
110+
}
111+
112+
/// The code that must already be on a network before `RaindexV6` can be
113+
/// broadcast there: the TOFU decimals reader.
114+
/// @return The dependencies.
115+
function raindexDependencies() internal pure returns (DeployDependency[] memory) {
116+
DeployDependency[] memory deps = new DeployDependency[](1);
117+
deps[0] = tofuDecimalsDependency();
84118
return deps;
85119
}
86120

@@ -118,7 +152,7 @@ abstract contract RaindexDeploySuites is RainDeploySuitesBase {
118152
storedBytecodeHash: LibRaindexDeploy.SUB_PARSER_DEPLOYED_CODEHASH,
119153
storedRuntimeCode: SUB_PARSER_RUNTIME_CODE_CANDIDATE,
120154
artifactPath: "src/concrete/parser/RaindexV6SubParser.sol:RaindexV6SubParser",
121-
dependencies: raindexDependencies(),
155+
dependencies: new DeployDependency[](0),
122156
mechanism: DeployMechanism.Zoltu,
123157
mechanismData: ""
124158
}),
@@ -159,7 +193,7 @@ abstract contract RaindexDeploySuites is RainDeploySuitesBase {
159193
storedBytecodeHash: LibRaindexDeploy.GENERIC_POOL_ARB_ORDER_TAKER_DEPLOYED_CODEHASH,
160194
storedRuntimeCode: GENERIC_POOL_ARB_OT_RUNTIME_CODE_CANDIDATE,
161195
artifactPath: "src/concrete/arb/GenericPoolRaindexV6ArbOrderTaker.sol:GenericPoolRaindexV6ArbOrderTaker",
162-
dependencies: new DeployDependency[](0),
196+
dependencies: arbDependencies(),
163197
mechanism: DeployMechanism.Zoltu,
164198
mechanismData: ""
165199
}),
@@ -178,7 +212,7 @@ abstract contract RaindexDeploySuites is RainDeploySuitesBase {
178212
storedBytecodeHash: LibRaindexDeploy.ROUTE_PROCESSOR_ARB_ORDER_TAKER_DEPLOYED_CODEHASH,
179213
storedRuntimeCode: RP_ARB_OT_RUNTIME_CODE_CANDIDATE,
180214
artifactPath: "src/concrete/arb/RouteProcessorRaindexV6ArbOrderTaker.sol:RouteProcessorRaindexV6ArbOrderTaker",
181-
dependencies: new DeployDependency[](0),
215+
dependencies: routeProcessorArbDependencies(),
182216
mechanism: DeployMechanism.Zoltu,
183217
mechanismData: ""
184218
}),
@@ -197,7 +231,7 @@ abstract contract RaindexDeploySuites is RainDeploySuitesBase {
197231
storedBytecodeHash: LibRaindexDeploy.GENERIC_POOL_FLASH_BORROWER_DEPLOYED_CODEHASH,
198232
storedRuntimeCode: GENERIC_POOL_FB_RUNTIME_CODE_CANDIDATE,
199233
artifactPath: "src/concrete/arb/GenericPoolRaindexV6FlashBorrower.sol:GenericPoolRaindexV6FlashBorrower",
200-
dependencies: new DeployDependency[](0),
234+
dependencies: arbDependencies(),
201235
mechanism: DeployMechanism.Zoltu,
202236
mechanismData: ""
203237
}),

‎src/abstract/RaindexV6ArbCommon.sol‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ struct RaindexV6ArbConfig {
1212
/// Thrown when the task does not match the expected hash.
1313
error WrongTask();
1414

15+
/// Thrown when an arb is called with a `raindex` that is not the trusted
16+
/// deterministic deployment. The arb grants `raindex` an unlimited token
17+
/// approval and calls it, so an untrusted address could drain the contract's
18+
/// balance.
19+
/// @param badRaindex The untrusted `raindex` passed to the arb.
20+
error BadRaindex(address badRaindex);
21+
1522
/// @title RaindexV6ArbCommon
1623
/// @notice Common base for arb contracts that interact with `Raindex`.
1724
/// Provides a `_beforeArb` hook that is called at the start of every arb

‎src/abstract/RaindexV6ArbOrderTaker.sol‎

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,15 @@ import {IERC20, SafeERC20} from "@openzeppelin-contracts-5.7.0/token/ERC20/utils
88
import {IRaindexV6} from "raindex-interface-0.1.8/src/interface/IRaindexV6.sol";
99
import {IRaindexV6ArbOrderTaker, TaskV2} from "raindex-interface-0.1.8/src/interface/IRaindexV6ArbOrderTaker.sol";
1010
import {TakeOrdersConfigV5, Float} from "raindex-interface-0.1.8/src/interface/IRaindexV6.sol";
11-
import {RaindexV6ArbCommon} from "./RaindexV6ArbCommon.sol";
11+
import {RaindexV6ArbCommon, BadRaindex} from "./RaindexV6ArbCommon.sol";
1212
import {LibRaindexArb} from "../lib/LibRaindexArb.sol";
1313
import {LibRaindexDeploy} from "../lib/deploy/LibRaindexDeploy.sol";
1414
import {IRaindexV6OrderTaker} from "raindex-interface-0.1.8/src/interface/IRaindexV6OrderTaker.sol";
1515
import {LibTOFUTokenDecimals} from "rain-tofu-erc20-decimals-0.1.4/src/lib/LibTOFUTokenDecimals.sol";
1616

17-
/// Thrown when `arb5` is called with a `raindex` that is not the trusted
18-
/// deterministic deployment. `arb5` grants `raindex` an unlimited token approval
19-
/// and calls it, so an untrusted address could drain the contract's balance.
20-
error BadRaindex(address badRaindex);
17+
/// Thrown when `onTakeOrders2` is called during an arb by anything other than
18+
/// the trusted raindex.
19+
error UnexpectedOnTakeOrdersCaller(address caller);
2120

2221
/// @title RaindexV6ArbOrderTaker
2322
/// @notice Arb contract that takes orders directly from a `Raindex` without
@@ -75,19 +74,24 @@ abstract contract RaindexV6ArbOrderTaker is
7574
}
7675

7776
/// @inheritdoc IRaindexV6OrderTaker
78-
/// @dev Empty no-op, and intentionally permissionless: the contract holds no
79-
/// value between operations, so there is nothing to protect via `msg.sender`
80-
/// validation.
77+
/// @dev While `arb5` is in flight only the trusted raindex may call this;
78+
/// any other caller reverts with `UnexpectedOnTakeOrdersCaller`. During an
79+
/// arb the contract holds the caller's `msg.value` and tokens, and
80+
/// `takeOrders4` runs order-owner-chosen code (e.g. the order's store) that
81+
/// could otherwise re-enter here and direct that value.
8182
///
82-
/// The permissionless entry is also the recovery path for value that reaches
83-
/// the contract by accident. Unsolicited transfers cannot be prevented: ERC20
84-
/// transfers have no recipient hook to revert in, and the arb legitimately
85-
/// receives ERC20 and ETH mid-operation. Because anyone may call the
86-
/// take-orders entrypoints, a stray balance is swept out by the next call
87-
/// rather than stranded; gating this hook to an active orderbook callback
88-
/// would instead brick such balances permanently. Concrete implementations
89-
/// that move value here (e.g. the generic-pool variant's unlimited
90-
/// approve-and-call with whole-ETH-balance forward) are safe only under this
91-
/// no-value-between-operations invariant.
92-
function onTakeOrders2(address, address, Float, Float, bytes calldata) public virtual override {}
83+
/// Outside an arb it is a permissionless no-op: the contract holds no value
84+
/// between operations, so there is nothing to protect. The permissionless
85+
/// entry is the recovery path for value that reaches the contract by
86+
/// accident. Unsolicited transfers cannot be prevented: ERC20 transfers have
87+
/// no recipient hook to revert in, and the arb legitimately receives ERC20
88+
/// and ETH mid-operation. A stray balance is swept out by the next call
89+
/// rather than stranded. Concrete implementations that move value here (e.g.
90+
/// the generic-pool variant's unlimited approve-and-call with whole-ETH-
91+
/// balance forward) rely on both properties.
92+
function onTakeOrders2(address, address, Float, Float, bytes calldata) public virtual override {
93+
if (_reentrancyGuardEntered() && msg.sender != LibRaindexDeploy.RAINDEX_DEPLOYED_ADDRESS) {
94+
revert UnexpectedOnTakeOrdersCaller(msg.sender);
95+
}
96+
}
9397
}

‎src/abstract/RaindexV6FlashBorrower.sol‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {ReentrancyGuard} from "@openzeppelin-contracts-5.7.0/utils/ReentrancyGua
99
import {ON_FLASH_LOAN_CALLBACK_SUCCESS} from "raindex-interface-0.1.8/src/interface/ierc3156/IERC3156FlashBorrower.sol";
1010
import {IRaindexV6, TakeOrdersConfigV5, TaskV2} from "raindex-interface-0.1.8/src/interface/IRaindexV6.sol";
1111
import {IERC3156FlashBorrower} from "raindex-interface-0.1.8/src/interface/ierc3156/IERC3156FlashBorrower.sol";
12-
import {RaindexV6ArbCommon} from "./RaindexV6ArbCommon.sol";
12+
import {RaindexV6ArbCommon, BadRaindex} from "./RaindexV6ArbCommon.sol";
1313
import {LibRaindexArb} from "../lib/LibRaindexArb.sol";
1414
import {LibRaindexDeploy} from "../lib/deploy/LibRaindexDeploy.sol";
1515
import {LibTOFUTokenDecimals} from "rain-tofu-erc20-decimals-0.1.4/src/lib/LibTOFUTokenDecimals.sol";
@@ -123,7 +123,8 @@ abstract contract RaindexV6FlashBorrower is IERC3156FlashBorrower, ReentrancyGua
123123
/// remaining assets are sent to the sender via `finalizeArb`.
124124
///
125125
/// @param raindex The `Raindex` contract to take orders from and flash
126-
/// loan against.
126+
/// loan against. MUST be the deterministic deployment, else reverts
127+
/// `BadRaindex`.
127128
/// @param takeOrders As per `IRaindexV6.takeOrders4`.
128129
/// @param exchangeData Arbitrary bytes that will be passed to `_exchange`
129130
/// after the flash loan is taken. The inheriting contract is responsible
@@ -142,6 +143,9 @@ abstract contract RaindexV6FlashBorrower is IERC3156FlashBorrower, ReentrancyGua
142143
if (takeOrders.orders.length == 0) {
143144
revert IRaindexV6.NoOrders();
144145
}
146+
if (address(raindex) != LibRaindexDeploy.RAINDEX_DEPLOYED_ADDRESS) {
147+
revert BadRaindex(address(raindex));
148+
}
145149
// The flash-loan amount below reads `minimumIO` as the order output the
146150
// taker receives, which only matches when `minimumIO` is the taker
147151
// input (`IOIsInput == true`).

0 commit comments

Comments
 (0)