Conversation
A limit order that uses a signed context oracle for pricing. The oracle server provides a live price feed (e.g. Pyth ETH/USD) signed as SignedContextV1. The order reads the price from signed-context, verifies expiry, applies an optional spread, and sets the IO ratio. - oracle-url placeholder: https://rain-oracle-server.fly.dev/context (to be updated once the server is deployed) - Base deployment only for now - Configurable spread parameter (0 = exact oracle price) - Expiry check ensures stale oracle data is rejected
WalkthroughIntroduces an oracle-backed limit order: new documentation and a Rain DSL strategy that fetches a signed price and expiry from an off-chain oracle (encoded via on-chain metadata), validates expiry, optionally applies a spread, and computes the IO ratio used during order execution. Changes
Sequence Diagram(s)mermaid 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 |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@src/oracle-limit.md`:
- Around line 1-35: Clarify the oracle URL wording and add the expiration revert
note: update the "Oracle server" paragraph to state whether the oracle-url field
is expected to be the full endpoint (e.g.,
https://rain-oracle-server.fly.dev/context) or a base URL that the caller
appends "/context", and explicitly show the full GET endpoint example; also add
a brief sentence (near "How it works" step 4 or the Parameters section) that the
order will revert with the message "Oracle data expired" when the signed-context
expiry (read via signed-context<0 1>()) is in the past so operators know the
failure behavior.
In `@src/oracle-limit.rain`:
- Line 6: The oracle-url key currently contains a placeholder value
("https://rain-oracle-server.fly.dev/context") that must be replaced before
release; update the oracle-url value in src/oracle-limit.rain to the final
deployed oracle endpoint and add a safeguard to prevent accidental merges with
the placeholder (either a comment next to oracle-url indicating it must be
updated and removed before release, or implement a CI check that fails when
oracle-url matches the known placeholder string). Ensure the check targets the
oracle-url configuration entry so PRs cannot be merged while the placeholder
remains.
- Around line 82-89: The inversion branch is dead because oracle-output-token is
currently bound to ${order.outputs.0.token.address}, which always equals
output-token(), so the equal-to(...) check always takes the first branch; either
make oracle-output-token an independent configurable binding (e.g., a new
GUI/backing field representing the oracle's base token) and use that independent
value in the equal-to check so inv(effective-price) can be reached, or remove
the conditional and replace the io expression with just effective-price; update
the binding where oracle-output-token is defined (currently at the binding for
oracle-output-token) and adjust the io expression referencing output-token(),
effective-price, and inv() accordingly.
- Around line 42-46: The binding "oracle-spread" currently only enforces min: 0
and needs an upper bound to prevent accidental huge values; update the binding
definition for oracle-spread to include a sensible max (e.g., max: 1 to
represent 100%) so user input is constrained, and ensure any validation/schema
that reads "oracle-spread" respects this new max constraint.
| # Oracle Limit | ||
|
|
||
| A limit order that uses a signed context oracle for pricing instead of a hardcoded exchange rate. | ||
|
|
||
| ## How it works | ||
|
|
||
| 1. An oracle server fetches a price feed (e.g. ETH/USD from Pyth) and signs it as `SignedContextV1` | ||
| 2. The oracle URL is encoded in the order's onchain metadata via `SignedContextOracleV1` | ||
| 3. When taking or clearing the order, the caller fetches signed context from the oracle and includes it in the transaction | ||
| 4. The order's rainlang reads the oracle price from `signed-context<0 0>()` and the expiry from `signed-context<0 1>()` | ||
| 5. The order verifies the data hasn't expired, applies an optional spread, and sets the IO ratio | ||
|
|
||
| ## Parameters | ||
|
|
||
| | Parameter | Description | | ||
| |-----------|-------------| | ||
| | `oracle-spread` | Percentage above oracle price to sell at (e.g. 0.01 = 1%). Set to 0 to sell at exact oracle price. | | ||
|
|
||
| ## Oracle server | ||
|
|
||
| The order expects an oracle server at the URL specified in `oracle-url` that responds to `GET /context` with: | ||
|
|
||
| ```json | ||
| { | ||
| "signer": "0x...", | ||
| "context": ["0x...<price_18_decimals>", "0x...<expiry_timestamp>"], | ||
| "signature": "0x..." | ||
| } | ||
| ``` | ||
|
|
||
| See [rain-oracle-server](https://github.com/rainlanguage/rain-oracle-server) for a reference implementation. | ||
|
|
||
| ## Networks | ||
|
|
||
| - Base |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Documentation looks good overall.
Clear explanation of the end-to-end flow, parameters, and expected oracle response schema. A couple of minor observations:
- Line 21: The wording "responds to
GET /context" may confuse readers since theoracle-urlin the.rainfile is already set tohttps://rain-oracle-server.fly.dev/context(i.e., the full endpoint). Consider clarifying whether/contextis a relative path appended by the caller or if theoracle-urlfield is the complete endpoint URL. - Consider briefly noting that the order will revert with
"Oracle data expired"if the signed context's expiry timestamp is in the past, so operators know what to expect.
🤖 Prompt for AI Agents
In `@src/oracle-limit.md` around lines 1 - 35, Clarify the oracle URL wording and
add the expiration revert note: update the "Oracle server" paragraph to state
whether the oracle-url field is expected to be the full endpoint (e.g.,
https://rain-oracle-server.fly.dev/context) or a base URL that the caller
appends "/context", and explicitly show the full GET endpoint example; also add
a brief sentence (near "How it works" step 4 or the Parameters section) that the
order will revert with the message "Oracle data expired" when the signed-context
expiry (read via signed-context<0 1>()) is in the past so operators know the
failure behavior.
| orders: | ||
| base: | ||
| orderbook: base | ||
| oracle-url: https://rain-oracle-server.fly.dev/context |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Placeholder oracle URL — ensure it's updated before release.
The PR objectives note this will be updated once the oracle server is deployed. Consider adding a comment or CI check to prevent merging with the placeholder URL still in place.
🤖 Prompt for AI Agents
In `@src/oracle-limit.rain` at line 6, The oracle-url key currently contains a
placeholder value ("https://rain-oracle-server.fly.dev/context") that must be
replaced before release; update the oracle-url value in src/oracle-limit.rain to
the final deployed oracle endpoint and add a safeguard to prevent accidental
merges with the placeholder (either a comment next to oracle-url indicating it
must be updated and removed before release, or implement a CI check that fails
when oracle-url matches the known placeholder string). Ensure the check targets
the oracle-url configuration entry so PRs cannot be merged while the placeholder
remains.
src/oracle-limit.rain
Outdated
| - binding: oracle-spread | ||
| name: Spread (%) | ||
| description: > | ||
| Percentage above oracle price to sell at. 0 = sell at exact oracle price. | ||
| e.g. 0.01 = 1% above oracle price. |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider adding a max constraint on oracle-spread.
There's a min: 0 but no upper bound. A user could accidentally enter a very large value (e.g., 100 instead of 0.01), resulting in a 10000% spread. Adding a reasonable max (e.g., 1 for 100%) would guard against input mistakes.
Proposed fix
min: 0
+ max: 1🤖 Prompt for AI Agents
In `@src/oracle-limit.rain` around lines 42 - 46, The binding "oracle-spread"
currently only enforces min: 0 and needs an upper bound to prevent accidental
huge values; update the binding definition for oracle-spread to include a
sensible max (e.g., max: 1 to represent 100%) so user input is constrained, and
ensure any validation/schema that reads "oracle-spread" respects this new max
constraint.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/oracle-limit.rain`:
- Around line 54-66: The oracle feed is not validated to be positive, so add an
ensure after reading oracle-price (and before computing max-output) that checks
greater-than(oracle-price 0) with an explanatory error message (e.g., "Oracle
price must be > 0"); keep the existing oracle-expiry ensure and the
io/max-output logic unchanged but place this new ensure near the oracle-price
declaration to prevent max-positive-value() from being computed when price is
zero or negative.
- Around line 65-66: Add the missing trailing comma after the max-output
expression: locate the line with "max-output: max-positive-value()" and insert a
comma so it becomes "max-output: max-positive-value()," to separate it from the
following "io:" expression, mirroring the pattern used by other strategies
(e.g., fixed-limit, fixed-spread, auction-dca) and preventing the deployment
syntax error.
---
Duplicate comments:
In `@src/oracle-limit.rain`:
- Around line 1-46: The reviewer accidentally posted a duplicate approval
comment; remove the duplicate review metadata so there is only a single
[approve_code_changes] (and drop the redundant [duplicate_comment]) in the PR
discussion/metadata, leaving the YAML content unchanged—the relevant context is
around the oracle-url and raindex-subparser entries in the src/oracle-limit.rain
GUI/deployments metadata where the approval was attached.
src/oracle-limit.rain
Outdated
| oracle-price: signed-context<0 0>(), | ||
|
|
||
| /* Read expiry timestamp from signed context column 0, row 1 */ | ||
| oracle-expiry: signed-context<0 1>(), | ||
|
|
||
| /* Ensure the oracle data hasn't expired */ | ||
| :ensure( | ||
| greater-than(oracle-expiry now()) | ||
| "Oracle data expired" | ||
| ), | ||
|
|
||
| max-output: max-positive-value() | ||
| io: oracle-price; |
There was a problem hiding this comment.
Missing validation that oracle-price is positive.
If the oracle ever returns a zero (or near-zero) price — due to a bug, stale feed, or misconfiguration — the order would effectively give away output tokens for free, since max-output is uncapped (max-positive-value()). Adding an ensure that oracle-price is greater than zero provides a critical safety net for the maker's funds, even when the oracle signer is trusted.
🛡️ Proposed fix — add a price sanity check
/* Read oracle price from signed context column 0, row 0 */
oracle-price: signed-context<0 0>(),
/* Read expiry timestamp from signed context column 0, row 1 */
oracle-expiry: signed-context<0 1>(),
/* Ensure the oracle data hasn't expired */
:ensure(
greater-than(oracle-expiry now())
"Oracle data expired"
),
+/* Ensure oracle price is non-zero */
+:ensure(
+ greater-than(oracle-price 0)
+ "Oracle price is zero"
+),
+
max-output: max-positive-value()
io: oracle-price;📝 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.
| oracle-price: signed-context<0 0>(), | |
| /* Read expiry timestamp from signed context column 0, row 1 */ | |
| oracle-expiry: signed-context<0 1>(), | |
| /* Ensure the oracle data hasn't expired */ | |
| :ensure( | |
| greater-than(oracle-expiry now()) | |
| "Oracle data expired" | |
| ), | |
| max-output: max-positive-value() | |
| io: oracle-price; | |
| oracle-price: signed-context<0 0>(), | |
| /* Read expiry timestamp from signed context column 0, row 1 */ | |
| oracle-expiry: signed-context<0 1>(), | |
| /* Ensure the oracle data hasn't expired */ | |
| :ensure( | |
| greater-than(oracle-expiry now()) | |
| "Oracle data expired" | |
| ), | |
| /* Ensure oracle price is non-zero */ | |
| :ensure( | |
| greater-than(oracle-price 0) | |
| "Oracle price is zero" | |
| ), | |
| max-output: max-positive-value() | |
| io: oracle-price; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/oracle-limit.rain` around lines 54 - 66, The oracle feed is not validated
to be positive, so add an ensure after reading oracle-price (and before
computing max-output) that checks greater-than(oracle-price 0) with an
explanatory error message (e.g., "Oracle price must be > 0"); keep the existing
oracle-expiry ensure and the io/max-output logic unchanged but place this new
ensure near the oracle-price declaration to prevent max-positive-value() from
being computed when price is zero or negative.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@registry`:
- Line 10: Replace the abbreviated commit SHA in the registry entry for
"oracle-limit" so it uses the full 40-character commit hash used across the
registry; locate the line containing "oracle-limit
https://raw.githubusercontent.com/rainlanguage/rain.strategies/efef4c3/src/oracle-limit.rain"
and update the URL to reference the repository rain.strategies with the full
commit SHA (the 40-char hash for the finalized commit) instead of "efef4c3" to
match existing entries and ensure reproducibility.
registry
Outdated
| claims https://raw.githubusercontent.com/rainlanguage/rain.strategies/7eba2d7fe25c57a29654bf91185854dc27c475c5/src/claims.rain | ||
| fixed-spread https://raw.githubusercontent.com/rainlanguage/rain.strategies/7eba2d7fe25c57a29654bf91185854dc27c475c5/src/fixed-spread.rain | ||
| folio https://raw.githubusercontent.com/rainlanguage/rain.strategies/7eba2d7fe25c57a29654bf91185854dc27c475c5/src/folio.rain | ||
| oracle-limit https://raw.githubusercontent.com/rainlanguage/rain.strategies/efef4c3/src/oracle-limit.rain |
There was a problem hiding this comment.
Use the full 40-character commit SHA to match the established registry pattern.
All other entries in this file pin URLs with the full commit hash (e.g., 7eba2d7fe25c57a29654bf91185854dc27c475c5), but this entry uses the abbreviated efef4c3. Abbreviated SHAs can become ambiguous as the repository grows and break reproducibility. Since the PR description notes the registry entry will be finalized after merge once the commit hash is known, this line may have been added prematurely.
-oracle-limit https://raw.githubusercontent.com/rainlanguage/rain.strategies/efef4c3/src/oracle-limit.rain
+oracle-limit https://raw.githubusercontent.com/rainlanguage/rain.strategies/<full-40-char-commit-sha>/src/oracle-limit.rainBased on learnings: "In the rain.strategies repository, the registry file uses full commit SHAs to pin strategy URLs as the current established pattern, rather than using tags or branches, as confirmed by project maintainer 0xgleb."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@registry` at line 10, Replace the abbreviated commit SHA in the registry
entry for "oracle-limit" so it uses the full 40-character commit hash used
across the registry; locate the line containing "oracle-limit
https://raw.githubusercontent.com/rainlanguage/rain.strategies/efef4c3/src/oracle-limit.rain"
and update the URL to reference the repository rain.strategies with the full
commit SHA (the 40-char hash for the finalized commit) instead of "efef4c3" to
match existing entries and ensure reproducibility.
Verifies signed context comes from the expected oracle signer address. The interpreter only checks signature validity - the strategy must verify the signer is trusted. Added oracle-signer binding and GUI field.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/oracle-limit.rain`:
- Around line 80-81: The implementation uses ratio: oracle-price but the
documented oracle-spread parameter is missing; add a configurable parameter
(e.g. oracle-spread) and apply it when computing the sell ratio so ratio =
oracle-price * (1 + oracle-spread) (handle oracle-spread = 0 to keep exact
price), update the relevant function/variable where ratio is set (reference
ratio and max-output in src/oracle-limit.rain) and add a matching GUI/deployment
field for oracle-spread so users can configure the percentage spread;
alternatively, if you choose not to support spreads, remove oracle-spread from
docs and ensure the GUI/deployment schema does not expose it.
- Around line 12-17: The scenario "base" is missing the required binding for the
declared required input oracle-signer (declared with ! and used by
calculate-io), so add a binding for oracle-signer in the scenarios base bindings
(or alternatively provide a default in the oracle-signer declaration) so the
scenario can compile and run; locate the bindings block under the base scenario
and add a test/mocked signer value for oracle-signer to satisfy the required
input used by calculate-io.
---
Duplicate comments:
In `@registry`:
- Line 10: The registry entry for oracle-limit uses an abbreviated commit SHA
("888cf13") in the URL; replace that short SHA with the repository's full
40-character commit SHA to match the established pinning pattern (e.g., replace
"https://raw.githubusercontent.com/rainlanguage/rain.strategies/888cf13/src/oracle-limit.rain"
with the same URL containing the full commit hash). Locate the line containing
the token "oracle-limit" in the registry file and update the URL to reference
the full commit SHA corresponding to that abbreviated one (use git/remote
history to resolve the full hash), ensuring consistency with other entries that
use full 40-character SHAs like "7eba2d7fe25c57a29654bf91185854dc27c475c5".
In `@src/oracle-limit.rain`:
- Line 6: The file contains a placeholder oracle-url value (oracle-url:
https://rain-oracle-server.fly.dev/context) that must be replaced before merge;
either update the oracle-url entry in src/oracle-limit.rain to the finalized
production oracle endpoint (replace the placeholder string) or add a CI check
that fails when oracle-url matches the dev placeholder pattern so merges are
blocked; locate the oracle-url key in src/oracle-limit.rain and implement the
change or add a CI gating check referencing that config key to prevent
accidental merges.
- Around line 68-81: The code lacks a check that oracle-price is positive, so a
zero/near-zero price with max-output: max-positive-value() can drain the vault;
add an explicit guard using greater-than(oracle-price 0) (e.g., a :ensure
clause) placed after reading oracle-price (signed-context<0 0>()) and before
computing max-output/max-positive-value() to abort with a clear error message
like "Oracle price must be > 0".
| scenarios: | ||
| base: | ||
| orderbook: base | ||
| runs: 1 | ||
| bindings: | ||
| raindex-subparser: 0x22839F16281E67E5Fd395fAFd1571e820CbD46cB |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, locate and read the full src/oracle-limit.rain file
cat -n src/oracle-limit.rainRepository: rainlanguage/rain.strategies
Length of output: 2975
🏁 Script executed:
# Search for oracle-signer declaration to confirm it's required (with !)
rg "oracle-signer" src/oracle-limit.rain -B 2 -A 2Repository: rainlanguage/rain.strategies
Length of output: 521
🏁 Script executed:
# Check if there are other .rain files and how they handle required GUI fields in scenarios
fd -e rain -type f | head -10Repository: rainlanguage/rain.strategies
Length of output: 242
oracle-signer is required but unbound in the scenario — direct scenario simulation will fail.
#oracle-signer is declared with ! (required, no default) at line 57 and is used in #calculate-io at line 64. The scenario at lines 12–17 only binds raindex-subparser; oracle-signer is absent. Any direct simulation of this scenario (e.g., rain test) will fail to compile due to the missing binding. The GUI deployment handles this by accepting oracle-signer as a user-provided field, but the scenario itself cannot run standalone.
Suggested fix
bindings:
raindex-subparser: 0x22839F16281E67E5Fd395fAFd1571e820CbD46cB
+ oracle-signer: 0x0000000000000000000000000000000000000000📝 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.
| scenarios: | |
| base: | |
| orderbook: base | |
| runs: 1 | |
| bindings: | |
| raindex-subparser: 0x22839F16281E67E5Fd395fAFd1571e820CbD46cB | |
| scenarios: | |
| base: | |
| orderbook: base | |
| runs: 1 | |
| bindings: | |
| raindex-subparser: 0x22839F16281E67E5Fd395fAFd1571e820CbD46cB | |
| oracle-signer: 0x0000000000000000000000000000000000000000 |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/oracle-limit.rain` around lines 12 - 17, The scenario "base" is missing
the required binding for the declared required input oracle-signer (declared
with ! and used by calculate-io), so add a binding for oracle-signer in the
scenarios base bindings (or alternatively provide a default in the oracle-signer
declaration) so the scenario can compile and run; locate the bindings block
under the base scenario and add a test/mocked signer value for oracle-signer to
satisfy the required input used by calculate-io.
| max-output: max-positive-value(), | ||
| ratio: oracle-price; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, explore the repository structure
git ls-files | head -20Repository: rainlanguage/rain.strategies
Length of output: 418
🏁 Script executed:
# Check if oracle-limit.rain exists and read around lines 80-81
wc -l src/oracle-limit.rain 2>/dev/null || echo "File may not exist at expected path"Repository: rainlanguage/rain.strategies
Length of output: 96
🏁 Script executed:
# Search for oracle-limit files in the repo
fd oracle-limitRepository: rainlanguage/rain.strategies
Length of output: 113
🏁 Script executed:
# Search for any documentation mentioning oracle-spread
rg "oracle-spread" --type mdRepository: rainlanguage/rain.strategies
Length of output: 212
🏁 Script executed:
# Read the full oracle-limit.rain file
cat -n src/oracle-limit.rainRepository: rainlanguage/rain.strategies
Length of output: 2975
🏁 Script executed:
# Read the full oracle-limit.md documentation
cat -n src/oracle-limit.mdRepository: rainlanguage/rain.strategies
Length of output: 1563
🏁 Script executed:
# Check git history for oracle-spread mentions
git log --oneline --all | head -20Repository: rainlanguage/rain.strategies
Length of output: 993
🏁 Script executed:
# Check recent changes to oracle-limit.rain
git log --oneline src/oracle-limit.rain | head -10Repository: rainlanguage/rain.strategies
Length of output: 133
🏁 Script executed:
# Check the full history of oracle-limit.rain to find oracle-spread references
git log -p src/oracle-limit.rain | grep -A 5 -B 5 "oracle-spread" | head -50Repository: rainlanguage/rain.strategies
Length of output: 54
🏁 Script executed:
# Check when oracle-spread was last in the file
git log --all -S "oracle-spread" -- src/oracle-limit.rainRepository: rainlanguage/rain.strategies
Length of output: 54
🏁 Script executed:
# Check the commit that added signer trust check to see what changed
git show 9e9e0e4 -- src/oracle-limit.rainRepository: rainlanguage/rain.strategies
Length of output: 3029
oracle-spread parameter is documented but missing from the implementation.
The oracle-limit.md documentation describes an oracle-spread parameter as "Percentage above oracle price to sell at (e.g. 0.01 = 1%). Set to 0 to sell at exact oracle price." and states that the order "applies an optional spread" (line 5). However, the current implementation sets ratio: oracle-price directly without any spread logic or configurable oracle-spread binding. Additionally, there is no corresponding GUI field for this parameter in the deployment configuration.
Either implement the oracle-spread functionality with a GUI field, or update the documentation to clarify that oracle pricing is at the exact oracle price without configurable spread.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/oracle-limit.rain` around lines 80 - 81, The implementation uses ratio:
oracle-price but the documented oracle-spread parameter is missing; add a
configurable parameter (e.g. oracle-spread) and apply it when computing the sell
ratio so ratio = oracle-price * (1 + oracle-spread) (handle oracle-spread = 0 to
keep exact price), update the relevant function/variable where ratio is set
(reference ratio and max-output in src/oracle-limit.rain) and add a matching
GUI/deployment field for oracle-spread so users can configure the percentage
spread; alternatively, if you choose not to support spreads, remove
oracle-spread from docs and ensure the GUI/deployment schema does not expose it.
Motivation
Raindex orders currently use hardcoded prices or onchain calculations. There is no standard way to price an order from an off-chain oracle feed (e.g. Pyth) while maintaining the trust guarantees of signed context.
This strategy demonstrates the signed context oracle pattern, where an off-chain server signs price data that the Rainlang strategy verifies at execution time.
Solution
New strategy: oracle-limit — a limit order that prices itself from a signed context oracle.
How it works
SignedContextV1oracle-urlin the order YAML encodes aRaindexSignedContextOracleV1metadata item in the order onchain metasigned-context<0 0>(), expiry fromsigned-context<0 1>()signer<0>()==oracle-signerbinding)Files
src/oracle-limit.rain— strategy with YAML front matter + Rainlangsrc/oracle-limit.md— documentationChecks