Set shares to equal each other

This commit is contained in:
Ian Philips 2022-07-21 15:15:15 -06:00
parent c8586e7703
commit 13aa1f9540
7 changed files with 66 additions and 49 deletions

View File

@ -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

View File

@ -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.')

View File

@ -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,

View File

@ -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>

View File

@ -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(),

View File

@ -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} />

View File

@ -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)}>