Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@ tests run 2048 iterations.

### Interfaces (`src/interface/`)

- **IRaindexV6** — Current stable interface. Vault-based order book with
- **IRaindexV7** — Current stable interface. Vault-based order book with
deposit/withdraw, add/remove orders, take orders (market buy), and clear
(match two orders with bounty). IERC3156 flash loan compliant. Supports
vaultless orders (vault ID `0` means tokens move directly from wallet) and
input/output-based take order limits via `IOIsInput` flag.
- **IRaindexV6OrderTaker / IRaindexV6ArbOrderTaker** — Callback interfaces for
- **IRaindexV7OrderTaker / IRaindexV7ArbOrderTaker** — Callback interfaces for
takers receiving tokens during `takeOrders`.
- **ierc3156/** — Flash loan interfaces (IERC3156FlashLender,
IERC3156FlashBorrower).
- **deprecated/** (v1-v5) — Old interface versions. Do not modify unless
undeprecating.
- **deprecated/** (v1-v6) — Old interface versions. Only import paths may change
(relocation, dependency bumps); declarations are frozen unless undeprecating.

### Interface Lifecycle

Expand All @@ -63,8 +63,8 @@ move.
valid inputs/outputs, nonce
- `OrderConfigV4` — Config for adding an order, includes meta and secret
- `IOV2` — Input/output config: token address + vault ID
- `TaskV2` — Evaluable + signed context, for post-operation callbacks
- `TakeOrdersConfigV4` / `TakeOrdersConfigV5` — Config for batch taking orders
- `TaskV3` — Evaluable + `SignedContextV2`, for post-operation callbacks
- `TakeOrdersConfigV6` / `TakeOrderConfigV5` — Config for batch taking orders
- `ClearConfigV2` / `ClearStateChangeV2` — Config and result for clearing two
matched orders

Expand All @@ -85,8 +85,8 @@ declares everything `rainlang-interface`'s own src imports
string messages.
- Interfaces use `pragma solidity ^0.8.18` (note: differs from interpreter
interface which uses `^0.8.25`).
- Versioned naming: interfaces (`IRaindexV6`), structs (`OrderV4`,
`ClearConfigV2`), events (`AddOrderV3`), functions (`deposit4`, `withdraw4`).
- Versioned naming: interfaces (`IRaindexV7`), structs (`OrderV4`,
`ClearConfigV2`), events (`AddOrderV3`), functions (`deposit5`, `withdraw5`).
- Use `//forge-lint: disable-next-line(...)` comments for lint suppressions:
`unused-import`, `mixed-case-variable`, `pascal-case-struct`.
- Branch naming: `YYYY-MM-DD-description`.
Expand Down
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ evm_version = "cancun"

[dependencies]
forge-std = "1.17.0"
"rainlang-interface" = "0.2.13"
"rainlang-interface" = "0.2.14"
rain-math-float = "0.3.10"
"@openzeppelin-contracts" = "5.7.0"
rain-lib-hash = "0.1.27"
Expand Down
2 changes: 1 addition & 1 deletion remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ rain-math-binary-0.1.4/=dependencies/rain-math-binary-0.1.4/
rain-math-float-0.3.10/=dependencies/rain-math-float-0.3.10/
rain-sol-codegen-0.1.39/=dependencies/rain-sol-codegen-0.1.39/
rain-solmem-0.1.28/=dependencies/rain-solmem-0.1.28/
rainlang-interface-0.2.13/=dependencies/rainlang-interface-0.2.13/
rainlang-interface-0.2.14/=dependencies/rainlang-interface-0.2.14/
8 changes: 4 additions & 4 deletions soldeer.lock
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ integrity = "e7508cd81a998a67118a0fca314d504dc62850d6b535d29c824f696f214e4b23"

[[dependencies]]
name = "rainlang-interface"
version = "0.2.13"
url = "https://soldeer-revisions.s3.amazonaws.com/rainlang-interface/0_2_13_11-10-2026_17:54:59_rainlang.zip"
checksum = "8128d2d63ee9c0d83e0ec6f9a5501bdd6da5f21ce3b3374cde2e08eaa4ef1800"
integrity = "07282d9bb019083c64273e829fa4a37016b9c4ddc67578afc7d8e14e235cf021"
version = "0.2.14"
url = "https://soldeer-revisions.s3.amazonaws.com/rainlang-interface/0_2_14_26-10-2026_13:25:43_rainlang.zip"
checksum = "854b90ada2a8756d1c3292fa1272c5630fc0ebf48955bf18f60db9d48e4f210e"
integrity = "d3c5c2983c62b09c3dda643150a3a2a8533c0526fa530b1ded91be69ac64bda5"
218 changes: 218 additions & 0 deletions src/interface/IRaindexV7.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
// SPDX-License-Identifier: LicenseRef-DCL-1.0
// SPDX-FileCopyrightText: Copyright (c) 2020 thedavidmeister
pragma solidity ^0.8.18;

import {IERC3156FlashLender} from "./ierc3156/IERC3156FlashLender.sol";
import {
IInterpreterCallerV5,
SignedContextV2,
EvaluableV4,

//forge-lint: disable-next-line(unused-import)
IInterpreterV4,

//forge-lint: disable-next-line(unused-import)
IInterpreterStoreV3
} from "rainlang-interface-0.2.14/src/interface/IInterpreterCallerV5.sol";

import {
ClearStateChangeV2,
ClearConfigV2,

//forge-lint: disable-next-line(unused-import)
IOV2,
OrderConfigV4,
OrderV4
} from "./deprecated/v5/IOrderBookV5.sol";

import {Float} from "rain-math-float-0.3.10/src/lib/LibDecimalFloat.sol";

/// Evaluable run after the primary call, e.g. by governance wrappers or fee
/// collectors.
/// @param evaluable The evaluable logic to run as part of the task.
/// @param signedContext Signed context provided to the evaluable.
struct TaskV3 {
EvaluableV4 evaluable;
SignedContextV2[] signedContext;
}

/// @param order The order to take.
/// @param inputIOIndex Index of the order's input matched with the taker
/// output.
/// @param outputIOIndex Index of the order's output matched with the taker
/// input.
/// @param signedContext Signed context for the taken order's eval.
struct TakeOrderConfigV5 {
OrderV4 order;
//forge-lint: disable-next-line(mixed-case-variable)
uint256 inputIOIndex;
//forge-lint: disable-next-line(mixed-case-variable)
uint256 outputIOIndex;
SignedContextV2[] signedContext;
}

/// @param minimumIO Taker's minimum total input or output; reverts if unmet.
/// @param maximumIO Taker's maximum total input or output.
/// @param maximumIORatio Max IO ratio per order, from the order's perspective.
/// @param IOIsInput Whether `minimumIO`/`maximumIO` bound taker input or output.
/// @param orders Taken in sequence as given; no onchain sorting.
/// @param data If non-empty, `onTakeOrders2` is called on the taker with it.
struct TakeOrdersConfigV6 {
//forge-lint: disable-next-line(mixed-case-variable)
Float minimumIO;
//forge-lint: disable-next-line(mixed-case-variable)
Float maximumIO;
//forge-lint: disable-next-line(mixed-case-variable)
Float maximumIORatio;
//forge-lint: disable-next-line(mixed-case-variable)
bool IOIsInput;
TakeOrderConfigV5[] orders;
bytes data;
}

/// @param order The order to quote.
/// @param inputIOIndex Index of the order's input to quote.
/// @param outputIOIndex Index of the order's output to quote.
/// @param signedContext Signed context for the quoted order's eval.
struct QuoteV3 {
OrderV4 order;
//forge-lint: disable-next-line(mixed-case-variable)
uint256 inputIOIndex;
//forge-lint: disable-next-line(mixed-case-variable)
uint256 outputIOIndex;
SignedContextV2[] signedContext;
}

/// @title IRaindexV7
/// @notice Raindex is an order book of expression-defined orders over
/// per-owner, per-token vaults. Amounts and IO ratios (input:output) are
/// Floats, converted via the token's `decimals` only when tokens move; tokens
/// without constant `decimals` are unsupported. Clears move only internal vault
/// balances, except for vault `0` IO. Rounding favours the order.
/// REBASING, FEE-ON-TRANSFER AND OTHER DYNAMIC BALANCE TOKENS ARE NOT
/// SUPPORTED. Raindex ONLY WORKS IF TOKEN BALANCES ARE 1:1 WITH
/// ADDITION/SUBTRACTION PER VAULT MOVEMENT: vaults are credited the requested
/// amount, not the amount received, so a fee-on-transfer deposit credits more
/// than Raindex receives.
/// Orders stay live until removed. Expression storage is namespaced by order
/// owner. Interpreters and stores are untrusted. All vault balances are
/// available as zero-fee ERC3156 flash loans; `withdraw5` and `takeOrders5`
/// repay the caller's loan before sending tokens. Vault ID `0` denotes a
/// vaultless IO that moves tokens directly from or to the owner's wallet.
interface IRaindexV7 is IERC3156FlashLender, IInterpreterCallerV5 {
error ZeroVaultId(address sender, address token);

error ZeroDepositAmount(address sender, address token, bytes32 vaultId);

/// Zero requested amount; a nonzero request MAY still move nothing.
error ZeroWithdrawTargetAmount(address sender, address token, bytes32 vaultId);

error OrderNoSources();

error OrderNoHandleIO();

error OrderNoInputs();

error OrderNoOutputs();

error ZeroMaximumIO();

error NoOrders();

/// An order's input and output tokens are identical.
error TokenSelfTrade();

event DepositV2(address sender, address token, bytes32 vaultId, uint256 depositAmountUint256);

/// @param withdrawAmount MAY be less than `targetAmount`.
/// @param withdrawAmountUint256 Absolute tokens moved onchain.
event WithdrawV2(
address sender,
address token,
bytes32 vaultId,
Float targetAmount,
Float withdrawAmount,
uint256 withdrawAmountUint256
);

/// @param order Full order, to be passed back as-is to take or clear it.
event AddOrderV3(address sender, bytes32 orderHash, OrderV4 order);

event RemoveOrderV3(address sender, bytes32 orderHash, OrderV4 order);

/// One per order taken. `input`/`output` are from the taker's perspective.
event TakeOrderV4(address sender, TakeOrderConfigV5 config, Float input, Float output);

/// The order is skipped rather than reverting the batch.
event OrderNotFound(address sender, address owner, bytes32 orderHash);

/// The order is skipped rather than reverting the batch.
event OrderZeroAmount(address sender, address owner, bytes32 orderHash);

/// The order is skipped rather than reverting the batch.
event OrderExceedsMaxRatio(address sender, address owner, bytes32 orderHash);

/// The order's calculate eval reverted or returned too few outputs. The
/// order is skipped rather than reverting the batch.
event OrderCalculateReverted(address sender, address owner, bytes32 orderHash);

/// Emitted before calculation.
event ClearV3(address sender, OrderV4 alice, OrderV4 bob, ClearConfigV2 clearConfig);

event AfterClearV2(address sender, ClearStateChangeV2 clearStateChange);

function vaultBalance2(address owner, address token, bytes32 vaultId) external view returns (Float balance);

/// MUST NOT modify vault balances; reverts if any task reverts.
function entask3(TaskV3[] calldata tasks) external;

/// Deposits for `msg.sender`; no shares, balances are 1:1 with tokens.
/// Reverts `ZeroDepositAmount` on zero amount, `ZeroVaultId` on vault `0`,
/// or if any task reverts.
function deposit5(address token, bytes32 vaultId, Float depositAmount, TaskV3[] calldata tasks) external;

/// Withdraws up to `targetAmount`. Reverts `ZeroWithdrawTargetAmount` on
/// zero target, `ZeroVaultId` on vault `0`, or if any task reverts.
function withdraw5(address token, bytes32 vaultId, Float targetAmount, TaskV3[] calldata tasks) external;

function orderExists(bytes32 orderHash) external view returns (bool exists);

/// Evaluates the order with the caller as counterparty, ignoring the
/// caller's balances. Values are Floats, not absolute token amounts.
/// Reverts `TokenSelfTrade`. `outputMax` and `ioRatio` are `0` if the
/// order does not exist.
function quote3(QuoteV3 calldata quoteConfig) external view returns (bool exists, Float outputMax, Float ioRatio);

/// Adds an order owned by `msg.sender`. Reverts `OrderNoSources`,
/// `OrderNoHandleIO`, `OrderNoInputs`, `OrderNoOutputs`, or if any task
/// reverts. Calculate MUST return at least max amount and IO ratio.
/// @return stateChanged False, with no state change or event, if the order
/// already exists.
function addOrder5(OrderConfigV4 calldata config, TaskV3[] calldata tasks) external returns (bool stateChanged);

/// Removes an order owned by `msg.sender`. Reverts if any task reverts.
/// @return stateChanged False, with no state change or event, if the order
/// is not live.
function removeOrder4(OrderV4 calldata order, TaskV3[] calldata tasks) external returns (bool stateChanged);

/// Takes orders in sequence until `maximumIO` is reached. Per-order
/// failures that depend on live state are skipped with an event; static
/// misconfiguration (e.g. token mismatch, `TokenSelfTrade`) reverts.
/// Reverts if `minimumIO` is not reached.
function takeOrders5(TakeOrdersConfigV6 calldata config)
external
returns (Float totalTakerInput, Float totalTakerOutput);

/// Matches two live orders from different owners; the ratio spread is paid
/// to `msg.sender`'s vaults per `clearConfig`. Reverts `TokenSelfTrade`,
/// or if either order's input exceeds the other's output.
/// @param aliceSignedContext Signed context for `alice`'s own eval.
/// @param bobSignedContext Signed context for `bob`'s own eval.
function clear4(
OrderV4 memory alice,
OrderV4 memory bob,
ClearConfigV2 calldata clearConfig,
SignedContextV2[] memory aliceSignedContext,
SignedContextV2[] memory bobSignedContext
) external;
}
12 changes: 12 additions & 0 deletions src/interface/IRaindexV7ArbOrderTaker.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: LicenseRef-DCL-1.0
// SPDX-FileCopyrightText: Copyright (c) 2020 thedavidmeister
pragma solidity ^0.8.18;

import {IRaindexV7OrderTaker} from "./IRaindexV7OrderTaker.sol";
import {TakeOrdersConfigV6, IRaindexV7, TaskV3} from "./IRaindexV7.sol";

interface IRaindexV7ArbOrderTaker is IRaindexV7OrderTaker {
/// Takes orders on `raindex` then runs `task`. Implementations MUST
/// validate that `raindex` is trusted.
function arb6(IRaindexV7 raindex, TakeOrdersConfigV6 calldata takeOrders, TaskV3 calldata task) external payable;
}
19 changes: 19 additions & 0 deletions src/interface/IRaindexV7OrderTaker.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: LicenseRef-DCL-1.0
// SPDX-FileCopyrightText: Copyright (c) 2020 thedavidmeister
pragma solidity ^0.8.18;

import {Float} from "./IRaindexV7.sol";

interface IRaindexV7OrderTaker {
/// Called by `takeOrders5` when its `data` is non-empty and input is
/// nonzero, after input is sent (net of any flash loan debt) and before
/// output is pulled. Implementations MUST validate `msg.sender` and MUST
/// NOT re-enter the Raindex.
function onTakeOrders2(
address inputToken,
address outputToken,
Float inputAmountSent,
Float totalOutputAmount,
bytes calldata takeOrdersData
) external;
}
6 changes: 3 additions & 3 deletions src/interface/deprecated/v1/IOrderBookV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ pragma solidity ^0.8.18;

import {IERC3156FlashLender} from "../../ierc3156/IERC3156FlashLender.sol";
//forge-lint: disable-next-line(unused-import)
import {LibEvaluable} from "rainlang-interface-0.2.13/src/lib/caller/LibEvaluable.sol";
import {LibEvaluable} from "rainlang-interface-0.2.14/src/lib/caller/LibEvaluable.sol";
import {
EvaluableConfig,
Evaluable,
SignedContext,
IInterpreterCallerV1
} from "rainlang-interface-0.2.13/src/interface/deprecated/v1/IInterpreterCallerV1.sol";
import {IExpressionDeployerV3} from "rainlang-interface-0.2.13/src/interface/deprecated/v1/IExpressionDeployerV3.sol";
} from "rainlang-interface-0.2.14/src/interface/deprecated/v1/IInterpreterCallerV1.sol";
import {IExpressionDeployerV3} from "rainlang-interface-0.2.14/src/interface/deprecated/v1/IExpressionDeployerV3.sol";

/// Configuration for a deposit. All deposits are processed by and for
/// `msg.sender` so the vaults are unambiguous here.
Expand Down
6 changes: 3 additions & 3 deletions src/interface/deprecated/v2/IOrderBookV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import {IERC3156FlashLender} from "../../ierc3156/IERC3156FlashLender.sol";
import {
EvaluableConfig,
Evaluable
} from "rainlang-interface-0.2.13/src/interface/deprecated/v1/IInterpreterCallerV1.sol";
} from "rainlang-interface-0.2.14/src/interface/deprecated/v1/IInterpreterCallerV1.sol";
import {
SignedContextV1,
IInterpreterCallerV2
} from "rainlang-interface-0.2.13/src/interface/deprecated/v1/IInterpreterCallerV2.sol";
import {IExpressionDeployerV2} from "rainlang-interface-0.2.13/src/interface/deprecated/v1/IExpressionDeployerV2.sol";
} from "rainlang-interface-0.2.14/src/interface/deprecated/v1/IInterpreterCallerV2.sol";
import {IExpressionDeployerV2} from "rainlang-interface-0.2.14/src/interface/deprecated/v1/IExpressionDeployerV2.sol";

/// Configuration for a deposit. All deposits are processed by and for
/// `msg.sender` so the vaults are unambiguous here.
Expand Down
4 changes: 2 additions & 2 deletions src/interface/deprecated/v3/IOrderBookV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import {
EvaluableConfigV3,
IInterpreterCallerV2,
SignedContextV1
} from "rainlang-interface-0.2.13/src/interface/deprecated/v1/IInterpreterCallerV2.sol";
import {IExpressionDeployerV3} from "rainlang-interface-0.2.13/src/interface/deprecated/v1/IExpressionDeployerV3.sol";
} from "rainlang-interface-0.2.14/src/interface/deprecated/v1/IInterpreterCallerV2.sol";
import {IExpressionDeployerV3} from "rainlang-interface-0.2.14/src/interface/deprecated/v1/IExpressionDeployerV3.sol";

/// Import unmodified structures from older versions of `IOrderBook`.
import {IO, ClearConfig, ClearStateChange} from "../v2/IOrderBookV2.sol";
Expand Down
2 changes: 1 addition & 1 deletion src/interface/deprecated/v4/IOrderBookV4.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {

//forge-lint: disable-next-line(unused-import)
IInterpreterStoreV2
} from "rainlang-interface-0.2.13/src/interface/deprecated/v2/IInterpreterCallerV3.sol";
} from "rainlang-interface-0.2.14/src/interface/deprecated/v2/IInterpreterCallerV3.sol";

/// Import unmodified structures from older versions of `IOrderBook`.
import {ClearStateChange, ClearConfig, IO} from "../v3/IOrderBookV3.sol";
Expand Down
2 changes: 1 addition & 1 deletion src/interface/deprecated/v5/IOrderBookV5.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {

//forge-lint: disable-next-line(unused-import)
IInterpreterStoreV3
} from "rainlang-interface-0.2.13/src/interface/IInterpreterCallerV4.sol";
} from "rainlang-interface-0.2.14/src/interface/deprecated/v3/IInterpreterCallerV4.sol";

/// Import unmodified structures from older versions of `IOrderBook`.
//forge-lint: disable-start(unused-import)
Expand Down
Loading
Loading