@@ -37,16 +37,17 @@ pub use pallet::*;
3737
3838#[ cfg( test) ]
3939mod mock;
40-
4140#[ cfg( test) ]
4241mod stable_swap_tests;
42+ #[ cfg( test) ]
43+ mod uniswap_tests;
4344
4445mod stable_swap;
4546mod uniswap;
4647
4748#[ frame_support:: pallet]
4849pub mod pallet {
49- use crate :: { uniswap:: Uniswap , PoolConfiguration :: ConstantProduct } ;
50+ use crate :: { stable_swap :: StableSwap , uniswap:: Uniswap , PoolConfiguration :: ConstantProduct } ;
5051 use codec:: { Codec , FullCodec } ;
5152 use composable_traits:: {
5253 currency:: { CurrencyFactory , LocalAssets } ,
@@ -67,8 +68,6 @@ pub mod pallet {
6768 Permill ,
6869 } ;
6970
70- use crate :: stable_swap:: StableSwap ;
71-
7271 #[ derive( RuntimeDebug , Encode , Decode , MaxEncodedLen , Clone , PartialEq , Eq , TypeInfo ) ]
7372 pub enum PoolInitConfiguration < AssetId > {
7473 StableSwap {
@@ -77,6 +76,11 @@ pub mod pallet {
7776 fee : Permill ,
7877 protocol_fee : Permill ,
7978 } ,
79+ ConstantProduct {
80+ pair : CurrencyPair < AssetId > ,
81+ fee : Permill ,
82+ owner_fee : Permill ,
83+ } ,
8084 }
8185
8286 #[ derive( RuntimeDebug , Encode , Decode , MaxEncodedLen , Clone , PartialEq , Eq , TypeInfo ) ]
@@ -93,6 +97,7 @@ pub mod pallet {
9397 PoolConfiguration < <T as frame_system:: Config >:: AccountId , <T as Config >:: AssetId > ;
9498 type PoolInitConfigurationOf < T > = PoolInitConfiguration < <T as Config >:: AssetId > ;
9599
100+ // TODO refactor event publishing with cu-23v2y3n
96101 #[ pallet:: event]
97102 #[ pallet:: generate_deposit( pub ( super ) fn deposit_event) ]
98103 pub enum Event < T : Config > {
@@ -416,13 +421,11 @@ pub mod pallet {
416421
417422 Ok ( pool_id)
418423 } ,
419- PoolInitConfiguration :: ConstantProduct ( constant_product_pool_info) =>
420- Uniswap :: < T > :: do_create_pool (
421- & constant_product_pool_info. owner ,
422- constant_product_pool_info. pair ,
423- constant_product_pool_info. fee ,
424- constant_product_pool_info. owner_fee ,
425- ) ,
424+ PoolInitConfiguration :: ConstantProduct { pair, fee, owner_fee } => {
425+ let pool_id = Uniswap :: < T > :: do_create_pool ( & who, pair, fee, owner_fee) ?;
426+ Self :: deposit_event ( Event :: PoolCreated { owner : who. clone ( ) , pool_id } ) ;
427+ Ok ( pool_id)
428+ } ,
426429 }
427430 }
428431
@@ -447,6 +450,10 @@ pub mod pallet {
447450 let base_amount = Self :: get_exchange_value ( pool_id, pair. base , quote_amount) ?;
448451 let base_amount_u: u128 = T :: Convert :: convert ( base_amount) ;
449452
453+ // https://uniswap.org/whitepaper.pdf
454+ // 3.2.1
455+ // we do not inflate the lp for the owner fees
456+ // cut is done before enforcing the invariant
450457 let ( lp_fee, protocol_fee) = if apply_fees {
451458 let lp_fee = fee. mul_floor ( base_amount_u) ;
452459 // protocol_fee is computed based on lp_fee
@@ -480,6 +487,7 @@ pub mod pallet {
480487 match pool {
481488 PoolConfiguration :: StableSwap ( stable_swap_pool_info) =>
482489 Ok ( stable_swap_pool_info. pair ) ,
490+ ConstantProduct ( constant_product_pool_info) => Ok ( constant_product_pool_info. pair ) ,
483491 }
484492 }
485493
@@ -498,6 +506,12 @@ pub mod pallet {
498506 asset_id,
499507 amount,
500508 ) ,
509+ ConstantProduct ( constant_product_pool_info) => Uniswap :: < T > :: get_exchange_value (
510+ constant_product_pool_info,
511+ pool_account,
512+ asset_id,
513+ amount,
514+ ) ,
501515 }
502516 }
503517
@@ -523,15 +537,34 @@ pub mod pallet {
523537 min_mint_amount,
524538 keep_alive,
525539 ) ?;
526- Self :: deposit_event ( Event :: < T > :: LiquidityAdded {
540+ Self :: deposit_event ( Event :: < T > :: LiquidityAddedToStableSwapPool {
527541 who : who. clone ( ) ,
528542 pool_id,
529543 base_amount,
530544 quote_amount,
531545 mint_amount,
532546 } ) ;
533547 } ,
548+ ConstantProduct ( constant_product_pool_info) => {
549+ let mint_amount = Uniswap :: < T > :: add_liquidity (
550+ who,
551+ constant_product_pool_info,
552+ pool_account,
553+ base_amount,
554+ quote_amount,
555+ min_mint_amount,
556+ keep_alive,
557+ ) ?;
558+ Self :: deposit_event ( Event :: < T > :: LiquidityAddedToConstantProductPool {
559+ who : who. clone ( ) ,
560+ pool_id,
561+ base_amount,
562+ quote_amount,
563+ minted_lp : mint_amount,
564+ } ) ;
565+ } ,
534566 }
567+ // TODO refactor event publishing with cu-23v2y3n
535568 Ok ( ( ) )
536569 }
537570
@@ -564,7 +597,25 @@ pub mod pallet {
564597 total_issuance : updated_lp,
565598 } ) ;
566599 } ,
600+ ConstantProduct ( constant_product_pool_info) => {
601+ let ( base_amount, quote_amount, updated_lp) = Uniswap :: < T > :: remove_liquidity (
602+ who,
603+ constant_product_pool_info,
604+ pool_account,
605+ lp_amount,
606+ min_base_amount,
607+ min_quote_amount,
608+ ) ?;
609+ Self :: deposit_event ( Event :: < T > :: LiquidityRemoved {
610+ pool_id,
611+ who : who. clone ( ) ,
612+ base_amount,
613+ quote_amount,
614+ total_issuance : updated_lp,
615+ } ) ;
616+ } ,
567617 }
618+ // TODO refactor event publishing with cu-23v2y3n
568619 Ok ( ( ) )
569620 }
570621
@@ -627,7 +678,53 @@ pub mod pallet {
627678
628679 Ok ( base_amount_excluding_fees)
629680 } ,
681+ ConstantProduct ( constant_product_pool_info) => {
682+ let ( base_amount, quote_amount, lp_fees, owner_fees) = Self :: do_compute_swap (
683+ pool_id,
684+ pair,
685+ quote_amount,
686+ true ,
687+ constant_product_pool_info. fee ,
688+ constant_product_pool_info. owner_fee ,
689+ ) ?;
690+ let total_fees = lp_fees. safe_add ( & owner_fees) ?;
691+ let quote_amount_including_fees = quote_amount. safe_add ( & total_fees) ?;
692+
693+ ensure ! ( base_amount >= min_receive, Error :: <T >:: CannotRespectMinimumRequested ) ;
694+
695+ let pool_account = Self :: account_id ( & pool_id) ;
696+ T :: Assets :: transfer (
697+ pair. quote ,
698+ who,
699+ & pool_account,
700+ quote_amount_including_fees,
701+ keep_alive,
702+ ) ?;
703+ // NOTE(hussein-aitlance): no need to keep alive the pool account
704+ T :: Assets :: transfer (
705+ pair. quote ,
706+ & pool_account,
707+ & constant_product_pool_info. owner ,
708+ owner_fees,
709+ false ,
710+ ) ?;
711+ T :: Assets :: transfer ( pair. base , & pool_account, who, base_amount, false ) ?;
712+
713+ Self :: deposit_event ( Event :: < T > :: Swapped {
714+ pool_id,
715+ who : who. clone ( ) ,
716+ base_asset : pair. base ,
717+ quote_asset : pair. quote ,
718+ base_amount,
719+ quote_amount,
720+ fee : total_fees,
721+ } ) ;
722+
723+ Ok ( base_amount)
724+ } ,
630725 }
726+
727+ // TODO refactor event publishing with cu-23v2y3n
631728 }
632729
633730 #[ transactional]
@@ -651,6 +748,15 @@ pub mod pallet {
651748 Self :: exchange ( who, pool_id, pair, dx, T :: Balance :: zero ( ) , keep_alive) ?;
652749 Ok ( amount)
653750 } ,
751+ ConstantProduct ( constant_product_pool) => {
752+ let pair = if asset_id == constant_product_pool. pair . base {
753+ constant_product_pool. pair
754+ } else {
755+ constant_product_pool. pair . swap ( )
756+ } ;
757+ let quote_amount = Self :: get_exchange_value ( pool_id, asset_id, amount) ?;
758+ Self :: exchange ( who, pool_id, pair, quote_amount, T :: Balance :: zero ( ) , keep_alive)
759+ } ,
654760 }
655761 }
656762
@@ -667,15 +773,15 @@ pub mod pallet {
667773 PoolConfiguration :: StableSwap ( pool) => {
668774 let pair =
669775 if asset_id == pool. pair . base { pool. pair . swap ( ) } else { pool. pair } ;
670- let dy = Self :: exchange (
671- who ,
672- pool_id ,
673- pair,
674- amount ,
675- Self :: Balance :: zero ( ) ,
676- keep_alive ,
677- ) ? ;
678- Ok ( dy )
776+ Self :: exchange ( who , pool_id , pair , amount , Self :: Balance :: zero ( ) , keep_alive )
777+ } ,
778+ ConstantProduct ( constant_product_pool ) => {
779+ let pair = if asset_id == constant_product_pool . pair . base {
780+ constant_product_pool . pair . swap ( )
781+ } else {
782+ constant_product_pool . pair
783+ } ;
784+ Self :: exchange ( who , pool_id , pair , amount , T :: Balance :: zero ( ) , keep_alive )
679785 } ,
680786 }
681787 }
0 commit comments