Skip to content

Cardano - LAFHIS#109

Open
igrinspan wants to merge 38 commits intopyth-network:mainfrom
matiWaisman:main
Open

Cardano - LAFHIS#109
igrinspan wants to merge 38 commits intopyth-network:mainfrom
matiWaisman:main

Conversation

@igrinspan
Copy link
Copy Markdown

@igrinspan igrinspan commented Mar 22, 2026

Pyth Examples Contribution

Type of Contribution

  • New Example Project (Adding a new example to demonstrate Pyth integration)
  • Bug Fix (Fixing an issue in existing examples)
  • Documentation Update (Improving README, comments, or guides)
  • Enhancement (Improving existing functionality or adding features)
  • Hackathon Submission (Submitting a project from a hackathon)

Project Information

Project/Example Name:

Pyth Product Used:

  • Pyth Price Feeds
  • Pyth Entropy
  • Multiple Products
  • Other: ___________

Blockchain/Platform:

  • Ethereum/EVM
  • Solana
  • Aptos
  • Sui
  • Fuel
  • Starknet
  • TON
  • Other: ___________

Description

What does this contribution do?

How does it integrate with Pyth?

What problem does it solve or demonstrate?

Directory Structure (for new examples)

[product]/[example-name]/
├── contract/          # Smart contracts (if applicable)
├── app/              # Frontend application (if applicable)  
├── README.md         # Project documentation
└── ...

Testing & Verification

How to Test This Contribution

Prerequisites

  • Node.js version: ___
  • Other dependencies: ___

Setup & Run Instructions

# Add your setup and run commands here
cd [path-to-your-example]
npm install
# ... other commands

Deployment Information (if applicable)

Network:

Contract Address(es):

Demo URL:

Checklist

Code Quality

  • Code follows existing patterns in the repository
  • Proper error handling implemented
  • No hardcoded values (use environment variables where appropriate)

Testing

  • Tested locally and works as expected
  • All existing functionality still works (no breaking changes)

Additional Context

Related Issues

Fixes #

Screenshots/Demo (if applicable)

Notes for Reviewers


Thank you for contributing to Pyth Examples!


Open with Devin

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 4 potential issues.

View 6 additional findings in Devin Review.

Open in Devin Review

// Determine winner (same formula as the validator)
const changeA = Math.trunc(((endA - startPriceA) * 1_000_000) / startPriceA);
const changeB = Math.trunc(((endB - startPriceB) * 1_000_000) / startPriceB);
const isDraw = Math.abs(changeA - changeB) < 1;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Draw threshold mismatch between API resolve route and on-chain validator causes transaction rejection

The on-chain validator at pyth-coin-stable-validators/validators/validators.ak:264 uses abs(change_a - change_b) < 100 as the draw threshold, but the API route resolve.ts at line 300 uses Math.abs(changeA - changeB) < 1. When the percentage change difference is between 1 and 99 (i.e. 0.0001% to 0.0099%), the off-chain code determines a winner and builds a winner-takes-all payout transaction. However, the on-chain validator considers this a draw and expects both players to receive their bet back. The transaction will be rejected by the Cardano node because the validator's payout check fails. The standalone resolve.mjs script correctly uses < 100 (line 235), so only the web app's resolve endpoint is affected.

Suggested change
const isDraw = Math.abs(changeA - changeB) < 1;
const isDraw = Math.abs(changeA - changeB) < 100;
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


// Token name for all victory tokens — fungible, same name across all duels.
// "horseshoe" encoded as UTF-8 hex
const horseshoe: ByteArray = "686f727365736f6f65"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Typo in winner_token.ak hex constant: 'horsesooe' instead of 'horseshoe'

The hex constant on line 10 of winner_token.ak is "686f727365736f6f65" which decodes to "horsesooe", not "horseshoe". The correct hex for "horseshoe" is 686f72736573686f65. The same typo is propagated to resolve.mjs:115. The Navbar horseshoe counter (Navbar.tsx:5) uses Buffer.from("horseshoe").toString("hex") which produces the correct hex, so tokens minted by the standalone resolve.mjs (using the winner_token Plutus validator) will not appear in the UI's horseshoe balance counter.

Suggested change
const horseshoe: ByteArray = "686f727365736f6f65"
const horseshoe: ByteArray = "686f72736573686f65"
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


const winnerScriptCbor = applyParamsToScript(WINNER_COMPILED_CODE, [cborBytesParam(BACKEND_PKH)], "CBOR");
const winnerPolicyId = resolveScriptHash(winnerScriptCbor, "V3");
const WINNER_TOKEN_NAME = "686f727365736f6f65"; // "horseshoe" UTF-8
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Same 'horsesooe' typo in resolve.mjs WINNER_TOKEN_NAME constant

The standalone resolve script at line 115 hardcodes the same incorrect hex "686f727365736f6f65" ("horsesooe") as the winner token name, matching the typo in winner_token.ak:10. This needs to be fixed alongside the Aiken validator to maintain consistency.

Suggested change
const WINNER_TOKEN_NAME = "686f727365736f6f65"; // "horseshoe" UTF-8
const WINNER_TOKEN_NAME = "686f72736573686f65"; // "horseshoe" UTF-8
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +9 to +13
const ONCHAIN_FEED_ID_BY_RATE: Partial<Record<GameRate, number>> = {
"ADA/USD": 16,
"BTC/USD": 29,
"ETH/USD": 36,
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Missing BNB/USD on-chain feed ID causes runtime error when user selects BNB/USD

The ONCHAIN_FEED_ID_BY_RATE map in onchain.ts only has entries for ADA/USD, BTC/USD, and ETH/USD. The GameRate type and UI dropdowns (in CreateGameConfigBar.tsx:3 and JoinGameConfigBar.tsx:4) allow selecting BNB/USD, but calling getOnchainFeedId("BNB/USD") throws "Missing on-chain feed id for BNB/USD". This means any user who selects BNB/USD in the create or join game flow will get an error.

Suggested change
const ONCHAIN_FEED_ID_BY_RATE: Partial<Record<GameRate, number>> = {
"ADA/USD": 16,
"BTC/USD": 29,
"ETH/USD": 36,
};
const ONCHAIN_FEED_ID_BY_RATE: Partial<Record<GameRate, number>> = {
"ADA/USD": 16,
"BTC/USD": 29,
"ETH/USD": 36,
"BNB/USD": 52, // TODO: verify correct Pyth Lazer feed ID for BNB/USD
};
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants