Conversation
| const result: UTxO[] = []; | ||
| const utxos = await this.getUtxos(addressOrCredential); | ||
| utxos.filter((utxo) => utxo.assets[unit] > 0n); | ||
| return result; |
There was a problem hiding this comment.
🔴 getUtxosWithUnit always returns an empty array — filter result is discarded
getUtxosWithUnit at lazer/cardano/hermes/server/src/offchain/hydra/provider.ts:63-67 creates an empty result array, calls utxos.filter(...) (which returns a new filtered array without mutating utxos), and then returns the original empty result. The filtered array is silently discarded, so this method will always return [] regardless of what UTxOs exist.
Code showing discarded filter result
async getUtxosWithUnit(...): Promise<UTxO[]> {
const result: UTxO[] = [];
const utxos = await this.getUtxos(addressOrCredential);
utxos.filter((utxo) => utxo.assets[unit] > 0n); // result discarded!
return result; // always empty
}| const result: UTxO[] = []; | |
| const utxos = await this.getUtxos(addressOrCredential); | |
| utxos.filter((utxo) => utxo.assets[unit] > 0n); | |
| return result; | |
| const result: UTxO[] = []; | |
| const utxos = await this.getUtxos(addressOrCredential); | |
| return utxos.filter((utxo) => utxo.assets[unit] > 0n); | |
| } |
Was this helpful? React with 👍 or 👎 to provide feedback.
| const marketInlineDatum = Data.to<MarketDatum>({ | ||
| startPrice: { | ||
| numerator: BigInt(price), | ||
| denominator: BigInt((10 ** exponent).toFixed(0)), | ||
| }, | ||
| endPrice: null, | ||
| remainingShares: 0n, | ||
| }, MarketDatum) |
There was a problem hiding this comment.
🔴 Market datum denominator becomes 0 for negative Pyth exponents (e.g., -8 for BTC/USD)
At lazer/cardano/hermes/server/src/market.ts:87, the denominator is computed as BigInt((10 ** exponent).toFixed(0)). Pyth BTC/USD feeds use a negative exponent (typically -8). 10 ** -8 evaluates to 1e-8 in JavaScript, and (1e-8).toFixed(0) produces "0", making denominator = 0n. This creates an invalid Price with a zero denominator, which would cause division-by-zero on-chain and also fail the validate_init_market check since the off-chain computed price won't match the on-chain rational arithmetic result from common_checks.ak:33-34.
| const marketInlineDatum = Data.to<MarketDatum>({ | |
| startPrice: { | |
| numerator: BigInt(price), | |
| denominator: BigInt((10 ** exponent).toFixed(0)), | |
| }, | |
| endPrice: null, | |
| remainingShares: 0n, | |
| }, MarketDatum) | |
| const marketInlineDatum = Data.to<MarketDatum>({ | |
| startPrice: { | |
| numerator: BigInt(price), | |
| denominator: BigInt(10 ** Math.abs(exponent)), | |
| }, | |
| endPrice: null, | |
| remainingShares: 0n, | |
| }, MarketDatum) |
Was this helpful? React with 👍 or 👎 to provide feedback.
| // Value is increased by the matched lovelace (1-to-1 with token scale in matching context) | ||
| let matched_lovelace = matched_amount | ||
| let expected_value = merge(own_value, from_lovelace(matched_lovelace)) |
There was a problem hiding this comment.
🔴 1,000,000x lovelace scale mismatch between match deposits and claim withdrawals
validate_process_match at market_checks.ak:260 deposits matched_amount lovelace per position token matched (1 lovelace = 1 token), but validate_claim_winnings at market_checks.ak:126 expects to withdraw claimed_tokens * 1_000_000 lovelace per token claimed (1 ADA = 1 token). This means the market UTxO accumulates far too little lovelace during matching to satisfy the claim validation. For example, matching 100 tokens deposits only 100 lovelace, but claiming those 100 tokens tries to withdraw 100,000,000 lovelace (100 ADA). The remaining_value ends up with deeply negative lovelace, making the value check at line 159 trivially pass for any output — effectively bypassing the intended value guard.
Prompt for agents
In lazer/cardano/hermes/onchain/lib/subvalidators/market_checks.ak, there is a lovelace scale mismatch between validate_process_match (line 260) and validate_claim_winnings (line 126). The match function uses matched_lovelace = matched_amount (1 lovelace per token) while the claim function uses claimed_tokens * 1_000_000 (1 ADA per token). These must use the same scale. Either change line 260 to matched_lovelace = matched_amount * 1_000_000 to match the claim logic, or change line 126 to paid_value = from_lovelace(claimed_tokens) to match the match logic. The choice depends on the intended economic design (whether 1 position token represents 1 lovelace or 1 ADA).
Was this helpful? React with 👍 or 👎 to provide feedback.
|
|
||
| for (const up of upBuys) { | ||
| for (const down of downBuys) { | ||
| if (up.price + down.price !== 1) continue; |
There was a problem hiding this comment.
🔴 Floating-point equality check up.price + down.price !== 1 will rarely match
At lazer/cardano/hermes/server/src/matcher.ts:23, the matcher uses strict inequality up.price + down.price !== 1 to check if two order prices sum to 1. Due to IEEE 754 floating-point representation, sums like 0.3 + 0.7 or 0.48 + 0.52 frequently produce results like 0.9999999999999999 or 1.0000000000000002 rather than exactly 1. This means most valid complementary orders will be skipped. An epsilon-based comparison should be used instead.
| if (up.price + down.price !== 1) continue; | |
| if (Math.abs(up.price + down.price - 1) > 1e-9) continue; |
Was this helpful? React with 👍 or 👎 to provide feedback.
Pyth Examples Contribution
Type of Contribution
Project Information
Hermes:
Pyth Product Used:
Blockchain/Platform:
Description
What does this contribution do?
5 minute market for Cardano L2 Hydra
How does it integrate with Pyth?
Uses price feeds on Cardano for validating the bets of users of whether or not an asset is above or below a threshold every 5 minutes in real time.
What problem does it solve or demonstrate?
It demonstrates an actual high speed integration of a 5 minute market with Cardano through an L2. Nothing that's shown on how to use on examples.
Directory Structure (for new examples)
Testing & Verification
How to Test This Contribution
Prerequisites
Setup & Run Instructions
Deployment Information (if applicable)
Network:
Contract Address(es):
Demo URL:
Checklist
Code Quality
Testing
Additional Context
Related Issues
Fixes #
Screenshots/Demo (if applicable)
Notes for Reviewers
Thank you for contributing to Pyth Examples!