diff --git a/common/contract.ts b/common/contract.ts index 2bf39335..8f7b5d84 100644 --- a/common/contract.ts +++ b/common/contract.ts @@ -82,6 +82,7 @@ export type PseudoNumeric = { min: number max: number isLogScale: boolean + resolutionValue?: number // same as binary market; map to everything to probability initialProbability: number diff --git a/functions/src/emails.ts b/functions/src/emails.ts index 19f4b230..ab0d5dac 100644 --- a/functions/src/emails.ts +++ b/functions/src/emails.ts @@ -8,6 +8,7 @@ import { DPM_CREATOR_FEE } from '../../common/fees' import { PrivateUser, User } from '../../common/user' import { formatMoney, formatPercent } from '../../common/util/format' import { getValueFromBucket } from '../../common/calculate-dpm' +import { formatNumericProbability } from '../../common/numeric' import { sendTemplateEmail } from './send-email' import { getPrivateUser, getUser } from './utils' @@ -88,10 +89,7 @@ const toDisplayResolution = ( resolutionProbability?: number, resolutions?: { [outcome: string]: number } ) => { - if ( - contract.outcomeType === 'BINARY' || - contract.outcomeType === 'PSEUDO_NUMERIC' - ) { + if (contract.outcomeType === 'BINARY') { const prob = resolutionProbability ?? getProbability(contract) const display = { @@ -104,6 +102,16 @@ const toDisplayResolution = ( return display || resolution } + if (contract.outcomeType === 'PSEUDO_NUMERIC') { + return ( + contract.resolutionValue?.toString() ?? + formatNumericProbability( + resolutionProbability ?? getProbability(contract), + contract + ) + ) + } + if (resolution === 'MKT' && resolutions) return 'MULTI' if (resolution === 'CANCEL') return 'N/A' diff --git a/functions/src/resolve-market.ts b/functions/src/resolve-market.ts index 43cb4839..87eaed58 100644 --- a/functions/src/resolve-market.ts +++ b/functions/src/resolve-market.ts @@ -54,6 +54,9 @@ export const resolveMarket = functions } else if (outcomeType === 'NUMERIC') { if (isNaN(+outcome) && outcome !== 'CANCEL') return { status: 'error', message: 'Invalid outcome' } + } else if (outcomeType === 'PSEUDO_NUMERIC') { + if (probabilityInt === undefined && outcome !== 'CANCEL') + return { status: 'error', message: 'Invalid outcome' } } else { return { status: 'error', message: 'Invalid contract outcomeType' } } @@ -62,7 +65,7 @@ export const resolveMarket = functions return { status: 'error', message: 'Invalid value' } if ( - outcomeType === 'BINARY' && + (outcomeType === 'BINARY' || outcomeType === 'PSEUDO_NUMERIC') && probabilityInt !== undefined && (probabilityInt < 0 || probabilityInt > 100 || @@ -111,16 +114,19 @@ export const resolveMarket = functions resolutionProbability ) + const resolutionInfo = + outcome !== 'CANCEL' + ? { resolutionValue: value, resolutionProbability, resolutions } + : {} + await contractDoc.update( removeUndefinedProps({ isResolved: true, resolution: outcome, - resolutionValue: value, resolutionTime, closeTime: newCloseTime, - resolutionProbability, - resolutions, collectedFees, + ...resolutionInfo, }) ) diff --git a/web/components/contract/contract-card.tsx b/web/components/contract/contract-card.tsx index 5422174b..247ec6bd 100644 --- a/web/components/contract/contract-card.tsx +++ b/web/components/contract/contract-card.tsx @@ -137,6 +137,13 @@ export function ContractCard(props: { /> )} + {outcomeType === 'PSEUDO_NUMERIC' && ( + + )} + {outcomeType === 'NUMERIC' && ( ) : (
- {formatNumericProbability(resolutionProbability ?? 0, contract)} + {resolutionValue ?? + formatNumericProbability(resolutionProbability ?? 0, contract)}
)} diff --git a/web/components/contract/quick-bet.tsx b/web/components/contract/quick-bet.tsx index ddd22a24..d8c2c3b2 100644 --- a/web/components/contract/quick-bet.tsx +++ b/web/components/contract/quick-bet.tsx @@ -306,11 +306,15 @@ function QuickOutcomeView(props: { // Return a number from 0 to 1 for this contract // Resolved contracts are set to 1, for coloring purposes (even if NO) function getProb(contract: Contract) { - const { outcomeType, resolution } = contract - return resolution + const { outcomeType, resolution, resolutionProbability } = contract + return resolutionProbability + ? resolutionProbability + : resolution ? 1 : outcomeType === 'BINARY' ? getBinaryProb(contract) + : outcomeType === 'PSEUDO_NUMERIC' + ? getProbability(contract) : outcomeType === 'FREE_RESPONSE' ? getOutcomeProbability(contract, getTopAnswer(contract)?.id || '') : outcomeType === 'NUMERIC' diff --git a/web/components/numeric-resolution-panel.tsx b/web/components/numeric-resolution-panel.tsx index 758b3fa3..849f24f7 100644 --- a/web/components/numeric-resolution-panel.tsx +++ b/web/components/numeric-resolution-panel.tsx @@ -21,6 +21,7 @@ export function NumericResolutionPanel(props: { }, []) const { contract, className } = props + const { min, max, outcomeType } = contract const [outcomeMode, setOutcomeMode] = useState< 'NUMBER' | 'CANCEL' | undefined @@ -32,15 +33,24 @@ export function NumericResolutionPanel(props: { const [error, setError] = useState(undefined) const resolve = async () => { - const finalOutcome = outcomeMode === 'NUMBER' ? outcome : 'CANCEL' + const finalOutcome = + outcomeMode === 'CANCEL' + ? 'CANCEL' + : outcomeType === 'PSEUDO_NUMERIC' + ? 'MKT' + : 'NUMBER' if (outcomeMode === undefined || finalOutcome === undefined) return setIsSubmitting(true) + const boundedValue = Math.max(Math.min(max, value ?? 0), min) + const probabilityInt = ((boundedValue - min) / (max - min)) * 100 + const result = await resolveMarket({ outcome: finalOutcome, value, contractId: contract.id, + probabilityInt, }).then((r) => r.data) console.log('resolved', outcome, 'result:', result) @@ -72,7 +82,7 @@ export function NumericResolutionPanel(props: { {outcomeMode === 'NUMBER' && ( (setValue(v), setOutcome(o))} />