@@ -287,13 +287,19 @@ export async function createTokenSwap(): Promise<void> {
287287 assert ( CURVE_TYPE == fetchedTokenSwap . curveType ) ;
288288}
289289
290- export async function deposit ( ) : Promise < void > {
290+ export async function depositAllTokenTypes ( ) : Promise < void > {
291291 const poolMintInfo = await tokenPool . getMintInfo ( ) ;
292292 const supply = poolMintInfo . supply . toNumber ( ) ;
293293 const swapTokenA = await mintA . getAccountInfo ( tokenAccountA ) ;
294- const tokenA = Math . floor ( ( swapTokenA . amount . toNumber ( ) * POOL_TOKEN_AMOUNT ) / ( supply + POOL_TOKEN_AMOUNT ) ) ;
294+ const tokenA = Math . floor (
295+ ( swapTokenA . amount . toNumber ( ) * POOL_TOKEN_AMOUNT ) /
296+ ( supply + POOL_TOKEN_AMOUNT ) ,
297+ ) ;
295298 const swapTokenB = await mintB . getAccountInfo ( tokenAccountB ) ;
296- const tokenB = Math . floor ( ( swapTokenB . amount . toNumber ( ) * POOL_TOKEN_AMOUNT ) / ( supply + POOL_TOKEN_AMOUNT ) ) ;
299+ const tokenB = Math . floor (
300+ ( swapTokenB . amount . toNumber ( ) * POOL_TOKEN_AMOUNT ) /
301+ ( supply + POOL_TOKEN_AMOUNT ) ,
302+ ) ;
297303
298304 console . log ( 'Creating depositor token a account' ) ;
299305 const userAccountA = await mintA . createAccount ( owner . publicKey ) ;
@@ -307,7 +313,7 @@ export async function deposit(): Promise<void> {
307313 const newAccountPool = await tokenPool . createAccount ( owner . publicKey ) ;
308314
309315 console . log ( 'Depositing into swap' ) ;
310- await tokenSwap . deposit (
316+ await tokenSwap . depositAllTokenTypes (
311317 userAccountA ,
312318 userAccountB ,
313319 newAccountPool ,
@@ -331,7 +337,7 @@ export async function deposit(): Promise<void> {
331337 assert ( info . amount . toNumber ( ) == POOL_TOKEN_AMOUNT ) ;
332338}
333339
334- export async function withdraw ( ) : Promise < void > {
340+ export async function withdrawAllTokenTypes ( ) : Promise < void > {
335341 const poolMintInfo = await tokenPool . getMintInfo ( ) ;
336342 const supply = poolMintInfo . supply . toNumber ( ) ;
337343 let swapTokenA = await mintA . getAccountInfo ( tokenAccountA ) ;
@@ -366,7 +372,7 @@ export async function withdraw(): Promise<void> {
366372 ) ;
367373
368374 console . log ( 'Withdrawing pool tokens for A and B tokens' ) ;
369- await tokenSwap . withdraw (
375+ await tokenSwap . withdrawAllTokenTypes (
370376 userAccountA ,
371377 userAccountB ,
372378 tokenAccountPool ,
@@ -463,6 +469,12 @@ export async function createAccountAndSwapAtomic(): Promise<void> {
463469 owner ,
464470 newAccount ,
465471 ) ;
472+
473+ let info ;
474+ info = await mintA . getAccountInfo ( tokenAccountA ) ;
475+ currentSwapTokenA = info . amount . toNumber ( ) ;
476+ info = await mintB . getAccountInfo ( tokenAccountB ) ;
477+ currentSwapTokenB = info . amount . toNumber ( ) ;
466478}
467479
468480export async function swap ( ) : Promise < void > {
@@ -515,3 +527,163 @@ export async function swap(): Promise<void> {
515527 assert ( info . amount . toNumber ( ) == HOST_SWAP_FEE ) ;
516528 }
517529}
530+
531+ function tradingTokensToPoolTokens (
532+ sourceAmount : number ,
533+ swapSourceAmount : number ,
534+ poolAmount : number ,
535+ ) : number {
536+ const tradingFee =
537+ ( sourceAmount / 2 ) * ( TRADING_FEE_NUMERATOR / TRADING_FEE_DENOMINATOR ) ;
538+ const sourceAmountPostFee = sourceAmount - tradingFee ;
539+ const root = Math . sqrt ( sourceAmountPostFee / swapSourceAmount + 1 ) ;
540+ return Math . floor ( poolAmount * ( root - 1 ) ) ;
541+ }
542+
543+ export async function depositSingleTokenTypeExactAmountIn ( ) : Promise < void > {
544+ // Pool token amount to deposit on one side
545+ const depositAmount = 10000 ;
546+
547+ const poolMintInfo = await tokenPool . getMintInfo ( ) ;
548+ const supply = poolMintInfo . supply . toNumber ( ) ;
549+ const swapTokenA = await mintA . getAccountInfo ( tokenAccountA ) ;
550+ const poolTokenA = tradingTokensToPoolTokens (
551+ depositAmount ,
552+ swapTokenA . amount . toNumber ( ) ,
553+ supply ,
554+ ) ;
555+ const swapTokenB = await mintB . getAccountInfo ( tokenAccountB ) ;
556+ const poolTokenB = tradingTokensToPoolTokens (
557+ depositAmount ,
558+ swapTokenB . amount . toNumber ( ) ,
559+ supply ,
560+ ) ;
561+
562+ console . log ( 'Creating depositor token a account' ) ;
563+ const userAccountA = await mintA . createAccount ( owner . publicKey ) ;
564+ await mintA . mintTo ( userAccountA , owner , [ ] , depositAmount ) ;
565+ await mintA . approve ( userAccountA , authority , owner , [ ] , depositAmount ) ;
566+ console . log ( 'Creating depositor token b account' ) ;
567+ const userAccountB = await mintB . createAccount ( owner . publicKey ) ;
568+ await mintB . mintTo ( userAccountB , owner , [ ] , depositAmount ) ;
569+ await mintB . approve ( userAccountB , authority , owner , [ ] , depositAmount ) ;
570+ console . log ( 'Creating depositor pool token account' ) ;
571+ const newAccountPool = await tokenPool . createAccount ( owner . publicKey ) ;
572+
573+ console . log ( 'Depositing token A into swap' ) ;
574+ await tokenSwap . depositSingleTokenTypeExactAmountIn (
575+ userAccountA ,
576+ newAccountPool ,
577+ depositAmount ,
578+ poolTokenA ,
579+ ) ;
580+
581+ let info ;
582+ info = await mintA . getAccountInfo ( userAccountA ) ;
583+ assert ( info . amount . toNumber ( ) == 0 ) ;
584+ info = await mintA . getAccountInfo ( tokenAccountA ) ;
585+ assert ( info . amount . toNumber ( ) == currentSwapTokenA + depositAmount ) ;
586+ currentSwapTokenA += depositAmount ;
587+
588+ console . log ( 'Depositing token B into swap' ) ;
589+ await tokenSwap . depositSingleTokenTypeExactAmountIn (
590+ userAccountB ,
591+ newAccountPool ,
592+ depositAmount ,
593+ poolTokenB ,
594+ ) ;
595+
596+ info = await mintB . getAccountInfo ( userAccountB ) ;
597+ assert ( info . amount . toNumber ( ) == 0 ) ;
598+ info = await mintB . getAccountInfo ( tokenAccountB ) ;
599+ assert ( info . amount . toNumber ( ) == currentSwapTokenB + depositAmount ) ;
600+ currentSwapTokenB += depositAmount ;
601+ info = await tokenPool . getAccountInfo ( newAccountPool ) ;
602+ assert ( info . amount . toNumber ( ) >= poolTokenA + poolTokenB ) ;
603+ }
604+
605+ export async function withdrawSingleTokenTypeExactAmountOut ( ) : Promise < void > {
606+ // Pool token amount to withdraw on one side
607+ const withdrawAmount = 50000 ;
608+ const roundingAmount = 1.0001 ; // make math a little easier
609+
610+ const poolMintInfo = await tokenPool . getMintInfo ( ) ;
611+ const supply = poolMintInfo . supply . toNumber ( ) ;
612+
613+ const swapTokenA = await mintA . getAccountInfo ( tokenAccountA ) ;
614+ const swapTokenAPost = swapTokenA . amount . toNumber ( ) - withdrawAmount ;
615+ const poolTokenA = tradingTokensToPoolTokens (
616+ withdrawAmount ,
617+ swapTokenAPost ,
618+ supply ,
619+ ) ;
620+ let adjustedPoolTokenA = poolTokenA * roundingAmount ;
621+ if ( OWNER_WITHDRAW_FEE_NUMERATOR !== 0 ) {
622+ adjustedPoolTokenA *=
623+ 1 + OWNER_WITHDRAW_FEE_NUMERATOR / OWNER_WITHDRAW_FEE_DENOMINATOR ;
624+ }
625+
626+ const swapTokenB = await mintB . getAccountInfo ( tokenAccountB ) ;
627+ const swapTokenBPost = swapTokenB . amount . toNumber ( ) - withdrawAmount ;
628+ const poolTokenB = tradingTokensToPoolTokens (
629+ withdrawAmount ,
630+ swapTokenBPost ,
631+ supply ,
632+ ) ;
633+ let adjustedPoolTokenB = poolTokenB * roundingAmount ;
634+ if ( OWNER_WITHDRAW_FEE_NUMERATOR !== 0 ) {
635+ adjustedPoolTokenB *=
636+ 1 + OWNER_WITHDRAW_FEE_NUMERATOR / OWNER_WITHDRAW_FEE_DENOMINATOR ;
637+ }
638+
639+ console . log ( 'Creating withdraw token a account' ) ;
640+ const userAccountA = await mintA . createAccount ( owner . publicKey ) ;
641+ console . log ( 'Creating withdraw token b account' ) ;
642+ const userAccountB = await mintB . createAccount ( owner . publicKey ) ;
643+ console . log ( 'Creating withdraw pool token account' ) ;
644+ const poolAccount = await tokenPool . getAccountInfo ( tokenAccountPool ) ;
645+ const poolTokenAmount = poolAccount . amount . toNumber ( ) ;
646+ await tokenPool . approve (
647+ tokenAccountPool ,
648+ authority ,
649+ owner ,
650+ [ ] ,
651+ adjustedPoolTokenA + adjustedPoolTokenB ,
652+ ) ;
653+
654+ console . log ( 'Withdrawing token A only' ) ;
655+ await tokenSwap . withdrawSingleTokenTypeExactAmountOut (
656+ userAccountA ,
657+ tokenAccountPool ,
658+ withdrawAmount ,
659+ adjustedPoolTokenA ,
660+ ) ;
661+
662+ let info ;
663+ info = await mintA . getAccountInfo ( userAccountA ) ;
664+ assert ( info . amount . toNumber ( ) == withdrawAmount ) ;
665+ info = await mintA . getAccountInfo ( tokenAccountA ) ;
666+ assert ( info . amount . toNumber ( ) == currentSwapTokenA - withdrawAmount ) ;
667+ currentSwapTokenA += withdrawAmount ;
668+ info = await tokenPool . getAccountInfo ( tokenAccountPool ) ;
669+ assert ( info . amount . toNumber ( ) >= poolTokenAmount - adjustedPoolTokenA ) ;
670+
671+ console . log ( 'Withdrawing token B only' ) ;
672+ await tokenSwap . withdrawSingleTokenTypeExactAmountOut (
673+ userAccountB ,
674+ tokenAccountPool ,
675+ withdrawAmount ,
676+ adjustedPoolTokenB ,
677+ ) ;
678+
679+ info = await mintB . getAccountInfo ( userAccountB ) ;
680+ assert ( info . amount . toNumber ( ) == withdrawAmount ) ;
681+ info = await mintB . getAccountInfo ( tokenAccountB ) ;
682+ assert ( info . amount . toNumber ( ) == currentSwapTokenB - withdrawAmount ) ;
683+ currentSwapTokenB += withdrawAmount ;
684+ info = await tokenPool . getAccountInfo ( tokenAccountPool ) ;
685+ assert (
686+ info . amount . toNumber ( ) >=
687+ poolTokenAmount - adjustedPoolTokenA - adjustedPoolTokenB ,
688+ ) ;
689+ }
0 commit comments