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 { 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<CPMM, Binary>,
contract: CPMMContract,
newLiquidityProvisionId: string
) => {
const { pool, p, totalLiquidity } = contract

View File

@ -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<CPMM, Binary>,
contract: CPMMBinaryContract,
anteId: string,
amount: number
) {
@ -47,7 +45,7 @@ export function getCpmmInitialLiquidity(
export function getAnteBets(
creator: User,
contract: FullContract<DPM, Binary>,
contract: DPMBinaryContract,
yesAnteId: string,
noAnteId: string
) {
@ -89,7 +87,7 @@ export function getAnteBets(
export function getFreeAnswerAnte(
anteBettorId: string,
contract: FullContract<DPM, FreeResponse>,
contract: FreeResponseContract,
anteBetId: string
) {
const { totalBets, totalShares } = contract
@ -117,7 +115,7 @@ export function getFreeAnswerAnte(
export function getNumericAnte(
anteBettorId: string,
contract: FullContract<DPM, Numeric>,
contract: NumericContract,
ante: number,
newBetId: string
) {

View File

@ -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<CPMM, Binary>,
contract: CPMMContract,
outcome: string,
bet: number
) {
@ -31,7 +31,7 @@ export function getCpmmProbabilityAfterBetBeforeFees(
}
export function getCpmmOutcomeProbabilityAfterBet(
contract: FullContract<CPMM, Binary>,
contract: CPMMContract,
outcome: string,
bet: number
) {
@ -59,7 +59,7 @@ function calculateCpmmShares(
}
export function getCpmmLiquidityFee(
contract: FullContract<CPMM, Binary>,
contract: CPMMContract,
bet: number,
outcome: string
) {
@ -78,7 +78,7 @@ export function getCpmmLiquidityFee(
}
export function calculateCpmmSharesAfterFee(
contract: FullContract<CPMM, Binary>,
contract: CPMMContract,
bet: number,
outcome: string
) {
@ -89,7 +89,7 @@ export function calculateCpmmSharesAfterFee(
}
export function calculateCpmmPurchase(
contract: FullContract<CPMM, Binary>,
contract: CPMMContract,
bet: number,
outcome: string
) {
@ -133,7 +133,7 @@ function sellSharesK(
}
function calculateCpmmShareValue(
contract: FullContract<CPMM, Binary>,
contract: CPMMContract,
shares: number,
outcome: 'YES' | 'NO'
) {
@ -168,7 +168,7 @@ function calculateCpmmShareValue(
}
export function calculateCpmmSale(
contract: FullContract<CPMM, Binary>,
contract: CPMMContract,
shares: number,
outcome: string
) {
@ -222,7 +222,7 @@ export function calculateCpmmSale(
}
export function getCpmmProbabilityAfterSale(
contract: FullContract<CPMM, Binary>,
contract: CPMMContract,
shares: number,
outcome: 'YES' | 'NO'
) {
@ -261,7 +261,7 @@ export function addCpmmLiquidity(
}
export function getCpmmLiquidityPoolWeights(
contract: FullContract<CPMM, Binary>,
contract: CPMMContract,
liquidities: LiquidityProvision[]
) {
const { p } = contract
@ -291,7 +291,7 @@ export function getCpmmLiquidityPoolWeights(
}
// export function removeCpmmLiquidity(
// contract: FullContract<CPMM, Binary>,
// contract: CPMMContract,
// liquidity: number
// ) {
// const { YES, NO } = contract.pool

View File

@ -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<DPM, any>,
contract: DPMContract,
bet: Bet,
shareValue: number
) {
@ -228,10 +221,7 @@ export function calculateDpmMoneyRatio(
return actual / expected
}
export function calculateDpmShareValue(
contract: FullContract<DPM, any>,
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<DPM, any>,
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<DPM, any>,
contract: DPMContract,
bet: Bet,
outcome: string
) {
@ -263,10 +250,7 @@ export function calculateDpmPayout(
return calculateStandardDpmPayout(contract, bet, outcome)
}
export function calculateDpmCancelPayout(
contract: FullContract<DPM, any>,
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<DPM, any>,
contract: DPMContract,
bet: Bet,
outcome: string
) {
@ -308,7 +292,7 @@ export function calculateStandardDpmPayout(
}
export function calculateDpmPayoutAfterCorrectBet(
contract: FullContract<DPM, any>,
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<DPM, Binary | FreeResponse | Numeric>,
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<DPM, Binary>,
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<DPM, any>, 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')

View File

@ -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<FixedPayouts, Binary>,
contract: CPMMContract,
bet: Bet,
outcome: string
) {
@ -23,10 +23,7 @@ export function calculateStandardFixedPayout(bet: Bet, outcome: string) {
return shares
}
function calculateFixedMktPayout(
contract: FullContract<FixedPayouts, Binary>,
bet: Bet
) {
function calculateFixedMktPayout(contract: CPMMContract, bet: Bet) {
const { resolutionProbability } = contract
const p =
resolutionProbability !== undefined

View File

@ -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<DPM | CPMM, Binary>) {
export function getProbability(contract: BinaryContract) {
return contract.mechanism === 'cpmm-1'
? getCpmmProbability(contract.pool, contract.p)
: getDpmProbability(contract.totalShares)
}
export function getInitialProbability(
contract: FullContract<DPM | CPMM, Binary>
) {
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<CPMM, Binary>,
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<CPMM, Binary>,
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<CPMM, Binary>,
shares,
outcome as 'YES' | 'NO'
)
? getCpmmProbabilityAfterSale(contract, shares, outcome as 'YES' | 'NO')
: getDpmProbabilityAfterSale(contract.totalShares, outcome, shares)
}

View File

@ -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<T extends AnyContractType = AnyContractType> = {
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<DPM | CPMM, Binary>
export type FreeResponseContract = FullContract<DPM | CPMM, FreeResponse>
export type NumericContract = FullContract<DPM, Numeric>
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',

View File

@ -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<CPMM, Binary>,
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<DPM, Binary>,
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<DPM, Multi | FreeResponse>,
contract: FreeResponseContract,
loanAmount: number
) => {
const { pool, totalShares, totalBets } = contract

View File

@ -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<DPM, any>,
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<DPM, any>,
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<DPM, any>,
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<DPM, any>,
contract: DPMContract,
bets: Bet[],
resolutionProbability?: number
) => {
@ -183,7 +180,7 @@ export const getDpmMktPayouts = (
export const getPayoutsMultiOutcome = (
resolutions: { [outcome: string]: number },
contract: FullContract<DPM, Multi | FreeResponse>,
contract: FreeResponseContract,
bets: Bet[]
) => {
const poolTotal = sum(Object.values(contract.pool))

View File

@ -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<FixedPayouts, Binary>,
contract: CPMMContract,
bets: Bet[],
liquidities: LiquidityProvision[]
) => {
@ -65,7 +65,7 @@ export const getStandardFixedPayouts = (
}
export const getLiquidityPoolPayouts = (
contract: FullContract<CPMM, Binary>,
contract: CPMMContract,
outcome: string,
liquidities: LiquidityProvision[]
) => {
@ -81,7 +81,7 @@ export const getLiquidityPoolPayouts = (
}
export const getMktFixedPayouts = (
contract: FullContract<FixedPayouts, Binary>,
contract: CPMMContract,
bets: Bet[],
liquidities: LiquidityProvision[],
resolutionProbability?: number
@ -116,7 +116,7 @@ export const getMktFixedPayouts = (
}
export const getLiquidityPoolProbPayouts = (
contract: FullContract<CPMM, Binary>,
contract: CPMMContract,
p: number,
liquidities: LiquidityProvision[]
) => {

View File

@ -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<FixedPayouts, Binary>,
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<DPM, Multi | FreeResponse>,
openBets
)
? getPayoutsMultiOutcome(resolutions, contract, openBets)
: getDpmMktPayouts(contract, openBets, resolutionProbability)
case 'CANCEL':
case undefined:
return getDpmCancelPayouts(contract, openBets)
default:

View File

@ -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<any, Binary>,
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) => {

View File

@ -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<DPM, any>,
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<CPMM, Binary>,
contract: CPMMContract,
prevLoanAmount: number,
newBetId: string
) => {

View File

@ -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<DPM, FreeResponse>,
loanAmount
)
getNewMultiBetInfo(answerId, amount, contract, loanAmount)
const newBalance = user.balance - amount
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 {
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<DPM, Binary>,
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<CPMM, Binary>,
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<DPM, FreeResponse>,
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<DPM, Numeric>,
contract as NumericContract,
ante,
anteBetDoc.id
)

View File

@ -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<CPMM, Binary>
const contract = contractSnap.data() as Contract
if (contract.outcomeType !== 'BINARY' || contract.mechanism !== 'cpmm-1')
return { status: 'success' }

View File

@ -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<DPM, Binary>
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<DPM, Binary>
)
const contracts = snapshot.docs.map((doc) => doc.data() as DPMBinaryContract)
console.log('Loaded contracts', contracts.length)

View File

@ -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<DPM, Binary>
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<CPMM, Binary>,
} as CPMMBinaryContract,
liquidityDocRef.id,
ante
)

View File

@ -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<DPM, Binary>
const contract = contractDoc.data() as DPMBinaryContract
const betDocs = await transaction.get(contractRef.collection('bets'))
const bets = sortBy(

View File

@ -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<CPMM, Binary>
const contract = contractSnap.data() as BinaryContract
const { closeTime, mechanism, collectedFees, volume } = contract
if (mechanism !== 'cpmm-1')

View File

@ -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<DPM, FreeResponse>
contract: FreeResponseContract
closePanel: () => void
className?: string
isModal?: boolean

View File

@ -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<DPM, FreeResponse>
contract: FreeResponseContract
showChoice: 'radio' | 'checkbox' | undefined
chosenProb: number | undefined
totalChosenProb?: number

View File

@ -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<DPM, FreeResponse>
contract: Contract & FreeResponse
resolveOption: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined
setResolveOption: (
option: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined

View File

@ -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<DPM, FreeResponse>
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<DPM, FreeResponse>
) => {
const computeProbsByOutcome = (bets: Bet[], contract: FreeResponseContract) => {
const { totalBets } = contract
const betsByOutcome = groupBy(bets, (bet) => bet.outcome)

View File

@ -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<DPM, FreeResponse>
}) {
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<DPM, FreeResponse>,
contract: FreeResponseContract,
answers: Answer[],
user: User | undefined | null
) {
@ -182,7 +180,7 @@ function getAnswerItems(
}
function OpenAnswer(props: {
contract: FullContract<any, FreeResponse>
contract: FreeResponseContract
answer: Answer
items: ActivityItem[]
type: string

View File

@ -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<DPM, FreeResponse>
}) {
export function CreateAnswerPanel(props: { contract: FreeResponseContract }) {
const { contract } = props
const user = useUser()
const [text, setText] = useState('')

View File

<
@ -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<DPM | CPMM, Binary>
contract: BinaryContract
className?: string
}) {
const { contract, className } = props
@ -78,7 +78,7 @@ export function BetPanel(props: {
}
export function BetPanelSwitcher(props: {
contract: FullContract<DPM | CPMM, Binary>
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 && (
<SellPanel
contract={contract as FullContract<CPMM, Binary>}
shares={yesShares || noShares}
sharesOutcome={sharesOutcome}
user={user}
userBets={userBets ?? []}
onSellSuccess={onBetSuccess}
/>
)}
{tradeType === 'SELL' &&
mechanism == 'cpmm-1' &&
user &&
sharesOutcome && (
<SellPanel
contract={contract}
shares={yesShares || noShares}
sharesOutcome={sharesOutcome}
user={user}
userBets={userBets ?? []}
onSellSuccess={onBetSuccess}