Set shares to equal each other
This commit is contained in:
parent
c8586e7703
commit
13aa1f9540
|
@ -11,7 +11,7 @@ export type Challenge = {
|
|||
message: string
|
||||
|
||||
// How much to put up
|
||||
amount: number
|
||||
creatorAmount: number
|
||||
|
||||
// YES or NO for now
|
||||
creatorsOutcome: string
|
||||
|
@ -49,6 +49,9 @@ export type Acceptance = {
|
|||
userName: string
|
||||
userAvatarUrl: string
|
||||
|
||||
// The amount acceptor put up
|
||||
amount: number
|
||||
|
||||
// The ID of the successful bet that tracks the money moved
|
||||
betId: string
|
||||
|
||||
|
|
|
@ -49,9 +49,13 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
|||
if (!creatorSnap.exists) throw new APIError(400, 'User not found.')
|
||||
const creator = creatorSnap.data() as User
|
||||
|
||||
const { amount, yourOutcome, creatorsOutcome, creatorsOutcomeProb } =
|
||||
const { creatorAmount, yourOutcome, creatorsOutcome, creatorsOutcomeProb } =
|
||||
challenge
|
||||
if (user.balance < amount) throw new APIError(400, 'Insufficient balance.')
|
||||
const yourCost =
|
||||
((1 - creatorsOutcomeProb) / creatorsOutcomeProb) * creatorAmount
|
||||
|
||||
if (user.balance < yourCost)
|
||||
throw new APIError(400, 'Insufficient balance.')
|
||||
|
||||
const { closeTime, outcomeType } = anyContract
|
||||
if (closeTime && Date.now() > closeTime)
|
||||
|
@ -61,22 +65,19 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
|||
|
||||
const contract = anyContract as CPMMBinaryContract
|
||||
const { YES: y, NO: n } = contract.pool
|
||||
const yourShares = (1 / (1 - creatorsOutcomeProb)) * amount
|
||||
const creatorShares = (1 / creatorsOutcomeProb) * amount
|
||||
const shares = (1 / creatorsOutcomeProb) * creatorAmount
|
||||
|
||||
const newYesShares = creatorsOutcome === 'YES' ? creatorShares : yourShares
|
||||
const newNoShares = creatorsOutcome === 'NO' ? creatorShares : yourShares
|
||||
const newPool = {
|
||||
YES: y + newYesShares,
|
||||
NO: n + newNoShares,
|
||||
YES: y + shares,
|
||||
NO: n + shares,
|
||||
}
|
||||
const probBefore = getCpmmProbability(contract.pool, contract.p)
|
||||
const probAfter = getCpmmProbability(newPool, contract.p)
|
||||
|
||||
const yourNewBet: CandidateBet = removeUndefinedProps({
|
||||
orderAmount: amount,
|
||||
amount: amount,
|
||||
shares: yourShares,
|
||||
orderAmount: yourCost,
|
||||
amount: yourCost,
|
||||
shares: shares,
|
||||
isCancelled: false,
|
||||
contractId: contract.id,
|
||||
outcome: yourOutcome,
|
||||
|
@ -98,9 +99,9 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
|||
log('Updated user balance.')
|
||||
|
||||
const creatorNewBet: CandidateBet = removeUndefinedProps({
|
||||
orderAmount: amount,
|
||||
amount: amount,
|
||||
shares: creatorShares,
|
||||
orderAmount: creatorAmount,
|
||||
amount: creatorAmount,
|
||||
shares: shares,
|
||||
isCancelled: false,
|
||||
contractId: contract.id,
|
||||
outcome: creatorsOutcome,
|
||||
|
@ -141,6 +142,7 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
|||
userId: user.id,
|
||||
betId: yourNewBetDoc.id,
|
||||
createdTime: Date.now(),
|
||||
amount: yourCost,
|
||||
userUsername: user.username,
|
||||
userName: user.name,
|
||||
userAvatarUrl: user.avatarUrl,
|
||||
|
@ -154,6 +156,7 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
|||
user,
|
||||
creator,
|
||||
challenge,
|
||||
yourCost,
|
||||
contract
|
||||
)
|
||||
log('Created notification.')
|
||||
|
|
|
@ -474,6 +474,7 @@ export const createChallengeAcceptedNotification = async (
|
|||
challenger: User,
|
||||
challengeCreator: User,
|
||||
challenge: Challenge,
|
||||
acceptedAmount: number,
|
||||
contract: Contract
|
||||
) => {
|
||||
const notificationRef = firestore
|
||||
|
@ -491,7 +492,7 @@ export const createChallengeAcceptedNotification = async (
|
|||
sourceUserName: challenger.name,
|
||||
sourceUserUsername: challenger.username,
|
||||
sourceUserAvatarUrl: challenger.avatarUrl,
|
||||
sourceText: challenge.amount.toString(),
|
||||
sourceText: acceptedAmount.toString(),
|
||||
sourceContractCreatorUsername: contract.creatorUsername,
|
||||
sourceContractTitle: contract.question,
|
||||
sourceContractSlug: contract.slug,
|
||||
|
|
|
@ -21,8 +21,9 @@ export function AcceptChallengeButton(props: {
|
|||
const [open, setOpen] = useState(false)
|
||||
const [errorText, setErrorText] = useState('')
|
||||
const [loading, setLoading] = useState(false)
|
||||
const yourProb = 1 - challenge.creatorsOutcomeProb
|
||||
|
||||
const { creatorsOutcomeProb, creatorAmount } = challenge
|
||||
const yourCost =
|
||||
((1 - creatorsOutcomeProb) / creatorsOutcomeProb) * creatorAmount
|
||||
useEffect(() => {
|
||||
setErrorText('')
|
||||
}, [open])
|
||||
|
@ -66,9 +67,7 @@ export function AcceptChallengeButton(props: {
|
|||
<Col className="w-full items-center justify-start gap-2">
|
||||
<Row className={'w-full justify-start gap-20'}>
|
||||
<span className={'min-w-[4rem] font-bold'}>Cost to you:</span>{' '}
|
||||
<span className={'text-red-500'}>
|
||||
{formatMoney(challenge.amount)}
|
||||
</span>
|
||||
<span className={'text-red-500'}>{formatMoney(yourCost)}</span>
|
||||
</Row>
|
||||
{/*<Row className={'w-full justify-start gap-8'}>*/}
|
||||
{/* <span className={'min-w-[4rem] font-bold'}>Probability:</span>{' '}*/}
|
||||
|
@ -84,7 +83,7 @@ export function AcceptChallengeButton(props: {
|
|||
</span>{' '}
|
||||
<Row className={'items-center justify-center'}>
|
||||
<span className={'text-primary'}>
|
||||
{formatMoney(challenge.amount / yourProb)}
|
||||
{formatMoney(challenge.creatorAmount)}
|
||||
</span>
|
||||
{/*<InfoTooltip text={"If you're right"} />*/}
|
||||
</Row>
|
||||
|
|
|
@ -46,7 +46,7 @@ export async function createChallenge(data: {
|
|||
slug,
|
||||
creatorId: creator.id,
|
||||
creatorUsername: creator.username,
|
||||
amount,
|
||||
creatorAmount: amount,
|
||||
contractSlug: contract.slug,
|
||||
contractId: contract.id,
|
||||
creatorsOutcome: outcome.toString(),
|
||||
|
|
|
@ -133,7 +133,7 @@ function ClosedChallengeContent(props: {
|
|||
const { resolution } = contract
|
||||
const {
|
||||
acceptances,
|
||||
amount,
|
||||
creatorAmount,
|
||||
creatorsOutcome,
|
||||
creatorsOutcomeProb,
|
||||
yourOutcome,
|
||||
|
@ -148,10 +148,13 @@ function ClosedChallengeContent(props: {
|
|||
setShowConfetti(true)
|
||||
}, [acceptances])
|
||||
const creatorWon = resolution === creatorsOutcome
|
||||
const amountWon = creatorWon ? acceptances[0].amount : creatorAmount
|
||||
const yourCost =
|
||||
((1 - creatorsOutcomeProb) / creatorsOutcomeProb) * creatorAmount
|
||||
|
||||
if (!user) return <LoadingIndicator />
|
||||
|
||||
const userWonCol = (user: User) => (
|
||||
const userWonCol = (user: User, amount: number) => (
|
||||
<Col className="w-full items-start justify-center gap-1 p-4">
|
||||
<Row className={'mb-2 w-full items-center justify-center gap-2'}>
|
||||
<span className={'mx-2 text-3xl'}>🥇</span>
|
||||
|
@ -171,7 +174,7 @@ function ClosedChallengeContent(props: {
|
|||
</Col>
|
||||
)
|
||||
|
||||
const userLostCol = (challenger: User) => (
|
||||
const userLostCol = (challenger: User, amount: number) => (
|
||||
<Col className="w-full items-start justify-center gap-1">
|
||||
{userRow(challenger)}
|
||||
<Row className={'w-full items-center justify-center'}>
|
||||
|
@ -186,23 +189,17 @@ function ClosedChallengeContent(props: {
|
|||
challenger: User,
|
||||
outcome: string,
|
||||
prob: number,
|
||||
lost?: boolean
|
||||
amount: number
|
||||
) => (
|
||||
<Col className="w-full items-start justify-center gap-1">
|
||||
{userRow(challenger)}
|
||||
<Row className={'w-full items-center justify-center'}>
|
||||
{!lost ? (
|
||||
<span className={'text-lg'}>
|
||||
is betting {formatMoney(amount)}
|
||||
{' on '}
|
||||
<BinaryOutcomeLabel outcome={outcome as any} /> at{' '}
|
||||
{Math.round(prob * 100)}%
|
||||
</span>
|
||||
) : (
|
||||
<span className={'text-lg'}>
|
||||
LOST <span className={'text-red-500'}>{formatMoney(amount)}</span>
|
||||
</span>
|
||||
)}
|
||||
<span className={'text-lg'}>
|
||||
is betting {formatMoney(amount)}
|
||||
{' on '}
|
||||
<BinaryOutcomeLabel outcome={outcome as any} /> at{' '}
|
||||
{Math.round(prob * 100)}%
|
||||
</span>
|
||||
</Row>
|
||||
</Col>
|
||||
)
|
||||
|
@ -242,10 +239,10 @@ function ClosedChallengeContent(props: {
|
|||
}
|
||||
>
|
||||
<Row className={'mt-4 w-full'}>
|
||||
{userWonCol(creatorWon ? creator : user)}
|
||||
{userWonCol(creatorWon ? creator : user, amountWon)}
|
||||
</Row>
|
||||
<Row className={'mt-4'}>
|
||||
{userLostCol(creatorWon ? user : creator)}
|
||||
{userLostCol(creatorWon ? user : creator, amountWon)}
|
||||
</Row>
|
||||
</Col>
|
||||
) : (
|
||||
|
@ -254,9 +251,14 @@ function ClosedChallengeContent(props: {
|
|||
'h-full w-full content-between justify-between gap-1 py-10 sm:flex-row'
|
||||
}
|
||||
>
|
||||
{userCol(creator, creatorsOutcome, creatorsOutcomeProb)}
|
||||
{userCol(
|
||||
creator,
|
||||
creatorsOutcome,
|
||||
creatorsOutcomeProb,
|
||||
creatorAmount
|
||||
)}
|
||||
<Col className="items-center justify-center py-4 text-xl">VS</Col>
|
||||
{userCol(user, yourOutcome, 1 - creatorsOutcomeProb)}
|
||||
{userCol(user, yourOutcome, 1 - creatorsOutcomeProb, yourCost)}
|
||||
</Col>
|
||||
)}
|
||||
<Spacer h={3} />
|
||||
|
@ -302,7 +304,7 @@ function OpenChallengeContent(props: {
|
|||
const { contract, challenge, creator, user, bets } = props
|
||||
const { question } = contract
|
||||
const {
|
||||
amount,
|
||||
creatorAmount,
|
||||
creatorId,
|
||||
creatorsOutcome,
|
||||
creatorsOutcomeProb,
|
||||
|
@ -331,11 +333,14 @@ function OpenChallengeContent(props: {
|
|||
|
||||
const isBinary = contract.outcomeType === 'BINARY'
|
||||
const isPseudoNumeric = contract.outcomeType === 'PSEUDO_NUMERIC'
|
||||
const yourCost =
|
||||
((1 - creatorsOutcomeProb) / creatorsOutcomeProb) * creatorAmount
|
||||
|
||||
const userColumn = (
|
||||
challenger: User | null | undefined,
|
||||
portfolioHistory: PortfolioMetrics[],
|
||||
outcome: string
|
||||
outcome: string,
|
||||
amount: number
|
||||
) => {
|
||||
const lastPortfolioMetrics = last(portfolioHistory)
|
||||
const prob =
|
||||
|
@ -408,12 +413,18 @@ function OpenChallengeContent(props: {
|
|||
'h-full max-h-[50vh] w-full content-between justify-between gap-1 py-10 sm:flex-row'
|
||||
}
|
||||
>
|
||||
{userColumn(creator, creatorPortfolioHistory, creatorsOutcome)}
|
||||
{userColumn(
|
||||
creator,
|
||||
creatorPortfolioHistory,
|
||||
creatorsOutcome,
|
||||
creatorAmount
|
||||
)}
|
||||
<Col className="items-center justify-center py-4 text-4xl">VS</Col>
|
||||
{userColumn(
|
||||
user?.id === creatorId ? undefined : user,
|
||||
portfolioHistory,
|
||||
yourOutcome
|
||||
yourOutcome,
|
||||
yourCost
|
||||
)}
|
||||
</Col>
|
||||
<Spacer h={3} />
|
||||
|
|
|
@ -205,7 +205,7 @@ function LinkSummaryRow(props: {
|
|||
</td>
|
||||
|
||||
<td className="px-5 py-4 font-medium text-gray-900">
|
||||
{formatMoney(link.amount)}
|
||||
{formatMoney(link.creatorAmount)}
|
||||
</td>
|
||||
<td
|
||||
className="relative px-5 py-4"
|
||||
|
@ -304,7 +304,7 @@ function PublicLinkSummaryRow(props: { link: Challenge; highlight: boolean }) {
|
|||
return (
|
||||
<tr id={link.slug} key={link.slug} className={className}>
|
||||
<td className="px-5 py-4 font-medium text-gray-900">
|
||||
{formatMoney(link.amount)}
|
||||
{formatMoney(link.creatorAmount)}
|
||||
</td>
|
||||
<td className="relative px-2 py-4">
|
||||
<SiteLink href={getChallengeUrl(link)}>
|
||||
|
|
Loading…
Reference in New Issue
Block a user