Conversation
… cases: success or withdraw.
This reverts commit 1b07918.
* Adds lock endpoint * Adds cancel endpoint * Moves cancel button, improves UX in ADA/USD --------- Co-authored-by: jdiaz_eryx <jdiaz@eryx.co>
# Conflicts: # lazer/cardano/backend/aiken.lock # lazer/cardano/backend/validators/pay_with_pyth.ak
| .payToAddress({ | ||
| address: Address.fromBech32(params.sponsorAddress), | ||
| assets: Assets.fromLovelace(lovelaceToSponsor), | ||
| }) |
There was a problem hiding this comment.
🔴 Unlock transaction fails when sponsor's remaining share is zero or below Cardano's minimum UTxO
The buildUnlockTxFromData function unconditionally creates a payment output to the sponsor for lovelaceToSponsor = totalLovelace - lovelaceToUser. When the ADA/USD price drops significantly (approaching the coverage multiplier threshold, e.g. ~50% for a 2x multiplier), lovelaceToUser approaches or equals totalLovelace, making lovelaceToSponsor zero or below Cardano's minimum UTxO requirement (~1-2 ADA). Cardano ledger rules reject any transaction output below the minimum UTxO, so the build() call will fail. This means legitimate unlock claims become impossible when the locked collateral barely covers the USD-equivalent owed to the user — the funds remain permanently locked until a cancel is performed. The on-chain validator (pay_with_pyth.ak:54-59) does NOT require a sponsor output — it only checks lovelace_of(output.value) >= lovelace_to_user for the user address — so the fix is to skip the sponsor output when lovelaceToSponsor is below the minimum UTxO threshold.
Prompt for agents
In lazer/cardano/backend/deployment/transactions/unlock.ts, around lines 249-278 in buildUnlockTxFromData, the sponsor payment output is unconditionally created. When lovelaceToSponsor is 0 or below the minimum UTxO value (~1_000_000 lovelace), this creates an invalid Cardano transaction output that will be rejected by the ledger.
Fix: After computing lovelaceToSponsor on line 249, add a constant like MIN_UTXO_LOVELACE = 1_000_000n (or a more precise estimate). Then conditionally build the transaction: only include the .payToAddress for the sponsor (lines 275-278) when lovelaceToSponsor >= MIN_UTXO_LOVELACE. When it's below the threshold but above 0, the small remainder can either be added to the user's output (lovelaceToUser += lovelaceToSponsor) or left as transaction fee. When it's exactly 0, simply omit the sponsor output. Update the check at line 244 accordingly — if lovelaceToUser > totalLovelace - MIN_UTXO_LOVELACE and lovelaceToUser <= totalLovelace, all locked ADA should go to the user with no sponsor output.
Was this helpful? React with 👍 or 👎 to provide feedback.
| const lockedAda = useMemo( | ||
| () => | ||
| requests | ||
| .filter((request) => request.status !== 'claimed') | ||
| .reduce((sum, request) => sum + request.lockAda, 0), | ||
| [requests], |
There was a problem hiding this comment.
🟡 "Open locked collateral" metric incorrectly includes cancelled requests
The lockedAda computation at App.tsx:84-89 filters out only claimed requests (request.status !== 'claimed'), which means cancelled requests are still counted. Once a request is cancelled, the sponsor has reclaimed the ADA from the script address — those funds are no longer locked on-chain. This inflates the "Open locked collateral" metric displayed to users. The SponsorDashboard at lazer/cardano/frontend/src/screens/SponsorDashboard.tsx:12-13 correctly excludes both claimed and cancelled statuses for its own metrics.
| const lockedAda = useMemo( | |
| () => | |
| requests | |
| .filter((request) => request.status !== 'claimed') | |
| .reduce((sum, request) => sum + request.lockAda, 0), | |
| [requests], | |
| const lockedAda = useMemo( | |
| () => | |
| requests | |
| .filter((request) => request.status !== 'claimed' && request.status !== 'cancelled') | |
| .reduce((sum, request) => sum + request.lockAda, 0), | |
| [requests], | |
| ); |
Was this helpful? React with 👍 or 👎 to provide feedback.
Pyth Examples Contribution
Type of Contribution
Project Information
Project/Example Name:
Pyth Product Used:
Blockchain/Platform:
Description
What does this contribution do?
Hackaton Submission
How does it integrate with Pyth?
Uses Pyth offchain API and Cardano contracts
What problem does it solve or demonstrate?
Explained in project's readme
Directory Structure (for new examples)
Explained in project's readme
Testing & Verification
How to Test This Contribution
Explained in project's readme
Prerequisites
Explained in project's readme
Setup & Run Instructions
Explained in project's readme
Deployment Information (if applicable)
Explained in project's readme
Checklist
Code Quality
Testing
Additional Context
Related Issues
Screenshots/Demo (if applicable)
Explained in project's readme
Notes for Reviewers
Explained in project's readme
Thank you for contributing to Pyth Examples!