An openOracle report is two limit orders at one implied price. If nobody takes either side before the timer expires, the price can settle. If someone takes one side, they must replace the report with a new two-sided report at a larger size, and the timer restarts. It is recommended to read Oracle Life Cycle before engaging with this page.The oracle contract stores a hash of each oracle game, with optional flags for storing game data onchain. Bots and indexers should keep the event data needed to reconstruct the current preimage.
The oracle is permissionless and the contract performs almost no parameter sanity checking on its own. Anyone can create a game with any token pair, any fee, any settlement time, any callback contract, any escalation halt, etc. It is on you, the participant, to validate every parameter of a game before you report on it or dispute it. Bad parameters can lock or drain your funds, make the game economically impossible to play, or otherwise put you in a position you didn’t intend. Treat every new game as untrusted input.
Each oracle game is keyed by a reportId. The contract stores oracleGame[reportId], a keccak256 hash of the OracleGame struct below together with binding context (report ID, creator, creation block number and timestamp):
currentAmount1 / currentAmount2 Current reported amount of each token. Their ratio is the reported price.currentReporter Address that owns the report position.token1 / token2 Token pair for the game. address(0) means native ETH.settlementTime Per-round timer. A report can settle only after this much time has passed without a dispute. Respects timeType.disputeDelay Optional delay before a report or dispute can be disputed. Respects timeType.escalationHalt currentAmount1 level where multiplier growth stops.multiplier Growth rate for currentAmount1 on each dispute. 140 means 1.4x.feePercentage Swap fee paid to the previous reporter when their report is disputed. 1000 = 0.01%protocolFee / protocolFeeRecipient Protocol fee paid to address protocolFeeRecipient when set. 1000 = 0.01%settlerReward Native ETH credited to whoever settles the game.callbackContract / callbackGasLimit Optional settlement callback target and gas limit.flags Bitfield for optional game behavior: 1 = timeType: use timestamps instead of block numbers for the game clock influences settlementTime and disputeDelay 2 = track dispute history 4 = store the full live OracleGame and helper from creation, update the game on disputes and settlement 8 = store finalPrice after settlement 16 = store settlementEligibility and update it on each dispute 32 = charge swap and protocol fees only when the standing report's currentAmount1 is at or above escalationHalt 64 = allow larger-than-minimum escalation up to escalationHalt
Creator, creation timestamp and creation block number when flag 4 is set. Add reportId to reconstruct PreimageHelper.
settlementEligibility(reportId)
Latest reportTimestamp + settlementTime when flag 16 is set.
finalPrice(reportId)
Settled ratio when flag 8 is set: floor(currentAmount1 * 1e30 / currentAmount2). This uses raw token amounts; account for token decimals.
disputeHistory(reportId, index)
Report amounts, block base fee and report time when flag 2 is set. Index 0 is the initial report.
settlementEligibility uses timestamps when flag 1 is set and block numbers otherwise. It stays at the eligibility value after settlement; reaching it does not mean someone has called settle(). The optional getters return zero/default values when their data has not been stored.
ReportSubmitted is emitted when a new game starts. ReportDisputed is emitted when the live report is replaced. ReportSettled only tells you the report settled; final amounts come from the preimage supplied to settle() or from optional storage flags.The packed payloads are tightly packed bytes instead of normal ABI-encoded event fields. Operators need a decoder for the packed layout.
Decoded packed values populate the OracleGame struct above and a small PreimageHelper. Every PreimageHelper field except reportId lives in the packed payload; reportId comes from the indexed event topic. dispute() and settle() take this pair as calldata. report() takes only the game parameters and creates the helper itself.
struct PreimageHelper { uint256 reportId; // comes from indexed event topic address creator; uint256 blockTimestamp; // game creation timestamp uint256 blockNumber; // game creation block number}
The state hash is:
keccak256(abi.encode(params, helper))
Use the decoded structs, not the tightly packed event bytes, for this hash. The helper’s creation fields stay unchanged across disputes and settlement.
1. token1 and token2 must be normal supported tokens2. callbackGasLimit must be safely below the practical transaction gas limit3. settlementTime should be low enough relative to the value of reporting or disputing, since your funds can be locked for at least that long
Outside native ETH with address(0) as the token address, only normal ERC-20s are supported. USDC and USDT-style return behavior is supported. Fee-on-transfer, rebasing, hook, and other unusual token mechanics are not supported.Inspect callbackGasLimit before entering a game. Settlement attempts a fixed callback if callbackContract is set. If the gas limit is impossible to fully attempt, settlement reverts and the current reporter’s funds can remain locked. Every disputer inherits the callback parameters from the original report.Inspect settlementTime with the same care. It is an arbitrary uncapped value set by the game creator, and reporter or disputer funds can be locked for at least that long. If the lock time is too long relative to the value of reporting or disputing, ignore the game.These are critical safety filters, but they are not the only parameters with serious consequences. Swap fees, protocol fees, settler reward, multiplier, escalation halt, and dispute delay can all make reporting or disputing unprofitable if misconfigured.
This lets a caller bind the transaction to the block number and timestamp range they expected when building the transaction. If the transaction is included in a block outside the allowed block number or timestamp bound, the call reverts.Timing validation is optional. If blockTimestamp is zero, the contract skips the entire check.
report() sets the game parameters and submits the first live report.When calling report(), pass reportTimestamp, lastReportOppoTime, settlementTimestamp, and numReports as zero inside params.OracleGame parameters behave as described in the Oracle game section above.If you fund a report with currentReporter set to another address, the report funds are credited to that address when the report settles or is later disputed.Funding can come from external token transfers, native ETH, or internal balances. If tryInternalBalance1 or tryInternalBalance2 is true, the contract tries to use currentReporter’s internal balance before pulling the rest externally. If currentReporter != msg.sender and an internal-balance flag is true, that token must be fully covered by internal balance and allowance or the call reverts. Any ETH required for the report, including settlerReward, must be supplied through msg.value.
currentAmount1 of token1currentAmount2 of token2settlerReward in native ETH
If a token is native ETH, the required external amount is paid through msg.value. If a token is an ERC-20, any required external amount is pulled from msg.sender.Any excess ETH is credited to currentReporter.After reporting, you are exposed to being disputed before the timer expires. See Counter-dispute risk below for the loss profile.
If an integrating application wants to pay someone to create a report, it can commit to the OracleGame parameters it wants and compensate whichever caller supplies a matching report.
A reportId is disputable from reportTimestamp + disputeDelay up to (but not past) reportTimestamp + settlementTime, where reportTimestamp is from the most recent ReportSubmitted or ReportDisputed event for that reportId. Both events publish the current live preimage; for dispute bots they are equivalent signals.Anyone can call dispute() to replace the live report with a larger two-sided report at a new implied price. A disputer earns the absolute difference in USD value between the two sides of the prior report, less the swap fee, the protocol fee and gas. The disputer also has exposure to being counter-disputed themselves.To dispute, call:
params and helper must reconstruct the current stored hash for reportId. If they do not, the call reverts.By passing in the matching preimage, the disputer is agreeing to the oracle game encoded in that hash. See the Oracle game section above for the rules baked into each parameter.The swap side is derived from your price revision: if newAmount2 * currentAmount1 > currentAmount2 * newAmount1, the swapped token is token2; otherwise it is token1. The previous reporter is paid out in the swapped token, which forces them into the cheap side and lets you capture the mispricing spread minus fees. Your new ratio newAmount1 / newAmount2 becomes the next reported price.newAmount1 normally follows:
With flag 64 set and currentAmount1 < escalationHalt, newAmount1 may instead be any amount from the calculated minimum through escalationHalt, inclusive. At or above the halt, it must still be exactly currentAmount1 + 1.newAmount2 is chosen by the disputer and sets the new price. Once the dispute lands, newAmount1 and newAmount2 become the next live report’s currentAmount1 and currentAmount2.Disputes are too late once the game reaches the settlement boundary:
currentTime >= reportTimestamp + settlementTime
Fees are charged on the old amount of the swapped token. The swap fee goes to the previous reporter. The protocol fee goes to protocolFeeRecipient if one is set. Both swap fee (feePercentage) and protocolFee are in 1e7 units, meaning 1000 corresponds to a fee of 0.01%.In a true self-dispute, where the previous reporter is also msg.sender and disputer, the previous position is netted into the new one instead of being paid out as a normal third-party dispute. The protocol fee still applies, subject to flag 32 below.tryInternalBalance1 and tryInternalBalance2 work the same way as in report(). If true, the contract tries to fund that token from disputer’s internal balance. If disputer != msg.sender, the internal balance and allowance must fully cover that token’s required contribution or the call reverts. If false, any required external ERC-20 contribution is pulled from msg.sender, and any required ETH must come from msg.value.With flag 32 set, both fees are zero while the standing report’s currentAmount1 < escalationHalt. A dispute that first reaches the halt is therefore fee-free; fees start on the next dispute. Without this flag, fees apply on every dispute.
Disputer funds: max(0, newAmount2 - currentAmount2) of token2 self-dispute: newAmount1 - currentAmount1 + protocolFee of token1 normal dispute: newAmount1 + currentAmount1 + swapFee + protocolFee of token1Disputer receives: max(0, currentAmount2 - newAmount2) of token2Previous reporter receives, normal dispute only: 2 * currentAmount1 + swapFee of token1
If the swapped token is token2:
Disputer funds: max(0, newAmount1 - currentAmount1) of token1 self-dispute: max(0, newAmount2 + protocolFee - currentAmount2) of token2 normal dispute: newAmount2 + currentAmount2 + swapFee + protocolFee of token2Disputer receives, self-dispute only: max(0, currentAmount2 - (newAmount2 + protocolFee)) of token2Previous reporter receives, normal dispute only: 2 * currentAmount2 + swapFee of token2
Any excess ETH is credited to disputer.The protocol fee recipient receives protocolFee of the swapped token if one is set.After disputing, your own report is exposed to being disputed in turn. See Counter-dispute risk below for the loss profile.
params and helper must match the current stored state hash. The contract then marks the game settled, credits the current reporter with both report amounts, credits the settler with settlerReward, optionally stores the final price or full final game, and emits ReportSettled(reportId).Settlement sets settlementTimestamp to the settlement block number or timestamp, according to flag 1, and stores the hash of that updated game. The pre-settlement preimage no longer matches.Game payouts are credited to internal balances. Users can later withdraw, or callers can use internal-balance helpers where appropriate.If callbackContract is set, settlement calls:
Any live report, whether submitted as an initial report or as a dispute, can itself be disputed before the timer expires. Your payout depends on which side the next dispute’s price implies is swapped. In the normal case, that is the lower-valued side.For example, if you reported 100 USD of WETH against 100 USD of USDC, and WETH then drops 1%, there is now roughly 99 USD of WETH and 100 USD of USDC in the report. A dispute at the corrected price takes the WETH side, and you receive 2 * 99 USD worth of WETH plus the swap fee on currentAmount1. If the swap fee is 1% and applies in this round, you additionally receive about 1% of 99 USD denominated in WETH. The protocol fee on currentAmount1 does not flow to you.Your realized loss versus the true price is the spread (1 USD) net of the swap fee credit.
Same as deposit, but funded by from via a Permit2 witness signature. The signature is only valid when relayed by the intended caller, crediting the intended beneficiary, attributed to the intended from, and matching the intended intent hash. ETH is not supported through this path.
internalTransferFrom(from, to, token, amount)
Moves internal balance from from to to. If from != msg.sender, the caller must hold sufficient internal allowance (see Delegation below).
Sends amount of token from the caller’s internal balance out as a real transfer, either to msg.sender or to the specified to. If amount exceeds the available balance, the contract sends what’s available instead of reverting.
pushOrCredit(token, to, amount)pushOrCredit(token, to, amount, gasLimit)
Debits the caller’s internal balance and tries to transfer the tokens to to externally. A failed ETH call, reverted ERC-20 call, or ERC-20 return value of false credits to’s internal balance instead. The ETH call uses 50,000 gas by default or the supplied gasLimit. ERC-20 calls do not use this gas cap, and malformed return data can still revert the call.address(0) as token means native ETH throughout. Internal balances keep a one-unit sentinel in touched slots, so the displayed raw storage amount may include dust that is not withdrawable.
approveInternal allows a spender to use the owner’s internal balance:
approveInternal(spender, token, amount)
This approval only applies to balances already inside the oracle. It does not approve external ERC-20 transfers. To change a nonzero allowance to another nonzero amount, first call approveInternal with zero. type(uint256).max gives an allowance that is not decremented when spent.A spender can use approved internal balance through internalTransferFrom, or through delegated report() / dispute() funding when the corresponding tryInternalBalance flag is true. If the flag is false, the contract expects msg.sender to fund that token externally. If the flag is true but the internal balance or internal allowance is insufficient, the call reverts.Only approve addresses you trust. A spender with internal allowance can move or spend your internal balance according to that allowance.
For the initial reporter, compensation must come from the application or strategy that asked for the report.A simple initial report() caller EV model is:
EV = external_compensation_usd - currentAmount1_to_usd * volatility_loss - gas_fees_usd
This ignores swap fees received when your dispute is itself disputed, which strictly help you as a disputer. swap_fee_usd and protocol_fee_usd are levied on the swapped token’s amount in the current report before you dispute, which is the smaller-valued side. Both fees are zero before escalation halt when flag 32 is set.volatility_loss captures the expected loss from being counter-disputed before the timer expires. When the token1/token2 ratio drifts during the settlement window, the next disputer can take the cheap side from you at the stale price, and the spread becomes your loss. The longer settlementTime is and the more the pair moves, the more loss you should price in. A fuller treatment of this term lives in Oracle Accuracy & Cost.An appropriate volatility_loss term is approximately:
0.65 * standard deviation of settlementTime returns for the token1/token2 ratio
You can increase the coefficient for more buffer, but that reduces competitiveness.Estimating short-window volatility has a high skill cap. If volatility spikes faster than your model adjusts, you can lose money.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"openOracle","colors":{"primary":"#00CF9C","light":"#00CF9C","dark":"#0a0a0a"},"logo":{"light":"https://mintcdn.com/openoracle/U4lTbao-51w4qpSW/logo-light.svg?fit=max\u0026auto=format\u0026n=U4lTbao-51w4qpSW\u0026q=85\u0026s=7cab4632108a10d7783fa0566fef0f8b","dark":"https://mintcdn.com/openoracle/U4lTbao-51w4qpSW/logo-dark.svg?fit=max\u0026auto=format\u0026n=U4lTbao-51w4qpSW\u0026q=85\u0026s=f76e5ef59387ce6616220541932ed8b0"},"favicon":"https://mintcdn.com/openoracle/TDFh-vE_gIrVCTZK/favicon-docs.svg?fit=max\u0026auto=format\u0026n=TDFh-vE_gIrVCTZK\u0026q=85\u0026s=fb54dc620a157a63cd933254487b4c59","seo":{"metatags":{"og:image":"https://docs.openoracle.org/og-docs.png","og:image:width":"1200","og:image:height":"630","og:image:type":"image/png","twitter:image":"https://docs.openoracle.org/og-docs.png","twitter:image:width":"1200","twitter:image:height":"630"}},"fonts":{"heading":{"family":"Berkeley Mono","weight":700,"source":"public/fonts/Berkeley Mono Variable.woff2","format":"woff2"}},"styling":{"latex":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"openoracle","hasAudioNarration":false,"actualSubdomain":"openoracle","customDomains":["docs.openoracle.org"],"gitSource":{"type":"github","owner":"openoracleproject","repo":"openoracle-monorepo","deployBranch":"main","contentDirectory":"documentation","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae20246f9cefd8f8d7a4970","collectionId":"d21dfaaa-7bf0-411b-aee7-12c64fc49891","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae20246f9cefd8f8d7a4970"},"entitlements":{},"buildId":"6ae20246f9cefd8f8d7a4970","clientVersion":"0.0.4021","searchFilterCounts":[{"language":"default","tag":"openPunt","count":19},{"language":"default","tag":"openLend","count":16},{"language":"default","tag":"openOracle","count":15},{"language":"default","tag":"Resources","count":9},{"language":"default","tag":"Contract Reference","count":8},{"language":"default","tag":"openSwap","count":8},{"language":"default","tag":"Introduction","count":6},{"language":"default","tag":"Documentation","count":6},{"language":"default","tag":"Technical Details","count":6},{"language":"default","tag":"Unique mechanics","count":6}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"custom.css","href":"/_mintlify/custom/openoracle/fb0f5ea2f4587486/custom.css"}],"page":{"pagePath":"openoracle/game-guide","slug":"/openoracle/game-guide","pageMetadata":{"title":"Smart Contract Reference","description":"Reference for participating in the openOracle game on-chain","href":"/openoracle/game-guide"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Reference for participating in the openOracle game on-chain\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,p:`p`,pre:`pre`,span:`span`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,..._provideComponents(),...props.components},{CodeBlock,Heading,Table,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(Heading,{level:`2`,id:`core-idea`,children:`Core idea`}),`\n`,_jsxs(_components.p,{children:[`An openOracle report is two limit orders at one implied price. If nobody takes either side before the timer expires, the price can settle. If someone takes one side, they must replace the report with a new two-sided report at a larger size, and the timer restarts. It is recommended to read `,_jsx(_components.a,{href:`/openoracle/oracle-life-cycle`,children:`Oracle Life Cycle`}),` before engaging with this page.`]}),`\n`,_jsx(_components.p,{children:`The oracle contract stores a hash of each oracle game, with optional flags for storing game data onchain. Bots and indexers should keep the event data needed to reconstruct the current preimage.`}),`\n`,_jsx(Warning,{children:_jsx(_components.p,{children:`The oracle is permissionless and the contract performs almost no parameter sanity checking on its own. Anyone can create a game with any token pair, any fee, any settlement time, any callback contract, any escalation halt, etc. It is on you, the participant, to validate every parameter of a game before you report on it or dispute it. Bad parameters can lock or drain your funds, make the game economically impossible to play, or otherwise put you in a position you didn’t intend. Treat every new game as untrusted input.`})}),`\n`,_jsx(Heading,{level:`2`,id:`oracle-game`,children:`Oracle game`}),`\n`,_jsxs(_components.p,{children:[`Each oracle game is keyed by a `,_jsx(_components.code,{children:`reportId`}),`. The contract stores `,_jsx(_components.code,{children:`oracleGame[reportId]`}),`, a keccak256 hash of the `,_jsx(_components.code,{children:`OracleGame`}),` struct below together with binding context (report ID, creator, creation block number and timestamp):`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`22`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`22`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`struct`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` OracleGame`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint128`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` currentAmount1;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint128`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` currentAmount2;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` address`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` currentReporter;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint48`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` reportTimestamp;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint48`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` settlementTimestamp;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` address`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` token1;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint48`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` lastReportOppoTime;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint48`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` settlementTime;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint128`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` escalationHalt;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` address`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` protocolFeeRecipient;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint96`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` settlerReward;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` address`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` token2;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint24`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` numReports;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint24`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` disputeDelay;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint24`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` feePercentage;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint16`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` multiplier;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` address`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` callbackContract;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint32`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` callbackGasLimit;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint24`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` protocolFee;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint8`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` flags;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Each field operates as follows:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`50`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`50`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`currentAmount1 / currentAmount2`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` Current reported amount of each token. Their ratio is the reported price.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`currentReporter`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` Address that owns the report position.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`token1 / token2`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` Token pair for the game. address(0) means native ETH.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`settlementTime`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` Per-round timer. A report can settle only after this much time has`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` passed without a dispute. Respects timeType.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`disputeDelay`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` Optional delay before a report or dispute can be disputed.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` Respects timeType.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`escalationHalt`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` currentAmount1 level where multiplier growth stops.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`multiplier`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` Growth rate for currentAmount1 on each dispute. 140 means 1.4x.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`feePercentage`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` Swap fee paid to the previous reporter when their report is disputed.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` 1000 = 0.01%`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`protocolFee / protocolFeeRecipient`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` Protocol fee paid to address protocolFeeRecipient when set.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` 1000 = 0.01%`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`settlerReward`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` Native ETH credited to whoever settles the game.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`callbackContract / callbackGasLimit`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` Optional settlement callback target and gas limit.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`flags`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` Bitfield for optional game behavior:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` 1 = timeType: use timestamps instead of block numbers for the game clock`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` influences settlementTime and disputeDelay`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` 2 = track dispute history`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` 4 = store the full live OracleGame and helper from creation,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` update the game on disputes and settlement`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` 8 = store finalPrice after settlement`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` 16 = store settlementEligibility and update it on each dispute`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` 32 = charge swap and protocol fees only when the standing report's`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` currentAmount1 is at or above escalationHalt`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` 64 = allow larger-than-minimum escalation up to escalationHalt`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(Heading,{level:`2`,id:`onchain-reads`,children:`Onchain reads`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Getter`}),_jsx(_components.th,{children:`Value`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`oracleGame(reportId)`})}),_jsx(_components.td,{children:`Current state hash, including after settlement.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`storedGame(reportId)`})}),_jsxs(_components.td,{children:[`Full current game when flag `,_jsx(_components.code,{children:`4`}),` is set.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`storedHelper(reportId)`})}),_jsxs(_components.td,{children:[`Creator, creation timestamp and creation block number when flag `,_jsx(_components.code,{children:`4`}),` is set. Add `,_jsx(_components.code,{children:`reportId`}),` to reconstruct `,_jsx(_components.code,{children:`PreimageHelper`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`settlementEligibility(reportId)`})}),_jsxs(_components.td,{children:[`Latest `,_jsx(_components.code,{children:`reportTimestamp + settlementTime`}),` when flag `,_jsx(_components.code,{children:`16`}),` is set.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`finalPrice(reportId)`})}),_jsxs(_components.td,{children:[`Settled ratio when flag `,_jsx(_components.code,{children:`8`}),` is set: `,_jsx(_components.code,{children:`floor(currentAmount1 * 1e30 / currentAmount2)`}),`. This uses raw token amounts; account for token decimals.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`disputeHistory(reportId, index)`})}),_jsxs(_components.td,{children:[`Report amounts, block base fee and report time when flag `,_jsx(_components.code,{children:`2`}),` is set. Index `,_jsx(_components.code,{children:`0`}),` is the initial report.`]})]})]})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`settlementEligibility`}),` uses timestamps when flag `,_jsx(_components.code,{children:`1`}),` is set and block numbers otherwise. It stays at the eligibility value after settlement; reaching it does not mean someone has called `,_jsx(_components.code,{children:`settle()`}),`. The optional getters return zero/default values when their data has not been stored.`]}),`\n`,_jsx(Heading,{level:`2`,id:`events-and-packed-layout`,children:`Events and packed layout`}),`\n`,_jsx(_components.p,{children:`There are three main oracle game events:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`event`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` ReportSubmitted`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`uint256`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` indexed`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` reportId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`bytes`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` packed`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`event`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` ReportDisputed`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`uint256`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` indexed`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` reportId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`bytes`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` packed`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`event`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` ReportSettled`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`uint256`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` indexed`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` reportId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`ReportSubmitted`}),` is emitted when a new game starts. `,_jsx(_components.code,{children:`ReportDisputed`}),` is emitted when the live report is replaced. `,_jsx(_components.code,{children:`ReportSettled`}),` only tells you the report settled; final amounts come from the preimage supplied to `,_jsx(_components.code,{children:`settle()`}),` or from optional storage flags.`]}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`packed`}),` payloads are tightly packed bytes instead of normal ABI-encoded event fields. Operators need a decoder for the packed layout.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`28`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`28`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`ReportSubmitted / ReportDisputed packed layout:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`currentAmount1 16 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`currentAmount2 16 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`currentReporter 20 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`reportTimestamp 6 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`settlementTimestamp 6 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`token1 20 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`lastReportOppoTime 6 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`settlementTime 6 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`escalationHalt 16 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`protocolFeeRecipient 20 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`settlerReward 12 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`token2 20 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`numReports 3 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`disputeDelay 3 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`feePercentage 3 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`multiplier 2 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`callbackContract 20 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`callbackGasLimit 4 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`protocolFee 3 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`flags 1 byte`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`creator 20 bytes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`blockTimestamp 6 bytes // game creation timestamp`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`blockNumber 6 bytes // game creation block number`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Total: 235 bytes. reportId is the indexed event topic.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`Decoded packed values populate the `,_jsx(_components.a,{href:`#oracle-game`,children:_jsx(_components.code,{children:`OracleGame`})}),` struct above and a small `,_jsx(_components.code,{children:`PreimageHelper`}),`. Every `,_jsx(_components.code,{children:`PreimageHelper`}),` field except `,_jsx(_components.code,{children:`reportId`}),` lives in the packed payload; `,_jsx(_components.code,{children:`reportId`}),` comes from the indexed event topic. `,_jsx(_components.code,{children:`dispute()`}),` and `,_jsx(_components.code,{children:`settle()`}),` take this pair as calldata. `,_jsx(_components.code,{children:`report()`}),` takes only the game parameters and creates the helper itself.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`6`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`struct`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` PreimageHelper`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint256`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` reportId; `}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// comes from indexed event topic`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` address`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` creator;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint256`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` blockTimestamp; `}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// game creation timestamp`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint256`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` blockNumber; `}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// game creation block number`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`The state hash is:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`keccak256`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`abi`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`encode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(params, helper))`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Use the decoded structs, not the tightly packed event bytes, for this hash. The helper’s creation fields stay unchanged across disputes and settlement.`}),`\n`,_jsx(Heading,{level:`2`,id:`critical-filters`,children:`Critical filters`}),`\n`,_jsx(_components.p,{children:`If a game does not match your filters, ignore it.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`1. token1 and token2 must be normal supported tokens`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`2. callbackGasLimit must be safely below the practical transaction gas limit`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`3. settlementTime should be low enough relative to the value of reporting`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` or disputing, since your funds can be locked for at least that long`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`Outside native ETH with `,_jsx(_components.code,{children:`address(0)`}),` as the token address, only normal ERC-20s are supported. USDC and USDT-style return behavior is supported. Fee-on-transfer, rebasing, hook, and other unusual token mechanics are not supported.`]}),`\n`,_jsxs(_components.p,{children:[`Inspect `,_jsx(_components.code,{children:`callbackGasLimit`}),` before entering a game. Settlement attempts a fixed callback if `,_jsx(_components.code,{children:`callbackContract`}),` is set. If the gas limit is impossible to fully attempt, settlement reverts and the current reporter’s funds can remain locked. Every disputer inherits the callback parameters from the original report.`]}),`\n`,_jsxs(_components.p,{children:[`Inspect `,_jsx(_components.code,{children:`settlementTime`}),` with the same care. It is an arbitrary uncapped value set by the game creator, and reporter or disputer funds can be locked for at least that long. If the lock time is too long relative to the value of reporting or disputing, ignore the game.`]}),`\n`,_jsx(_components.p,{children:`These are critical safety filters, but they are not the only parameters with serious consequences. Swap fees, protocol fees, settler reward, multiplier, escalation halt, and dispute delay can all make reporting or disputing unprofitable if misconfigured.`}),`\n`,_jsx(Heading,{level:`2`,id:`timing-boundaries`,children:`Timing Boundaries`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`report()`}),` and `,_jsx(_components.code,{children:`dispute()`}),` both accept timing boundaries:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`6`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`struct`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` TimingBoundaries`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint256`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` blockNumber;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint256`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` blockNumberBound;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint256`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` blockTimestamp;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint256`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` blockTimestampBound;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`This lets a caller bind the transaction to the block number and timestamp range they expected when building the transaction. If the transaction is included in a block outside the allowed block number or timestamp bound, the call reverts.`}),`\n`,_jsxs(_components.p,{children:[`Timing validation is optional. If `,_jsx(_components.code,{children:`blockTimestamp`}),` is zero, the contract skips the entire check.`]}),`\n`,_jsx(Heading,{level:`2`,id:`playing-the-game`,children:`Playing the game`}),`\n`,_jsx(Heading,{level:`3`,id:`reporting-/-creating-a-game`,children:`Reporting / Creating a game`}),`\n`,_jsxs(_components.p,{children:[`Anyone can call `,_jsx(_components.code,{children:`report()`}),` to open a new oracle game with a chosen token pair and initial price:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`6`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` report`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` OracleGame`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` calldata`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` params`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` bool`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` tryInternalBalance1`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` bool`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` tryInternalBalance2`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` TimingBoundaries`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` calldata`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` timing`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`external`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` payable`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` returns`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`uint256`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` reportId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`report()`}),` sets the game parameters and submits the first live report.`]}),`\n`,_jsxs(_components.p,{children:[`When calling `,_jsx(_components.code,{children:`report()`}),`, pass `,_jsx(_components.code,{children:`reportTimestamp`}),`, `,_jsx(_components.code,{children:`lastReportOppoTime`}),`, `,_jsx(_components.code,{children:`settlementTimestamp`}),`, and `,_jsx(_components.code,{children:`numReports`}),` as zero inside `,_jsx(_components.code,{children:`params`}),`.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`OracleGame`}),` parameters behave as described in the `,_jsx(_components.a,{href:`#oracle-game`,children:`Oracle game`}),` section above.`]}),`\n`,_jsxs(_components.p,{children:[`If you fund a report with `,_jsx(_components.code,{children:`currentReporter`}),` set to another address, the report funds are credited to that address when the report settles or is later disputed.`]}),`\n`,_jsxs(_components.p,{children:[`Funding can come from external token transfers, native ETH, or internal balances. If `,_jsx(_components.code,{children:`tryInternalBalance1`}),` or `,_jsx(_components.code,{children:`tryInternalBalance2`}),` is true, the contract tries to use `,_jsx(_components.code,{children:`currentReporter`}),`’s internal balance before pulling the rest externally. If `,_jsx(_components.code,{children:`currentReporter != msg.sender`}),` and an internal-balance flag is true, that token must be fully covered by internal balance and allowance or the call reverts. Any ETH required for the report, including `,_jsx(_components.code,{children:`settlerReward`}),`, must be supplied through `,_jsx(_components.code,{children:`msg.value`}),`.`]}),`\n`,_jsx(Heading,{level:`4`,id:`token-flows`,children:`Token flows`}),`\n`,_jsx(_components.p,{children:`To create a report, the game must be funded with:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`4`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`currentAmount1 of token1`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`currentAmount2 of token2`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`settlerReward in native ETH`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`If a token is native ETH, the required external amount is paid through `,_jsx(_components.code,{children:`msg.value`}),`. If a token is an ERC-20, any required external amount is pulled from `,_jsx(_components.code,{children:`msg.sender`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Any excess ETH is credited to `,_jsx(_components.code,{children:`currentReporter`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`After reporting, you are exposed to being disputed before the timer expires. See `,_jsx(_components.a,{href:`#counter-dispute-risk`,children:`Counter-dispute risk`}),` below for the loss profile.`]}),`\n`,_jsx(Heading,{level:`4`,id:`paying-someone-else-to-report`,children:`Paying someone else to report`}),`\n`,_jsxs(_components.p,{children:[`If an integrating application wants to pay someone to create a report, it can commit to the `,_jsx(_components.code,{children:`OracleGame`}),` parameters it wants and compensate whichever caller supplies a matching report.`]}),`\n`,_jsx(Heading,{level:`3`,id:`disputing`,children:`Disputing`}),`\n`,_jsxs(_components.p,{children:[`A `,_jsx(_components.code,{children:`reportId`}),` is disputable from `,_jsx(_components.code,{children:`reportTimestamp + disputeDelay`}),` up to (but not past) `,_jsx(_components.code,{children:`reportTimestamp + settlementTime`}),`, where `,_jsx(_components.code,{children:`reportTimestamp`}),` is from the most recent `,_jsx(_components.code,{children:`ReportSubmitted`}),` or `,_jsx(_components.code,{children:`ReportDisputed`}),` event for that `,_jsx(_components.code,{children:`reportId`}),`. Both events publish the current live preimage; for dispute bots they are equivalent signals.`]}),`\n`,_jsxs(_components.p,{children:[`Anyone can call `,_jsx(_components.code,{children:`dispute()`}),` to replace the live report with a larger two-sided report at a new implied price. A disputer earns the absolute difference in USD value between the two sides of the prior report, less the swap fee, the protocol fee and gas. The disputer also has exposure to being counter-disputed themselves.`]}),`\n`,_jsx(_components.p,{children:`To dispute, call:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`11`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`11`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` dispute`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint256`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` reportId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint128`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` newAmount1`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint128`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` newAmount2`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` address`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` disputer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` bool`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` tryInternalBalance1`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` bool`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` tryInternalBalance2`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` OracleGame`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` calldata`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` params`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` PreimageHelper`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` calldata`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` helper`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` TimingBoundaries`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` calldata`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` timing`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`external`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` payable`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`params`}),` and `,_jsx(_components.code,{children:`helper`}),` must reconstruct the current stored hash for `,_jsx(_components.code,{children:`reportId`}),`. If they do not, the call reverts.`]}),`\n`,_jsxs(_components.p,{children:[`By passing in the matching preimage, the disputer is agreeing to the oracle game encoded in that hash. See the `,_jsx(_components.a,{href:`#oracle-game`,children:`Oracle game`}),` section above for the rules baked into each parameter.`]}),`\n`,_jsxs(_components.p,{children:[`The swap side is derived from your price revision: if `,_jsx(_components.code,{children:`newAmount2 * currentAmount1 > currentAmount2 * newAmount1`}),`, the swapped token is `,_jsx(_components.code,{children:`token2`}),`; otherwise it is `,_jsx(_components.code,{children:`token1`}),`. The previous reporter is paid out in the swapped token, which forces them into the cheap side and lets you capture the mispricing spread minus fees. Your new ratio `,_jsx(_components.code,{children:`newAmount1 / newAmount2`}),` becomes the next reported price.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`newAmount1`}),` normally follows:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`if currentAmount1 \u003c escalationHalt`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` newAmount1 = min(escalationHalt, floor(currentAmount1 * multiplier / 100))`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`else`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` newAmount1 = currentAmount1 + 1`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`With flag `,_jsx(_components.code,{children:`64`}),` set and `,_jsx(_components.code,{children:`currentAmount1 \u003c escalationHalt`}),`, `,_jsx(_components.code,{children:`newAmount1`}),` may instead be any amount from the calculated minimum through `,_jsx(_components.code,{children:`escalationHalt`}),`, inclusive. At or above the halt, it must still be exactly `,_jsx(_components.code,{children:`currentAmount1 + 1`}),`.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`newAmount2`}),` is chosen by the disputer and sets the new price. Once the dispute lands, `,_jsx(_components.code,{children:`newAmount1`}),` and `,_jsx(_components.code,{children:`newAmount2`}),` become the next live report’s `,_jsx(_components.code,{children:`currentAmount1`}),` and `,_jsx(_components.code,{children:`currentAmount2`}),`.`]}),`\n`,_jsx(_components.p,{children:`Disputes are too late once the game reaches the settlement boundary:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`currentTime >= reportTimestamp + settlementTime`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`Fees are charged on the old amount of the swapped token. The swap fee goes to the previous reporter. The protocol fee goes to `,_jsx(_components.code,{children:`protocolFeeRecipient`}),` if one is set. Both swap fee (`,_jsx(_components.code,{children:`feePercentage`}),`) and `,_jsx(_components.code,{children:`protocolFee`}),` are in 1e7 units, meaning 1000 corresponds to a fee of 0.01%.`]}),`\n`,_jsxs(_components.p,{children:[`In a true self-dispute, where the previous reporter is also `,_jsx(_components.code,{children:`msg.sender`}),` and `,_jsx(_components.code,{children:`disputer`}),`, the previous position is netted into the new one instead of being paid out as a normal third-party dispute. The protocol fee still applies, subject to flag `,_jsx(_components.code,{children:`32`}),` below.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`tryInternalBalance1`}),` and `,_jsx(_components.code,{children:`tryInternalBalance2`}),` work the same way as in `,_jsx(_components.code,{children:`report()`}),`. If true, the contract tries to fund that token from `,_jsx(_components.code,{children:`disputer`}),`’s internal balance. If `,_jsx(_components.code,{children:`disputer != msg.sender`}),`, the internal balance and allowance must fully cover that token’s required contribution or the call reverts. If false, any required external ERC-20 contribution is pulled from `,_jsx(_components.code,{children:`msg.sender`}),`, and any required ETH must come from `,_jsx(_components.code,{children:`msg.value`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`With flag `,_jsx(_components.code,{children:`32`}),` set, both fees are zero while the standing report’s `,_jsx(_components.code,{children:`currentAmount1 \u003c escalationHalt`}),`. A dispute that first reaches the halt is therefore fee-free; fees start on the next dispute. Without this flag, fees apply on every dispute.`]}),`\n`,_jsx(Heading,{level:`4`,id:`token-flows-2`,children:`Token flows`}),`\n`,_jsxs(_components.p,{children:[`If the swapped token is `,_jsx(_components.code,{children:`token1`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`15`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`15`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Disputer funds:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` max(0, newAmount2 - currentAmount2) of token2`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` self-dispute:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` newAmount1 - currentAmount1 + protocolFee of token1`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` normal dispute:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` newAmount1 + currentAmount1 + swapFee + protocolFee of token1`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Disputer receives:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` max(0, currentAmount2 - newAmount2) of token2`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Previous reporter receives, normal dispute only:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` 2 * currentAmount1 + swapFee of token1`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`If the swapped token is `,_jsx(_components.code,{children:`token2`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`15`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`15`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Disputer funds:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` max(0, newAmount1 - currentAmount1) of token1`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` self-dispute:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` max(0, newAmount2 + protocolFee - currentAmount2) of token2`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` normal dispute:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` newAmount2 + currentAmount2 + swapFee + protocolFee of token2`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Disputer receives, self-dispute only:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` max(0, currentAmount2 - (newAmount2 + protocolFee)) of token2`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Previous reporter receives, normal dispute only:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` 2 * currentAmount2 + swapFee of token2`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`Any excess ETH is credited to `,_jsx(_components.code,{children:`disputer`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`The protocol fee recipient receives `,_jsx(_components.code,{children:`protocolFee`}),` of the swapped token if one is set.`]}),`\n`,_jsxs(_components.p,{children:[`After disputing, your own report is exposed to being disputed in turn. See `,_jsx(_components.a,{href:`#counter-dispute-risk`,children:`Counter-dispute risk`}),` below for the loss profile.`]}),`\n`,_jsx(Heading,{level:`3`,id:`settling`,children:`Settling`}),`\n`,_jsxs(_components.p,{children:[`Once the latest report has survived for `,_jsx(_components.code,{children:`settlementTime`}),`, anyone can settle:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`5`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` settle`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint256`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` reportId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` OracleGame`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` calldata`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` params`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` PreimageHelper`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` calldata`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` helper`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`external`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`params`}),` and `,_jsx(_components.code,{children:`helper`}),` must match the current stored state hash. The contract then marks the game settled, credits the current reporter with both report amounts, credits the settler with `,_jsx(_components.code,{children:`settlerReward`}),`, optionally stores the final price or full final game, and emits `,_jsx(_components.code,{children:`ReportSettled(reportId)`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Settlement sets `,_jsx(_components.code,{children:`settlementTimestamp`}),` to the settlement block number or timestamp, according to flag `,_jsx(_components.code,{children:`1`}),`, and stores the hash of that updated game. The pre-settlement preimage no longer matches.`]}),`\n`,_jsx(_components.p,{children:`Game payouts are credited to internal balances. Users can later withdraw, or callers can use internal-balance helpers where appropriate.`}),`\n`,_jsxs(_components.p,{children:[`If `,_jsx(_components.code,{children:`callbackContract`}),` is set, settlement calls:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`8`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`openOracleCallback`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint256`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` reportId,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint256`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` currentAmount1,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint256`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` currentAmount2,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` uint256`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` currentTime,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` address`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` token1,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` address`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` token2`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Callback failure itself does not undo settlement, but an impossible callback gas limit can still make settlement revert.`}),`\n`,_jsx(Heading,{level:`3`,id:`counter-dispute-risk`,children:`Counter-dispute risk`}),`\n`,_jsx(_components.p,{children:`Any live report, whether submitted as an initial report or as a dispute, can itself be disputed before the timer expires. Your payout depends on which side the next dispute’s price implies is swapped. In the normal case, that is the lower-valued side.`}),`\n`,_jsxs(_components.p,{children:[`For example, if you reported 100 USD of WETH against 100 USD of USDC, and WETH then drops 1%, there is now roughly 99 USD of WETH and 100 USD of USDC in the report. A dispute at the corrected price takes the WETH side, and you receive `,_jsx(_components.code,{children:`2 * 99 USD`}),` worth of WETH plus the swap fee on `,_jsx(_components.code,{children:`currentAmount1`}),`. If the swap fee is 1% and applies in this round, you additionally receive about 1% of 99 USD denominated in WETH. The protocol fee on `,_jsx(_components.code,{children:`currentAmount1`}),` does not flow to you.`]}),`\n`,_jsx(_components.p,{children:`Your realized loss versus the true price is the spread (1 USD) net of the swap fee credit.`}),`\n`,_jsx(Heading,{level:`2`,id:`internal-balances`,children:`Internal balances`}),`\n`,_jsx(_components.p,{children:`Internal balances let repeat participants report or dispute without moving tokens externally on every call. Functions to manage internal balances:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`deposit`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(token, amount, beneficiary)`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Pulls `,_jsx(_components.code,{children:`amount`}),` of `,_jsx(_components.code,{children:`token`}),` from `,_jsx(_components.code,{children:`msg.sender`}),` and credits `,_jsx(_components.code,{children:`beneficiary`}),`’s internal balance. If depositing ETH, `,_jsx(_components.code,{children:`msg.value`}),` must match `,_jsx(_components.code,{children:`amount`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`depositFromPermit2`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(amount, beneficiary, from, intent, permit, signature)`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Same as `,_jsx(_components.code,{children:`deposit`}),`, but funded by `,_jsx(_components.code,{children:`from`}),` via a Permit2 witness signature. The signature is only valid when relayed by the intended caller, crediting the intended beneficiary, attributed to the intended `,_jsx(_components.code,{children:`from`}),`, and matching the intended intent hash. ETH is not supported through this path.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`internalTransferFrom`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(from, to, token, amount)`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Moves internal balance from `,_jsx(_components.code,{children:`from`}),` to `,_jsx(_components.code,{children:`to`}),`. If `,_jsx(_components.code,{children:`from != msg.sender`}),`, the caller must hold sufficient internal allowance (see Delegation below).`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`withdraw`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(token, amount)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`withdrawTo`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(token, amount, to)`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Sends `,_jsx(_components.code,{children:`amount`}),` of `,_jsx(_components.code,{children:`token`}),` from the caller’s internal balance out as a real transfer, either to `,_jsx(_components.code,{children:`msg.sender`}),` or to the specified `,_jsx(_components.code,{children:`to`}),`. If `,_jsx(_components.code,{children:`amount`}),` exceeds the available balance, the contract sends what’s available instead of reverting.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`pushOrCredit`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(token, to, amount)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`pushOrCredit`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(token, to, amount, gasLimit)`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Debits the caller’s internal balance and tries to transfer the tokens to `,_jsx(_components.code,{children:`to`}),` externally. A failed ETH call, reverted ERC-20 call, or ERC-20 return value of `,_jsx(_components.code,{children:`false`}),` credits `,_jsx(_components.code,{children:`to`}),`’s internal balance instead. The ETH call uses 50,000 gas by default or the supplied `,_jsx(_components.code,{children:`gasLimit`}),`. ERC-20 calls do not use this gas cap, and malformed return data can still revert the call.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`address(0)`}),` as `,_jsx(_components.code,{children:`token`}),` means native ETH throughout. Internal balances keep a one-unit sentinel in touched slots, so the displayed raw storage amount may include dust that is not withdrawable.`]}),`\n`,_jsx(Heading,{level:`2`,id:`delegation`,children:`Delegation`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`approveInternal`}),` allows a spender to use the owner’s internal balance:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`solidity`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`solidity`,children:_jsxs(_components.code,{language:`solidity`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`approveInternal`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(spender, token, amount)`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`This approval only applies to balances already inside the oracle. It does not approve external ERC-20 transfers. To change a nonzero allowance to another nonzero amount, first call `,_jsx(_components.code,{children:`approveInternal`}),` with zero. `,_jsx(_components.code,{children:`type(uint256).max`}),` gives an allowance that is not decremented when spent.`]}),`\n`,_jsxs(_components.p,{children:[`A spender can use approved internal balance through `,_jsx(_components.code,{children:`internalTransferFrom`}),`, or through delegated `,_jsx(_components.code,{children:`report()`}),` / `,_jsx(_components.code,{children:`dispute()`}),` funding when the corresponding `,_jsx(_components.code,{children:`tryInternalBalance`}),` flag is true. If the flag is false, the contract expects `,_jsx(_components.code,{children:`msg.sender`}),` to fund that token externally. If the flag is true but the internal balance or internal allowance is insufficient, the call reverts.`]}),`\n`,_jsx(_components.p,{children:`Only approve addresses you trust. A spender with internal allowance can move or spend your internal balance according to that allowance.`}),`\n`,_jsx(Heading,{level:`2`,id:`expected-value`,children:`Expected value`}),`\n`,_jsx(_components.p,{children:`For the initial reporter, compensation must come from the application or strategy that asked for the report.`}),`\n`,_jsxs(_components.p,{children:[`A simple initial `,_jsx(_components.code,{children:`report()`}),` caller EV model is:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`4`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`EV = external_compensation_usd`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` - currentAmount1_to_usd * volatility_loss`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` - gas_fees_usd`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(_components.p,{children:`For a disputer:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`EV = abs(currentAmount1_to_usd - currentAmount2_to_usd)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` - swap_fee_usd`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` - protocol_fee_usd`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` - newAmount1_to_usd * volatility_loss`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` - gas_fees_usd`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`This ignores swap fees received when your dispute is itself disputed, which strictly help you as a disputer. `,_jsx(_components.code,{children:`swap_fee_usd`}),` and `,_jsx(_components.code,{children:`protocol_fee_usd`}),` are levied on the swapped token’s amount in the current report before you dispute, which is the smaller-valued side. Both fees are zero before escalation halt when flag `,_jsx(_components.code,{children:`32`}),` is set.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`volatility_loss`}),` captures the expected loss from being `,_jsx(_components.a,{href:`#counter-dispute-risk`,children:`counter-disputed`}),` before the timer expires. When the `,_jsx(_components.code,{children:`token1/token2`}),` ratio drifts during the settlement window, the next disputer can take the cheap side from you at the stale price, and the spread becomes your loss. The longer `,_jsx(_components.code,{children:`settlementTime`}),` is and the more the pair moves, the more loss you should price in. A fuller treatment of this term lives in `,_jsx(_components.a,{href:`/openoracle/oracle-accuracy-cost`,children:`Oracle Accuracy \u0026 Cost`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`An appropriate `,_jsx(_components.code,{children:`volatility_loss`}),` term is approximately:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`0.65 * standard deviation of settlementTime returns for the token1/token2 ratio`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(_components.p,{children:`You can increase the coefficient for more buffer, but that reduces competitiveness.`}),`\n`,_jsx(_components.p,{children:`Estimating short-window volatility has a high skill cap. If volatility spikes faster than your model adjusts, you can lose money.`})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Smart Contract Reference","description":"Reference for participating in the openOracle game on-chain","href":"/openoracle/game-guide"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Core idea","slug":"core-idea","depth":2,"children":[]},{"title":"Oracle game","slug":"oracle-game","depth":2,"children":[]},{"title":"Onchain reads","slug":"onchain-reads","depth":2,"children":[]},{"title":"Events and packed layout","slug":"events-and-packed-layout","depth":2,"children":[]},{"title":"Critical filters","slug":"critical-filters","depth":2,"children":[]},{"title":"Timing Boundaries","slug":"timing-boundaries","depth":2,"children":[]},{"title":"Playing the game","slug":"playing-the-game","depth":2,"children":[{"title":"Reporting / Creating a game","slug":"reporting-/-creating-a-game","depth":3,"children":[]},{"title":"Token flows","slug":"token-flows","depth":4,"children":[]},{"title":"Paying someone else to report","slug":"paying-someone-else-to-report","depth":4,"children":[]},{"title":"Disputing","slug":"disputing","depth":3,"children":[]},{"title":"Token flows","slug":"token-flows-2","depth":4,"children":[]},{"title":"Settling","slug":"settling","depth":3,"children":[]},{"title":"Counter-dispute risk","slug":"counter-dispute-risk","depth":3,"children":[]}]},{"title":"Internal balances","slug":"internal-balances","depth":2,"children":[]},{"title":"Delegation","slug":"delegation","depth":2,"children":[]},{"title":"Expected value","slug":"expected-value","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/openoracle/8d396e0d9fab644d/grain.js"],"subdomain":"openoracle","siteName":"openOracle","title":"Smart Contract Reference - openOracle","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-08T20:39:44.647Z","originalFileLocation":"openoracle/game-guide.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Reference for participating in the openOracle game on-chain\">\u003cmeta data-mint-head name=\"application-name\" content=\"openOracle\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/openoracle/4U7-r7MOZWBqUEI3/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/openoracle/4U7-r7MOZWBqUEI3/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/openoracle/4U7-r7MOZWBqUEI3/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/openoracle/4U7-r7MOZWBqUEI3/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/openoracle/4U7-r7MOZWBqUEI3/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/openoracle/4U7-r7MOZWBqUEI3/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/openoracle/4U7-r7MOZWBqUEI3/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/openoracle/4U7-r7MOZWBqUEI3/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/openoracle/4U7-r7MOZWBqUEI3/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Smart Contract Reference - openOracle\">\u003cmeta data-mint-head property=\"og:description\" content=\"Reference for participating in the openOracle game on-chain\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"openOracle\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.openoracle.org/openoracle/game-guide\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://docs.openoracle.org/og-docs.png\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Smart Contract Reference - openOracle\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Reference for participating in the openOracle game on-chain\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://docs.openoracle.org/og-docs.png\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/openoracle/4U7-r7MOZWBqUEI3/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"openOracle\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#00CF9C\">\u003cmeta data-mint-head name=\"og:image:type\" content=\"image/png\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.openoracle.org/openoracle/game-guide\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/openoracle/game-guide.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.openoracle.org/#organization\",\"name\":\"openOracle\",\"url\":\"https://docs.openoracle.org\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/openoracle/U4lTbao-51w4qpSW/logo-light.svg?fit=max\u0026auto=format\u0026n=U4lTbao-51w4qpSW\u0026q=85\u0026s=7cab4632108a10d7783fa0566fef0f8b\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.openoracle.org#website\",\"name\":\"openOracle\",\"url\":\"https://docs.openoracle.org\",\"publisher\":{\"@id\":\"https://docs.openoracle.org/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.openoracle.org/openoracle/game-guide#webpage\",\"url\":\"https://docs.openoracle.org/openoracle/game-guide\",\"name\":\"Smart Contract Reference\",\"description\":\"Reference for participating in the openOracle game on-chain\",\"dateModified\":\"2026-09-08T20:39:44.647Z\",\"isPartOf\":{\"@id\":\"https://docs.openoracle.org#website\"},\"breadcrumb\":{\"@id\":\"https://docs.openoracle.org/openoracle/game-guide#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.openoracle.org/openoracle/game-guide#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"openOracle\",\"item\":\"https://docs.openoracle.org\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Smart Contract Reference\",\"item\":\"https://docs.openoracle.org/openoracle/game-guide\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.openoracle.org/openoracle/game-guide#article\",\"headline\":\"Smart Contract Reference\",\"name\":\"Smart Contract Reference\",\"description\":\"Reference for participating in the openOracle game on-chain\",\"url\":\"https://docs.openoracle.org/openoracle/game-guide\",\"mainEntityOfPage\":{\"@id\":\"https://docs.openoracle.org/openoracle/game-guide#webpage\"},\"image\":\"https://docs.openoracle.org/og-docs.png\",\"dateModified\":\"2026-09-08T20:39:44.647Z\",\"publisher\":{\"@id\":\"https://docs.openoracle.org/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.openoracle.org#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"openOracle\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"openOracle","nav":{"global":null,"tabs":[{"tab":"openOracle","groups":[{"group":"Home","pages":[{"title":"openOracle","href":""}]},{"group":"Documentation","pages":[{"title":"openOracle","sidebarTitle":"Introduction","href":"/openoracle/introduction"},{"title":"Advantages","href":"/openoracle/advantages"},{"title":"Oracle Life Cycle","href":"/openoracle/oracle-life-cycle"},{"title":"Contracts","href":"/openoracle/contracts"},{"title":"Discord \u0026 Socials","href":"/openoracle/discord-socials"},{"title":"Terms of Service \u0026 Disclaimer","description":"Legal terms and disclaimers","href":"/openoracle/tos-disclaimer"}]},{"group":"Contract Reference","pages":[{"title":"Smart Contract Reference","href":"/openoracle/game-guide"}]},{"group":"Technical Details","pages":[{"title":"Terminology","sidebarTitle":"Terminology","description":"Key terms and definitions used throughout the openOracle documentation","href":"/openoracle/terminology"},{"title":"Oracle Accuracy\n\u0026 Cost\n","sidebarTitle":"Oracle Accuracy \u0026 Cost","href":"/openoracle/oracle-accuracy-cost"},{"title":"Attack\nVectors\n","sidebarTitle":"Attack Vectors","href":"/openoracle/attack-vectors"},{"title":"Attack Vectors (Inclusion)","sidebarTitle":"Attack Vectors (Inclusion)","href":"/openoracle/attack-vectors-inclusion"},{"title":"Economic\nBounds\n","sidebarTitle":"Economic Bounds","href":"/openoracle/economic-bounds"},{"title":"Guardrails","sidebarTitle":"Guardrails","href":"/openoracle/guardrails"}]},{"group":"Brand","pages":[{"title":"Brand Guidelines","href":"/brand/guidelines"}]}]},{"tab":"openSwap","pages":[{"title":"openSwap","href":"/openswap-v2/introduction"}]},{"tab":"openLend","pages":[{"title":"openLend","href":"/openlend/introduction"}]},{"tab":"openPunt","pages":[{"title":"openPunt","href":"/punt/introduction"}]}]},"title":"Smart Contract Reference - openOracle","buildId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","deploymentId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","dynamics":[],"chunks":[]}