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:
parent
30adb5e1f8
commit
7c4ec2a8e3
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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[]
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
|
@ -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
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -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' }
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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('')
|
||||||
|
|
|
@ -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,9 +157,12 @@ 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' &&
|
||||||
|
mechanism == 'cpmm-1' &&
|
||||||
|
user &&
|
||||||
|
sharesOutcome && (
|
||||||
<SellPanel
|
<SellPanel
|
||||||
contract={contract as FullContract<CPMM, Binary>}
|
contract={contract}
|
||||||
shares={yesShares || noShares}
|
shares={yesShares || noShares}
|
||||||
sharesOutcome={sharesOutcome}
|
sharesOutcome={sharesOutcome}
|
||||||
user={user}
|
user={user}
|
||||||
|
@ -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'
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,9 +291,8 @@ 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
|
||||||
|
@ -304,12 +302,16 @@ function MyContractBets(props: {
|
||||||
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}
|
||||||
|
|
|
@ -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
|
||||||
}) {
|
}) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}) {
|
}) {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>,
|
|
||||||
bets,
|
|
||||||
comments,
|
|
||||||
user,
|
|
||||||
{
|
|
||||||
sortByProb: false,
|
sortByProb: false,
|
||||||
abbreviated: true,
|
abbreviated: true,
|
||||||
reversed: 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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}>
|
||||||
|
|
|
@ -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(() => {
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 && (
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user