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
This commit is contained in:
Marshall Polaris 2022-05-31 19:42:35 -07:00 committed by GitHub
parent 30adb5e1f8
commit 7c4ec2a8e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 245 additions and 436 deletions

View File

@ -1,12 +1,12 @@
import { addCpmmLiquidity, getCpmmLiquidity } from './calculate-cpmm' import { addCpmmLiquidity, getCpmmLiquidity } from './calculate-cpmm'
import { Binary, CPMM, FullContract } from './contract' import { CPMMContract } from './contract'
import { LiquidityProvision } from './liquidity-provision' import { LiquidityProvision } from './liquidity-provision'
import { User } from './user' import { User } from './user'
export const getNewLiquidityProvision = ( export const getNewLiquidityProvision = (
user: User, user: User,
amount: number, amount: number,
contract: FullContract<CPMM, Binary>, contract: CPMMContract,
newLiquidityProvisionId: string newLiquidityProvisionId: string
) => { ) => {
const { pool, p, totalLiquidity } = contract const { pool, p, totalLiquidity } = contract

View File

@ -2,12 +2,10 @@ import { range } from 'lodash'
import { Bet, NumericBet } from './bet' import { Bet, NumericBet } from './bet'
import { getDpmProbability, getValueFromBucket } from './calculate-dpm' import { getDpmProbability, getValueFromBucket } from './calculate-dpm'
import { import {
Binary, CPMMBinaryContract,
CPMM, DPMBinaryContract,
DPM, FreeResponseContract,
FreeResponse, NumericContract,
FullContract,
Numeric,
} from './contract' } from './contract'
import { User } from './user' import { User } from './user'
import { LiquidityProvision } from './liquidity-provision' import { LiquidityProvision } from './liquidity-provision'
@ -23,7 +21,7 @@ export const HOUSE_LIQUIDITY_PROVIDER_ID = 'IPTOzEqrpkWmEzh6hwvAyY9PqFb2' // @Ma
export function getCpmmInitialLiquidity( export function getCpmmInitialLiquidity(
providerId: string, providerId: string,
contract: FullContract<CPMM, Binary>, contract: CPMMBinaryContract,
anteId: string, anteId: string,
amount: number amount: number
) { ) {
@ -47,7 +45,7 @@ export function getCpmmInitialLiquidity(
export function getAnteBets( export function getAnteBets(
creator: User, creator: User,
contract: FullContract<DPM, Binary>, contract: DPMBinaryContract,
yesAnteId: string, yesAnteId: string,
noAnteId: string noAnteId: string
) { ) {
@ -89,7 +87,7 @@ export function getAnteBets(
export function getFreeAnswerAnte( export function getFreeAnswerAnte(
anteBettorId: string, anteBettorId: string,
contract: FullContract<DPM, FreeResponse>, contract: FreeResponseContract,
anteBetId: string anteBetId: string
) { ) {
const { totalBets, totalShares } = contract const { totalBets, totalShares } = contract
@ -117,7 +115,7 @@ export function getFreeAnswerAnte(
export function getNumericAnte( export function getNumericAnte(
anteBettorId: string, anteBettorId: string,
contract: FullContract<DPM, Numeric>, contract: NumericContract,
ante: number, ante: number,
newBetId: string newBetId: string
) { ) {

View File

@ -1,6 +1,6 @@
import { sum, groupBy, mapValues, sumBy } from 'lodash' 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 { CREATOR_FEE, Fees, LIQUIDITY_FEE, noFees, PLATFORM_FEE } from './fees'
import { LiquidityProvision } from './liquidity-provision' import { LiquidityProvision } from './liquidity-provision'
import { addObjects } from './util/object' import { addObjects } from './util/object'
@ -14,7 +14,7 @@ export function getCpmmProbability(
} }
export function getCpmmProbabilityAfterBetBeforeFees( export function getCpmmProbabilityAfterBetBeforeFees(
contract: FullContract<CPMM, Binary>, contract: CPMMContract,
outcome: string, outcome: string,
bet: number bet: number
) { ) {
@ -31,7 +31,7 @@ export function getCpmmProbabilityAfterBetBeforeFees(
} }
export function getCpmmOutcomeProbabilityAfterBet( export function getCpmmOutcomeProbabilityAfterBet(
contract: FullContract<CPMM, Binary>, contract: CPMMContract,
outcome: string, outcome: string,
bet: number bet: number
) { ) {
@ -59,7 +59,7 @@ function calculateCpmmShares(
} }
export function getCpmmLiquidityFee( export function getCpmmLiquidityFee(
contract: FullContract<CPMM, Binary>, contract: CPMMContract,
bet: number, bet: number,
outcome: string outcome: string
) { ) {
@ -78,7 +78,7 @@ export function getCpmmLiquidityFee(
} }
export function calculateCpmmSharesAfterFee( export function calculateCpmmSharesAfterFee(
contract: FullContract<CPMM, Binary>, contract: CPMMContract,
bet: number, bet: number,
outcome: string outcome: string
) { ) {
@ -89,7 +89,7 @@ export function calculateCpmmSharesAfterFee(
} }
export function calculateCpmmPurchase( export function calculateCpmmPurchase(
contract: FullContract<CPMM, Binary>, contract: CPMMContract,
bet: number, bet: number,
outcome: string outcome: string
) { ) {
@ -133,7 +133,7 @@ function sellSharesK(
} }
function calculateCpmmShareValue( function calculateCpmmShareValue(
contract: FullContract<CPMM, Binary>, contract: CPMMContract,
shares: number, shares: number,
outcome: 'YES' | 'NO' outcome: 'YES' | 'NO'
) { ) {
@ -168,7 +168,7 @@ function calculateCpmmShareValue(
} }
export function calculateCpmmSale( export function calculateCpmmSale(
contract: FullContract<CPMM, Binary>, contract: CPMMContract,
shares: number, shares: number,
outcome: string outcome: string
) { ) {
@ -222,7 +222,7 @@ export function calculateCpmmSale(
} }
export function getCpmmProbabilityAfterSale( export function getCpmmProbabilityAfterSale(
contract: FullContract<CPMM, Binary>, contract: CPMMContract,
shares: number, shares: number,
outcome: 'YES' | 'NO' outcome: 'YES' | 'NO'
) { ) {
@ -261,7 +261,7 @@ export function addCpmmLiquidity(
} }
export function getCpmmLiquidityPoolWeights( export function getCpmmLiquidityPoolWeights(
contract: FullContract<CPMM, Binary>, contract: CPMMContract,
liquidities: LiquidityProvision[] liquidities: LiquidityProvision[]
) { ) {
const { p } = contract const { p } = contract
@ -291,7 +291,7 @@ export function getCpmmLiquidityPoolWeights(
} }
// export function removeCpmmLiquidity( // export function removeCpmmLiquidity(
// contract: FullContract<CPMM, Binary>, // contract: CPMMContract,
// liquidity: number // liquidity: number
// ) { // ) {
// const { YES, NO } = contract.pool // const { YES, NO } = contract.pool

View File

@ -1,13 +1,6 @@
import { cloneDeep, range, sum, sumBy, sortBy, mapValues } from 'lodash' import { cloneDeep, range, sum, sumBy, sortBy, mapValues } from 'lodash'
import { Bet, NumericBet } from './bet' import { Bet, NumericBet } from './bet'
import { import { DPMContract, DPMBinaryContract, NumericContract } from './contract'
Binary,
DPM,
FreeResponse,
FullContract,
Numeric,
NumericContract,
} from './contract'
import { DPM_FEES } from './fees' import { DPM_FEES } from './fees'
import { normpdf } from '../common/util/math' import { normpdf } from '../common/util/math'
import { addObjects } from './util/object' import { addObjects } from './util/object'
@ -202,7 +195,7 @@ export function calculateDpmRawShareValue(
} }
export function calculateDpmMoneyRatio( export function calculateDpmMoneyRatio(
contract: FullContract<DPM, any>, contract: DPMContract,
bet: Bet, bet: Bet,
shareValue: number shareValue: number
) { ) {
@ -228,10 +221,7 @@ export function calculateDpmMoneyRatio(
return actual / expected return actual / expected
} }
export function calculateDpmShareValue( export function calculateDpmShareValue(contract: DPMContract, bet: Bet) {
contract: FullContract<DPM, any>,
bet: Bet
) {
const { pool, totalShares } = contract const { pool, totalShares } = contract
const { shares, outcome } = bet const { shares, outcome } = bet
@ -243,17 +233,14 @@ export function calculateDpmShareValue(
return adjShareValue return adjShareValue
} }
export function calculateDpmSaleAmount( export function calculateDpmSaleAmount(contract: DPMContract, bet: Bet) {
contract: FullContract<DPM, any>,
bet: Bet
) {
const { amount } = bet const { amount } = bet
const winnings = calculateDpmShareValue(contract, bet) const winnings = calculateDpmShareValue(contract, bet)
return deductDpmFees(amount, winnings) return deductDpmFees(amount, winnings)
} }
export function calculateDpmPayout( export function calculateDpmPayout(
contract: FullContract<DPM, any>, contract: DPMContract,
bet: Bet, bet: Bet,
outcome: string outcome: string
) { ) {
@ -263,10 +250,7 @@ export function calculateDpmPayout(
return calculateStandardDpmPayout(contract, bet, outcome) return calculateStandardDpmPayout(contract, bet, outcome)
} }
export function calculateDpmCancelPayout( export function calculateDpmCancelPayout(contract: DPMContract, bet: Bet) {
contract: FullContract<DPM, any>,
bet: Bet
) {
const { totalBets, pool } = contract const { totalBets, pool } = contract
const betTotal = sum(Object.values(totalBets)) const betTotal = sum(Object.values(totalBets))
const poolTotal = sum(Object.values(pool)) const poolTotal = sum(Object.values(pool))
@ -275,7 +259,7 @@ export function calculateDpmCancelPayout(
} }
export function calculateStandardDpmPayout( export function calculateStandardDpmPayout(
contract: FullContract<DPM, any>, contract: DPMContract,
bet: Bet, bet: Bet,
outcome: string outcome: string
) { ) {
@ -308,7 +292,7 @@ export function calculateStandardDpmPayout(
} }
export function calculateDpmPayoutAfterCorrectBet( export function calculateDpmPayoutAfterCorrectBet(
contract: FullContract<DPM, any>, contract: DPMContract,
bet: Bet bet: Bet
) { ) {
const { totalShares, pool, totalBets, outcomeType } = contract const { totalShares, pool, totalBets, outcomeType } = contract
@ -338,13 +322,10 @@ export function calculateDpmPayoutAfterCorrectBet(
: outcomeType, : outcomeType,
} }
return calculateStandardDpmPayout(newContract, bet, outcome) return calculateStandardDpmPayout(newContract as any, bet, outcome)
} }
function calculateMktDpmPayout( function calculateMktDpmPayout(contract: DPMContract, bet: Bet) {
contract: FullContract<DPM, Binary | FreeResponse | Numeric>,
bet: Bet
) {
if (contract.outcomeType === 'BINARY') if (contract.outcomeType === 'BINARY')
return calculateBinaryMktDpmPayout(contract, bet) return calculateBinaryMktDpmPayout(contract, bet)
@ -389,10 +370,7 @@ function calculateMktDpmPayout(
return deductDpmFees(amount, winnings) return deductDpmFees(amount, winnings)
} }
function calculateBinaryMktDpmPayout( function calculateBinaryMktDpmPayout(contract: DPMBinaryContract, bet: Bet) {
contract: FullContract<DPM, Binary>,
bet: Bet
) {
const { resolutionProbability, totalShares, phantomShares } = contract const { resolutionProbability, totalShares, phantomShares } = contract
const p = const p =
resolutionProbability !== undefined resolutionProbability !== undefined
@ -413,7 +391,7 @@ function calculateBinaryMktDpmPayout(
return deductDpmFees(amount, winnings) return deductDpmFees(amount, winnings)
} }
export function resolvedDpmPayout(contract: FullContract<DPM, any>, bet: Bet) { export function resolvedDpmPayout(contract: DPMContract, bet: Bet) {
if (contract.resolution) if (contract.resolution)
return calculateDpmPayout(contract, bet, contract.resolution) return calculateDpmPayout(contract, bet, contract.resolution)
throw new Error('Contract was not resolved') throw new Error('Contract was not resolved')

View File

@ -1,9 +1,9 @@
import { Bet } from './bet' import { Bet } from './bet'
import { getProbability } from './calculate' import { getProbability } from './calculate'
import { Binary, FixedPayouts, FullContract } from './contract' import { CPMMContract } from './contract'
export function calculateFixedPayout( export function calculateFixedPayout(
contract: FullContract<FixedPayouts, Binary>, contract: CPMMContract,
bet: Bet, bet: Bet,
outcome: string outcome: string
) { ) {
@ -23,10 +23,7 @@ export function calculateStandardFixedPayout(bet: Bet, outcome: string) {
return shares return shares
} }
function calculateFixedMktPayout( function calculateFixedMktPayout(contract: CPMMContract, bet: Bet) {
contract: FullContract<FixedPayouts, Binary>,
bet: Bet
) {
const { resolutionProbability } = contract const { resolutionProbability } = contract
const p = const p =
resolutionProbability !== undefined resolutionProbability !== undefined

View File

@ -18,24 +18,15 @@ import {
getDpmProbabilityAfterSale, getDpmProbabilityAfterSale,
} from './calculate-dpm' } from './calculate-dpm'
import { calculateFixedPayout } from './calculate-fixed-payouts' import { calculateFixedPayout } from './calculate-fixed-payouts'
import { import { Contract, BinaryContract, FreeResponseContract } from './contract'
Binary,
Contract,
CPMM,
DPM,
FreeResponseContract,
FullContract,
} from './contract'
export function getProbability(contract: FullContract<DPM | CPMM, Binary>) { export function getProbability(contract: BinaryContract) {
return contract.mechanism === 'cpmm-1' return contract.mechanism === 'cpmm-1'
? getCpmmProbability(contract.pool, contract.p) ? getCpmmProbability(contract.pool, contract.p)
: getDpmProbability(contract.totalShares) : getDpmProbability(contract.totalShares)
} }
export function getInitialProbability( export function getInitialProbability(contract: BinaryContract) {
contract: FullContract<DPM | CPMM, Binary>
) {
if (contract.initialProbability) return contract.initialProbability if (contract.initialProbability) return contract.initialProbability
if (contract.mechanism === 'dpm-2' || (contract as any).totalShares) if (contract.mechanism === 'dpm-2' || (contract as any).totalShares)
@ -59,11 +50,7 @@ export function getOutcomeProbabilityAfterBet(
bet: number bet: number
) { ) {
return contract.mechanism === 'cpmm-1' return contract.mechanism === 'cpmm-1'
? getCpmmOutcomeProbabilityAfterBet( ? getCpmmOutcomeProbabilityAfterBet(contract, outcome, bet)
contract as FullContract<CPMM, Binary>,
outcome,
bet
)
: getDpmOutcomeProbabilityAfterBet(contract.totalShares, outcome, bet) : getDpmOutcomeProbabilityAfterBet(contract.totalShares, outcome, bet)
} }
@ -73,11 +60,7 @@ export function calculateShares(
betChoice: string betChoice: string
) { ) {
return contract.mechanism === 'cpmm-1' return contract.mechanism === 'cpmm-1'
? calculateCpmmSharesAfterFee( ? calculateCpmmSharesAfterFee(contract, bet, betChoice)
contract as FullContract<CPMM, Binary>,
bet,
betChoice
)
: calculateDpmShares(contract.totalShares, bet, betChoice) : calculateDpmShares(contract.totalShares, bet, betChoice)
} }
@ -99,11 +82,7 @@ export function getProbabilityAfterSale(
shares: number shares: number
) { ) {
return contract.mechanism === 'cpmm-1' return contract.mechanism === 'cpmm-1'
? getCpmmProbabilityAfterSale( ? getCpmmProbabilityAfterSale(contract, shares, outcome as 'YES' | 'NO')
contract as FullContract<CPMM, Binary>,
shares,
outcome as 'YES' | 'NO'
)
: getDpmProbabilityAfterSale(contract.totalShares, outcome, shares) : getDpmProbabilityAfterSale(contract.totalShares, outcome, shares)
} }

View File

@ -1,10 +1,15 @@
import { Answer } from './answer' import { Answer } from './answer'
import { Fees } from './fees' import { Fees } from './fees'
export type FullContract< export type AnyMechanism = DPM | CPMM
M extends DPM | CPMM, export type AnyOutcomeType = Binary | Multi | FreeResponse | Numeric
T extends Binary | Multi | FreeResponse | Numeric export type AnyContractType =
> = { | (CPMM & Binary)
| (DPM & Binary)
| (DPM & (Multi | FreeResponse))
| (DPM & Numeric)
export type Contract<T extends AnyContractType = AnyContractType> = {
id: string id: string
slug: string // auto-generated; must be unique slug: string // auto-generated; must be unique
@ -36,16 +41,15 @@ export type FullContract<
volume7Days: number volume7Days: number
collectedFees: Fees collectedFees: Fees
} & M & } & T
T
export type Contract = FullContract< export type BinaryContract = Contract & Binary
DPM | CPMM, export type NumericContract = Contract & Numeric
Binary | Multi | FreeResponse | Numeric export type FreeResponseContract = Contract & FreeResponse
> export type DPMContract = Contract & DPM
export type BinaryContract = FullContract<DPM | CPMM, Binary> export type CPMMContract = Contract & CPMM
export type FreeResponseContract = FullContract<DPM | CPMM, FreeResponse> export type DPMBinaryContract = BinaryContract & DPM
export type NumericContract = FullContract<DPM, Numeric> export type CPMMBinaryContract = BinaryContract & CPMM
export type DPM = { export type DPM = {
mechanism: 'dpm-2' mechanism: 'dpm-2'
@ -63,8 +67,6 @@ export type CPMM = {
totalLiquidity: number // in M$ totalLiquidity: number // in M$
} }
export type FixedPayouts = CPMM
export type Binary = { export type Binary = {
outcomeType: 'BINARY' outcomeType: 'BINARY'
initialProbability: number initialProbability: number
@ -94,7 +96,7 @@ export type Numeric = {
resolutionValue?: number resolutionValue?: number
} }
export type outcomeType = 'BINARY' | 'MULTI' | 'FREE_RESPONSE' | 'NUMERIC' export type outcomeType = AnyOutcomeType['outcomeType']
export const OUTCOME_TYPES = [ export const OUTCOME_TYPES = [
'BINARY', 'BINARY',
'MULTI', 'MULTI',

View File

@ -10,12 +10,9 @@ import {
} from './calculate-dpm' } from './calculate-dpm'
import { calculateCpmmPurchase, getCpmmProbability } from './calculate-cpmm' import { calculateCpmmPurchase, getCpmmProbability } from './calculate-cpmm'
import { import {
Binary, CPMMBinaryContract,
CPMM, DPMBinaryContract,
DPM, FreeResponseContract,
FreeResponse,
FullContract,
Multi,
NumericContract, NumericContract,
} from './contract' } from './contract'
import { noFees } from './fees' import { noFees } from './fees'
@ -35,7 +32,7 @@ export type BetInfo = {
export const getNewBinaryCpmmBetInfo = ( export const getNewBinaryCpmmBetInfo = (
outcome: 'YES' | 'NO', outcome: 'YES' | 'NO',
amount: number, amount: number,
contract: FullContract<CPMM, Binary>, contract: CPMMBinaryContract,
loanAmount: number loanAmount: number
) => { ) => {
const { shares, newPool, newP, fees } = calculateCpmmPurchase( const { shares, newPool, newP, fees } = calculateCpmmPurchase(
@ -69,7 +66,7 @@ export const getNewBinaryCpmmBetInfo = (
export const getNewBinaryDpmBetInfo = ( export const getNewBinaryDpmBetInfo = (
outcome: 'YES' | 'NO', outcome: 'YES' | 'NO',
amount: number, amount: number,
contract: FullContract<DPM, Binary>, contract: DPMBinaryContract,
loanAmount: number loanAmount: number
) => { ) => {
const { YES: yesPool, NO: noPool } = contract.pool const { YES: yesPool, NO: noPool } = contract.pool
@ -116,7 +113,7 @@ export const getNewBinaryDpmBetInfo = (
export const getNewMultiBetInfo = ( export const getNewMultiBetInfo = (
outcome: string, outcome: string,
amount: number, amount: number,
contract: FullContract<DPM, Multi | FreeResponse>, contract: FreeResponseContract,
loanAmount: number loanAmount: number
) => { ) => {
const { pool, totalShares, totalBets } = contract const { pool, totalShares, totalBets } = contract

View File

@ -2,14 +2,11 @@ import { sum, groupBy, sumBy, mapValues } from 'lodash'
import { Bet, NumericBet } from './bet' import { Bet, NumericBet } from './bet'
import { deductDpmFees, getDpmProbability } from './calculate-dpm' 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 { DPM_CREATOR_FEE, DPM_FEES, DPM_PLATFORM_FEE } from './fees'
import { addObjects } from './util/object' import { addObjects } from './util/object'
export const getDpmCancelPayouts = ( export const getDpmCancelPayouts = (contract: DPMContract, bets: Bet[]) => {
contract: FullContract<DPM, any>,
bets: Bet[]
) => {
const { pool } = contract const { pool } = contract
const poolTotal = sum(Object.values(pool)) const poolTotal = sum(Object.values(pool))
console.log('resolved N/A, pool M$', poolTotal) console.log('resolved N/A, pool M$', poolTotal)
@ -31,7 +28,7 @@ export const getDpmCancelPayouts = (
export const getDpmStandardPayouts = ( export const getDpmStandardPayouts = (
outcome: string, outcome: string,
contract: FullContract<DPM, any>, contract: DPMContract,
bets: Bet[] bets: Bet[]
) => { ) => {
const winningBets = bets.filter((bet) => bet.outcome === outcome) const winningBets = bets.filter((bet) => bet.outcome === outcome)
@ -78,7 +75,7 @@ export const getDpmStandardPayouts = (
export const getNumericDpmPayouts = ( export const getNumericDpmPayouts = (
outcome: string, outcome: string,
contract: FullContract<DPM, any>, contract: DPMContract,
bets: NumericBet[] bets: NumericBet[]
) => { ) => {
const totalShares = sumBy(bets, (bet) => bet.allOutcomeShares[outcome] ?? 0) const totalShares = sumBy(bets, (bet) => bet.allOutcomeShares[outcome] ?? 0)
@ -129,7 +126,7 @@ export const getNumericDpmPayouts = (
} }
export const getDpmMktPayouts = ( export const getDpmMktPayouts = (
contract: FullContract<DPM, any>, contract: DPMContract,
bets: Bet[], bets: Bet[],
resolutionProbability?: number resolutionProbability?: number
) => { ) => {
@ -183,7 +180,7 @@ export const getDpmMktPayouts = (
export const getPayoutsMultiOutcome = ( export const getPayoutsMultiOutcome = (
resolutions: { [outcome: string]: number }, resolutions: { [outcome: string]: number },
contract: FullContract<DPM, Multi | FreeResponse>, contract: FreeResponseContract,
bets: Bet[] bets: Bet[]
) => { ) => {
const poolTotal = sum(Object.values(contract.pool)) const poolTotal = sum(Object.values(contract.pool))

View File

@ -3,7 +3,7 @@ import { sum } from 'lodash'
import { Bet } from './bet' import { Bet } from './bet'
import { getProbability } from './calculate' import { getProbability } from './calculate'
import { getCpmmLiquidityPoolWeights } from './calculate-cpmm' import { getCpmmLiquidityPoolWeights } from './calculate-cpmm'
import { Binary, CPMM, FixedPayouts, FullContract } from './contract' import { CPMMContract } from './contract'
import { noFees } from './fees' import { noFees } from './fees'
import { LiquidityProvision } from './liquidity-provision' import { LiquidityProvision } from './liquidity-provision'
@ -30,7 +30,7 @@ export const getFixedCancelPayouts = (
export const getStandardFixedPayouts = ( export const getStandardFixedPayouts = (
outcome: string, outcome: string,
contract: FullContract<FixedPayouts, Binary>, contract: CPMMContract,
bets: Bet[], bets: Bet[],
liquidities: LiquidityProvision[] liquidities: LiquidityProvision[]
) => { ) => {
@ -65,7 +65,7 @@ export const getStandardFixedPayouts = (
} }
export const getLiquidityPoolPayouts = ( export const getLiquidityPoolPayouts = (
contract: FullContract<CPMM, Binary>, contract: CPMMContract,
outcome: string, outcome: string,
liquidities: LiquidityProvision[] liquidities: LiquidityProvision[]
) => { ) => {
@ -81,7 +81,7 @@ export const getLiquidityPoolPayouts = (
} }
export const getMktFixedPayouts = ( export const getMktFixedPayouts = (
contract: FullContract<FixedPayouts, Binary>, contract: CPMMContract,
bets: Bet[], bets: Bet[],
liquidities: LiquidityProvision[], liquidities: LiquidityProvision[],
resolutionProbability?: number resolutionProbability?: number
@ -116,7 +116,7 @@ export const getMktFixedPayouts = (
} }
export const getLiquidityPoolProbPayouts = ( export const getLiquidityPoolProbPayouts = (
contract: FullContract<CPMM, Binary>, contract: CPMMContract,
p: number, p: number,
liquidities: LiquidityProvision[] liquidities: LiquidityProvision[]
) => { ) => {

View File

@ -1,15 +1,7 @@
import { sumBy, groupBy, mapValues } from 'lodash' import { sumBy, groupBy, mapValues } from 'lodash'
import { Bet, NumericBet } from './bet' import { Bet, NumericBet } from './bet'
import { import { Contract, CPMMBinaryContract, DPMContract } from './contract'
Binary,
Contract,
DPM,
FixedPayouts,
FreeResponse,
FullContract,
Multi,
} from './contract'
import { Fees } from './fees' import { Fees } from './fees'
import { LiquidityProvision } from './liquidity-provision' import { LiquidityProvision } from './liquidity-provision'
import { import {
@ -55,7 +47,7 @@ export type PayoutInfo = {
} }
export const getPayouts = ( export const getPayouts = (
outcome: string, outcome: string | undefined,
resolutions: { resolutions: {
[outcome: string]: number [outcome: string]: number
}, },
@ -73,7 +65,6 @@ export const getPayouts = (
resolutionProbability resolutionProbability
) )
} }
return getDpmPayouts( return getDpmPayouts(
outcome, outcome,
resolutions, resolutions,
@ -84,8 +75,8 @@ export const getPayouts = (
} }
export const getFixedPayouts = ( export const getFixedPayouts = (
outcome: string, outcome: string | undefined,
contract: FullContract<FixedPayouts, Binary>, contract: CPMMBinaryContract,
bets: Bet[], bets: Bet[],
liquidities: LiquidityProvision[], liquidities: LiquidityProvision[],
resolutionProbability?: number resolutionProbability?: number
@ -108,11 +99,11 @@ export const getFixedPayouts = (
} }
export const getDpmPayouts = ( export const getDpmPayouts = (
outcome: string, outcome: string | undefined,
resolutions: { resolutions: {
[outcome: string]: number [outcome: string]: number
}, },
contract: Contract, contract: DPMContract,
bets: Bet[], bets: Bet[],
resolutionProbability?: number resolutionProbability?: number
): PayoutInfo => { ): PayoutInfo => {
@ -125,13 +116,10 @@ export const getDpmPayouts = (
case 'MKT': case 'MKT':
return contract.outcomeType === 'FREE_RESPONSE' return contract.outcomeType === 'FREE_RESPONSE'
? getPayoutsMultiOutcome( ? getPayoutsMultiOutcome(resolutions, contract, openBets)
resolutions,
contract as FullContract<DPM, Multi | FreeResponse>,
openBets
)
: getDpmMktPayouts(contract, openBets, resolutionProbability) : getDpmMktPayouts(contract, openBets, resolutionProbability)
case 'CANCEL': case 'CANCEL':
case undefined:
return getDpmCancelPayouts(contract, openBets) return getDpmCancelPayouts(contract, openBets)
default: default:

View File

@ -1,7 +1,7 @@
import { groupBy, sumBy, mapValues, partition } from 'lodash' import { groupBy, sumBy, mapValues, partition } from 'lodash'
import { Bet } from './bet' import { Bet } from './bet'
import { Binary, Contract, FullContract } from './contract' import { Contract } from './contract'
import { getPayouts } from './payouts' import { getPayouts } from './payouts'
export function scoreCreators(contracts: Contract[]) { export function scoreCreators(contracts: Contract[]) {
@ -24,23 +24,24 @@ export function scoreTraders(contracts: Contract[], bets: Bet[][]) {
return userScores return userScores
} }
export function scoreUsersByContract( export function scoreUsersByContract(contract: Contract, bets: Bet[]) {
contract: FullContract<any, Binary>, const { resolution } = contract
bets: Bet[] const resolutionProb =
) { contract.outcomeType == 'BINARY'
const { resolution, resolutionProbability } = contract ? contract.resolutionProbability
: undefined
const [closedBets, openBets] = partition( const [closedBets, openBets] = partition(
bets, bets,
(bet) => bet.isSold || bet.sale (bet) => bet.isSold || bet.sale
) )
const { payouts: resolvePayouts } = getPayouts( const { payouts: resolvePayouts } = getPayouts(
resolution, resolution as string,
{}, {},
contract, contract,
openBets, openBets,
[], [],
resolutionProbability resolutionProb
) )
const salePayouts = closedBets.map((bet) => { const salePayouts = closedBets.map((bet) => {

View File

@ -5,14 +5,14 @@ import {
deductDpmFees, deductDpmFees,
} from './calculate-dpm' } from './calculate-dpm'
import { calculateCpmmSale, getCpmmProbability } from './calculate-cpmm' 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 { DPM_CREATOR_FEE, DPM_PLATFORM_FEE, Fees } from './fees'
import { User } from './user' import { User } from './user'
export const getSellBetInfo = ( export const getSellBetInfo = (
user: User, user: User,
bet: Bet, bet: Bet,
contract: FullContract<DPM, any>, contract: DPMContract,
newBetId: string newBetId: string
) => { ) => {
const { pool, totalShares, totalBets } = contract const { pool, totalShares, totalBets } = contract
@ -87,7 +87,7 @@ export const getCpmmSellBetInfo = (
user: User, user: User,
shares: number, shares: number,
outcome: 'YES' | 'NO', outcome: 'YES' | 'NO',
contract: FullContract<CPMM, Binary>, contract: CPMMContract,
prevLoanAmount: number, prevLoanAmount: number,
newBetId: string newBetId: string
) => { ) => {

View File

@ -1,12 +1,7 @@
import * as functions from 'firebase-functions' import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin' import * as admin from 'firebase-admin'
import { import { Contract } from '../../common/contract'
Contract,
DPM,
FreeResponse,
FullContract,
} from '../../common/contract'
import { User } from '../../common/user' import { User } from '../../common/user'
import { getNewMultiBetInfo } from '../../common/new-bet' import { getNewMultiBetInfo } from '../../common/new-bet'
import { Answer, MAX_ANSWER_LENGTH } from '../../common/answer' 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 loanAmount = 0
const { newBet, newPool, newTotalShares, newTotalBets } = const { newBet, newPool, newTotalShares, newTotalBets } =
getNewMultiBetInfo( getNewMultiBetInfo(answerId, amount, contract, loanAmount)
answerId,
amount,
contract as FullContract<DPM, FreeResponse>,
loanAmount
)
const newBalance = user.balance - amount const newBalance = user.balance - amount
const betDoc = firestore.collection(`contracts/${contractId}/bets`).doc() const betDoc = firestore.collection(`contracts/${contractId}/bets`).doc()

View File

@ -2,16 +2,13 @@ import * as admin from 'firebase-admin'
import { z } from 'zod' import { z } from 'zod'
import { import {
Binary, CPMMBinaryContract,
Contract, Contract,
CPMM, FreeResponseContract,
DPM,
FreeResponse,
FullContract,
MAX_DESCRIPTION_LENGTH, MAX_DESCRIPTION_LENGTH,
MAX_QUESTION_LENGTH, MAX_QUESTION_LENGTH,
MAX_TAG_LENGTH, MAX_TAG_LENGTH,
Numeric, NumericContract,
OUTCOME_TYPES, OUTCOME_TYPES,
} from '../../common/contract' } from '../../common/contract'
import { slugify } from '../../common/util/slugify' import { slugify } from '../../common/util/slugify'
@ -22,7 +19,6 @@ import { APIError, newEndpoint, validate, zTimestamp } from './api'
import { import {
FIXED_ANTE, FIXED_ANTE,
getAnteBets,
getCpmmInitialLiquidity, getCpmmInitialLiquidity,
getFreeAnswerAnte, getFreeAnswerAnte,
getNumericAnte, getNumericAnte,
@ -117,30 +113,14 @@ export const createContract = newEndpoint(['POST'], async (req, [user, _]) => {
const providerId = isFree ? HOUSE_LIQUIDITY_PROVIDER_ID : user.id const providerId = isFree ? HOUSE_LIQUIDITY_PROVIDER_ID : user.id
if (outcomeType === 'BINARY' && contract.mechanism === 'dpm-2') { if (outcomeType === 'BINARY') {
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<DPM, Binary>,
yesBetDoc.id,
noBetDoc.id
)
await yesBetDoc.set(yesBet)
await noBetDoc.set(noBet)
} else if (outcomeType === 'BINARY') {
const liquidityDoc = firestore const liquidityDoc = firestore
.collection(`contracts/${contract.id}/liquidity`) .collection(`contracts/${contract.id}/liquidity`)
.doc() .doc()
const lp = getCpmmInitialLiquidity( const lp = getCpmmInitialLiquidity(
providerId, providerId,
contract as FullContract<CPMM, Binary>, contract as CPMMBinaryContract,
liquidityDoc.id, liquidityDoc.id,
ante ante
) )
@ -160,7 +140,7 @@ export const createContract = newEndpoint(['POST'], async (req, [user, _]) => {
const anteBet = getFreeAnswerAnte( const anteBet = getFreeAnswerAnte(
providerId, providerId,
contract as FullContract<DPM, FreeResponse>, contract as FreeResponseContract,
anteBetDoc.id anteBetDoc.id
) )
await anteBetDoc.set(anteBet) await anteBetDoc.set(anteBet)
@ -171,7 +151,7 @@ export const createContract = newEndpoint(['POST'], async (req, [user, _]) => {
const anteBet = getNumericAnte( const anteBet = getNumericAnte(
providerId, providerId,
contract as FullContract<DPM, Numeric>, contract as NumericContract,
ante, ante,
anteBetDoc.id anteBetDoc.id
) )

View File

@ -4,7 +4,7 @@ import { partition, sumBy } from 'lodash'
import { Bet } from '../../common/bet' import { Bet } from '../../common/bet'
import { getProbability } from '../../common/calculate' import { getProbability } from '../../common/calculate'
import { Binary, CPMM, FullContract } from '../../common/contract' import { Contract } from '../../common/contract'
import { noFees } from '../../common/fees' import { noFees } from '../../common/fees'
import { User } from '../../common/user' import { User } from '../../common/user'
@ -15,7 +15,7 @@ export const redeemShares = async (userId: string, contractId: string) => {
if (!contractSnap.exists) if (!contractSnap.exists)
return { status: 'error', message: 'Invalid contract' } return { status: 'error', message: 'Invalid contract' }
const contract = contractSnap.data() as FullContract<CPMM, Binary> const contract = contractSnap.data() as Contract
if (contract.outcomeType !== 'BINARY' || contract.mechanism !== 'cpmm-1') if (contract.outcomeType !== 'BINARY' || contract.mechanism !== 'cpmm-1')
return { status: 'success' } return { status: 'success' }

View File

@ -6,14 +6,14 @@ initAdmin()
import { Bet } from '../../../common/bet' import { Bet } from '../../../common/bet'
import { getDpmProbability } from '../../../common/calculate-dpm' import { getDpmProbability } from '../../../common/calculate-dpm'
import { Binary, Contract, DPM, FullContract } from '../../../common/contract' import { DPMBinaryContract } from '../../../common/contract'
type DocRef = admin.firestore.DocumentReference type DocRef = admin.firestore.DocumentReference
const firestore = admin.firestore() const firestore = admin.firestore()
async function migrateContract( async function migrateContract(
contractRef: DocRef, contractRef: DocRef,
contract: FullContract<DPM, Binary> contract: DPMBinaryContract
) { ) {
const bets = await contractRef const bets = await contractRef
.collection('bets') .collection('bets')
@ -34,9 +34,7 @@ async function migrateContract(
async function migrateContracts() { async function migrateContracts() {
const snapshot = await firestore.collection('contracts').get() const snapshot = await firestore.collection('contracts').get()
const contracts = snapshot.docs.map( const contracts = snapshot.docs.map((doc) => doc.data() as DPMBinaryContract)
(doc) => doc.data() as FullContract<DPM, Binary>
)
console.log('Loaded contracts', contracts.length) console.log('Loaded contracts', contracts.length)

View File

@ -5,18 +5,15 @@ import { initAdmin } from './script-init'
initAdmin() initAdmin()
import { import {
Binary,
Contract, Contract,
CPMM, DPMBinaryContract,
DPM, CPMMBinaryContract,
FullContract,
} from '../../../common/contract' } from '../../../common/contract'
import { Bet } from '../../../common/bet' import { Bet } from '../../../common/bet'
import { import {
calculateDpmPayout, calculateDpmPayout,
getDpmProbability, getDpmProbability,
} from '../../../common/calculate-dpm' } from '../../../common/calculate-dpm'
import { User } from '../../../common/user'
import { getCpmmInitialLiquidity } from '../../../common/antes' import { getCpmmInitialLiquidity } from '../../../common/antes'
import { noFees } from '../../../common/fees' import { noFees } from '../../../common/fees'
import { addObjects } from '../../../common/util/object' import { addObjects } from '../../../common/util/object'
@ -28,7 +25,7 @@ const firestore = admin.firestore()
async function recalculateContract(contractRef: DocRef, isCommit = false) { async function recalculateContract(contractRef: DocRef, isCommit = false) {
await firestore.runTransaction(async (transaction) => { await firestore.runTransaction(async (transaction) => {
const contractDoc = await transaction.get(contractRef) const contractDoc = await transaction.get(contractRef)
const contract = contractDoc.data() as FullContract<DPM, Binary> const contract = contractDoc.data() as DPMBinaryContract
if (!contract?.slug) { if (!contract?.slug) {
console.log('missing slug; id=', contractRef.id) console.log('missing slug; id=', contractRef.id)
@ -110,7 +107,7 @@ async function recalculateContract(contractRef: DocRef, isCommit = false) {
{ {
...contract, ...contract,
...contractUpdate, ...contractUpdate,
} as FullContract<CPMM, Binary>, } as CPMMBinaryContract,
liquidityDocRef.id, liquidityDocRef.id,
ante ante
) )

View File

@ -4,7 +4,7 @@ import { sortBy, sumBy } from 'lodash'
import { initAdmin } from './script-init' import { initAdmin } from './script-init'
initAdmin() initAdmin()
import { Binary, Contract, DPM, FullContract } from '../../../common/contract' import { Contract, DPMBinaryContract } from '../../../common/contract'
import { Bet } from '../../../common/bet' import { Bet } from '../../../common/bet'
import { import {
calculateDpmShares, calculateDpmShares,
@ -32,7 +32,7 @@ async function recalculateContract(
await firestore.runTransaction(async (transaction) => { await firestore.runTransaction(async (transaction) => {
const contractDoc = await transaction.get(contractRef) const contractDoc = await transaction.get(contractRef)
const contract = contractDoc.data() as FullContract<DPM, Binary> const contract = contractDoc.data() as DPMBinaryContract
const betDocs = await transaction.get(contractRef.collection('bets')) const betDocs = await transaction.get(contractRef.collection('bets'))
const bets = sortBy( const bets = sortBy(

View File

@ -2,7 +2,7 @@ import { partition, sumBy } from 'lodash'
import * as admin from 'firebase-admin' import * as admin from 'firebase-admin'
import * as functions from 'firebase-functions' import * as functions from 'firebase-functions'
import { Binary, CPMM, FullContract } from '../../common/contract' import { BinaryContract } from '../../common/contract'
import { User } from '../../common/user' import { User } from '../../common/user'
import { getCpmmSellBetInfo } from '../../common/sell-bet' import { getCpmmSellBetInfo } from '../../common/sell-bet'
import { addObjects, removeUndefinedProps } from '../../common/util/object' 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) const contractSnap = await transaction.get(contractDoc)
if (!contractSnap.exists) if (!contractSnap.exists)
return { status: 'error', message: 'Invalid contract' } return { status: 'error', message: 'Invalid contract' }
const contract = contractSnap.data() as FullContract<CPMM, Binary> const contract = contractSnap.data() as BinaryContract
const { closeTime, mechanism, collectedFees, volume } = contract const { closeTime, mechanism, collectedFees, volume } = contract
if (mechanism !== 'cpmm-1') if (mechanism !== 'cpmm-1')

View File

@ -3,7 +3,7 @@ import { useEffect, useRef, useState } from 'react'
import { XIcon } from '@heroicons/react/solid' import { XIcon } from '@heroicons/react/solid'
import { Answer } from 'common/answer' import { Answer } from 'common/answer'
import { DPM, FreeResponse, FullContract } from 'common/contract' import { FreeResponseContract } from 'common/contract'
import { BuyAmountInput } from '../amount-input' import { BuyAmountInput } from '../amount-input'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { APIError, placeBet } from 'web/lib/firebase/api-call' import { APIError, placeBet } from 'web/lib/firebase/api-call'
@ -27,7 +27,7 @@ import { Bet } from 'common/bet'
export function AnswerBetPanel(props: { export function AnswerBetPanel(props: {
answer: Answer answer: Answer
contract: FullContract<DPM, FreeResponse> contract: FreeResponseContract
closePanel: () => void closePanel: () => void
className?: string className?: string
isModal?: boolean isModal?: boolean

View File

@ -1,7 +1,7 @@
import clsx from 'clsx' import clsx from 'clsx'
import { Answer } from 'common/answer' import { Answer } from 'common/answer'
import { DPM, FreeResponse, FullContract } from 'common/contract' import { FreeResponseContract } from 'common/contract'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { Row } from '../layout/row' import { Row } from '../layout/row'
import { Avatar } from '../avatar' import { Avatar } from '../avatar'
@ -13,7 +13,7 @@ import { Linkify } from '../linkify'
export function AnswerItem(props: { export function AnswerItem(props: {
answer: Answer answer: Answer
contract: FullContract<DPM, FreeResponse> contract: FreeResponseContract
showChoice: 'radio' | 'checkbox' | undefined showChoice: 'radio' | 'checkbox' | undefined
chosenProb: number | undefined chosenProb: number | undefined
totalChosenProb?: number totalChosenProb?: number

View File

@ -2,7 +2,7 @@ import clsx from 'clsx'
import { sum, mapValues } from 'lodash' import { sum, mapValues } from 'lodash'
import { useState } from 'react' import { useState } from 'react'
import { DPM, FreeResponse, FullContract } from 'common/contract' import { Contract, FreeResponse } from 'common/contract'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { resolveMarket } from 'web/lib/firebase/fn-call' import { resolveMarket } from 'web/lib/firebase/fn-call'
import { Row } from '../layout/row' import { Row } from '../layout/row'
@ -11,7 +11,7 @@ import { ResolveConfirmationButton } from '../confirmation-button'
import { removeUndefinedProps } from 'common/util/object' import { removeUndefinedProps } from 'common/util/object'
export function AnswerResolvePanel(props: { export function AnswerResolvePanel(props: {
contract: FullContract<DPM, FreeResponse> contract: Contract & FreeResponse
resolveOption: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined resolveOption: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined
setResolveOption: ( setResolveOption: (
option: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined option: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined

View File

@ -5,7 +5,7 @@ import { groupBy, sortBy, sumBy } from 'lodash'
import { memo } from 'react' import { memo } from 'react'
import { Bet } from 'common/bet' import { Bet } from 'common/bet'
import { DPM, FreeResponse, FullContract } from 'common/contract' import { FreeResponseContract } from 'common/contract'
import { getOutcomeProbability } from 'common/calculate' import { getOutcomeProbability } from 'common/calculate'
import { useBets } from 'web/hooks/use-bets' import { useBets } from 'web/hooks/use-bets'
import { useWindowSize } from 'web/hooks/use-window-size' import { useWindowSize } from 'web/hooks/use-window-size'
@ -13,7 +13,7 @@ import { useWindowSize } from 'web/hooks/use-window-size'
const NUM_LINES = 6 const NUM_LINES = 6
export const AnswersGraph = memo(function AnswersGraph(props: { export const AnswersGraph = memo(function AnswersGraph(props: {
contract: FullContract<DPM, FreeResponse> contract: FreeResponseContract
bets: Bet[] bets: Bet[]
height?: number height?: number
}) { }) {
@ -161,10 +161,7 @@ function formatTime(time: number, includeTime: boolean) {
return dayjs(time).format('MMM D') return dayjs(time).format('MMM D')
} }
const computeProbsByOutcome = ( const computeProbsByOutcome = (bets: Bet[], contract: FreeResponseContract) => {
bets: Bet[],
contract: FullContract<DPM, FreeResponse>
) => {
const { totalBets } = contract const { totalBets } = contract
const betsByOutcome = groupBy(bets, (bet) => bet.outcome) const betsByOutcome = groupBy(bets, (bet) => bet.outcome)

View File

@ -1,7 +1,7 @@
import { sortBy, partition, sum, uniq } from 'lodash' import { sortBy, partition, sum, uniq } from 'lodash'
import { useLayoutEffect, useState } from 'react' import { useLayoutEffect, useState } from 'react'
import { DPM, FreeResponse, FullContract } from 'common/contract' import { FreeResponseContract } from 'common/contract'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { useUser } from 'web/hooks/use-user' import { useUser } from 'web/hooks/use-user'
import { getDpmOutcomeProbability } from 'common/calculate-dpm' import { getDpmOutcomeProbability } from 'common/calculate-dpm'
@ -25,9 +25,7 @@ import { UserLink } from 'web/components/user-page'
import { Linkify } from 'web/components/linkify' import { Linkify } from 'web/components/linkify'
import { BuyButton } from 'web/components/yes-no-selector' import { BuyButton } from 'web/components/yes-no-selector'
export function AnswersPanel(props: { export function AnswersPanel(props: { contract: FreeResponseContract }) {
contract: FullContract<DPM, FreeResponse>
}) {
const { contract } = props const { contract } = props
const { creatorId, resolution, resolutions, totalBets } = contract const { creatorId, resolution, resolutions, totalBets } = contract
@ -154,7 +152,7 @@ export function AnswersPanel(props: {
} }
function getAnswerItems( function getAnswerItems(
contract: FullContract<DPM, FreeResponse>, contract: FreeResponseContract,
answers: Answer[], answers: Answer[],
user: User | undefined | null user: User | undefined | null
) { ) {
@ -182,7 +180,7 @@ function getAnswerItems(
} }
function OpenAnswer(props: { function OpenAnswer(props: {
contract: FullContract<any, FreeResponse> contract: FreeResponseContract
answer: Answer answer: Answer
items: ActivityItem[] items: ActivityItem[]
type: string type: string

View File

@ -2,7 +2,7 @@ import clsx from 'clsx'
import { useState } from 'react' import { useState } from 'react'
import Textarea from 'react-expanding-textarea' import Textarea from 'react-expanding-textarea'
import { DPM, FreeResponse, FullContract } from 'common/contract' import { FreeResponseContract } from 'common/contract'
import { BuyAmountInput } from '../amount-input' import { BuyAmountInput } from '../amount-input'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { createAnswer } from 'web/lib/firebase/fn-call' 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 { Bet } from 'common/bet'
import { MAX_ANSWER_LENGTH } from 'common/answer' import { MAX_ANSWER_LENGTH } from 'common/answer'
export function CreateAnswerPanel(props: { export function CreateAnswerPanel(props: { contract: FreeResponseContract }) {
contract: FullContract<DPM, FreeResponse>
}) {
const { contract } = props const { contract } = props
const user = useUser() const user = useUser()
const [text, setText] = useState('') const [text, setText] = useState('')

View File

@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react'
import { partition, sumBy } from 'lodash' import { partition, sumBy } from 'lodash'
import { useUser } from 'web/hooks/use-user' 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 { Col } from './layout/col'
import { Row } from './layout/row' import { Row } from './layout/row'
import { Spacer } from './layout/spacer' import { Spacer } from './layout/spacer'
@ -39,7 +39,7 @@ import { useSaveShares } from './use-save-shares'
import { SignUpPrompt } from './sign-up-prompt' import { SignUpPrompt } from './sign-up-prompt'
export function BetPanel(props: { export function BetPanel(props: {
contract: FullContract<DPM | CPMM, Binary> contract: BinaryContract
className?: string className?: string
}) { }) {
const { contract, className } = props const { contract, className } = props
@ -78,7 +78,7 @@ export function BetPanel(props: {
} }
export function BetPanelSwitcher(props: { export function BetPanelSwitcher(props: {
contract: FullContract<DPM | CPMM, Binary> contract: BinaryContract
className?: string className?: string
title?: string // Set if BetPanel is on a feed modal title?: string // Set if BetPanel is on a feed modal
selected?: 'YES' | 'NO' selected?: 'YES' | 'NO'
@ -157,16 +157,19 @@ export function BetPanelSwitcher(props: {
text={tradeType === 'BUY' ? title ?? 'Place a trade' : 'Sell shares'} text={tradeType === 'BUY' ? title ?? 'Place a trade' : 'Sell shares'}
/> />
{tradeType === 'SELL' && user && sharesOutcome && ( {tradeType === 'SELL' &&
<SellPanel mechanism == 'cpmm-1' &&
contract={contract as FullContract<CPMM, Binary>} user &&
shares={yesShares || noShares} sharesOutcome && (
sharesOutcome={sharesOutcome} <SellPanel
user={user} contract={contract}
userBets={userBets ?? []} shares={yesShares || noShares}
onSellSuccess={onBetSuccess} sharesOutcome={sharesOutcome}
/> user={user}
)} userBets={userBets ?? []}
onSellSuccess={onBetSuccess}
/>
)}
{tradeType === 'BUY' && ( {tradeType === 'BUY' && (
<BuyPanel <BuyPanel
@ -184,7 +187,7 @@ export function BetPanelSwitcher(props: {
} }
function BuyPanel(props: { function BuyPanel(props: {
contract: FullContract<DPM | CPMM, Binary> contract: BinaryContract
user: User | null | undefined user: User | null | undefined
selected?: 'YES' | 'NO' selected?: 'YES' | 'NO'
onBuySuccess?: () => void onBuySuccess?: () => void
@ -374,7 +377,7 @@ function BuyPanel(props: {
} }
export function SellPanel(props: { export function SellPanel(props: {
contract: FullContract<CPMM, Binary> contract: CPMMBinaryContract
userBets: Bet[] userBets: Bet[]
shares: number shares: number
sharesOutcome: 'YES' | 'NO' sharesOutcome: 'YES' | 'NO'

View File

@ -3,7 +3,7 @@ import clsx from 'clsx'
import { BetPanelSwitcher } from './bet-panel' import { BetPanelSwitcher } from './bet-panel'
import { YesNoSelector } from './yes-no-selector' 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 { Modal } from './layout/modal'
import { SellButton } from './sell-button' import { SellButton } from './sell-button'
import { useUser } from 'web/hooks/use-user' 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. // Inline version of a bet panel. Opens BetPanel in a new modal.
export default function BetRow(props: { export default function BetRow(props: {
contract: FullContract<DPM | CPMM, Binary> contract: BinaryContract
className?: string className?: string
btnClassName?: string btnClassName?: string
betPanelClassName?: string betPanelClassName?: string

View File

@ -255,7 +255,6 @@ function MyContractBets(props: {
const [collapsed, setCollapsed] = useState(true) const [collapsed, setCollapsed] = useState(true)
const isBinary = outcomeType === 'BINARY' const isBinary = outcomeType === 'BINARY'
const probPercent = getBinaryProbPercent(contract)
const { payout, profit, profitPercent, invested } = getContractBetMetrics( const { payout, profit, profitPercent, invested } = getContractBetMetrics(
contract, contract,
@ -292,24 +291,27 @@ function MyContractBets(props: {
</Row> </Row>
<Row className="flex-1 items-center gap-2 text-sm text-gray-500"> <Row className="flex-1 items-center gap-2 text-sm text-gray-500">
{(isBinary || resolution) && ( {resolution ? (
<> <>
{resolution ? ( <div>
<div> Resolved{' '}
Resolved{' '} <OutcomeLabel
<OutcomeLabel outcome={resolution}
outcome={resolution} value={resolutionValue}
value={resolutionValue} contract={contract}
contract={contract} truncate="short"
truncate="short" />
/> </div>
</div>
) : (
<div className="text-primary text-lg">{probPercent}</div>
)}
<div></div> <div></div>
</> </>
)} ) : isBinary ? (
<>
<div className="text-primary text-lg">
{getBinaryProbPercent(contract)}
</div>
<div></div>
</>
) : null}
<UserLink <UserLink
name={contract.creatorName} name={contract.creatorName}
username={contract.creatorUsername} username={contract.creatorUsername}

View File

@ -2,19 +2,12 @@ import clsx from 'clsx'
import Link from 'next/link' import Link from 'next/link'
import { Row } from '../layout/row' import { Row } from '../layout/row'
import { formatLargeNumber, formatPercent } from 'common/util/format' import { formatLargeNumber, formatPercent } from 'common/util/format'
import { import { contractPath, getBinaryProbPercent } from 'web/lib/firebase/contracts'
Contract,
contractPath,
getBinaryProbPercent,
} from 'web/lib/firebase/contracts'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { import {
Binary, Contract,
CPMM, BinaryContract,
DPM,
FreeResponse,
FreeResponseContract, FreeResponseContract,
FullContract,
NumericContract, NumericContract,
} from 'common/contract' } from 'common/contract'
import { import {
@ -83,15 +76,12 @@ export function ContractCard(props: {
{outcomeType === 'FREE_RESPONSE' && {outcomeType === 'FREE_RESPONSE' &&
(resolution ? ( (resolution ? (
<FreeResponseOutcomeLabel <FreeResponseOutcomeLabel
contract={contract as FreeResponseContract} contract={contract}
resolution={resolution} resolution={resolution}
truncate={'long'} truncate={'long'}
/> />
) : ( ) : (
<FreeResponseTopAnswer <FreeResponseTopAnswer contract={contract} truncate="long" />
contract={contract as FullContract<DPM, FreeResponse>}
truncate="long"
/>
))} ))}
<MiscDetails <MiscDetails
@ -114,14 +104,14 @@ export function ContractCard(props: {
{outcomeType === 'NUMERIC' && ( {outcomeType === 'NUMERIC' && (
<NumericResolutionOrExpectation <NumericResolutionOrExpectation
className="items-center" className="items-center"
contract={contract as NumericContract} contract={contract}
/> />
)} )}
{outcomeType === 'FREE_RESPONSE' && ( {outcomeType === 'FREE_RESPONSE' && (
<FreeResponseResolutionOrChance <FreeResponseResolutionOrChance
className="self-end text-gray-600" className="self-end text-gray-600"
contract={contract as FullContract<DPM, FreeResponse>} contract={contract}
truncate="long" truncate="long"
/> />
)} )}
@ -135,7 +125,7 @@ export function ContractCard(props: {
} }
export function BinaryResolutionOrChance(props: { export function BinaryResolutionOrChance(props: {
contract: FullContract<DPM | CPMM, Binary> contract: BinaryContract
large?: boolean large?: boolean
className?: string className?: string
}) { }) {

View File

@ -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 { Col } from '../layout/col'
import { Spacer } from '../layout/spacer' import { Spacer } from '../layout/spacer'
import { ContractProbGraph } from './contract-prob-graph' import { ContractProbGraph } from './contract-prob-graph'
@ -16,12 +16,7 @@ import { Bet } from 'common/bet'
import { Comment } from 'common/comment' import { Comment } from 'common/comment'
import BetRow from '../bet-row' import BetRow from '../bet-row'
import { AnswersGraph } from '../answers/answers-graph' import { AnswersGraph } from '../answers/answers-graph'
import { import { Contract } from 'common/contract'
DPM,
FreeResponse,
FullContract,
NumericContract,
} from 'common/contract'
import { ContractDescription } from './contract-description' import { ContractDescription } from './contract-description'
import { ContractDetails } from './contract-details' import { ContractDetails } from './contract-details'
import { ShareMarket } from '../share-market' import { ShareMarket } from '../share-market'
@ -58,7 +53,7 @@ export const ContractOverview = (props: {
{outcomeType === 'NUMERIC' && ( {outcomeType === 'NUMERIC' && (
<NumericResolutionOrExpectation <NumericResolutionOrExpectation
contract={contract as NumericContract} contract={contract}
className="hidden items-end xl:flex" className="hidden items-end xl:flex"
/> />
)} )}
@ -82,9 +77,7 @@ export const ContractOverview = (props: {
{outcomeType === 'NUMERIC' && ( {outcomeType === 'NUMERIC' && (
<Row className="items-center justify-between gap-4 xl:hidden"> <Row className="items-center justify-between gap-4 xl:hidden">
<NumericResolutionOrExpectation <NumericResolutionOrExpectation contract={contract} />
contract={contract as NumericContract}
/>
</Row> </Row>
)} )}
@ -97,14 +90,9 @@ export const ContractOverview = (props: {
<Spacer h={4} /> <Spacer h={4} />
{isBinary && <ContractProbGraph contract={contract} bets={bets} />}{' '} {isBinary && <ContractProbGraph contract={contract} bets={bets} />}{' '}
{outcomeType === 'FREE_RESPONSE' && ( {outcomeType === 'FREE_RESPONSE' && (
<AnswersGraph <AnswersGraph contract={contract} bets={bets} />
contract={contract as FullContract<DPM, FreeResponse>}
bets={bets}
/>
)}
{outcomeType === 'NUMERIC' && (
<NumericGraph contract={contract as NumericContract} />
)} )}
{outcomeType === 'NUMERIC' && <NumericGraph contract={contract} />}
{(contract.description || isCreator) && <Spacer h={6} />} {(contract.description || isCreator) && <Spacer h={6} />}
{isCreator && <ShareMarket className="px-2" contract={contract} />} {isCreator && <ShareMarket className="px-2" contract={contract} />}
<ContractDescription <ContractDescription

View File

@ -4,12 +4,12 @@ import dayjs from 'dayjs'
import { memo } from 'react' import { memo } from 'react'
import { Bet } from 'common/bet' import { Bet } from 'common/bet'
import { getInitialProbability } from 'common/calculate' import { getInitialProbability } from 'common/calculate'
import { Binary, CPMM, DPM, FullContract } from 'common/contract' import { BinaryContract } from 'common/contract'
import { useBetsWithoutAntes } from 'web/hooks/use-bets' import { useBetsWithoutAntes } from 'web/hooks/use-bets'
import { useWindowSize } from 'web/hooks/use-window-size' import { useWindowSize } from 'web/hooks/use-window-size'
export const ContractProbGraph = memo(function ContractProbGraph(props: { export const ContractProbGraph = memo(function ContractProbGraph(props: {
contract: FullContract<DPM | CPMM, Binary> contract: BinaryContract
bets: Bet[] bets: Bet[]
height?: number height?: number
}) { }) {

View File

@ -5,16 +5,8 @@ import {
getTopAnswer, getTopAnswer,
} from 'common/calculate' } from 'common/calculate'
import { getExpectedValue } from 'common/calculate-dpm' import { getExpectedValue } from 'common/calculate-dpm'
import {
Contract,
FullContract,
CPMM,
DPM,
Binary,
NumericContract,
FreeResponseContract,
} from 'common/contract'
import { User } from 'common/user' import { User } from 'common/user'
import { Contract, NumericContract } from 'common/contract'
import { import {
formatLargeNumber, formatLargeNumber,
formatMoney, formatMoney,
@ -39,12 +31,12 @@ export function QuickBet(props: { contract: Contract; user: User }) {
const userBets = useUserContractBets(user.id, contract.id) const userBets = useUserContractBets(user.id, contract.id)
const topAnswer = const topAnswer =
contract.outcomeType === 'FREE_RESPONSE' contract.outcomeType === 'FREE_RESPONSE'
? getTopAnswer(contract as FreeResponseContract) ? getTopAnswer(contract)
: undefined : undefined
// TODO: yes/no from useSaveShares doesn't work on numeric contracts // TODO: yes/no from useSaveShares doesn't work on numeric contracts
const { yesFloorShares, noFloorShares } = useSaveShares( const { yesFloorShares, noFloorShares } = useSaveShares(
contract as FullContract<DPM | CPMM, Binary | FreeResponseContract>, contract,
userBets, userBets,
topAnswer?.number.toString() || undefined topAnswer?.number.toString() || undefined
) )
@ -226,10 +218,10 @@ function QuickOutcomeView(props: {
display = getBinaryProbPercent(contract) display = getBinaryProbPercent(contract)
break break
case 'NUMERIC': case 'NUMERIC':
display = formatLargeNumber(getExpectedValue(contract as NumericContract)) display = formatLargeNumber(getExpectedValue(contract))
break break
case 'FREE_RESPONSE': { case 'FREE_RESPONSE': {
const topAnswer = getTopAnswer(contract as FreeResponseContract) const topAnswer = getTopAnswer(contract)
display = display =
topAnswer && topAnswer &&
formatPercent(getOutcomeProbability(contract, topAnswer.id)) formatPercent(getOutcomeProbability(contract, topAnswer.id))
@ -257,7 +249,7 @@ function getProb(contract: Contract) {
: outcomeType === 'FREE_RESPONSE' : outcomeType === 'FREE_RESPONSE'
? getOutcomeProbability(contract, getTopAnswer(contract)?.id || '') ? getOutcomeProbability(contract, getTopAnswer(contract)?.id || '')
: outcomeType === 'NUMERIC' : outcomeType === 'NUMERIC'
? getNumericScale(contract as NumericContract) ? getNumericScale(contract)
: 1 // Should not happen : 1 // Should not happen
} }

View File

@ -4,7 +4,7 @@ import { Answer } from 'common/answer'
import { Bet } from 'common/bet' import { Bet } from 'common/bet'
import { getOutcomeProbability } from 'common/calculate' import { getOutcomeProbability } from 'common/calculate'
import { Comment } from 'common/comment' 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 { User } from 'common/user'
import { mapCommentsByBetId } from 'web/lib/firebase/comments' import { mapCommentsByBetId } from 'web/lib/firebase/comments'
@ -188,7 +188,7 @@ function groupBets(
} }
function getAnswerGroups( function getAnswerGroups(
contract: FullContract<DPM, FreeResponse>, contract: FreeResponseContract,
bets: Bet[], bets: Bet[],
comments: Comment[], comments: Comment[],
user: User | undefined | null, user: User | undefined | null,
@ -269,7 +269,7 @@ function getAnswerGroups(
} }
function getAnswerAndCommentInputGroups( function getAnswerAndCommentInputGroups(
contract: FullContract<DPM, FreeResponse>, contract: FreeResponseContract,
bets: Bet[], bets: Bet[],
comments: Comment[], comments: Comment[],
user: User | undefined | null user: User | undefined | null
@ -493,17 +493,11 @@ export function getRecentContractActivityItems(
const items = [] const items = []
if (contract.outcomeType === 'FREE_RESPONSE') { if (contract.outcomeType === 'FREE_RESPONSE') {
items.push( items.push(
...getAnswerGroups( ...getAnswerGroups(contract, bets, comments, user, {
contract as FullContract<DPM, FreeResponse>, sortByProb: false,
bets, abbreviated: true,
comments, reversed: true,
user, })
{
sortByProb: false,
abbreviated: true,
reversed: true,
}
)
) )
} else { } else {
items.push( items.push(
@ -587,7 +581,7 @@ export function getSpecificContractActivityItems(
case 'free-response-comment-answer-groups': case 'free-response-comment-answer-groups':
items.push( items.push(
...getAnswerAndCommentInputGroups( ...getAnswerAndCommentInputGroups(
contract as FullContract<DPM, FreeResponse>, contract as FreeResponseContract,
bets, bets,
comments, comments,
user user

View File

@ -1,4 +1,3 @@
import { FreeResponse, FullContract } from 'common/contract'
import { Answer } from 'common/answer' import { Answer } from 'common/answer'
import { ActivityItem } from 'web/components/feed/activity-items' import { ActivityItem } from 'web/components/feed/activity-items'
import { Bet } from 'common/bet' import { Bet } from 'common/bet'
@ -26,7 +25,7 @@ import { CopyLinkDateTimeComponent } from 'web/components/feed/copy-link-date-ti
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
export function FeedAnswerCommentGroup(props: { export function FeedAnswerCommentGroup(props: {
contract: FullContract<any, FreeResponse> contract: any
answer: Answer answer: Answer
items: ActivityItem[] items: ActivityItem[]
type: string type: string

View File

@ -3,16 +3,7 @@ import { ReactNode } from 'react'
import { Answer } from 'common/answer' import { Answer } from 'common/answer'
import { getProbability } from 'common/calculate' import { getProbability } from 'common/calculate'
import { getValueFromBucket } from 'common/calculate-dpm' import { getValueFromBucket } from 'common/calculate-dpm'
import { import { BinaryContract, Contract, NumericContract } from 'common/contract'
Binary,
Contract,
CPMM,
DPM,
FreeResponse,
FreeResponseContract,
FullContract,
NumericContract,
} from 'common/contract'
import { formatPercent } from 'common/util/format' import { formatPercent } from 'common/util/format'
import { ClientRender } from './client-render' import { ClientRender } from './client-render'
@ -36,7 +27,7 @@ export function OutcomeLabel(props: {
return ( return (
<FreeResponseOutcomeLabel <FreeResponseOutcomeLabel
contract={contract as FullContract<DPM, FreeResponse>} contract={contract}
resolution={outcome} resolution={outcome}
truncate={truncate} truncate={truncate}
answerClassName={'font-bold text-base-400'} answerClassName={'font-bold text-base-400'}
@ -56,7 +47,7 @@ export function BinaryOutcomeLabel(props: {
} }
export function BinaryContractOutcomeLabel(props: { export function BinaryContractOutcomeLabel(props: {
contract: FullContract<DPM | CPMM, Binary> contract: BinaryContract
resolution: 'YES' | 'NO' | 'CANCEL' | 'MKT' resolution: 'YES' | 'NO' | 'CANCEL' | 'MKT'
}) { }) {
const { contract, resolution } = props const { contract, resolution } = props
@ -70,7 +61,7 @@ export function BinaryContractOutcomeLabel(props: {
} }
export function FreeResponseOutcomeLabel(props: { export function FreeResponseOutcomeLabel(props: {
contract: FreeResponseContract contract: Contract
resolution: string | 'CANCEL' | 'MKT' resolution: string | 'CANCEL' | 'MKT'
truncate: 'short' | 'long' | 'none' truncate: 'short' | 'long' | 'none'
answerClassName?: string answerClassName?: string
@ -80,8 +71,9 @@ export function FreeResponseOutcomeLabel(props: {
if (resolution === 'CANCEL') return <CancelLabel /> if (resolution === 'CANCEL') return <CancelLabel />
if (resolution === 'MKT') return <MultiLabel /> if (resolution === 'MKT') return <MultiLabel />
const { answers } = contract const answers =
const chosen = answers?.find((answer) => answer.id === resolution) contract.outcomeType === 'FREE_RESPONSE' ? contract.answers : []
const chosen = answers.find((answer) => answer.id === resolution)
if (!chosen) return <AnswerNumberLabel number={resolution} /> if (!chosen) return <AnswerNumberLabel number={resolution} />
return ( return (
<FreeResponseAnswerToolTip text={chosen.text}> <FreeResponseAnswerToolTip text={chosen.text}>

View File

@ -10,12 +10,12 @@ import { resolveMarket } from 'web/lib/firebase/fn-call'
import { ProbabilitySelector } from './probability-selector' import { ProbabilitySelector } from './probability-selector'
import { DPM_CREATOR_FEE } from 'common/fees' import { DPM_CREATOR_FEE } from 'common/fees'
import { getProbability } from 'common/calculate' import { getProbability } from 'common/calculate'
import { Binary, CPMM, DPM, FullContract } from 'common/contract' import { BinaryContract } from 'common/contract'
import { formatMoney } from 'common/util/format' import { formatMoney } from 'common/util/format'
export function ResolutionPanel(props: { export function ResolutionPanel(props: {
creator: User creator: User
contract: FullContract<DPM | CPMM, Binary> contract: BinaryContract
className?: string className?: string
}) { }) {
useEffect(() => { useEffect(() => {

View File

@ -1,4 +1,4 @@
import { Binary, CPMM, DPM, FullContract } from 'common/contract' import { BinaryContract } from 'common/contract'
import { User } from 'common/user' import { User } from 'common/user'
import { useUserContractBets } from 'web/hooks/use-user-bets' import { useUserContractBets } from 'web/hooks/use-user-bets'
import { useState } from 'react' import { useState } from 'react'
@ -7,7 +7,7 @@ import clsx from 'clsx'
import { SellSharesModal } from './sell-modal' import { SellSharesModal } from './sell-modal'
export function SellButton(props: { export function SellButton(props: {
contract: FullContract<DPM | CPMM, Binary> contract: BinaryContract
user: User | null | undefined user: User | null | undefined
sharesOutcome: 'YES' | 'NO' | undefined sharesOutcome: 'YES' | 'NO' | undefined
shares: number shares: number
@ -40,7 +40,7 @@ export function SellButton(props: {
{showSellModal && ( {showSellModal && (
<SellSharesModal <SellSharesModal
className={panelClassName} className={panelClassName}
contract={contract as FullContract<CPMM, Binary>} contract={contract}
user={user} user={user}
userBets={userBets ?? []} userBets={userBets ?? []}
shares={shares} shares={shares}

View File

@ -1,4 +1,4 @@
import { Binary, CPMM, FullContract } from 'common/contract' import { CPMMBinaryContract } from 'common/contract'
import { Bet } from 'common/bet' import { Bet } from 'common/bet'
import { User } from 'common/user' import { User } from 'common/user'
import { Modal } from './layout/modal' import { Modal } from './layout/modal'
@ -11,7 +11,7 @@ import clsx from 'clsx'
export function SellSharesModal(props: { export function SellSharesModal(props: {
className?: string className?: string
contract: FullContract<CPMM, Binary> contract: CPMMBinaryContract
userBets: Bet[] userBets: Bet[]
shares: number shares: number
sharesOutcome: 'YES' | 'NO' sharesOutcome: 'YES' | 'NO'

View File

@ -1,4 +1,4 @@
import { Binary, CPMM, DPM, FullContract } from 'common/contract' import { BinaryContract } from 'common/contract'
import { User } from 'common/user' import { User } from 'common/user'
import { useState } from 'react' import { useState } from 'react'
import { Col } from './layout/col' import { Col } from './layout/col'
@ -10,7 +10,7 @@ import { useSaveShares } from './use-save-shares'
import { SellSharesModal } from './sell-modal' import { SellSharesModal } from './sell-modal'
export function SellRow(props: { export function SellRow(props: {
contract: FullContract<DPM | CPMM, Binary> contract: BinaryContract
user: User | null | undefined user: User | null | undefined
className?: string className?: string
}) { }) {
@ -61,7 +61,7 @@ export function SellRow(props: {
</Col> </Col>
{showSellModal && ( {showSellModal && (
<SellSharesModal <SellSharesModal
contract={contract as FullContract<CPMM, Binary>} contract={contract}
user={user} user={user}
userBets={userBets ?? []} userBets={userBets ?? []}
shares={yesShares || noShares} shares={yesShares || noShares}

View File

@ -1,17 +1,11 @@
import { import { Contract } from 'common/contract'
Binary,
CPMM,
DPM,
FreeResponseContract,
FullContract,
} from 'common/contract'
import { Bet } from 'common/bet' import { Bet } from 'common/bet'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { partition, sumBy } from 'lodash' import { partition, sumBy } from 'lodash'
import { safeLocalStorage } from 'web/lib/util/local' import { safeLocalStorage } from 'web/lib/util/local'
export const useSaveShares = ( export const useSaveShares = (
contract: FullContract<CPMM | DPM, Binary | FreeResponseContract>, contract: Contract,
userBets: Bet[] | undefined, userBets: Bet[] | undefined,
freeResponseAnswerOutcome?: string freeResponseAnswerOutcome?: string
) => { ) => {

View File

@ -17,7 +17,7 @@ import { range, sortBy, sum } from 'lodash'
import { app } from './init' import { app } from './init'
import { getValues, listenForValue, listenForValues } from './utils' 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 { getDpmProbability } from 'common/calculate-dpm'
import { createRNG, shuffle } from 'common/util/random' import { createRNG, shuffle } from 'common/util/random'
import { getCpmmProbability } from 'common/calculate-cpmm' import { getCpmmProbability } from 'common/calculate-cpmm'
@ -63,18 +63,18 @@ export function contractPool(contract: Contract) {
: 'Empty pool' : 'Empty pool'
} }
export function getBinaryProb(contract: FullContract<any, Binary>) { export function getBinaryProb(contract: BinaryContract) {
const { totalShares, pool, p, resolutionProbability, mechanism } = contract const { pool, resolutionProbability, mechanism } = contract
return ( return (
resolutionProbability ?? resolutionProbability ??
(mechanism === 'cpmm-1' (mechanism === 'cpmm-1'
? getCpmmProbability(pool, p) ? getCpmmProbability(pool, contract.p)
: getDpmProbability(totalShares)) : getDpmProbability(contract.totalShares))
) )
} }
export function getBinaryProbPercent(contract: FullContract<any, Binary>) { export function getBinaryProbPercent(contract: BinaryContract) {
return formatPercent(getBinaryProb(contract)) return formatPercent(getBinaryProb(contract))
} }

View File

@ -30,13 +30,6 @@ import { formatMoney } from 'common/util/format'
import { useUserById } from 'web/hooks/use-users' import { useUserById } from 'web/hooks/use-users'
import { ContractTabs } from 'web/components/contract/contract-tabs' import { ContractTabs } from 'web/components/contract/contract-tabs'
import { FirstArgument } from 'common/util/types' import { FirstArgument } from 'common/util/types'
import {
BinaryContract,
DPM,
FreeResponse,
FullContract,
NumericContract,
} from 'common/contract'
import { contractTextDetails } from 'web/components/contract/contract-details' import { contractTextDetails } from 'web/components/contract/contract-details'
import { useWindowSize } from 'web/hooks/use-window-size' import { useWindowSize } from 'web/hooks/use-window-size'
import Confetti from 'react-confetti' import Confetti from 'react-confetti'
@ -143,24 +136,15 @@ export function ContractPageContent(props: FirstArgument<typeof ContractPage>) {
<Col className="gap-4"> <Col className="gap-4">
{allowTrade && {allowTrade &&
(isNumeric ? ( (isNumeric ? (
<NumericBetPanel <NumericBetPanel className="hidden xl:flex" contract={contract} />
className="hidden xl:flex"
contract={contract as NumericContract}
/>
) : ( ) : (
<BetPanel className="hidden xl:flex" contract={contract} /> <BetPanel className="hidden xl:flex" contract={contract} />
))} ))}
{allowResolve && {allowResolve &&
(isNumeric ? ( (isNumeric ? (
<NumericResolutionPanel <NumericResolutionPanel creator={user} contract={contract} />
creator={user}
contract={contract as NumericContract}
/>
) : ( ) : (
<ResolutionPanel <ResolutionPanel creator={user} contract={contract} />
creator={user}
contract={contract as BinaryContract}
/>
))} ))}
</Col> </Col>
) : null ) : null
@ -205,18 +189,13 @@ export function ContractPageContent(props: FirstArgument<typeof ContractPage>) {
{outcomeType === 'FREE_RESPONSE' && ( {outcomeType === 'FREE_RESPONSE' && (
<> <>
<Spacer h={4} /> <Spacer h={4} />
<AnswersPanel <AnswersPanel contract={contract} />
contract={contract as FullContract<DPM, FreeResponse>}
/>
<Spacer h={4} /> <Spacer h={4} />
</> </>
)} )}
{isNumeric && ( {isNumeric && (
<NumericBetPanel <NumericBetPanel className="xl:hidden" contract={contract} />
className="xl:hidden"
contract={contract as NumericContract}
/>
)} )}
{isResolved && ( {isResolved && (

View File

@ -1,12 +1,5 @@
import { Bet } from 'common/bet' import { Bet } from 'common/bet'
import { import { Contract } from 'common/contract'
BinaryContract,
Contract,
DPM,
FreeResponse,
FullContract,
NumericContract,
} from 'common/contract'
import { DOMAIN } from 'common/envs/constants' import { DOMAIN } from 'common/envs/constants'
import { AnswersGraph } from 'web/components/answers/answers-graph' import { AnswersGraph } from 'web/components/answers/answers-graph'
import BetRow from 'web/components/bet-row' import BetRow from 'web/components/bet-row'
@ -117,10 +110,9 @@ function ContractEmbed(props: { contract: Contract; bets: Bet[] }) {
{isBinary && ( {isBinary && (
<Row className="items-center gap-4"> <Row className="items-center gap-4">
<BetRow // this fails typechecking, but it doesn't explode because we will
contract={contract as BinaryContract} never
betPanelClassName="scale-75" <BetRow contract={contract as any} betPanelClassName="scale-75" />
/>
<BinaryResolutionOrChance contract={contract} /> <BinaryResolutionOrChance contract={contract} />
</Row> </Row>
)} )}
@ -133,9 +125,7 @@ function ContractEmbed(props: { contract: Contract; bets: Bet[] }) {
)} )}
{outcomeType === 'NUMERIC' && ( {outcomeType === 'NUMERIC' && (
<NumericResolutionOrExpectation <NumericResolutionOrExpectation contract={contract} />
contract={contract as NumericContract}
/>
)} )}
</Row> </Row>
@ -152,18 +142,11 @@ function ContractEmbed(props: { contract: Contract; bets: Bet[] }) {
)} )}
{outcomeType === 'FREE_RESPONSE' && ( {outcomeType === 'FREE_RESPONSE' && (
<AnswersGraph <AnswersGraph contract={contract} bets={bets} height={graphHeight} />
contract={contract as FullContract<DPM, FreeResponse>}
bets={bets}
height={graphHeight}
/>
)} )}
{outcomeType === 'NUMERIC' && ( {outcomeType === 'NUMERIC' && (
<NumericGraph <NumericGraph contract={contract} height={graphHeight} />
contract={contract as NumericContract}
height={graphHeight}
/>
)} )}
</div> </div>
</Col> </Col>

View File

@ -5,7 +5,7 @@ import { useState } from 'react'
import Textarea from 'react-expanding-textarea' import Textarea from 'react-expanding-textarea'
import { getProbability } from 'common/calculate' 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 { parseWordsAsTags } from 'common/util/parse'
import { BuyAmountInput } from 'web/components/amount-input' import { BuyAmountInput } from 'web/components/amount-input'
import { InfoTooltip } from 'web/components/info-tooltip' import { InfoTooltip } from 'web/components/info-tooltip'
@ -26,7 +26,7 @@ type Prediction = {
createdUrl?: string createdUrl?: string
} }
function toPrediction(contract: FullContract<DPM | CPMM, Binary>): Prediction { function toPrediction(contract: BinaryContract): Prediction {
const startProb = getProbability(contract) const startProb = getProbability(contract)
return { return {
question: contract.question, question: contract.question,
@ -102,9 +102,7 @@ export default function MakePredictions() {
const [description, setDescription] = useState('') const [description, setDescription] = useState('')
const [tags, setTags] = useState('') const [tags, setTags] = useState('')
const [isSubmitting, setIsSubmitting] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false)
const [createdContracts, setCreatedContracts] = useState< const [createdContracts, setCreatedContracts] = useState<BinaryContract[]>([])
FullContract<DPM | CPMM, Binary>[]
>([])
const [ante, setAnte] = useState<number | undefined>(100) const [ante, setAnte] = useState<number | undefined>(100)
const [anteError, setAnteError] = useState<string | undefined>() const [anteError, setAnteError] = useState<string | undefined>()
@ -155,7 +153,7 @@ ${TEST_VALUE}
ante, ante,
closeTime, closeTime,
tags: parseWordsAsTags(tags), tags: parseWordsAsTags(tags),
})) as FullContract<DPM | CPMM, Binary> })) as BinaryContract
setCreatedContracts((prev) => [...prev, contract]) setCreatedContracts((prev) => [...prev, contract])
} }