Install
$ agentstack add skill-omermaksutii-rugproof-oracle-manipulation ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README — it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming — see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps — measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Oracle manipulation detection
When this applies
Any code that consumes a price feed or derives a price from on-chain state:
- Chainlink:
latestAnswer,latestRoundData,getRoundData - Uniswap V2:
getReserves,getAmountsOut,price0Average - Uniswap V3/V4:
slot0,observe,consult - Curve:
get_virtual_price,get_dy - Balancer:
getRate - Custom oracle modules, on-chain TWAPs
- LP token pricing, collateral valuation, liquidation thresholds, mint/burn rates
Detection patterns
Spot price from AMM (CRITICAL — funds at risk)
(uint112 r0, uint112 r1,) = pair.getReserves();
uint256 price = r1 * 1e18 / r0; // ← flash-loan manipulable in one block
Stale Chainlink data (HIGH)
(, int256 answer,,,) = feed.latestRoundData(); // ← ignores updatedAt and answeredInRound
Required checks:
updatedAt != 0block.timestamp - updatedAt = roundIdanswer > 0- Heartbeat sanity: ETH/USD is 1h on mainnet but 24h on some L2s — verify
latestAnswer (deprecated, no freshness) (HIGH)
int256 p = feed.latestAnswer(); // ← deprecated, prefer latestRoundData
Single-source dependence (HIGH)
Only one oracle, no fallback, no cross-check against a second source.
Uniswap V3 slot0 without TWAP (CRITICAL)
(uint160 sqrtPriceX96,,,,,,) = pool.slot0(); // ← spot, manipulable
Use observe() for TWAP with sufficient lookback (≥30min for shallow pools).
Insufficient TWAP window (HIGH)
TWAP < 5 min on volatile assets or low-liquidity pools is gameable across two blocks.
Read-only reentrancy on oracle (HIGH)
Reading getVirtualPrice / getReserves mid-callback — see [[reentrancy]] §Read-only.
LP token priced via reserves directly (CRITICAL)
LP token price should use the fair LP price formula (Alpha Homora's method), not reserve / totalSupply.
Price scaling errors (HIGH)
Chainlink answers come in feed-specific decimals; mixing ETH/USD (8 decimals) with token (18 decimals) without normalizing produces silent off-by-1e10 errors.
Sequencer uptime ignored (HIGH on L2s)
On Arbitrum, Optimism, Base — must check SequencerUptimeFeed to avoid stale prices when sequencer is down.
Severity rubric
| Pattern | Severity | |---|---| | Spot-price from AMM used in liquidation/mint | Critical | | Uniswap V3 slot0 used for collateral pricing | Critical | | LP token priced via raw reserve / totalSupply | Critical | | latestRoundData without freshness/round checks | High | | Single oracle, no fallback, financial-critical path | High | | Sequencer uptime check missing on L2 | High | | Insufficient TWAP window (<5min on shallow pool) | High | | Stale heartbeat for known-volatile asset | High | | latestAnswer (deprecated) used | Medium | | Decimal-scaling mistake | High |
Remediation patterns
- For Chainlink: validate
(roundId, answer, , updatedAt, answeredInRound)— guard against stale + zero + non-positive + round-mismatch. - Use multiple oracles with deviation check (e.g. Chainlink + Uniswap V3 TWAP with ≥30min window).
- For LP tokens, use fair-LP-price math:
2 * sqrt(r0 * r1 * p0 * p1) / totalSupply. - On L2s, integrate Chainlink's
SequencerUptimeFeed(Arbitrum, Optimism, Base). - Avoid
slot0and spot-price reads for anything that affects user funds.
False-positive notes
- Display-only prices (UI/event metadata, not affecting fund flow) — Info-only.
getReservesused purely for ratio diagnostics with no downstream effect — Info.
Related
- [[flash-loan-attacks]] — most oracle attacks are funded by flash loans
- [[reentrancy]] — read-only reentrancy is an oracle-staleness issue
- [[mev-frontrunning]] — TWAP-window timing
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: omermaksutii
- Source: omermaksutii/RugProof
- License: MIT
- Homepage: https://omermaksutii.github.io/RugProof
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.