enable resolve MKT
This commit is contained in:
parent
87e7a2a6d1
commit
389e11db48
|
@ -24,7 +24,7 @@ export const resolveMarket = functions
|
|||
|
||||
const { outcome, contractId } = data
|
||||
|
||||
if (!['YES', 'NO', 'CANCEL'].includes(outcome))
|
||||
if (!['YES', 'NO', 'MKT', 'CANCEL'].includes(outcome))
|
||||
return { status: 'error', message: 'Invalid outcome' }
|
||||
|
||||
const contractDoc = firestore.doc(`contracts/${contractId}`)
|
||||
|
|
|
@ -357,11 +357,12 @@ function SellButton(props: { contract: Contract; bet: Bet }) {
|
|||
)
|
||||
}
|
||||
|
||||
function OutcomeLabel(props: { outcome: 'YES' | 'NO' | 'CANCEL' }) {
|
||||
function OutcomeLabel(props: { outcome: 'YES' | 'NO' | 'CANCEL' | 'MKT' }) {
|
||||
const { outcome } = props
|
||||
|
||||
if (outcome === 'YES') return <YesLabel />
|
||||
if (outcome === 'NO') return <NoLabel />
|
||||
if (outcome === 'MKT') return <MarketLabel />
|
||||
return <CancelLabel />
|
||||
}
|
||||
|
||||
|
@ -376,3 +377,7 @@ function NoLabel() {
|
|||
function CancelLabel() {
|
||||
return <span className="text-yellow-400">N/A</span>
|
||||
}
|
||||
|
||||
function MarketLabel() {
|
||||
return <span className="text-blue-400">MKT</span>
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ export const ContractOverview = (props: {
|
|||
const resolutionColor = {
|
||||
YES: 'text-primary',
|
||||
NO: 'text-red-400',
|
||||
MKT: 'text-blue-400',
|
||||
CANCEL: 'text-yellow-400',
|
||||
'': '', // Empty if unresolved
|
||||
}[contract.resolution || '']
|
||||
|
|
|
@ -44,6 +44,7 @@ function ContractCard(props: { contract: Contract }) {
|
|||
const resolutionColor = {
|
||||
YES: 'text-primary',
|
||||
NO: 'text-red-400',
|
||||
MKT: 'text-blue-400',
|
||||
CANCEL: 'text-yellow-400',
|
||||
'': '', // Empty if unresolved
|
||||
}[contract.resolution || '']
|
||||
|
@ -51,6 +52,7 @@ function ContractCard(props: { contract: Contract }) {
|
|||
const resolutionText = {
|
||||
YES: 'YES',
|
||||
NO: 'NO',
|
||||
MKT: 'MKT',
|
||||
CANCEL: 'N/A',
|
||||
'': '',
|
||||
}[contract.resolution || '']
|
||||
|
|
|
@ -20,7 +20,9 @@ export function ResolutionPanel(props: {
|
|||
}) {
|
||||
const { contract, className } = props
|
||||
|
||||
const [outcome, setOutcome] = useState<'YES' | 'NO' | 'CANCEL' | undefined>()
|
||||
const [outcome, setOutcome] = useState<
|
||||
'YES' | 'NO' | 'MKT' | 'CANCEL' | undefined
|
||||
>()
|
||||
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
const [error, setError] = useState<string | undefined>(undefined)
|
||||
|
@ -48,6 +50,8 @@ export function ResolutionPanel(props: {
|
|||
? 'bg-red-400 hover:bg-red-500'
|
||||
: outcome === 'CANCEL'
|
||||
? 'bg-yellow-400 hover:bg-yellow-500'
|
||||
: outcome === 'MKT'
|
||||
? 'bg-blue-400 hover:bg-blue-500'
|
||||
: 'btn-disabled'
|
||||
|
||||
return (
|
||||
|
@ -74,6 +78,11 @@ export function ResolutionPanel(props: {
|
|||
<>Winnings will be paid out to NO bettors. You earn 1% of the pool.</>
|
||||
) : outcome === 'CANCEL' ? (
|
||||
<>The pool will be returned to traders with no fees.</>
|
||||
) : outcome === 'MKT' ? (
|
||||
<>
|
||||
Traders will be paid out at the current implied probability. You
|
||||
earn 1% of the pool.
|
||||
</>
|
||||
) : (
|
||||
<>Resolving this market will immediately pay out traders.</>
|
||||
)}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import clsx from 'clsx'
|
||||
import React from 'react'
|
||||
import { Col } from './layout/col'
|
||||
import { Row } from './layout/row'
|
||||
|
||||
export function YesNoSelector(props: {
|
||||
|
@ -29,48 +30,60 @@ export function YesNoSelector(props: {
|
|||
}
|
||||
|
||||
export function YesNoCancelSelector(props: {
|
||||
selected: 'YES' | 'NO' | 'CANCEL' | undefined
|
||||
onSelect: (selected: 'YES' | 'NO' | 'CANCEL') => void
|
||||
selected: 'YES' | 'NO' | 'MKT' | 'CANCEL' | undefined
|
||||
onSelect: (selected: 'YES' | 'NO' | 'MKT' | 'CANCEL') => void
|
||||
className?: string
|
||||
btnClassName?: string
|
||||
}) {
|
||||
const { selected, onSelect, className } = props
|
||||
|
||||
const btnClassName = clsx('px-6', props.btnClassName)
|
||||
const btnClassName = clsx('px-6 flex-1', props.btnClassName)
|
||||
|
||||
return (
|
||||
<Row className={clsx('space-x-3', className)}>
|
||||
<Button
|
||||
color={selected === 'YES' ? 'green' : 'gray'}
|
||||
onClick={() => onSelect('YES')}
|
||||
className={btnClassName}
|
||||
>
|
||||
YES
|
||||
</Button>
|
||||
<Col>
|
||||
<Row className={clsx('space-x-3 w-full', className)}>
|
||||
<Button
|
||||
color={selected === 'YES' ? 'green' : 'gray'}
|
||||
onClick={() => onSelect('YES')}
|
||||
className={btnClassName}
|
||||
>
|
||||
YES
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
color={selected === 'NO' ? 'red' : 'gray'}
|
||||
onClick={() => onSelect('NO')}
|
||||
className={btnClassName}
|
||||
>
|
||||
NO
|
||||
</Button>
|
||||
<Button
|
||||
color={selected === 'NO' ? 'red' : 'gray'}
|
||||
onClick={() => onSelect('NO')}
|
||||
className={btnClassName}
|
||||
>
|
||||
NO
|
||||
</Button>
|
||||
</Row>
|
||||
|
||||
<Button
|
||||
color={selected === 'CANCEL' ? 'yellow' : 'gray'}
|
||||
onClick={() => onSelect('CANCEL')}
|
||||
className={btnClassName}
|
||||
>
|
||||
N/A
|
||||
</Button>
|
||||
</Row>
|
||||
<Row className={clsx('space-x-3 w-full', className)}>
|
||||
<Button
|
||||
color={selected === 'MKT' ? 'blue' : 'gray'}
|
||||
onClick={() => onSelect('MKT')}
|
||||
className={clsx(btnClassName, 'btn-sm')}
|
||||
>
|
||||
MKT
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
color={selected === 'CANCEL' ? 'yellow' : 'gray'}
|
||||
onClick={() => onSelect('CANCEL')}
|
||||
className={clsx(btnClassName, 'btn-sm')}
|
||||
>
|
||||
N/A
|
||||
</Button>
|
||||
</Row>
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
|
||||
function Button(props: {
|
||||
className?: string
|
||||
onClick?: () => void
|
||||
color: 'green' | 'red' | 'yellow' | 'gray'
|
||||
color: 'green' | 'red' | 'blue' | 'yellow' | 'gray'
|
||||
children?: any
|
||||
}) {
|
||||
const { className, onClick, children, color } = props
|
||||
|
@ -83,6 +96,7 @@ function Button(props: {
|
|||
color === 'green' && 'btn-primary',
|
||||
color === 'red' && 'bg-red-400 hover:bg-red-500',
|
||||
color === 'yellow' && 'bg-yellow-400 hover:bg-yellow-500',
|
||||
color === 'blue' && 'bg-blue-400 hover:bg-blue-500',
|
||||
color === 'gray' && 'text-gray-700 bg-gray-300 hover:bg-gray-400',
|
||||
className
|
||||
)}
|
||||
|
|
|
@ -37,27 +37,36 @@ export function calculateShares(
|
|||
export function calculatePayout(
|
||||
contract: Contract,
|
||||
bet: Bet,
|
||||
outcome: 'YES' | 'NO' | 'CANCEL'
|
||||
outcome: 'YES' | 'NO' | 'CANCEL' | 'MKT'
|
||||
) {
|
||||
const { amount, outcome: betOutcome, shares } = bet
|
||||
|
||||
if (outcome === 'CANCEL') return amount
|
||||
if (betOutcome !== outcome) return 0
|
||||
|
||||
const impliedProbabilility =
|
||||
contract.pool.YES ** 2 / (contract.pool.YES ** 2 + contract.pool.NO ** 2)
|
||||
|
||||
const p =
|
||||
outcome === 'MKT'
|
||||
? betOutcome === 'YES'
|
||||
? impliedProbabilility
|
||||
: 1 - impliedProbabilility
|
||||
: outcome === 'YES'
|
||||
? 1
|
||||
: 0
|
||||
|
||||
const { totalShares, totalBets } = contract
|
||||
|
||||
if (totalShares[outcome] === 0) return 0
|
||||
|
||||
const startPool = contract.startPool.YES + contract.startPool.NO
|
||||
const truePool = contract.pool.YES + contract.pool.NO - startPool
|
||||
|
||||
if (totalBets[outcome] <= truePool)
|
||||
return (amount / totalBets[outcome]) * truePool
|
||||
if (totalBets[betOutcome] <= truePool)
|
||||
return p * (amount / totalBets[betOutcome]) * truePool
|
||||
|
||||
const total = totalShares[outcome] - totalBets[outcome]
|
||||
const winningsPool = truePool - totalBets[outcome]
|
||||
const total = totalShares[betOutcome] - totalBets[betOutcome]
|
||||
const winningsPool = truePool - totalBets[betOutcome]
|
||||
|
||||
return (1 - fees) * (amount + ((shares - amount) / total) * winningsPool)
|
||||
return p * (1 - fees) * (amount + ((shares - amount) / total) * winningsPool)
|
||||
}
|
||||
|
||||
export function resolvedPayout(contract: Contract, bet: Bet) {
|
||||
|
|
|
@ -2,8 +2,8 @@ import { getFirestore } from '@firebase/firestore'
|
|||
import { initializeApp } from 'firebase/app'
|
||||
|
||||
// TODO: Reenable this when we have a way to set the Firebase db in dev
|
||||
// export const isProd = process.env.NODE_ENV === 'production'
|
||||
export const isProd = true
|
||||
export const isProd = process.env.NODE_ENV === 'production'
|
||||
// export const isProd = true
|
||||
|
||||
const firebaseConfig = isProd
|
||||
? {
|
||||
|
|
Loading…
Reference in New Issue
Block a user