Conversation
Orders can now specify an optional oracle-url that points to a signed context oracle server. When present, tooling encodes a SignedContextOracleV1 metadata item into the order's RainMetaDocumentV1, enabling oracle discovery by takers and indexers.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds an optional Changes
Sequence Diagram(s)sequenceDiagram
participant Order as Order Front Matter
participant Chain as RainMetaDocumentV1 (On-chain)
participant Consumer as Consumer / Indexer
participant Oracle as Signed Context Oracle Server
Order->>Chain: encode RaindexSignedContextOracleV1 metadata (includes oracle-url)
Consumer->>Chain: read order metadata (discover oracle-url)
Consumer->>Oracle: POST ABI-encoded (OrderV4, inputIOIndex, outputIOIndex, counterparty)
Oracle-->>Consumer: 200 JSON { signer, context[], signature }
Consumer->>Consumer: verify EIP-191 signature over keccak256(abi.encodePacked(context[]))
Consumer->>Chain: use verified context for order evaluation/indexing
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Adds optional oracle-url field to OrderCfg, parsed from the YAML front matter orders section. When present, this URL identifies a signed context oracle server for the order. Changes: - Add oracle_url: Option<String> to OrderCfg struct - Parse oracle-url via optional_string in YAML parsing - Add oracle-url to ALLOWED_ORDER_KEYS - Update Default and PartialEq impls - Add test for oracle-url parsing (present + absent) Spec: rainlanguage/specs#45 Chained on: #2459 (Phase 4)
The signed context is provided by the caller during take/clear, not just 'at take-time'. Updated wording to be precise about the usage context.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@ob-yaml.md`:
- Around line 285-292: Update the Oracle URL documentation to state transport
and security expectations: require HTTPS for the `oracle-url` to prevent
downgrade/MITM, recommend servers use TLS with valid certificates, and document
that endpoints encoded via `SignedContextOracleV1` (magic 0xff7a1507ba4419ca)
into `RainMetaDocumentV1` are discoverable onchain so callers should not assume
confidentiality of the URL; also suggest optional authentication approaches
(e.g., bearer tokens, client TLS certs, or signature verification of
`SignedContextV1` responses) and indicate that callers must validate TLS and
signature/auth metadata when retrieving `SignedContextV1`.
- Around line 287-289: Update the wording in the documentation fragment that
describes oracle metadata: change “onchain” to “on-chain” and “webapp” to “web
app” to match standard terminology; locate the text mentioning `oracle-url`,
`SignedContextV1`, `SignedContextOracleV1`, and `RainMetaDocumentV1` (including
the magic `0xff7a1507ba4419ca`) and apply the two spelling/wording fixes there.
ob-yaml.md
Outdated
| ### Oracle URL | ||
|
|
||
| Orders that require external data (e.g. price feeds) can specify an `oracle-url`. This URL points to a server that returns `SignedContextV1` data. The signed context is provided by the caller when taking or clearing the order — the order's rainlang can then read this data from the signed context columns during evaluation. | ||
|
|
||
| When `oracle-url` is specified, the tooling encodes a `SignedContextOracleV1` metadata item (magic `0xff7a1507ba4419ca`) into the order's `RainMetaDocumentV1`. This allows the oracle endpoint to be discovered onchain by anyone who needs to take or clear the order (e.g. Raindex bots, the webapp, or other takers). | ||
|
|
||
| The oracle server MUST respond to `GET` requests and return a JSON object matching the `SignedContextV1` struct: | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Clarify transport/security expectations for oracle-url.
Consider stating whether the URL must be HTTPS (or otherwise authenticated) to avoid leaking endpoint access patterns or enabling downgrade/mitm risks.
🧰 Tools
🪛 LanguageTool
[grammar] ~289-~289: Ensure spelling is correct
Context: ...ws the oracle endpoint to be discovered onchain by anyone who needs to take or clear th...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~289-~289: Ensure spelling is correct
Context: ...clear the order (e.g. Raindex bots, the webapp, or other takers). The oracle server M...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents
In `@ob-yaml.md` around lines 285 - 292, Update the Oracle URL documentation to
state transport and security expectations: require HTTPS for the `oracle-url` to
prevent downgrade/MITM, recommend servers use TLS with valid certificates, and
document that endpoints encoded via `SignedContextOracleV1` (magic
0xff7a1507ba4419ca) into `RainMetaDocumentV1` are discoverable onchain so
callers should not assume confidentiality of the URL; also suggest optional
authentication approaches (e.g., bearer tokens, client TLS certs, or signature
verification of `SignedContextV1` responses) and indicate that callers must
validate TLS and signature/auth metadata when retrieving `SignedContextV1`.
ob-yaml.md
Outdated
| Orders that require external data (e.g. price feeds) can specify an `oracle-url`. This URL points to a server that returns `SignedContextV1` data. The signed context is provided by the caller when taking or clearing the order — the order's rainlang can then read this data from the signed context columns during evaluation. | ||
|
|
||
| When `oracle-url` is specified, the tooling encodes a `SignedContextOracleV1` metadata item (magic `0xff7a1507ba4419ca`) into the order's `RainMetaDocumentV1`. This allows the oracle endpoint to be discovered onchain by anyone who needs to take or clear the order (e.g. Raindex bots, the webapp, or other takers). |
There was a problem hiding this comment.
Fix spelling/wording: “on-chain”, “web app”.
Minor doc polish to match standard terminology.
✏️ Suggested edit
-This allows the oracle endpoint to be discovered onchain by anyone who needs to take or clear the order (e.g. Raindex bots, the webapp, or other takers).
+This allows the oracle endpoint to be discovered on-chain by anyone who needs to take or clear the order (e.g. Raindex bots, the web app, or other takers).📝 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.
| Orders that require external data (e.g. price feeds) can specify an `oracle-url`. This URL points to a server that returns `SignedContextV1` data. The signed context is provided by the caller when taking or clearing the order — the order's rainlang can then read this data from the signed context columns during evaluation. | |
| When `oracle-url` is specified, the tooling encodes a `SignedContextOracleV1` metadata item (magic `0xff7a1507ba4419ca`) into the order's `RainMetaDocumentV1`. This allows the oracle endpoint to be discovered onchain by anyone who needs to take or clear the order (e.g. Raindex bots, the webapp, or other takers). | |
| Orders that require external data (e.g. price feeds) can specify an `oracle-url`. This URL points to a server that returns `SignedContextV1` data. The signed context is provided by the caller when taking or clearing the order — the order's rainlang can then read this data from the signed context columns during evaluation. | |
| When `oracle-url` is specified, the tooling encodes a `SignedContextOracleV1` metadata item (magic `0xff7a1507ba4419ca`) into the order's `RainMetaDocumentV1`. This allows the oracle endpoint to be discovered on-chain by anyone who needs to take or clear the order (e.g. Raindex bots, the web app, or other takers). |
🧰 Tools
🪛 LanguageTool
[grammar] ~289-~289: Ensure spelling is correct
Context: ...ws the oracle endpoint to be discovered onchain by anyone who needs to take or clear th...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~289-~289: Ensure spelling is correct
Context: ...clear the order (e.g. Raindex bots, the webapp, or other takers). The oracle server M...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents
In `@ob-yaml.md` around lines 287 - 289, Update the wording in the documentation
fragment that describes oracle metadata: change “onchain” to “on-chain” and
“webapp” to “web app” to match standard terminology; locate the text mentioning
`oracle-url`, `SignedContextV1`, `SignedContextOracleV1`, and
`RainMetaDocumentV1` (including the magic `0xff7a1507ba4419ca`) and apply the
two spelling/wording fixes there.
Adds optional oracle-url field to OrderCfg, parsed from the YAML front matter orders section. When present, this URL identifies a signed context oracle server for the order. Changes: - Add oracle_url: Option<String> to OrderCfg struct - Parse oracle-url via optional_string in YAML parsing - Add oracle-url to ALLOWED_ORDER_KEYS - Update Default and PartialEq impls - Add test for oracle-url parsing (present + absent) Spec: rainlanguage/specs#45 Chained on: #2459 (Phase 4)
Adds optional oracle-url field to OrderCfg, parsed from the YAML front matter orders section. When present, this URL identifies a signed context oracle server for the order. Changes: - Add oracle_url: Option<String> to OrderCfg struct - Parse oracle-url via optional_string in YAML parsing - Add oracle-url to ALLOWED_ORDER_KEYS - Update Default and PartialEq impls - Add test for oracle-url parsing (present + absent) Spec: rainlanguage/specs#45 Chained on: #2459 (Phase 4)
Adds a dedicated spec (signed-context-oracle.md) defining the full protocol for signed context oracle servers compatible with Rain orderbook: - POST endpoint with ABI-encoded request body - (OrderV4, uint256 inputIOIndex, uint256 outputIOIndex, address counterparty) - SignedContextV1 JSON response format - EIP-191 signing requirements - Context layout conventions (Rain DecimalFloat) - Price direction, expiry, security considerations Updates ob-yaml.md oracle-url section to reference the standalone spec instead of inlining protocol details. Also fixes: - GET → POST (matches implementation) - SignedContextOracleV1 → RaindexSignedContextOracleV1 (matches rename)
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
ob-yaml.md (1)
289-289:⚠️ Potential issue | 🟡 Minor
webapp→web app.✏️ Suggested fix
-This allows the oracle endpoint to be discovered on-chain by anyone who needs to take or clear the order (e.g. Raindex bots, the webapp, or other takers). +This allows the oracle endpoint to be discovered on-chain by anyone who needs to take or clear the order (e.g. Raindex bots, the web app, or other takers).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@ob-yaml.md` at line 289, The phrase "webapp" should be changed to "web app" in the sentence describing discovery of the oracle endpoint; update the text that mentions `oracle-url` and `RaindexSignedContextOracleV1`/`RainMetaDocumentV1` so it reads "web app" instead of "webapp" (locate the sentence referencing `oracle-url`, `RaindexSignedContextOracleV1`, and `RainMetaDocumentV1` and replace the single word).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@signed-context-oracle.md`:
- Around line 171-177: Add a security note explaining cross-order replay risk
and how to mitigate it: state that signed contexts (context[]) are not
cryptographically bound to a specific order and therefore a valid signed context
can be reused with a different order in takeOrders4(); recommend adding an
explicit binding such as including keccak256(order hash) or the ABI-encoded
OrderV4 bytes32 in the context array and checking that value inside the Rainlang
expression, and mention this as an alternative to relying solely on short
expiry.
- Around line 9-15: The Markdown fenced diagram in signed-context-oracle.md
lacks a language identifier and triggers MD040; update the opening fence from
``` to ```text for the ASCII diagram block so the fence becomes ```text (keep
the closing ``` unchanged) to silence the lint rule and preserve the diagram
content.
---
Duplicate comments:
In `@ob-yaml.md`:
- Line 289: The phrase "webapp" should be changed to "web app" in the sentence
describing discovery of the oracle endpoint; update the text that mentions
`oracle-url` and `RaindexSignedContextOracleV1`/`RainMetaDocumentV1` so it reads
"web app" instead of "webapp" (locate the sentence referencing `oracle-url`,
`RaindexSignedContextOracleV1`, and `RainMetaDocumentV1` and replace the single
word).
signed-context-oracle.md
Outdated
| ``` | ||
| External Data Source → Oracle Server → SignedContextV1 JSON | ||
| ↓ | ||
| Client (bot/webapp) → POST request → receives signed context | ||
| ↓ | ||
| Orderbook Contract → verifies EIP-191 signature → Rainlang evaluation | ||
| ``` |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Add a language identifier to the ASCII diagram fence to silence MD040.
✏️ Suggested fix
-```
+```text
External Data Source → Oracle Server → SignedContextV1 JSON🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@signed-context-oracle.md` around lines 9 - 15, The Markdown fenced diagram in
signed-context-oracle.md lacks a language identifier and triggers MD040; update
the opening fence from ``` to ```text for the ASCII diagram block so the fence
becomes ```text (keep the closing ``` unchanged) to silence the lint rule and
preserve the diagram content.
signed-context-oracle.md
Outdated
| ## Security Considerations | ||
|
|
||
| - **Signer trust:** The Rainlang expression is responsible for checking the signer address. An oracle server's signer address should be published and verified out-of-band. | ||
| - **Expiry:** Always check expiry on-chain. Without expiry checks, a stale signed context could be replayed indefinitely. | ||
| - **Counterparty:** The counterparty address may be `address(0)` at quote time. Oracle servers SHOULD handle this gracefully (e.g. ignore the counterparty field for price-only oracles). | ||
| - **HTTPS:** Oracle URLs SHOULD use HTTPS in production. Tooling MAY reject non-HTTPS URLs. | ||
| - **CORS:** Oracle servers SHOULD allow cross-origin requests (permissive CORS) so that browser-based frontends can fetch signed contexts directly. |
There was a problem hiding this comment.
Security consideration missing: cross-order context replay.
The signed context (e.g., [price, expiry]) commits only to context[] values — it contains no cryptographic binding to a specific order hash, inputIOIndex, or outputIOIndex. A valid signed context obtained for order A could be submitted alongside a different order B's takeOrders4() call, as long as both orders trust the same signer and the context is within its expiry window.
The short-expiry recommendation (line 150) limits the window but doesn't eliminate the risk. Consider adding a bullet such as:
Context binding: Signed contexts are not bound to a specific order. If per-order exclusivity is required, include the
keccak256of the order hash (or the fullOrderV4ABI encoding) as an additionalbytes32in thecontextarray, and check it in the Rainlang expression.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@signed-context-oracle.md` around lines 171 - 177, Add a security note
explaining cross-order replay risk and how to mitigate it: state that signed
contexts (context[]) are not cryptographically bound to a specific order and
therefore a valid signed context can be reused with a different order in
takeOrders4(); recommend adding an explicit binding such as including
keccak256(order hash) or the ABI-encoded OrderV4 bytes32 in the context array
and checking that value inside the Rainlang expression, and mention this as an
alternative to relying solely on short expiry.
- Add motivation: why pull oracles, separation of placer and solver/taker - Remove implementation-specific SHOULDs (expiry, price direction, counterparty handling) - Clarify security model: order owner bears the risk, chooses their protections - Rain DecimalFloat encoding is a SHOULD for numeric context values - Onchain discovery via metadata is a MUST (core to the spec) - Fix on-chain → onchain - Move expiry, price direction, counterparty notes to reference implementation
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (3)
signed-context-oracle.md (2)
13-15:⚠️ Potential issue | 🟠 MajorHTTPS not required — the protocol spec should mandate it.
The endpoint section specifies only that the oracle server "MUST expose a
POSTendpoint" at theoracle-url, but imposes no transport security requirement. A plain-HTTP oracle-url exposes the full ABI-encodedOrderV4(includingbytecode, vault IDs, owner address) and thecounterpartyaddress to passive observers, and allows a network-level MITM to substitute the signed context — defeating the trust assumptions described in the Security Model section.Given that the signed context is trusted by the contract as long as the signature validates (line 122), a MITM returning a valid but adversarial signed context (if the signer key is shared or otherwise obtainable) could manipulate order evaluation.
Consider adding to the Endpoint section:
The oracle server MUST expose a `POST` endpoint. The URL of this endpoint is the `oracle-url` specified in the order configuration (see [ob-yaml spec](./ob-yaml.md)). + +The `oracle-url` MUST use the `https` scheme. Clients MUST reject oracle URLs with non-HTTPS schemes before sending the request. Oracle servers MUST present a valid TLS certificate.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@signed-context-oracle.md` around lines 13 - 15, The spec currently allows an oracle `POST` endpoint at `oracle-url` without requiring transport security; update the Endpoint section to mandate HTTPS/TLS (e.g., require `https://` scheme or equivalent TLS protection) for the `oracle-url` so the full ABI-encoded `OrderV4`, `bytecode`, `vault IDs`, `owner` and `counterparty` are protected in transit and to prevent MITM substitution of the `signed context` that the contract trusts; reference the `oracle-url`, the `POST` endpoint, and the `signed context`/`OrderV4` in the updated text and note that plain HTTP is disallowed.
112-122:⚠️ Potential issue | 🟠 MajorCross-order context replay not addressed — existing unresolved concern.
The Security Model does not mention that signed contexts are not bound to a specific order. A valid
(signer, context[], signature)tuple obtained for order A can be replayed against order B during the same expiry window, provided both orders trust the same signer address. The three bullet points under the order owner's responsibilities mention "expiry checks" and "price bounds" but say nothing about per-order binding.Consider adding a bullet:
- Include any onchain protections they want in their Rainlang expression (e.g. expiry checks, zero ratio guards, price bounds, or any other validation) +- Understand that signed contexts are not cryptographically bound to a specific order. If per-order exclusivity is required, include a commitment to the order hash (e.g. `keccak256(abi.encode(order))` cast to `bytes32`) as an element in `context[]` and assert it in the Rainlang expression.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@signed-context-oracle.md` around lines 112 - 122, The Security Model must call out that signed contexts (the (signer, context[], signature) tuple) are not bound to a specific order and therefore can be replayed across orders sharing the same signer; update the responsibilities to add a bullet instructing order owners to enforce per-order binding (e.g., include the order ID/order hash or unique order-specific nonce inside the signed context or to verify the order identifier inside their Rainlang expression) and to always validate that the signed context’s embedded order identifier matches the on-chain order before using the context.ob-yaml.md (1)
285-291:⚠️ Potential issue | 🟠 MajorTransport security for
oracle-urlstill unspecified — consider addressing in the Signed Context Oracle spec.Neither ob-yaml.md nor the linked signed-context-oracle.md explicitly requires or recommends HTTPS for the oracle-url value. A plain-HTTP oracle-url would expose the ABI-encoded order struct (including counterparty and vault indices) in transit and enable MITM substitution of the signed context. The security model in signed-context-oracle.md (lines 112–122) is the right place to mandate or STRONGLY RECOMMEND HTTPS (and valid TLS certificates).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@ob-yaml.md` around lines 285 - 291, Update the Signed Context Oracle spec to explicitly require or strongly recommend TLS (HTTPS) and valid certificate verification for any oracle-url, and add a short note in ob-yaml.md alongside the `oracle-url` / `RaindexSignedContextOracleV1` description referencing that transport must use HTTPS with certificate validation to prevent MITM and exposure of ABI-encoded order data; mention acceptable exceptions (if any) and point readers to the exact section in signed-context-oracle.md for detailed transport and certificate requirements.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@signed-context-oracle.md`:
- Around line 96-102: The spec currently instructs signing the raw prefix+hash
which omits the additional keccak256 used by EIP-191; update the instructions
around steps 2–3 to explicitly compute the EIP-191 message hash (e.g., call out
toEthSignedMessageHash semantics) by taking final = keccak256("\x19Ethereum
Signed Message:\n32" || keccak256(abi.encodePacked(...))) and then sign(final)
so signatures will match on-chain verification (LibContext.build / ECDSA.recover
using toEthSignedMessageHash).
- Around line 85-92: Update the "Error (4xx/5xx)" response block in
signed-context-oracle.md to explicitly include the Content-Type header (e.g.,
Content-Type: application/json) for error responses so clients can reliably
parse the body; modify the Error (4xx/5xx) section to show the header alongside
the JSON body example and ensure the documentation mirrors the success (200)
response format.
---
Duplicate comments:
In `@ob-yaml.md`:
- Around line 285-291: Update the Signed Context Oracle spec to explicitly
require or strongly recommend TLS (HTTPS) and valid certificate verification for
any oracle-url, and add a short note in ob-yaml.md alongside the `oracle-url` /
`RaindexSignedContextOracleV1` description referencing that transport must use
HTTPS with certificate validation to prevent MITM and exposure of ABI-encoded
order data; mention acceptable exceptions (if any) and point readers to the
exact section in signed-context-oracle.md for detailed transport and certificate
requirements.
In `@signed-context-oracle.md`:
- Around line 13-15: The spec currently allows an oracle `POST` endpoint at
`oracle-url` without requiring transport security; update the Endpoint section
to mandate HTTPS/TLS (e.g., require `https://` scheme or equivalent TLS
protection) for the `oracle-url` so the full ABI-encoded `OrderV4`, `bytecode`,
`vault IDs`, `owner` and `counterparty` are protected in transit and to prevent
MITM substitution of the `signed context` that the contract trusts; reference
the `oracle-url`, the `POST` endpoint, and the `signed context`/`OrderV4` in the
updated text and note that plain HTTP is disallowed.
- Around line 112-122: The Security Model must call out that signed contexts
(the (signer, context[], signature) tuple) are not bound to a specific order and
therefore can be replayed across orders sharing the same signer; update the
responsibilities to add a bullet instructing order owners to enforce per-order
binding (e.g., include the order ID/order hash or unique order-specific nonce
inside the signed context or to verify the order identifier inside their
Rainlang expression) and to always validate that the signed context’s embedded
order identifier matches the on-chain order before using the context.
- Break signing into 4 explicit steps so implementors don't miss the outer keccak256 from toEthSignedMessageHash - Note that personal_sign/sign_message handles it automatically - Add Content-Type: application/json to error response section
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
signed-context-oracle.md (1)
117-128: Cross-order context replay risk is still unaddressed.The signed context commits only to
context[]values with no binding to a specific order hash,inputIOIndex, oroutputIOIndex. A valid signed context obtained for order A can be replayed against order B in atakeOrders4()call if both orders trust the same signer and the context is within its expiry window. The short-expiry recommendation (line 124) limits the window but does not eliminate the risk. Consider adding a note such as:Context binding: If per-order exclusivity is required, include
keccak256of the order hash as an additionalbytes32in thecontextarray and verify it in the Rainlang expression.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@signed-context-oracle.md` around lines 117 - 128, Signed context isn't bound to a specific order or IO indices, so a valid signed context can be replayed from order A against order B in takeOrders4() when the same signer is trusted; fix by documenting a recommended mitigation: bind the context to the order by adding keccak256(orderHash) (and optionally keccak256(orderHash, inputIOIndex, outputIOIndex)) as an extra bytes32 entry in the context[] and require the Rainlang expression to verify that bytes32 is present and matches the expected keccak256, so replayed contexts are invalid for other orders or IO indices.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@signed-context-oracle.md`:
- Around line 13-15: The spec currently leaves transport security for the
oracle-url unspecified; update the document to require TLS by mandating that the
oracle POST endpoint (the oracle-url) use HTTPS (require the https:// scheme)
and that clients and servers validate certificates (recommend use of CA-signed
certs and modern TLS versions), and add a MUST/SHOULD statement referencing the
POST endpoint, OrderV4, and counterparty to ensure request confidentiality
(e.g., "oracle-url MUST be an https:// URL and oracle servers MUST support TLS
with certificate validation"); also note that implementations SHOULD enforce
secure defaults (no plaintext HTTP fallback) and consider HSTS and recommended
cipher suites.
- Around line 117-128: Update the Security Model text to explicitly require that
Rainlang expressions validate the declared signer: when using SignedContextV1
with takeOrders4(), the expression must check that ECDSA.recover(context_hash,
signature) == signer and that signer matches the order owner's intended oracle
address (or a value derived from it); reference the
SignedContextV1/takeOrders4() flow and the signer/context_hash/signature symbols
so the guidance clearly instructs order owners to add an explicit signer-address
check in their Rainlang expression.
---
Duplicate comments:
In `@signed-context-oracle.md`:
- Around line 117-128: Signed context isn't bound to a specific order or IO
indices, so a valid signed context can be replayed from order A against order B
in takeOrders4() when the same signer is trusted; fix by documenting a
recommended mitigation: bind the context to the order by adding
keccak256(orderHash) (and optionally keccak256(orderHash, inputIOIndex,
outputIOIndex)) as an extra bytes32 entry in the context[] and require the
Rainlang expression to verify that bytes32 is present and matches the expected
keccak256, so replayed contexts are invalid for other orders or IO indices.
| The oracle server MUST expose a `POST` endpoint. The URL of this endpoint is the `oracle-url` specified in the order configuration (see [ob-yaml spec](./ob-yaml.md)). | ||
|
|
||
| There is no `GET` fallback. The request body is always required. |
There was a problem hiding this comment.
Transport security for the oracle URL is unspecified — recommend mandating HTTPS.
Every request includes the full OrderV4 struct and the counterparty address. Transmitting these over plaintext HTTP leaks pre-confirmation execution intent (taker identity, which order is being taken, timing), which is actionable information for front-running or taker-suppression even though the same data eventually appears on-chain. The signature protects response integrity but not request confidentiality.
The spec should add a SHOULD/MUST constraint:
📝 Proposed addition
The oracle server MUST expose a `POST` endpoint. The URL of this endpoint is the `oracle-url`
specified in the order configuration (see [ob-yaml spec](./ob-yaml.md)).
+The `oracle-url` MUST use the `https://` scheme. HTTP endpoints MUST NOT be used, as the
+request body contains sensitive execution intent (taker address, full order struct) that
+would be exposed in plaintext to network observers.
+
There is no `GET` fallback. The request body is always required.📝 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.
| The oracle server MUST expose a `POST` endpoint. The URL of this endpoint is the `oracle-url` specified in the order configuration (see [ob-yaml spec](./ob-yaml.md)). | |
| There is no `GET` fallback. The request body is always required. | |
| The oracle server MUST expose a `POST` endpoint. The URL of this endpoint is the `oracle-url` specified in the order configuration (see [ob-yaml spec](./ob-yaml.md)). | |
| The `oracle-url` MUST use the `https://` scheme. HTTP endpoints MUST NOT be used, as the request body contains sensitive execution intent (taker address, full order struct) that would be exposed in plaintext to network observers. | |
| There is no `GET` fallback. The request body is always required. |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@signed-context-oracle.md` around lines 13 - 15, The spec currently leaves
transport security for the oracle-url unspecified; update the document to
require TLS by mandating that the oracle POST endpoint (the oracle-url) use
HTTPS (require the https:// scheme) and that clients and servers validate
certificates (recommend use of CA-signed certs and modern TLS versions), and add
a MUST/SHOULD statement referencing the POST endpoint, OrderV4, and counterparty
to ensure request confidentiality (e.g., "oracle-url MUST be an https:// URL and
oracle servers MUST support TLS with certificate validation"); also note that
implementations SHOULD enforce secure defaults (no plaintext HTTP fallback) and
consider HSTS and recommended cipher suites.
| ## Security Model | ||
|
|
||
| The order owner is the party who stands to lose funds if the oracle misbehaves — they are trusting the oracle server (identified by its signer address) with control over the data their order uses to calculate ratios, maximums, and any other logic. | ||
|
|
||
| It is the order owner's responsibility to: | ||
|
|
||
| - Choose an oracle and signer they trust | ||
| - Include any onchain protections they want in their Rainlang expression (e.g. expiry checks, zero ratio guards, price bounds, or any other validation) | ||
| - Understand that the oracle server has full knowledge of the order struct, IO pair, and counterparty for every request | ||
|
|
||
| The contract enforces only that the signature is valid for the declared signer address. All other validation is up to the Rainlang expression. | ||
|
|
There was a problem hiding this comment.
Security model should explicitly require signer-address verification in the Rainlang expression.
The signer field is a runtime input supplied by the taker when constructing SignedContextV1 for takeOrders4(). The contract verifies only that ECDSA.recover(context_hash, signature) == signer — it does not check that signer matches any address the order owner intended. Without an explicit signer check in the expression, a taker can generate their own key pair, sign arbitrary context values, set signer to their own address, and the contract will accept it.
Line 127 mentions this indirectly ("All other validation is up to the Rainlang expression"), but an order owner who misses this will deploy a fully open oracle socket. Add an explicit bullet to the responsibility list:
📝 Proposed addition
It is the order owner's responsibility to:
- Choose an oracle and signer they trust
+- **Verify the signer address in the Rainlang expression.** The contract does not enforce
+ which signer is used; it only checks that the signature is valid for the declared signer.
+ The expression MUST compare the runtime signer against a trusted address hardcoded at
+ order-placement time, otherwise any party can inject arbitrary context.
- Include any onchain protections they want in their Rainlang expression (e.g. expiry checks,
zero ratio guards, price bounds, or any other validation)🧰 Tools
🪛 LanguageTool
[grammar] ~124-~124: Ensure spelling is correct
Context: ...cle and signer they trust - Include any onchain protections they want in their Rainlang...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~125-~125: Ensure spelling is correct
Context: ... server has full knowledge of the order struct, IO pair, and counterparty for every re...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@signed-context-oracle.md` around lines 117 - 128, Update the Security Model
text to explicitly require that Rainlang expressions validate the declared
signer: when using SignedContextV1 with takeOrders4(), the expression must check
that ECDSA.recover(context_hash, signature) == signer and that signer matches
the order owner's intended oracle address (or a value derived from it);
reference the SignedContextV1/takeOrders4() flow and the
signer/context_hash/signature symbols so the guidance clearly instructs order
owners to add an explicit signer-address check in their Rainlang expression.
- Change request from single tuple to array of tuples - Change response from single JSON object to array - Array length must match between request and response - Each signature applies to its corresponding context array
Adds optional oracle-url field to OrderCfg, parsed from the YAML front matter orders section. When present, this URL identifies a signed context oracle server for the order. Changes: - Add oracle_url: Option<String> to OrderCfg struct - Parse oracle-url via optional_string in YAML parsing - Add oracle-url to ALLOWED_ORDER_KEYS - Update Default and PartialEq impls - Add test for oracle-url parsing (present + absent) Spec: rainlanguage/specs#45 Chained on: #2459 (Phase 4)
Adds optional oracle-url field to OrderCfg, parsed from the YAML front matter orders section. When present, this URL identifies a signed context oracle server for the order. Changes: - Add oracle_url: Option<String> to OrderCfg struct - Parse oracle-url via optional_string in YAML parsing - Add oracle-url to ALLOWED_ORDER_KEYS - Update Default and PartialEq impls - Add test for oracle-url parsing (present + absent) Spec: rainlanguage/specs#45 Chained on: #2459 (Phase 4)
* fix: prettier formatting * feat: parse oracle-url from YAML order config (Phase 6) Adds optional oracle-url field to OrderCfg, parsed from the YAML front matter orders section. When present, this URL identifies a signed context oracle server for the order. Changes: - Add oracle_url: Option<String> to OrderCfg struct - Parse oracle-url via optional_string in YAML parsing - Add oracle-url to ALLOWED_ORDER_KEYS - Update Default and PartialEq impls - Add test for oracle-url parsing (present + absent) Spec: rainlanguage/specs#45 Chained on: #2459 (Phase 4) * feat: encode oracle-url into order metadata (Phase 7) When an order has oracle_url set in its config, new_from_deployment now creates a SignedContextOracleV1 meta item and includes it in the order's additional_meta. This means orders deployed with oracle-url in their YAML will have the oracle endpoint encoded in their onchain RainMetaDocumentV1, making it discoverable by takers and indexers (Phase 2 reads it back). Changes: - Import SignedContextOracleV1 in add_order.rs - In new_from_deployment: parse oracle_url, create meta item, append to additional_meta * propagate RaindexSignedContextOracleV1 rename to add_order.rs * fix: cargo fmt formatting --------- Co-authored-by: Josh Hardy <josh@rainlang.xyz>
Motivation
Orders that require external data (e.g. price feeds) at take-time currently have no way to advertise their oracle endpoint in the YAML config. This adds the spec for it.
Changes
Adds an optional
oracle-urlfield to theorderssection of the ob-yaml spec. When present, tooling encodes aSignedContextOracleV1metadata item (magic0xff7a1507ba4419ca) into the order'sRainMetaDocumentV1, enabling oracle endpoint discovery by takers and indexers.Includes:
SignedContextV1JSON)oracle-urlContext
Part of the signed context oracle integration:
Summary by CodeRabbit