Feat/l2 tezoracle - #463
Conversation
…oy TezFinOracle - add configure_pyth_oracle.js (staged setPythCore/setPythMaxAge/setFeedIds/configurePriceBounds/configureMaxPriceAge admin sequence) - add verify_shadownet_pyth_oracle.js (read-only live smoke test: native feeds, proxy/alias mapping, getPrice vs get_price_with_timestamp, getValidatedPrice) - add e2e/shell_scripts/shadownet_pyth_smoke_test.sh orchestrating the full flow - add contracts/tests/fixtures/pyth_abi_fixtures_test.py - extend TezFinOracleTest.py with L2 proxy-mapping equivalence checks - redeploy TezFinOracle to Shadownet and run the staged Pyth activation sequence
c14321d to
157ffbe
Compare
|
I reviewed the current PR head (
Please add tests exercising the actual |
|
Contract-level SmartPy regression tests were added through a test-only harness that invokes the actual TezFinOracle decoder methods. The tests cover canonical negative exponents, malformed exponent sign extension, canonical positive and negative prices, and malformed signed-int64 values. Validation results:
Updated TezFinOracle contract hash:
|
KevinMehrabi
left a comment
There was a problem hiding this comment.
I re-reviewed commit ebd1cf3269f67f6b06f6392a5c217f4529cce20d independently. The signed ABI decoder fixes are correct and the contract tests pass, but I found the following remaining blockers.
-
The Shadownet E2E script does not deploy the contract it compiles.
e2e/shell_scripts/shadownet_pyth_smoke_test.sh:42-44compilesTezFinOracleinto/tmp/tezfin_oracle_compiled, but itsREDEPLOY=1path at lines 58-60 invokesdeploy.js. That command usesTezFinBuild/compiled_contractsthroughutil.js:525-529, not the fresh/tmpoutput. In a clean checkout that directory does not exist; in a reused checkout it may contain stale or unrelated full-protocol artifacts. Please make the smoke test originate the freshly compiled oracle artifact it just produced, using a fresh/copy-on-write Shadownet manifest, and add a regression or dry-run test proving the compile output consumed by the deployment step is the same output produced earlier in the script. -
The “no mainnet override” confidence-limit guard trusts a profile label rather than the connected chain.
configure_pyth_oracle.js:71treats the run as mainnet only whenconfig.networkProfile === 'mainnet', and it resolves the approval gate beforecreateTezosClient()returns the actual chain ID. A configuration whose RPC andchainIdpoint to mainnet but whosenetworkProfileis accidentallyshadownetcan therefore useALLOW_UNAPPROVED_CONFIDENCE_LIMITS=1on mainnet, contrary to the script's documented guarantee. Please derive this gate from the actual connected chain ID (and fail closed if either the profile or actual chain is mainnet), validate the deployment manifest'schainIdagainst that connection before any writes, and add tests for a mislabeled mainnet profile and a mismatched manifest. -
The checked-in compiled hash manifest is stale. Two clean reproducible builds, using Python 3.9 and Python 3.11, produced identical hashes to each other, but they do not match
compiled-contract-hashes.jsonforCUSDt,CXTZ,Comptroller,CtzBTC, orGovernance(including several storage hashes). Only the newTezFinOracleentry matches. CI currently overwrites this tracked path and uploads the newly generated file (.github/workflows/ci.yml:54-63) without checking whether the committed file was already current, so green CI does not catch the discrepancy. Please regenerate the entire checked-in manifest from a clean build and make CI fail when a fresh generated manifest differs from the tracked release artifact. -
The documented confidence-measurement tool is absent and the required measurement is still incomplete.
docs/PYTH_CONFIDENCE_MEASUREMENT_REPORT.md:16-51documentsdeploy/deploy_script/measure_pyth_confidence.js, includingcollect-onchain,collect, andreportmodes, but that file is not present in this branch. The same report explicitly contains zero samples and marks every acceptance item incomplete at lines 70-99. Please commit the referenced collector and its tests/usage, then add the completed per-feed empirical output when the run finishes. Until that evidence is present, the proposed confidence limits must remain non-production and this PR should not be described as the frozen production audit handoff.
Please also update the PR description: it still describes the old 25% confidence rule, 13 fixtures, and the prior operation size, while this head uses per-feed bps limits, 32 fixture cases, and the smaller current artifact.
Independent verification completed on this head:
- 12/12 SmartPy suites passed under Node 22.16.0.
- All 32 Pyth ABI fixture cases passed.
- 36/36 deployment guard tests passed.
- IRM wiring, governance payload, deployment wiring, operation-size, and reproducible-build checks passed.
- The new canonical signed-int64/int32 decoder boundary tests passed.
Once the four blockers above are corrected, please request another review.
1. Shadownet E2E script now deploys the artifact it just compiled
2. Mainnet confidence-limit gate now derives from the actual connected chain
3. compiled-contract-hashes.json staleness is now caught by CIA fresh clean build was regenerated and diffed against the committed file - it is already current for every contract (no changes needed). CI now adds an explicit 4. Confidence-measurement tool committed, with completed 24h evidence
|
5a51e22 to
c1da35a
Compare
KevinMehrabi
left a comment
There was a problem hiding this comment.
Thank you for the update. I re-reviewed commit c1da35a8b837b4933b81e62062414d786c83012c. The mainnet-chain gate and compiled-hash corrections are resolved, and the new deployment guard tests pass. The following items remain before approval of PR #463:
-
REDEPLOY=1still does not guarantee a fresh origination. The script now passes the newly compiled directory todeploy_compiled_target.js, which is an improvement. However, it still passes the existing Shadownet manifest, and that manifest already containsTezFinOracle.runDeployment()therefore verifies and skips the existing address when it matches, or rejects it when it differs; it does not originate the newly compiled oracle. Please use a fresh/copy-on-write manifest for the redeployment step, or explicitly remove only the copied manifest'sTezFinOracleentry, and add a test proving thatREDEPLOY=1reaches a new origination without modifying the checked-in manifest. -
The 24-hour measurement results are not independently reproducible from the PR. The report contains numerical results, but the underlying per-feed CSV observations are not included or attached. Please commit or attach the raw dataset (or an immutable, checksummed artifact) together with the exact collection period, RPC, Pyth Core address, and feed IDs so the reported figures can be independently regenerated.
-
The committed reporting tool cannot reproduce several figures in the report and has no tests. Its
reportmode currently calculates confidence percentiles and rejection counts only. It does not calculate the reported uniquepublish_timecounts, per-threshold freshness, time-weighted system uptime, stale episodes, longest episode, or total downtime. Please make the tool deterministically generate every reported table/statistic from the supplied data and add focused tests for parsing, percentiles/boundaries, repeated publish times, freshness thresholds, downtime/episode accounting, and failed/missing feed observations. -
The PR description still contains the obsolete 25% rule. Under “Changes,” it says excessive confidence is
conf > price / 4, which conflicts with the feed-specific 25/50/10 bps policy later in the same description. Please remove or correct that statement.
The normal-period results are useful, but the report still marks stressed/high-volatility measurement as pending. That may remain an explicit production-activation gate rather than a code-merge blocker, provided the PR and audit handoff clearly state that the proposed confidence limits are not yet approved for production. Real-Pyth signed-update compatibility and any proxy-market activation likewise remain separate production gates.
Please request another review after the four PR changes above are addressed. PR #464 should remain review-only and must not be merged into the production branch.
|
KevinMehrabi
left a comment
There was a problem hiding this comment.
Re-reviewed current head 4b444b0cfeb9f3e58f9f44c778816ef21703b403. The four remaining blockers from the previous review are resolved:
REDEPLOY=1now uses a copy-on-write manifest, removes only the copiedTezFinOracleentry, performs a fresh origination from the just-compiled artifact, and preserves the source manifest. The regression test exercises the origination path.- The three raw 1,440-observation CSV datasets are committed with checksums, collection window, RPC, Pyth Core address, and feed IDs.
- The reporting tool now deterministically reproduces the confidence percentiles, rejection counts, unique publish-time counts, per-feed freshness, time-weighted uptime/downtime, and stale episodes. Focused tests cover parsing, boundaries, repeated quotes, failed/missing observations, and availability accounting.
- The PR description now states the configured 25/50/10-bps feed-specific limits instead of the obsolete 25% rule.
Independent verification on this head:
npm testindeploy/deploy_script: 59/59 passed.- The committed raw datasets reproduce the published report and all three documented SHA-256 checksums exactly.
- GitHub contract, deployment-script, and TypeScript CI jobs are all green.
- The branch is mergeable and no new code-level blocker was found.
Approved for code merge. This approval does not authorize a production oracle switch or market activation. The stressed/high-volatility measurement, governance approval of the final confidence and freshness policies, reproducible real-Pyth signed-update compatibility on a healthy deployment, the production updater/monitoring plan, and separate depeg/activation policies for proxy-priced markets remain production gates. PR #464 remains review-only and must not be merged.
Summary
Adds direct native Pyth price reads to the existing Etherlink Michelson
TezFinOraclethrough NACstaticcall_evm.The production call path is:
Changes
Price:(int64 price, uint64 conf, int32 expo, uint256 publishTime).rawConf * 10,000 > rawPrice * maxConfidenceBps(BTC/USD: 25 bps, XTZ/USD: 50 bps, USDT/USD: 10 bps);getValidatedPricechecks and Comptroller-facing interface.tzBTC -> BTC/USD;XTZ -> XTZ/USD;USDtz/USDt -> USDT/USD.shadownetdeploy profile, staged oracle configuration script, read-only verification script, and smoke-test runner.Pyth Configuration
e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b430affd4b8ad136a21d79bc82450a325ee12ff55a235abc242666e423b8bcffd032b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b0x2880aB155794e7179c9eE2e38200202908C17B4360s60s24-Hour On-Chain Measurement
Collected one sample per feed per minute from Etherlink Mainnet Pyth Core: 1,440 observations per feed. These are polling observations, not necessarily independent Pyth updates.
Unique
publish_timecounts were BTC 1,018, XTZ 1,020, and USDT 1,020. Confidence rejections added zero unavailability during this run.Time-weighted system uptime, with all three feeds required to be fresh, was 38.908% at a 60s threshold, 92.813% at 180s, 98.457% at 300s, and 99.869% at 600s. The run recorded 16 stale episodes, a longest stale episode of 413 seconds, and 22 minutes 12 seconds of total stale downtime.
Validation
npm testindeploy/deploy_script: 59/59 passed.bash contracts/tests/run_tests.sh ~/smartpy-cli/SmartPy.sh: 12/12 SmartPy suites passed.test_operation_size.py:TezFinOracle25,178 bytes; 7,590 bytes below the 32,768-byte limit.test_irm_wiring.py,test_deploy_pipeline_wiring.py, andtest_mainnet_governance_payload.py: passed.compiled-contract-hashes.jsonmatches a fresh clean build.