From 13aa1f95402c5c53f172b3b9f1ba4d96ce7cc840 Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Thu, 21 Jul 2022 15:15:15 -0600 Subject: [PATCH] Set shares to equal each other --- common/challenge.ts | 5 +- functions/src/accept-challenge.ts | 31 +++++----- functions/src/create-notification.ts | 3 +- .../challenges/accept-challenge-button.tsx | 11 ++-- web/lib/firebase/challenges.ts | 2 +- .../[contractSlug]/[challengeSlug].tsx | 59 +++++++++++-------- web/pages/challenges/index.tsx | 4 +- 7 files changed, 66 insertions(+), 49 deletions(-) diff --git a/common/challenge.ts b/common/challenge.ts index 2cafe019..5900743a 100644 --- a/common/challenge.ts +++ b/common/challenge.ts @@ -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 diff --git a/functions/src/accept-challenge.ts b/functions/src/accept-challenge.ts index a43afa9a..0720e71d 100644 --- a/functions/src/accept-challenge.ts +++ b/functions/src/accept-challenge.ts @@ -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.') diff --git a/functions/src/create-notification.ts b/functions/src/create-notification.ts index 480d72b1..6cc7631e 100644 --- a/functions/src/create-notification.ts +++ b/functions/src/create-notification.ts @@ -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, diff --git a/web/components/challenges/accept-challenge-button.tsx b/web/components/challenges/accept-challenge-button.tsx index 27bb710e..a8490079 100644 --- a/web/components/challenges/accept-challenge-button.tsx +++ b/web/components/challenges/accept-challenge-button.tsx @@ -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: { Cost to you:{' '} - - {formatMoney(challenge.amount)} - + {formatMoney(yourCost)} {/**/} {/* Probability:{' '}*/} @@ -84,7 +83,7 @@ export function AcceptChallengeButton(props: { {' '} - {formatMoney(challenge.amount / yourProb)} + {formatMoney(challenge.creatorAmount)} {/**/} diff --git a/web/lib/firebase/challenges.ts b/web/lib/firebase/challenges.ts index 6413c65b..9a3e1972 100644 --- a/web/lib/firebase/challenges.ts +++ b/web/lib/firebase/challenges.ts @@ -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(), diff --git a/web/pages/challenges/[username]/[contractSlug]/[challengeSlug].tsx b/web/pages/challenges/[username]/[contractSlug]/[challengeSlug].tsx index 2aebaa18..50b36b69 100644 --- a/web/pages/challenges/[username]/[contractSlug]/[challengeSlug].tsx +++ b/web/pages/challenges/[username]/[contractSlug]/[challengeSlug].tsx @@ -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 - const userWonCol = (user: User) => ( + const userWonCol = (user: User, amount: number) => ( 🥇 @@ -171,7 +174,7 @@ function ClosedChallengeContent(props: { ) - const userLostCol = (challenger: User) => ( + const userLostCol = (challenger: User, amount: number) => ( {userRow(challenger)} @@ -186,23 +189,17 @@ function ClosedChallengeContent(props: { challenger: User, outcome: string, prob: number, - lost?: boolean + amount: number ) => ( {userRow(challenger)} - {!lost ? ( - - is betting {formatMoney(amount)} - {' on '} - at{' '} - {Math.round(prob * 100)}% - - ) : ( - - LOST {formatMoney(amount)} - - )} + + is betting {formatMoney(amount)} + {' on '} + at{' '} + {Math.round(prob * 100)}% + ) @@ -242,10 +239,10 @@ function ClosedChallengeContent(props: { } > - {userWonCol(creatorWon ? creator : user)} + {userWonCol(creatorWon ? creator : user, amountWon)} - {userLostCol(creatorWon ? user : creator)} + {userLostCol(creatorWon ? user : creator, amountWon)} ) : ( @@ -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 + )} VS - {userCol(user, yourOutcome, 1 - creatorsOutcomeProb)} + {userCol(user, yourOutcome, 1 - creatorsOutcomeProb, yourCost)} )} @@ -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 + )} VS {userColumn( user?.id === creatorId ? undefined : user, portfolioHistory, - yourOutcome + yourOutcome, + yourCost )} diff --git a/web/pages/challenges/index.tsx b/web/pages/challenges/index.tsx index 6b8f20e2..4add5fab 100644 --- a/web/pages/challenges/index.tsx +++ b/web/pages/challenges/index.tsx @@ -205,7 +205,7 @@ function LinkSummaryRow(props: { - {formatMoney(link.amount)} + {formatMoney(link.creatorAmount)} - {formatMoney(link.amount)} + {formatMoney(link.creatorAmount)}