From 7c4ec2a8e38761fa54f56469398b06d94112f025 Mon Sep 17 00:00:00 2001 From: Marshall Polaris Date: Tue, 31 May 2022 19:42:35 -0700 Subject: [PATCH] Refactor contract typing to be more concise and more correct (#355) * Refactor contract types slightly * Refactor contract types greatly * Kill dead binary DPM contract creation code * Use BinaryContract, DPMContract, etc. type aliases --- common/add-liquidity.ts | 4 +- common/antes.ts | 18 ++++---- common/calculate-cpmm.ts | 22 ++++----- common/calculate-dpm.ts | 46 +++++-------------- common/calculate-fixed-payouts.ts | 9 ++-- common/calculate.ts | 33 +++---------- common/contract.ts | 34 +++++++------- common/new-bet.ts | 15 +++--- common/payouts-dpm.ts | 15 +++--- common/payouts-fixed.ts | 10 ++-- common/payouts.ts | 28 ++++------- common/scoring.ts | 17 +++---- common/sell-bet.ts | 6 +-- functions/src/create-answer.ts | 14 +----- functions/src/create-contract.ts | 34 +++----------- functions/src/redeem-shares.ts | 4 +- .../src/scripts/correct-bet-probability.ts | 8 ++-- functions/src/scripts/migrate-to-cfmm.ts | 11 ++--- functions/src/scripts/migrate-to-dpm-2.ts | 4 +- functions/src/sell-shares.ts | 4 +- web/components/answers/answer-bet-panel.tsx | 4 +- web/components/answers/answer-item.tsx | 4 +- .../answers/answer-resolve-panel.tsx | 4 +- web/components/answers/answers-graph.tsx | 9 ++-- web/components/answers/answers-panel.tsx | 10 ++-- .../answers/create-answer-panel.tsx | 6 +-- web/components/bet-panel.tsx | 33 +++++++------ web/components/bet-row.tsx | 4 +- web/components/bets-list.tsx | 34 +++++++------- web/components/contract/contract-card.tsx | 26 ++++------- web/components/contract/contract-overview.tsx | 24 +++------- .../contract/contract-prob-graph.tsx | 4 +- web/components/contract/quick-bet.tsx | 20 +++----- web/components/feed/activity-items.ts | 24 ++++------ .../feed/feed-answer-comment-group.tsx | 3 +- web/components/outcome-label.tsx | 22 +++------ web/components/resolution-panel.tsx | 4 +- web/components/sell-button.tsx | 6 +-- web/components/sell-modal.tsx | 4 +- web/components/sell-row.tsx | 6 +-- web/components/use-save-shares.ts | 10 +--- web/lib/firebase/contracts.ts | 12 ++--- web/pages/[username]/[contractSlug].tsx | 31 ++----------- web/pages/embed/[username]/[contractSlug].tsx | 31 +++---------- web/pages/make-predictions.tsx | 10 ++-- 45 files changed, 245 insertions(+), 436 deletions(-) diff --git a/common/add-liquidity.ts b/common/add-liquidity.ts index 0421bcb5..254b8936 100644 --- a/common/add-liquidity.ts +++ b/common/add-liquidity.ts @@ -1,12 +1,12 @@ import { addCpmmLiquidity, getCpmmLiquidity } from './calculate-cpmm' -import { Binary, CPMM, FullContract } from './contract' +import { CPMMContract } from './contract' import { LiquidityProvision } from './liquidity-provision' import { User } from './user' export const getNewLiquidityProvision = ( user: User, amount: number, - contract: FullContract, + contract: CPMMContract, newLiquidityProvisionId: string ) => { const { pool, p, totalLiquidity } = contract diff --git a/common/antes.ts b/common/antes.ts index e104796f..becc9b7e 100644 --- a/common/antes.ts +++ b/common/antes.ts @@ -2,12 +2,10 @@ import { range } from 'lodash' import { Bet, NumericBet } from './bet' import { getDpmProbability, getValueFromBucket } from './calculate-dpm' import { - Binary, - CPMM, - DPM, - FreeResponse, - FullContract, - Numeric, + CPMMBinaryContract, + DPMBinaryContract, + FreeResponseContract, + NumericContract, } from './contract' import { User } from './user' import { LiquidityProvision } from './liquidity-provision' @@ -23,7 +21,7 @@ export const HOUSE_LIQUIDITY_PROVIDER_ID = 'IPTOzEqrpkWmEzh6hwvAyY9PqFb2' // @Ma export function getCpmmInitialLiquidity( providerId: string, - contract: FullContract, + contract: CPMMBinaryContract, anteId: string, amount: number ) { @@ -47,7 +45,7 @@ export function getCpmmInitialLiquidity( export function getAnteBets( creator: User, - contract: FullContract, + contract: DPMBinaryContract, yesAnteId: string, noAnteId: string ) { @@ -89,7 +87,7 @@ export function getAnteBets( export function getFreeAnswerAnte( anteBettorId: string, - contract: FullContract, + contract: FreeResponseContract, anteBetId: string ) { const { totalBets, totalShares } = contract @@ -117,7 +115,7 @@ export function getFreeAnswerAnte( export function getNumericAnte( anteBettorId: string, - contract: FullContract, + contract: NumericContract, ante: number, newBetId: string ) { diff --git a/common/calculate-cpmm.ts b/common/calculate-cpmm.ts index 4ced5b16..485f32c8 100644 --- a/common/calculate-cpmm.ts +++ b/common/calculate-cpmm.ts @@ -1,6 +1,6 @@ import { sum, groupBy, mapValues, sumBy } from 'lodash' -import { Binary, CPMM, FullContract } from './contract' +import { CPMMContract } from './contract' import { CREATOR_FEE, Fees, LIQUIDITY_FEE, noFees, PLATFORM_FEE } from './fees' import { LiquidityProvision } from './liquidity-provision' import { addObjects } from './util/object' @@ -14,7 +14,7 @@ export function getCpmmProbability( } export function getCpmmProbabilityAfterBetBeforeFees( - contract: FullContract, + contract: CPMMContract, outcome: string, bet: number ) { @@ -31,7 +31,7 @@ export function getCpmmProbabilityAfterBetBeforeFees( } export function getCpmmOutcomeProbabilityAfterBet( - contract: FullContract, + contract: CPMMContract, outcome: string, bet: number ) { @@ -59,7 +59,7 @@ function calculateCpmmShares( } export function getCpmmLiquidityFee( - contract: FullContract, + contract: CPMMContract, bet: number, outcome: string ) { @@ -78,7 +78,7 @@ export function getCpmmLiquidityFee( } export function calculateCpmmSharesAfterFee( - contract: FullContract, + contract: CPMMContract, bet: number, outcome: string ) { @@ -89,7 +89,7 @@ export function calculateCpmmSharesAfterFee( } export function calculateCpmmPurchase( - contract: FullContract, + contract: CPMMContract, bet: number, outcome: string ) { @@ -133,7 +133,7 @@ function sellSharesK( } function calculateCpmmShareValue( - contract: FullContract, + contract: CPMMContract, shares: number, outcome: 'YES' | 'NO' ) { @@ -168,7 +168,7 @@ function calculateCpmmShareValue( } export function calculateCpmmSale( - contract: FullContract, + contract: CPMMContract, shares: number, outcome: string ) { @@ -222,7 +222,7 @@ export function calculateCpmmSale( } export function getCpmmProbabilityAfterSale( - contract: FullContract, + contract: CPMMContract, shares: number, outcome: 'YES' | 'NO' ) { @@ -261,7 +261,7 @@ export function addCpmmLiquidity( } export function getCpmmLiquidityPoolWeights( - contract: FullContract, + contract: CPMMContract, liquidities: LiquidityProvision[] ) { const { p } = contract @@ -291,7 +291,7 @@ export function getCpmmLiquidityPoolWeights( } // export function removeCpmmLiquidity( -// contract: FullContract, +// contract: CPMMContract, // liquidity: number // ) { // const { YES, NO } = contract.pool diff --git a/common/calculate-dpm.ts b/common/calculate-dpm.ts index 104b5ef7..4d31bf3b 100644 --- a/common/calculate-dpm.ts +++ b/common/calculate-dpm.ts @@ -1,13 +1,6 @@ import { cloneDeep, range, sum, sumBy, sortBy, mapValues } from 'lodash' import { Bet, NumericBet } from './bet' -import { - Binary, - DPM, - FreeResponse, - FullContract, - Numeric, - NumericContract, -} from './contract' +import { DPMContract, DPMBinaryContract, NumericContract } from './contract' import { DPM_FEES } from './fees' import { normpdf } from '../common/util/math' import { addObjects } from './util/object' @@ -202,7 +195,7 @@ export function calculateDpmRawShareValue( } export function calculateDpmMoneyRatio( - contract: FullContract, + contract: DPMContract, bet: Bet, shareValue: number ) { @@ -228,10 +221,7 @@ export function calculateDpmMoneyRatio( return actual / expected } -export function calculateDpmShareValue( - contract: FullContract, - bet: Bet -) { +export function calculateDpmShareValue(contract: DPMContract, bet: Bet) { const { pool, totalShares } = contract const { shares, outcome } = bet @@ -243,17 +233,14 @@ export function calculateDpmShareValue( return adjShareValue } -export function calculateDpmSaleAmount( - contract: FullContract, - bet: Bet -) { +export function calculateDpmSaleAmount(contract: DPMContract, bet: Bet) { const { amount } = bet const winnings = calculateDpmShareValue(contract, bet) return deductDpmFees(amount, winnings) } export function calculateDpmPayout( - contract: FullContract, + contract: DPMContract, bet: Bet, outcome: string ) { @@ -263,10 +250,7 @@ export function calculateDpmPayout( return calculateStandardDpmPayout(contract, bet, outcome) } -export function calculateDpmCancelPayout( - contract: FullContract, - bet: Bet -) { +export function calculateDpmCancelPayout(contract: DPMContract, bet: Bet) { const { totalBets, pool } = contract const betTotal = sum(Object.values(totalBets)) const poolTotal = sum(Object.values(pool)) @@ -275,7 +259,7 @@ export function calculateDpmCancelPayout( } export function calculateStandardDpmPayout( - contract: FullContract, + contract: DPMContract, bet: Bet, outcome: string ) { @@ -308,7 +292,7 @@ export function calculateStandardDpmPayout( } export function calculateDpmPayoutAfterCorrectBet( - contract: FullContract, + contract: DPMContract, bet: Bet ) { const { totalShares, pool, totalBets, outcomeType } = contract @@ -338,13 +322,10 @@ export function calculateDpmPayoutAfterCorrectBet( : outcomeType, } - return calculateStandardDpmPayout(newContract, bet, outcome) + return calculateStandardDpmPayout(newContract as any, bet, outcome) } -function calculateMktDpmPayout( - contract: FullContract, - bet: Bet -) { +function calculateMktDpmPayout(contract: DPMContract, bet: Bet) { if (contract.outcomeType === 'BINARY') return calculateBinaryMktDpmPayout(contract, bet) @@ -389,10 +370,7 @@ function calculateMktDpmPayout( return deductDpmFees(amount, winnings) } -function calculateBinaryMktDpmPayout( - contract: FullContract, - bet: Bet -) { +function calculateBinaryMktDpmPayout(contract: DPMBinaryContract, bet: Bet) { const { resolutionProbability, totalShares, phantomShares } = contract const p = resolutionProbability !== undefined @@ -413,7 +391,7 @@ function calculateBinaryMktDpmPayout( return deductDpmFees(amount, winnings) } -export function resolvedDpmPayout(contract: FullContract, bet: Bet) { +export function resolvedDpmPayout(contract: DPMContract, bet: Bet) { if (contract.resolution) return calculateDpmPayout(contract, bet, contract.resolution) throw new Error('Contract was not resolved') diff --git a/common/calculate-fixed-payouts.ts b/common/calculate-fixed-payouts.ts index 9c6ff536..a5eacb3d 100644 --- a/common/calculate-fixed-payouts.ts +++ b/common/calculate-fixed-payouts.ts @@ -1,9 +1,9 @@ import { Bet } from './bet' import { getProbability } from './calculate' -import { Binary, FixedPayouts, FullContract } from './contract' +import { CPMMContract } from './contract' export function calculateFixedPayout( - contract: FullContract, + contract: CPMMContract, bet: Bet, outcome: string ) { @@ -23,10 +23,7 @@ export function calculateStandardFixedPayout(bet: Bet, outcome: string) { return shares } -function calculateFixedMktPayout( - contract: FullContract, - bet: Bet -) { +function calculateFixedMktPayout(contract: CPMMContract, bet: Bet) { const { resolutionProbability } = contract const p = resolutionProbability !== undefined diff --git a/common/calculate.ts b/common/calculate.ts index 43b04af8..b7d79f2f 100644 --- a/common/calculate.ts +++ b/common/calculate.ts @@ -18,24 +18,15 @@ import { getDpmProbabilityAfterSale, } from './calculate-dpm' import { calculateFixedPayout } from './calculate-fixed-payouts' -import { - Binary, - Contract, - CPMM, - DPM, - FreeResponseContract, - FullContract, -} from './contract' +import { Contract, BinaryContract, FreeResponseContract } from './contract' -export function getProbability(contract: FullContract) { +export function getProbability(contract: BinaryContract) { return contract.mechanism === 'cpmm-1' ? getCpmmProbability(contract.pool, contract.p) : getDpmProbability(contract.totalShares) } -export function getInitialProbability( - contract: FullContract -) { +export function getInitialProbability(contract: BinaryContract) { if (contract.initialProbability) return contract.initialProbability if (contract.mechanism === 'dpm-2' || (contract as any).totalShares) @@ -59,11 +50,7 @@ export function getOutcomeProbabilityAfterBet( bet: number ) { return contract.mechanism === 'cpmm-1' - ? getCpmmOutcomeProbabilityAfterBet( - contract as FullContract, - outcome, - bet - ) + ? getCpmmOutcomeProbabilityAfterBet(contract, outcome, bet) : getDpmOutcomeProbabilityAfterBet(contract.totalShares, outcome, bet) } @@ -73,11 +60,7 @@ export function calculateShares( betChoice: string ) { return contract.mechanism === 'cpmm-1' - ? calculateCpmmSharesAfterFee( - contract as FullContract, - bet, - betChoice - ) + ? calculateCpmmSharesAfterFee(contract, bet, betChoice) : calculateDpmShares(contract.totalShares, bet, betChoice) } @@ -99,11 +82,7 @@ export function getProbabilityAfterSale( shares: number ) { return contract.mechanism === 'cpmm-1' - ? getCpmmProbabilityAfterSale( - contract as FullContract, - shares, - outcome as 'YES' | 'NO' - ) + ? getCpmmProbabilityAfterSale(contract, shares, outcome as 'YES' | 'NO') : getDpmProbabilityAfterSale(contract.totalShares, outcome, shares) } diff --git a/common/contract.ts b/common/contract.ts index e9b768ea..2abda13a 100644 --- a/common/contract.ts +++ b/common/contract.ts @@ -1,10 +1,15 @@ import { Answer } from './answer' import { Fees } from './fees' -export type FullContract< - M extends DPM | CPMM, - T extends Binary | Multi | FreeResponse | Numeric -> = { +export type AnyMechanism = DPM | CPMM +export type AnyOutcomeType = Binary | Multi | FreeResponse | Numeric +export type AnyContractType = + | (CPMM & Binary) + | (DPM & Binary) + | (DPM & (Multi | FreeResponse)) + | (DPM & Numeric) + +export type Contract = { id: string slug: string // auto-generated; must be unique @@ -36,16 +41,15 @@ export type FullContract< volume7Days: number collectedFees: Fees -} & M & - T +} & T -export type Contract = FullContract< - DPM | CPMM, - Binary | Multi | FreeResponse | Numeric -> -export type BinaryContract = FullContract -export type FreeResponseContract = FullContract -export type NumericContract = FullContract +export type BinaryContract = Contract & Binary +export type NumericContract = Contract & Numeric +export type FreeResponseContract = Contract & FreeResponse +export type DPMContract = Contract & DPM +export type CPMMContract = Contract & CPMM +export type DPMBinaryContract = BinaryContract & DPM +export type CPMMBinaryContract = BinaryContract & CPMM export type DPM = { mechanism: 'dpm-2' @@ -63,8 +67,6 @@ export type CPMM = { totalLiquidity: number // in M$ } -export type FixedPayouts = CPMM - export type Binary = { outcomeType: 'BINARY' initialProbability: number @@ -94,7 +96,7 @@ export type Numeric = { resolutionValue?: number } -export type outcomeType = 'BINARY' | 'MULTI' | 'FREE_RESPONSE' | 'NUMERIC' +export type outcomeType = AnyOutcomeType['outcomeType'] export const OUTCOME_TYPES = [ 'BINARY', 'MULTI', diff --git a/common/new-bet.ts b/common/new-bet.ts index 1053ec58..ba799624 100644 --- a/common/new-bet.ts +++ b/common/new-bet.ts @@ -10,12 +10,9 @@ import { } from './calculate-dpm' import { calculateCpmmPurchase, getCpmmProbability } from './calculate-cpmm' import { - Binary, - CPMM, - DPM, - FreeResponse, - FullContract, - Multi, + CPMMBinaryContract, + DPMBinaryContract, + FreeResponseContract, NumericContract, } from './contract' import { noFees } from './fees' @@ -35,7 +32,7 @@ export type BetInfo = { export const getNewBinaryCpmmBetInfo = ( outcome: 'YES' | 'NO', amount: number, - contract: FullContract, + contract: CPMMBinaryContract, loanAmount: number ) => { const { shares, newPool, newP, fees } = calculateCpmmPurchase( @@ -69,7 +66,7 @@ export const getNewBinaryCpmmBetInfo = ( export const getNewBinaryDpmBetInfo = ( outcome: 'YES' | 'NO', amount: number, - contract: FullContract, + contract: DPMBinaryContract, loanAmount: number ) => { const { YES: yesPool, NO: noPool } = contract.pool @@ -116,7 +113,7 @@ export const getNewBinaryDpmBetInfo = ( export const getNewMultiBetInfo = ( outcome: string, amount: number, - contract: FullContract, + contract: FreeResponseContract, loanAmount: number ) => { const { pool, totalShares, totalBets } = contract diff --git a/common/payouts-dpm.ts b/common/payouts-dpm.ts index 300a906f..6cecddff 100644 --- a/common/payouts-dpm.ts +++ b/common/payouts-dpm.ts @@ -2,14 +2,11 @@ import { sum, groupBy, sumBy, mapValues } from 'lodash' import { Bet, NumericBet } from './bet' import { deductDpmFees, getDpmProbability } from './calculate-dpm' -import { DPM, FreeResponse, FullContract, Multi } from './contract' +import { DPMContract, FreeResponseContract } from './contract' import { DPM_CREATOR_FEE, DPM_FEES, DPM_PLATFORM_FEE } from './fees' import { addObjects } from './util/object' -export const getDpmCancelPayouts = ( - contract: FullContract, - bets: Bet[] -) => { +export const getDpmCancelPayouts = (contract: DPMContract, bets: Bet[]) => { const { pool } = contract const poolTotal = sum(Object.values(pool)) console.log('resolved N/A, pool M$', poolTotal) @@ -31,7 +28,7 @@ export const getDpmCancelPayouts = ( export const getDpmStandardPayouts = ( outcome: string, - contract: FullContract, + contract: DPMContract, bets: Bet[] ) => { const winningBets = bets.filter((bet) => bet.outcome === outcome) @@ -78,7 +75,7 @@ export const getDpmStandardPayouts = ( export const getNumericDpmPayouts = ( outcome: string, - contract: FullContract, + contract: DPMContract, bets: NumericBet[] ) => { const totalShares = sumBy(bets, (bet) => bet.allOutcomeShares[outcome] ?? 0) @@ -129,7 +126,7 @@ export const getNumericDpmPayouts = ( } export const getDpmMktPayouts = ( - contract: FullContract, + contract: DPMContract, bets: Bet[], resolutionProbability?: number ) => { @@ -183,7 +180,7 @@ export const getDpmMktPayouts = ( export const getPayoutsMultiOutcome = ( resolutions: { [outcome: string]: number }, - contract: FullContract, + contract: FreeResponseContract, bets: Bet[] ) => { const poolTotal = sum(Object.values(contract.pool)) diff --git a/common/payouts-fixed.ts b/common/payouts-fixed.ts index 1f4f2f4b..4e06042b 100644 --- a/common/payouts-fixed.ts +++ b/common/payouts-fixed.ts @@ -3,7 +3,7 @@ import { sum } from 'lodash' import { Bet } from './bet' import { getProbability } from './calculate' import { getCpmmLiquidityPoolWeights } from './calculate-cpmm' -import { Binary, CPMM, FixedPayouts, FullContract } from './contract' +import { CPMMContract } from './contract' import { noFees } from './fees' import { LiquidityProvision } from './liquidity-provision' @@ -30,7 +30,7 @@ export const getFixedCancelPayouts = ( export const getStandardFixedPayouts = ( outcome: string, - contract: FullContract, + contract: CPMMContract, bets: Bet[], liquidities: LiquidityProvision[] ) => { @@ -65,7 +65,7 @@ export const getStandardFixedPayouts = ( } export const getLiquidityPoolPayouts = ( - contract: FullContract, + contract: CPMMContract, outcome: string, liquidities: LiquidityProvision[] ) => { @@ -81,7 +81,7 @@ export const getLiquidityPoolPayouts = ( } export const getMktFixedPayouts = ( - contract: FullContract, + contract: CPMMContract, bets: Bet[], liquidities: LiquidityProvision[], resolutionProbability?: number @@ -116,7 +116,7 @@ export const getMktFixedPayouts = ( } export const getLiquidityPoolProbPayouts = ( - contract: FullContract, + contract: CPMMContract, p: number, liquidities: LiquidityProvision[] ) => { diff --git a/common/payouts.ts b/common/payouts.ts index 68fb8694..a3f105cf 100644 --- a/common/payouts.ts +++ b/common/payouts.ts @@ -1,15 +1,7 @@ import { sumBy, groupBy, mapValues } from 'lodash' import { Bet, NumericBet } from './bet' -import { - Binary, - Contract, - DPM, - FixedPayouts, - FreeResponse, - FullContract, - Multi, -} from './contract' +import { Contract, CPMMBinaryContract, DPMContract } from './contract' import { Fees } from './fees' import { LiquidityProvision } from './liquidity-provision' import { @@ -55,7 +47,7 @@ export type PayoutInfo = { } export const getPayouts = ( - outcome: string, + outcome: string | undefined, resolutions: { [outcome: string]: number }, @@ -73,7 +65,6 @@ export const getPayouts = ( resolutionProbability ) } - return getDpmPayouts( outcome, resolutions, @@ -84,8 +75,8 @@ export const getPayouts = ( } export const getFixedPayouts = ( - outcome: string, - contract: FullContract, + outcome: string | undefined, + contract: CPMMBinaryContract, bets: Bet[], liquidities: LiquidityProvision[], resolutionProbability?: number @@ -108,11 +99,11 @@ export const getFixedPayouts = ( } export const getDpmPayouts = ( - outcome: string, + outcome: string | undefined, resolutions: { [outcome: string]: number }, - contract: Contract, + contract: DPMContract, bets: Bet[], resolutionProbability?: number ): PayoutInfo => { @@ -125,13 +116,10 @@ export const getDpmPayouts = ( case 'MKT': return contract.outcomeType === 'FREE_RESPONSE' - ? getPayoutsMultiOutcome( - resolutions, - contract as FullContract, - openBets - ) + ? getPayoutsMultiOutcome(resolutions, contract, openBets) : getDpmMktPayouts(contract, openBets, resolutionProbability) case 'CANCEL': + case undefined: return getDpmCancelPayouts(contract, openBets) default: diff --git a/common/scoring.ts b/common/scoring.ts index 3f0c44b6..e910aa2f 100644 --- a/common/scoring.ts +++ b/common/scoring.ts @@ -1,7 +1,7 @@ import { groupBy, sumBy, mapValues, partition } from 'lodash' import { Bet } from './bet' -import { Binary, Contract, FullContract } from './contract' +import { Contract } from './contract' import { getPayouts } from './payouts' export function scoreCreators(contracts: Contract[]) { @@ -24,23 +24,24 @@ export function scoreTraders(contracts: Contract[], bets: Bet[][]) { return userScores } -export function scoreUsersByContract( - contract: FullContract, - bets: Bet[] -) { - const { resolution, resolutionProbability } = contract +export function scoreUsersByContract(contract: Contract, bets: Bet[]) { + const { resolution } = contract + const resolutionProb = + contract.outcomeType == 'BINARY' + ? contract.resolutionProbability + : undefined const [closedBets, openBets] = partition( bets, (bet) => bet.isSold || bet.sale ) const { payouts: resolvePayouts } = getPayouts( - resolution, + resolution as string, {}, contract, openBets, [], - resolutionProbability + resolutionProb ) const salePayouts = closedBets.map((bet) => { diff --git a/common/sell-bet.ts b/common/sell-bet.ts index 5392ab67..233e478f 100644 --- a/common/sell-bet.ts +++ b/common/sell-bet.ts @@ -5,14 +5,14 @@ import { deductDpmFees, } from './calculate-dpm' import { calculateCpmmSale, getCpmmProbability } from './calculate-cpmm' -import { Binary, DPM, CPMM, FullContract } from './contract' +import { CPMMContract, DPMContract } from './contract' import { DPM_CREATOR_FEE, DPM_PLATFORM_FEE, Fees } from './fees' import { User } from './user' export const getSellBetInfo = ( user: User, bet: Bet, - contract: FullContract, + contract: DPMContract, newBetId: string ) => { const { pool, totalShares, totalBets } = contract @@ -87,7 +87,7 @@ export const getCpmmSellBetInfo = ( user: User, shares: number, outcome: 'YES' | 'NO', - contract: FullContract, + contract: CPMMContract, prevLoanAmount: number, newBetId: string ) => { diff --git a/functions/src/create-answer.ts b/functions/src/create-answer.ts index 7fbe5416..7becfc7f 100644 --- a/functions/src/create-answer.ts +++ b/functions/src/create-answer.ts @@ -1,12 +1,7 @@ import * as functions from 'firebase-functions' import * as admin from 'firebase-admin' -import { - Contract, - DPM, - FreeResponse, - FullContract, -} from '../../common/contract' +import { Contract } from '../../common/contract' import { User } from '../../common/user' import { getNewMultiBetInfo } from '../../common/new-bet' import { Answer, MAX_ANSWER_LENGTH } from '../../common/answer' @@ -96,12 +91,7 @@ export const createAnswer = functions.runWith({ minInstances: 1 }).https.onCall( const loanAmount = 0 const { newBet, newPool, newTotalShares, newTotalBets } = - getNewMultiBetInfo( - answerId, - amount, - contract as FullContract, - loanAmount - ) + getNewMultiBetInfo(answerId, amount, contract, loanAmount) const newBalance = user.balance - amount const betDoc = firestore.collection(`contracts/${contractId}/bets`).doc() diff --git a/functions/src/create-contract.ts b/functions/src/create-contract.ts index ab65180b..805e4f6a 100644 --- a/functions/src/create-contract.ts +++ b/functions/src/create-contract.ts @@ -2,16 +2,13 @@ import * as admin from 'firebase-admin' import { z } from 'zod' import { - Binary, + CPMMBinaryContract, Contract, - CPMM, - DPM, - FreeResponse, - FullContract, + FreeResponseContract, MAX_DESCRIPTION_LENGTH, MAX_QUESTION_LENGTH, MAX_TAG_LENGTH, - Numeric, + NumericContract, OUTCOME_TYPES, } from '../../common/contract' import { slugify } from '../../common/util/slugify' @@ -22,7 +19,6 @@ import { APIError, newEndpoint, validate, zTimestamp } from './api' import { FIXED_ANTE, - getAnteBets, getCpmmInitialLiquidity, getFreeAnswerAnte, getNumericAnte, @@ -117,30 +113,14 @@ export const createContract = newEndpoint(['POST'], async (req, [user, _]) => { const providerId = isFree ? HOUSE_LIQUIDITY_PROVIDER_ID : user.id - if (outcomeType === 'BINARY' && contract.mechanism === 'dpm-2') { - const yesBetDoc = firestore - .collection(`contracts/${contract.id}/bets`) - .doc() - - const noBetDoc = firestore.collection(`contracts/${contract.id}/bets`).doc() - - const { yesBet, noBet } = getAnteBets( - user, - contract as FullContract, - yesBetDoc.id, - noBetDoc.id - ) - - await yesBetDoc.set(yesBet) - await noBetDoc.set(noBet) - } else if (outcomeType === 'BINARY') { + if (outcomeType === 'BINARY') { const liquidityDoc = firestore .collection(`contracts/${contract.id}/liquidity`) .doc() const lp = getCpmmInitialLiquidity( providerId, - contract as FullContract, + contract as CPMMBinaryContract, liquidityDoc.id, ante ) @@ -160,7 +140,7 @@ export const createContract = newEndpoint(['POST'], async (req, [user, _]) => { const anteBet = getFreeAnswerAnte( providerId, - contract as FullContract, + contract as FreeResponseContract, anteBetDoc.id ) await anteBetDoc.set(anteBet) @@ -171,7 +151,7 @@ export const createContract = newEndpoint(['POST'], async (req, [user, _]) => { const anteBet = getNumericAnte( providerId, - contract as FullContract, + contract as NumericContract, ante, anteBetDoc.id ) diff --git a/functions/src/redeem-shares.ts b/functions/src/redeem-shares.ts index b4c31223..bdd3ab94 100644 --- a/functions/src/redeem-shares.ts +++ b/functions/src/redeem-shares.ts @@ -4,7 +4,7 @@ import { partition, sumBy } from 'lodash' import { Bet } from '../../common/bet' import { getProbability } from '../../common/calculate' -import { Binary, CPMM, FullContract } from '../../common/contract' +import { Contract } from '../../common/contract' import { noFees } from '../../common/fees' import { User } from '../../common/user' @@ -15,7 +15,7 @@ export const redeemShares = async (userId: string, contractId: string) => { if (!contractSnap.exists) return { status: 'error', message: 'Invalid contract' } - const contract = contractSnap.data() as FullContract + const contract = contractSnap.data() as Contract if (contract.outcomeType !== 'BINARY' || contract.mechanism !== 'cpmm-1') return { status: 'success' } diff --git a/functions/src/scripts/correct-bet-probability.ts b/functions/src/scripts/correct-bet-probability.ts index 77321b7c..5a6ba730 100644 --- a/functions/src/scripts/correct-bet-probability.ts +++ b/functions/src/scripts/correct-bet-probability.ts @@ -6,14 +6,14 @@ initAdmin() import { Bet } from '../../../common/bet' import { getDpmProbability } from '../../../common/calculate-dpm' -import { Binary, Contract, DPM, FullContract } from '../../../common/contract' +import { DPMBinaryContract } from '../../../common/contract' type DocRef = admin.firestore.DocumentReference const firestore = admin.firestore() async function migrateContract( contractRef: DocRef, - contract: FullContract + contract: DPMBinaryContract ) { const bets = await contractRef .collection('bets') @@ -34,9 +34,7 @@ async function migrateContract( async function migrateContracts() { const snapshot = await firestore.collection('contracts').get() - const contracts = snapshot.docs.map( - (doc) => doc.data() as FullContract - ) + const contracts = snapshot.docs.map((doc) => doc.data() as DPMBinaryContract) console.log('Loaded contracts', contracts.length) diff --git a/functions/src/scripts/migrate-to-cfmm.ts b/functions/src/scripts/migrate-to-cfmm.ts index 65452e6c..039b04be 100644 --- a/functions/src/scripts/migrate-to-cfmm.ts +++ b/functions/src/scripts/migrate-to-cfmm.ts @@ -5,18 +5,15 @@ import { initAdmin } from './script-init' initAdmin() import { - Binary, Contract, - CPMM, - DPM, - FullContract, + DPMBinaryContract, + CPMMBinaryContract, } from '../../../common/contract' import { Bet } from '../../../common/bet' import { calculateDpmPayout, getDpmProbability, } from '../../../common/calculate-dpm' -import { User } from '../../../common/user' import { getCpmmInitialLiquidity } from '../../../common/antes' import { noFees } from '../../../common/fees' import { addObjects } from '../../../common/util/object' @@ -28,7 +25,7 @@ const firestore = admin.firestore() async function recalculateContract(contractRef: DocRef, isCommit = false) { await firestore.runTransaction(async (transaction) => { const contractDoc = await transaction.get(contractRef) - const contract = contractDoc.data() as FullContract + const contract = contractDoc.data() as DPMBinaryContract if (!contract?.slug) { console.log('missing slug; id=', contractRef.id) @@ -110,7 +107,7 @@ async function recalculateContract(contractRef: DocRef, isCommit = false) { { ...contract, ...contractUpdate, - } as FullContract, + } as CPMMBinaryContract, liquidityDocRef.id, ante ) diff --git a/functions/src/scripts/migrate-to-dpm-2.ts b/functions/src/scripts/migrate-to-dpm-2.ts index 64294ed9..ffbd1ef2 100644 --- a/functions/src/scripts/migrate-to-dpm-2.ts +++ b/functions/src/scripts/migrate-to-dpm-2.ts @@ -4,7 +4,7 @@ import { sortBy, sumBy } from 'lodash' import { initAdmin } from './script-init' initAdmin() -import { Binary, Contract, DPM, FullContract } from '../../../common/contract' +import { Contract, DPMBinaryContract } from '../../../common/contract' import { Bet } from '../../../common/bet' import { calculateDpmShares, @@ -32,7 +32,7 @@ async function recalculateContract( await firestore.runTransaction(async (transaction) => { const contractDoc = await transaction.get(contractRef) - const contract = contractDoc.data() as FullContract + const contract = contractDoc.data() as DPMBinaryContract const betDocs = await transaction.get(contractRef.collection('bets')) const bets = sortBy( diff --git a/functions/src/sell-shares.ts b/functions/src/sell-shares.ts index c4166b8b..e6bd66ab 100644 --- a/functions/src/sell-shares.ts +++ b/functions/src/sell-shares.ts @@ -2,7 +2,7 @@ import { partition, sumBy } from 'lodash' import * as admin from 'firebase-admin' import * as functions from 'firebase-functions' -import { Binary, CPMM, FullContract } from '../../common/contract' +import { BinaryContract } from '../../common/contract' import { User } from '../../common/user' import { getCpmmSellBetInfo } from '../../common/sell-bet' import { addObjects, removeUndefinedProps } from '../../common/util/object' @@ -35,7 +35,7 @@ export const sellShares = functions.runWith({ minInstances: 1 }).https.onCall( const contractSnap = await transaction.get(contractDoc) if (!contractSnap.exists) return { status: 'error', message: 'Invalid contract' } - const contract = contractSnap.data() as FullContract + const contract = contractSnap.data() as BinaryContract const { closeTime, mechanism, collectedFees, volume } = contract if (mechanism !== 'cpmm-1') diff --git a/web/components/answers/answer-bet-panel.tsx b/web/components/answers/answer-bet-panel.tsx index fb9e1270..ccb4fd14 100644 --- a/web/components/answers/answer-bet-panel.tsx +++ b/web/components/answers/answer-bet-panel.tsx @@ -3,7 +3,7 @@ import { useEffect, useRef, useState } from 'react' import { XIcon } from '@heroicons/react/solid' import { Answer } from 'common/answer' -import { DPM, FreeResponse, FullContract } from 'common/contract' +import { FreeResponseContract } from 'common/contract' import { BuyAmountInput } from '../amount-input' import { Col } from '../layout/col' import { APIError, placeBet } from 'web/lib/firebase/api-call' @@ -27,7 +27,7 @@ import { Bet } from 'common/bet' export function AnswerBetPanel(props: { answer: Answer - contract: FullContract + contract: FreeResponseContract closePanel: () => void className?: string isModal?: boolean diff --git a/web/components/answers/answer-item.tsx b/web/components/answers/answer-item.tsx index ccda34ea..87756a07 100644 --- a/web/components/answers/answer-item.tsx +++ b/web/components/answers/answer-item.tsx @@ -1,7 +1,7 @@ import clsx from 'clsx' import { Answer } from 'common/answer' -import { DPM, FreeResponse, FullContract } from 'common/contract' +import { FreeResponseContract } from 'common/contract' import { Col } from '../layout/col' import { Row } from '../layout/row' import { Avatar } from '../avatar' @@ -13,7 +13,7 @@ import { Linkify } from '../linkify' export function AnswerItem(props: { answer: Answer - contract: FullContract + contract: FreeResponseContract showChoice: 'radio' | 'checkbox' | undefined chosenProb: number | undefined totalChosenProb?: number diff --git a/web/components/answers/answer-resolve-panel.tsx b/web/components/answers/answer-resolve-panel.tsx index 7de19b5d..81b94550 100644 --- a/web/components/answers/answer-resolve-panel.tsx +++ b/web/components/answers/answer-resolve-panel.tsx @@ -2,7 +2,7 @@ import clsx from 'clsx' import { sum, mapValues } from 'lodash' import { useState } from 'react' -import { DPM, FreeResponse, FullContract } from 'common/contract' +import { Contract, FreeResponse } from 'common/contract' import { Col } from '../layout/col' import { resolveMarket } from 'web/lib/firebase/fn-call' import { Row } from '../layout/row' @@ -11,7 +11,7 @@ import { ResolveConfirmationButton } from '../confirmation-button' import { removeUndefinedProps } from 'common/util/object' export function AnswerResolvePanel(props: { - contract: FullContract + contract: Contract & FreeResponse resolveOption: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined setResolveOption: ( option: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined diff --git a/web/components/answers/answers-graph.tsx b/web/components/answers/answers-graph.tsx index 4d983353..f279151d 100644 --- a/web/components/answers/answers-graph.tsx +++ b/web/components/answers/answers-graph.tsx @@ -5,7 +5,7 @@ import { groupBy, sortBy, sumBy } from 'lodash' import { memo } from 'react' import { Bet } from 'common/bet' -import { DPM, FreeResponse, FullContract } from 'common/contract' +import { FreeResponseContract } from 'common/contract' import { getOutcomeProbability } from 'common/calculate' import { useBets } from 'web/hooks/use-bets' import { useWindowSize } from 'web/hooks/use-window-size' @@ -13,7 +13,7 @@ import { useWindowSize } from 'web/hooks/use-window-size' const NUM_LINES = 6 export const AnswersGraph = memo(function AnswersGraph(props: { - contract: FullContract + contract: FreeResponseContract bets: Bet[] height?: number }) { @@ -161,10 +161,7 @@ function formatTime(time: number, includeTime: boolean) { return dayjs(time).format('MMM D') } -const computeProbsByOutcome = ( - bets: Bet[], - contract: FullContract -) => { +const computeProbsByOutcome = (bets: Bet[], contract: FreeResponseContract) => { const { totalBets } = contract const betsByOutcome = groupBy(bets, (bet) => bet.outcome) diff --git a/web/components/answers/answers-panel.tsx b/web/components/answers/answers-panel.tsx index 7b3bc8cd..f2e344c6 100644 --- a/web/components/answers/answers-panel.tsx +++ b/web/components/answers/answers-panel.tsx @@ -1,7 +1,7 @@ import { sortBy, partition, sum, uniq } from 'lodash' import { useLayoutEffect, useState } from 'react' -import { DPM, FreeResponse, FullContract } from 'common/contract' +import { FreeResponseContract } from 'common/contract' import { Col } from '../layout/col' import { useUser } from 'web/hooks/use-user' import { getDpmOutcomeProbability } from 'common/calculate-dpm' @@ -25,9 +25,7 @@ import { UserLink } from 'web/components/user-page' import { Linkify } from 'web/components/linkify' import { BuyButton } from 'web/components/yes-no-selector' -export function AnswersPanel(props: { - contract: FullContract -}) { +export function AnswersPanel(props: { contract: FreeResponseContract }) { const { contract } = props const { creatorId, resolution, resolutions, totalBets } = contract @@ -154,7 +152,7 @@ export function AnswersPanel(props: { } function getAnswerItems( - contract: FullContract, + contract: FreeResponseContract, answers: Answer[], user: User | undefined | null ) { @@ -182,7 +180,7 @@ function getAnswerItems( } function OpenAnswer(props: { - contract: FullContract + contract: FreeResponseContract answer: Answer items: ActivityItem[] type: string diff --git a/web/components/answers/create-answer-panel.tsx b/web/components/answers/create-answer-panel.tsx index d0ae6996..6d9739cc 100644 --- a/web/components/answers/create-answer-panel.tsx +++ b/web/components/answers/create-answer-panel.tsx @@ -2,7 +2,7 @@ import clsx from 'clsx' import { useState } from 'react' import Textarea from 'react-expanding-textarea' -import { DPM, FreeResponse, FullContract } from 'common/contract' +import { FreeResponseContract } from 'common/contract' import { BuyAmountInput } from '../amount-input' import { Col } from '../layout/col' import { createAnswer } from 'web/lib/firebase/fn-call' @@ -23,9 +23,7 @@ import { firebaseLogin } from 'web/lib/firebase/users' import { Bet } from 'common/bet' import { MAX_ANSWER_LENGTH } from 'common/answer' -export function CreateAnswerPanel(props: { - contract: FullContract -}) { +export function CreateAnswerPanel(props: { contract: FreeResponseContract }) { const { contract } = props const user = useUser() const [text, setText] = useState('') diff --git a/web/components/bet-panel.tsx b/web/components/bet-panel.tsx index 8010e8de..536a2898 100644 --- a/web/components/bet-panel.tsx +++ b/web/components/bet-panel.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react' import { partition, sumBy } from 'lodash' import { useUser } from 'web/hooks/use-user' -import { Binary, CPMM, DPM, FullContract } from 'common/contract' +import { BinaryContract, CPMMBinaryContract } from 'common/contract' import { Col } from './layout/col' import { Row } from './layout/row' import { Spacer } from './layout/spacer' @@ -39,7 +39,7 @@ import { useSaveShares } from './use-save-shares' import { SignUpPrompt } from './sign-up-prompt' export function BetPanel(props: { - contract: FullContract + contract: BinaryContract className?: string }) { const { contract, className } = props @@ -78,7 +78,7 @@ export function BetPanel(props: { } export function BetPanelSwitcher(props: { - contract: FullContract + contract: BinaryContract className?: string title?: string // Set if BetPanel is on a feed modal selected?: 'YES' | 'NO' @@ -157,16 +157,19 @@ export function BetPanelSwitcher(props: { text={tradeType === 'BUY' ? title ?? 'Place a trade' : 'Sell shares'} /> - {tradeType === 'SELL' && user && sharesOutcome && ( - } - shares={yesShares || noShares} - sharesOutcome={sharesOutcome} - user={user} - userBets={userBets ?? []} - onSellSuccess={onBetSuccess} - /> - )} + {tradeType === 'SELL' && + mechanism == 'cpmm-1' && + user && + sharesOutcome && ( + + )} {tradeType === 'BUY' && ( + contract: BinaryContract user: User | null | undefined selected?: 'YES' | 'NO' onBuySuccess?: () => void @@ -374,7 +377,7 @@ function BuyPanel(props: { } export function SellPanel(props: { - contract: FullContract + contract: CPMMBinaryContract userBets: Bet[] shares: number sharesOutcome: 'YES' | 'NO' diff --git a/web/components/bet-row.tsx b/web/components/bet-row.tsx index 5298a433..9621f7a9 100644 --- a/web/components/bet-row.tsx +++ b/web/components/bet-row.tsx @@ -3,7 +3,7 @@ import clsx from 'clsx' import { BetPanelSwitcher } from './bet-panel' import { YesNoSelector } from './yes-no-selector' -import { Binary, CPMM, DPM, FullContract } from 'common/contract' +import { BinaryContract } from 'common/contract' import { Modal } from './layout/modal' import { SellButton } from './sell-button' import { useUser } from 'web/hooks/use-user' @@ -12,7 +12,7 @@ import { useSaveShares } from './use-save-shares' // Inline version of a bet panel. Opens BetPanel in a new modal. export default function BetRow(props: { - contract: FullContract + contract: BinaryContract className?: string btnClassName?: string betPanelClassName?: string diff --git a/web/components/bets-list.tsx b/web/components/bets-list.tsx index a56ded54..e71a72ad 100644 --- a/web/components/bets-list.tsx +++ b/web/components/bets-list.tsx @@ -255,7 +255,6 @@ function MyContractBets(props: { const [collapsed, setCollapsed] = useState(true) const isBinary = outcomeType === 'BINARY' - const probPercent = getBinaryProbPercent(contract) const { payout, profit, profitPercent, invested } = getContractBetMetrics( contract, @@ -292,24 +291,27 @@ function MyContractBets(props: { - {(isBinary || resolution) && ( + {resolution ? ( <> - {resolution ? ( -
- Resolved{' '} - -
- ) : ( -
{probPercent}
- )} +
+ Resolved{' '} + +
- )} + ) : isBinary ? ( + <> +
+ {getBinaryProbPercent(contract)} +
+
+ + ) : null} ) : ( - } - truncate="long" - /> + ))} )} {outcomeType === 'FREE_RESPONSE' && ( } + contract={contract} truncate="long" /> )} @@ -135,7 +125,7 @@ export function ContractCard(props: { } export function BinaryResolutionOrChance(props: { - contract: FullContract + contract: BinaryContract large?: boolean className?: string }) { diff --git a/web/components/contract/contract-overview.tsx b/web/components/contract/contract-overview.tsx index 4d1d772e..a8608ae6 100644 --- a/web/components/contract/contract-overview.tsx +++ b/web/components/contract/contract-overview.tsx @@ -1,4 +1,4 @@ -import { Contract, tradingAllowed } from 'web/lib/firebase/contracts' +import { tradingAllowed } from 'web/lib/firebase/contracts' import { Col } from '../layout/col' import { Spacer } from '../layout/spacer' import { ContractProbGraph } from './contract-prob-graph' @@ -16,12 +16,7 @@ import { Bet } from 'common/bet' import { Comment } from 'common/comment' import BetRow from '../bet-row' import { AnswersGraph } from '../answers/answers-graph' -import { - DPM, - FreeResponse, - FullContract, - NumericContract, -} from 'common/contract' +import { Contract } from 'common/contract' import { ContractDescription } from './contract-description' import { ContractDetails } from './contract-details' import { ShareMarket } from '../share-market' @@ -58,7 +53,7 @@ export const ContractOverview = (props: { {outcomeType === 'NUMERIC' && ( )} @@ -82,9 +77,7 @@ export const ContractOverview = (props: { {outcomeType === 'NUMERIC' && ( - + )} @@ -97,14 +90,9 @@ export const ContractOverview = (props: { {isBinary && }{' '} {outcomeType === 'FREE_RESPONSE' && ( - } - bets={bets} - /> - )} - {outcomeType === 'NUMERIC' && ( - + )} + {outcomeType === 'NUMERIC' && } {(contract.description || isCreator) && } {isCreator && } + contract: BinaryContract bets: Bet[] height?: number }) { diff --git a/web/components/contract/quick-bet.tsx b/web/components/contract/quick-bet.tsx index 1c73e40d..4c0e2ce5 100644 --- a/web/components/contract/quick-bet.tsx +++ b/web/components/contract/quick-bet.tsx @@ -5,16 +5,8 @@ import { getTopAnswer, } from 'common/calculate' import { getExpectedValue } from 'common/calculate-dpm' -import { - Contract, - FullContract, - CPMM, - DPM, - Binary, - NumericContract, - FreeResponseContract, -} from 'common/contract' import { User } from 'common/user' +import { Contract, NumericContract } from 'common/contract' import { formatLargeNumber, formatMoney, @@ -39,12 +31,12 @@ export function QuickBet(props: { contract: Contract; user: User }) { const userBets = useUserContractBets(user.id, contract.id) const topAnswer = contract.outcomeType === 'FREE_RESPONSE' - ? getTopAnswer(contract as FreeResponseContract) + ? getTopAnswer(contract) : undefined // TODO: yes/no from useSaveShares doesn't work on numeric contracts const { yesFloorShares, noFloorShares } = useSaveShares( - contract as FullContract, + contract, userBets, topAnswer?.number.toString() || undefined ) @@ -226,10 +218,10 @@ function QuickOutcomeView(props: { display = getBinaryProbPercent(contract) break case 'NUMERIC': - display = formatLargeNumber(getExpectedValue(contract as NumericContract)) + display = formatLargeNumber(getExpectedValue(contract)) break case 'FREE_RESPONSE': { - const topAnswer = getTopAnswer(contract as FreeResponseContract) + const topAnswer = getTopAnswer(contract) display = topAnswer && formatPercent(getOutcomeProbability(contract, topAnswer.id)) @@ -257,7 +249,7 @@ function getProb(contract: Contract) { : outcomeType === 'FREE_RESPONSE' ? getOutcomeProbability(contract, getTopAnswer(contract)?.id || '') : outcomeType === 'NUMERIC' - ? getNumericScale(contract as NumericContract) + ? getNumericScale(contract) : 1 // Should not happen } diff --git a/web/components/feed/activity-items.ts b/web/components/feed/activity-items.ts index fce2cdc4..f59853e9 100644 --- a/web/components/feed/activity-items.ts +++ b/web/components/feed/activity-items.ts @@ -4,7 +4,7 @@ import { Answer } from 'common/answer' import { Bet } from 'common/bet' import { getOutcomeProbability } from 'common/calculate' import { Comment } from 'common/comment' -import { Contract, DPM, FreeResponse, FullContract } from 'common/contract' +import { Contract, FreeResponseContract } from 'common/contract' import { User } from 'common/user' import { mapCommentsByBetId } from 'web/lib/firebase/comments' @@ -188,7 +188,7 @@ function groupBets( } function getAnswerGroups( - contract: FullContract, + contract: FreeResponseContract, bets: Bet[], comments: Comment[], user: User | undefined | null, @@ -269,7 +269,7 @@ function getAnswerGroups( } function getAnswerAndCommentInputGroups( - contract: FullContract, + contract: FreeResponseContract, bets: Bet[], comments: Comment[], user: User | undefined | null @@ -493,17 +493,11 @@ export function getRecentContractActivityItems( const items = [] if (contract.outcomeType === 'FREE_RESPONSE') { items.push( - ...getAnswerGroups( - contract as FullContract, - bets, - comments, - user, - { - sortByProb: false, - abbreviated: true, - reversed: true, - } - ) + ...getAnswerGroups(contract, bets, comments, user, { + sortByProb: false, + abbreviated: true, + reversed: true, + }) ) } else { items.push( @@ -587,7 +581,7 @@ export function getSpecificContractActivityItems( case 'free-response-comment-answer-groups': items.push( ...getAnswerAndCommentInputGroups( - contract as FullContract, + contract as FreeResponseContract, bets, comments, user diff --git a/web/components/feed/feed-answer-comment-group.tsx b/web/components/feed/feed-answer-comment-group.tsx index a184dd3c..1b976668 100644 --- a/web/components/feed/feed-answer-comment-group.tsx +++ b/web/components/feed/feed-answer-comment-group.tsx @@ -1,4 +1,3 @@ -import { FreeResponse, FullContract } from 'common/contract' import { Answer } from 'common/answer' import { ActivityItem } from 'web/components/feed/activity-items' import { Bet } from 'common/bet' @@ -26,7 +25,7 @@ import { CopyLinkDateTimeComponent } from 'web/components/feed/copy-link-date-ti import { useRouter } from 'next/router' export function FeedAnswerCommentGroup(props: { - contract: FullContract + contract: any answer: Answer items: ActivityItem[] type: string diff --git a/web/components/outcome-label.tsx b/web/components/outcome-label.tsx index 7cbfa144..8737953e 100644 --- a/web/components/outcome-label.tsx +++ b/web/components/outcome-label.tsx @@ -3,16 +3,7 @@ import { ReactNode } from 'react' import { Answer } from 'common/answer' import { getProbability } from 'common/calculate' import { getValueFromBucket } from 'common/calculate-dpm' -import { - Binary, - Contract, - CPMM, - DPM, - FreeResponse, - FreeResponseContract, - FullContract, - NumericContract, -} from 'common/contract' +import { BinaryContract, Contract, NumericContract } from 'common/contract' import { formatPercent } from 'common/util/format' import { ClientRender } from './client-render' @@ -36,7 +27,7 @@ export function OutcomeLabel(props: { return ( } + contract={contract} resolution={outcome} truncate={truncate} answerClassName={'font-bold text-base-400'} @@ -56,7 +47,7 @@ export function BinaryOutcomeLabel(props: { } export function BinaryContractOutcomeLabel(props: { - contract: FullContract + contract: BinaryContract resolution: 'YES' | 'NO' | 'CANCEL' | 'MKT' }) { const { contract, resolution } = props @@ -70,7 +61,7 @@ export function BinaryContractOutcomeLabel(props: { } export function FreeResponseOutcomeLabel(props: { - contract: FreeResponseContract + contract: Contract resolution: string | 'CANCEL' | 'MKT' truncate: 'short' | 'long' | 'none' answerClassName?: string @@ -80,8 +71,9 @@ export function FreeResponseOutcomeLabel(props: { if (resolution === 'CANCEL') return if (resolution === 'MKT') return - const { answers } = contract - const chosen = answers?.find((answer) => answer.id === resolution) + const answers = + contract.outcomeType === 'FREE_RESPONSE' ? contract.answers : [] + const chosen = answers.find((answer) => answer.id === resolution) if (!chosen) return return ( diff --git a/web/components/resolution-panel.tsx b/web/components/resolution-panel.tsx index d37e9084..fc031b22 100644 --- a/web/components/resolution-panel.tsx +++ b/web/components/resolution-panel.tsx @@ -10,12 +10,12 @@ import { resolveMarket } from 'web/lib/firebase/fn-call' import { ProbabilitySelector } from './probability-selector' import { DPM_CREATOR_FEE } from 'common/fees' import { getProbability } from 'common/calculate' -import { Binary, CPMM, DPM, FullContract } from 'common/contract' +import { BinaryContract } from 'common/contract' import { formatMoney } from 'common/util/format' export function ResolutionPanel(props: { creator: User - contract: FullContract + contract: BinaryContract className?: string }) { useEffect(() => { diff --git a/web/components/sell-button.tsx b/web/components/sell-button.tsx index 17c8db3e..2b3734a5 100644 --- a/web/components/sell-button.tsx +++ b/web/components/sell-button.tsx @@ -1,4 +1,4 @@ -import { Binary, CPMM, DPM, FullContract } from 'common/contract' +import { BinaryContract } from 'common/contract' import { User } from 'common/user' import { useUserContractBets } from 'web/hooks/use-user-bets' import { useState } from 'react' @@ -7,7 +7,7 @@ import clsx from 'clsx' import { SellSharesModal } from './sell-modal' export function SellButton(props: { - contract: FullContract + contract: BinaryContract user: User | null | undefined sharesOutcome: 'YES' | 'NO' | undefined shares: number @@ -40,7 +40,7 @@ export function SellButton(props: { {showSellModal && ( } + contract={contract} user={user} userBets={userBets ?? []} shares={shares} diff --git a/web/components/sell-modal.tsx b/web/components/sell-modal.tsx index 3e620e24..f5a1af67 100644 --- a/web/components/sell-modal.tsx +++ b/web/components/sell-modal.tsx @@ -1,4 +1,4 @@ -import { Binary, CPMM, FullContract } from 'common/contract' +import { CPMMBinaryContract } from 'common/contract' import { Bet } from 'common/bet' import { User } from 'common/user' import { Modal } from './layout/modal' @@ -11,7 +11,7 @@ import clsx from 'clsx' export function SellSharesModal(props: { className?: string - contract: FullContract + contract: CPMMBinaryContract userBets: Bet[] shares: number sharesOutcome: 'YES' | 'NO' diff --git a/web/components/sell-row.tsx b/web/components/sell-row.tsx index 2ec50c72..4fe2536f 100644 --- a/web/components/sell-row.tsx +++ b/web/components/sell-row.tsx @@ -1,4 +1,4 @@ -import { Binary, CPMM, DPM, FullContract } from 'common/contract' +import { BinaryContract } from 'common/contract' import { User } from 'common/user' import { useState } from 'react' import { Col } from './layout/col' @@ -10,7 +10,7 @@ import { useSaveShares } from './use-save-shares' import { SellSharesModal } from './sell-modal' export function SellRow(props: { - contract: FullContract + contract: BinaryContract user: User | null | undefined className?: string }) { @@ -61,7 +61,7 @@ export function SellRow(props: { {showSellModal && ( } + contract={contract} user={user} userBets={userBets ?? []} shares={yesShares || noShares} diff --git a/web/components/use-save-shares.ts b/web/components/use-save-shares.ts index 9bf3e739..494c1f29 100644 --- a/web/components/use-save-shares.ts +++ b/web/components/use-save-shares.ts @@ -1,17 +1,11 @@ -import { - Binary, - CPMM, - DPM, - FreeResponseContract, - FullContract, -} from 'common/contract' +import { Contract } from 'common/contract' import { Bet } from 'common/bet' import { useEffect, useState } from 'react' import { partition, sumBy } from 'lodash' import { safeLocalStorage } from 'web/lib/util/local' export const useSaveShares = ( - contract: FullContract, + contract: Contract, userBets: Bet[] | undefined, freeResponseAnswerOutcome?: string ) => { diff --git a/web/lib/firebase/contracts.ts b/web/lib/firebase/contracts.ts index 3ea413ce..472f7bda 100644 --- a/web/lib/firebase/contracts.ts +++ b/web/lib/firebase/contracts.ts @@ -17,7 +17,7 @@ import { range, sortBy, sum } from 'lodash' import { app } from './init' import { getValues, listenForValue, listenForValues } from './utils' -import { Binary, Contract, FullContract } from 'common/contract' +import { BinaryContract, Contract } from 'common/contract' import { getDpmProbability } from 'common/calculate-dpm' import { createRNG, shuffle } from 'common/util/random' import { getCpmmProbability } from 'common/calculate-cpmm' @@ -63,18 +63,18 @@ export function contractPool(contract: Contract) { : 'Empty pool' } -export function getBinaryProb(contract: FullContract) { - const { totalShares, pool, p, resolutionProbability, mechanism } = contract +export function getBinaryProb(contract: BinaryContract) { + const { pool, resolutionProbability, mechanism } = contract return ( resolutionProbability ?? (mechanism === 'cpmm-1' - ? getCpmmProbability(pool, p) - : getDpmProbability(totalShares)) + ? getCpmmProbability(pool, contract.p) + : getDpmProbability(contract.totalShares)) ) } -export function getBinaryProbPercent(contract: FullContract) { +export function getBinaryProbPercent(contract: BinaryContract) { return formatPercent(getBinaryProb(contract)) } diff --git a/web/pages/[username]/[contractSlug].tsx b/web/pages/[username]/[contractSlug].tsx index 120f3cb7..e340e12a 100644 --- a/web/pages/[username]/[contractSlug].tsx +++ b/web/pages/[username]/[contractSlug].tsx @@ -30,13 +30,6 @@ import { formatMoney } from 'common/util/format' import { useUserById } from 'web/hooks/use-users' import { ContractTabs } from 'web/components/contract/contract-tabs' import { FirstArgument } from 'common/util/types' -import { - BinaryContract, - DPM, - FreeResponse, - FullContract, - NumericContract, -} from 'common/contract' import { contractTextDetails } from 'web/components/contract/contract-details' import { useWindowSize } from 'web/hooks/use-window-size' import Confetti from 'react-confetti' @@ -143,24 +136,15 @@ export function ContractPageContent(props: FirstArgument) { {allowTrade && (isNumeric ? ( - + ) : ( ))} {allowResolve && (isNumeric ? ( - + ) : ( - + ))} ) : null @@ -205,18 +189,13 @@ export function ContractPageContent(props: FirstArgument) { {outcomeType === 'FREE_RESPONSE' && ( <> - } - /> + )} {isNumeric && ( - + )} {isResolved && ( diff --git a/web/pages/embed/[username]/[contractSlug].tsx b/web/pages/embed/[username]/[contractSlug].tsx index ff485aae..57b6ab45 100644 --- a/web/pages/embed/[username]/[contractSlug].tsx +++ b/web/pages/embed/[username]/[contractSlug].tsx @@ -1,12 +1,5 @@ import { Bet } from 'common/bet' -import { - BinaryContract, - Contract, - DPM, - FreeResponse, - FullContract, - NumericContract, -} from 'common/contract' +import { Contract } from 'common/contract' import { DOMAIN } from 'common/envs/constants' import { AnswersGraph } from 'web/components/answers/answers-graph' import BetRow from 'web/components/bet-row' @@ -117,10 +110,9 @@ function ContractEmbed(props: { contract: Contract; bets: Bet[] }) { {isBinary && ( - + // this fails typechecking, but it doesn't explode because we will + never + )} @@ -133,9 +125,7 @@ function ContractEmbed(props: { contract: Contract; bets: Bet[] }) { )} {outcomeType === 'NUMERIC' && ( - + )}
@@ -152,18 +142,11 @@ function ContractEmbed(props: { contract: Contract; bets: Bet[] }) { )} {outcomeType === 'FREE_RESPONSE' && ( - } - bets={bets} - height={graphHeight} - /> + )} {outcomeType === 'NUMERIC' && ( - + )} diff --git a/web/pages/make-predictions.tsx b/web/pages/make-predictions.tsx index 55fba2ce..dccef955 100644 --- a/web/pages/make-predictions.tsx +++ b/web/pages/make-predictions.tsx @@ -5,7 +5,7 @@ import { useState } from 'react' import Textarea from 'react-expanding-textarea' import { getProbability } from 'common/calculate' -import { Binary, CPMM, DPM, FullContract } from 'common/contract' +import { BinaryContract } from 'common/contract' import { parseWordsAsTags } from 'common/util/parse' import { BuyAmountInput } from 'web/components/amount-input' import { InfoTooltip } from 'web/components/info-tooltip' @@ -26,7 +26,7 @@ type Prediction = { createdUrl?: string } -function toPrediction(contract: FullContract): Prediction { +function toPrediction(contract: BinaryContract): Prediction { const startProb = getProbability(contract) return { question: contract.question, @@ -102,9 +102,7 @@ export default function MakePredictions() { const [description, setDescription] = useState('') const [tags, setTags] = useState('') const [isSubmitting, setIsSubmitting] = useState(false) - const [createdContracts, setCreatedContracts] = useState< - FullContract[] - >([]) + const [createdContracts, setCreatedContracts] = useState([]) const [ante, setAnte] = useState(100) const [anteError, setAnteError] = useState() @@ -155,7 +153,7 @@ ${TEST_VALUE} ante, closeTime, tags: parseWordsAsTags(tags), - })) as FullContract + })) as BinaryContract setCreatedContracts((prev) => [...prev, contract]) }